/** * Minimal TPM 2.0 binary-format parser. * * The TPM marshals structured data as big-endian size-prefixed bytes — * distinct from CBOR / DER / JSON and wholly specific to the TCG's TPM * Structures specification. Verification of a TPM quote requires * extracting exactly three fields from the `TPMS_ATTEST` structure: * * - `magic` — 4-byte constant, must equal `TPM_GENERATED_VALUE`. * - `type` — 2-byte constant, `TPM_ST_ATTEST_QUOTE` for quotes. * - `qualifiedSigner` — length-prefixed `TPM2B_NAME`, identifies the AK. * - `extraData` — length-prefixed `TPM2B_DATA`, this is where * motebit threads the identity binding. * * We deliberately skip the remainder (clockInfo, firmwareVersion, the * attested quote body containing PCR digests) — motebit's claim is * about identity binding, not platform-state attestation. The body's * signature (produced by TPM2_Quote using the AK) covers the entire * serialized `TPMS_ATTEST`; any byte drift would invalidate it. * * Hand-rolled over `node-tpm2-pts`: the parser is ~80 LOC and covers * exactly our needs. Pulling a dep for that would cross a larger * attack surface than the struct we parse. * * References: * - TCG TPM 2.0 Library, Part 2: Structures — §10.12 `TPMS_ATTEST`. * - TCG TPM 2.0 Library, Part 1: Architecture — §36.1 `TPM2B_*` types. */ /** Constant magic value every TPM-signed attest carries. */ export declare const TPM_GENERATED_VALUE = 4283712327; /** `TPM_ST_ATTEST_QUOTE` — the structure-tag identifying a quote attestation. */ export declare const TPM_ST_ATTEST_QUOTE = 32792; /** * Parsed view of a `TPMS_ATTEST` structure's header + identity-binding * fields. Callers verify signature bytes against the full structure; * this view exposes only the fields participating in motebit's * verification rules. */ export interface TpmsAttest { /** Must equal `TPM_GENERATED_VALUE` (`0xff544347`). */ readonly magic: number; /** Structure tag, e.g. `TPM_ST_ATTEST_QUOTE`. */ readonly type: number; /** Qualified signer name — `TPM2B_NAME` bytes (hash-alg + digest). */ readonly qualifiedSigner: Uint8Array; /** Caller-supplied extra-data — `TPM2B_DATA` bytes. Identity binding lives here. */ readonly extraData: Uint8Array; /** The rest of the serialized body, kept so callers can re-verify the signature. */ readonly trailer: Uint8Array; } /** * Parse a TPM 2.0 `TPMS_ATTEST` structure. Throws on malformed input; * the outer `verify.ts` catches and converts to the fail-closed result * shape. * * Wire layout: * uint32 magic ; 4 bytes * uint16 type ; 2 bytes * TPM2B_NAME qualifiedSigner ; uint16 size || bytes * TPM2B_DATA extraData ; uint16 size || bytes * TPMS_CLOCK_INFO clockInfo ; 17 bytes (fixed) * uint64 firmwareVersion ; 8 bytes * TPMU_ATTEST attested ; variable, tag-specific * * We extract magic / type / qualifiedSigner / extraData and stash the * rest in `trailer` so the caller can reconstruct the full signed * bytes when verifying the AK signature. The caller retains the * original buffer; this view points into it via length-accurate * subarray copies. */ export declare function parseTpmsAttest(bytes: Uint8Array): TpmsAttest; /** * Build a minimal `TPMS_ATTEST` byte sequence for tests. * * Tests fabricate a valid-shape attest so the verifier's parsing + * extraData-binding code paths exercise without a real TPM. Production * minting lives in the Rust bridge — never call `composeTpmsAttest` * outside `__tests__/` or you'll drift from what a real TPM would sign. * * `trailer` defaults to a deterministic 17-byte clockInfo + 8-byte * firmwareVersion filler + 4-byte quote filler so the resulting bytes * pass the minimum-length check during parsing; tests that need the * real trailing fields can override. */ export declare function composeTpmsAttestForTest(input: { readonly magic?: number; readonly type?: number; readonly qualifiedSigner: Uint8Array; readonly extraData: Uint8Array; readonly trailer?: Uint8Array; }): Uint8Array; //# sourceMappingURL=tpm-parse.d.ts.map