Skip to content

feat(attestor): tpm-quote — measured-boot + TPM2 quote bound to build id #274

Description

@colek42

Summary

Add a tpm-quote attestor that anchors a build to a physical or virtual TPM 2.0: it captures a TPM2_Quote over selected PCRs, the AK→EK→manufacturer-root certificate chain, and the TCG/UEFI event log, with the cilock collection/build id bound as the quote's qualifying nonce. This is the foundation of the hardware-root-of-trust track — the sibling cloud-attestation and command-run-ima issues build on it.

Why — the SLSA Build-Environment gap

Today rookery can attest the cloud's word on instance identity (aws-iid, gcp-iit), but nothing produces a hardware-measured boot quote. That is precisely the gap at SLSA Build-Environment L2/L3:

  • BuildEnv L2 (attested instantiation): signed reference values for bootloader, guest kernel, build agent, root filesystem; Secure Boot + vTPM; a signed quote for the build environment's system state, bound to the build id.
  • BuildEnv L3 (hardware-attested): TPM / confidential computing; a signed quote for the host boot process and the environment's system state from trusted hardware.

tpm-quote is the attestor that produces this evidence, and a Rego gate makes a verifier reject a build whose measured boot diverges from signed golden values.

Design

  • Name: tpm-quote · Type: https://aflock.ai/attestations/tpm-quote/v0.1
  • Collects: TPM2_Quote over PCRs (e.g. 0=firmware, 1=config, 7=SecureBoot, 10=IMA/kernel; configurable bank SHA-256/384), AK public + cert chain, EK public + cert chain to the manufacturer root, the TCG event log (/sys/kernel/security/tpm0/binary_bios_measurements), and the quote signature (RSASSA-PSS / ECDSA).
  • Nonce binding: the quote's qualifying data = sha256(collection_id) so the quote is provably for this build run (anti-replay).
  • Subjects: tpm-ek-pubkey-hash:<alg>:<digest> (binds the TPM hardware), tpm-ak-pubkey-hash:…, tpm-event-log-digest:….
  • Fits the existing attestor pattern (plugins/attestors/aws-iid): init()RegisterAttestation, Attest(ctx), Subjects(), Schema(), predicate struct with json tags.

Predicate sketch

{
  "ak_public": "<b64>", "ak_cert_chain": ["<pem>", ""],
  "ek_public": "<b64>", "ek_cert_chain": ["<pem>", ""],
  "pcr_bank": "sha256", "pcr_indices": [0,1,7,10],
  "quoted_pcrs": { "0": "<b64>", "7": "<b64>", "10": "<b64>" },
  "quote_blob": "<b64 TPMS_ATTEST>", "quote_signature": "<b64>",
  "nonce": "<sha256(build_id)>",
  "event_log_raw": "<b64 TCG log>",
  "platform_type": "physical|aws-nitro|gcp-cvm|azure-cvm|kvm"
}

Verification (RegoV0 gate)

  1. Validate AK cert → EK cert → manufacturer root (trust store); check validity window.
  2. Verify the quote signature over TPMS_ATTEST with the AK public key.
  3. Verify nonce == sha256(build_id) (freshness / binding).
  4. Replay the event log into simulated PCRs and confirm it reproduces quoted_pcrs.
  5. Compare against signed golden PCR reference values with a configurable drift allowance (firmware/Secure-Boot PCRs strict; IMA/PCR-10 handled by command-run-ima).

Libraries

github.com/google/go-tpm/tpm2, github.com/google/go-attestation/attest, github.com/google/go-tpm-tools/{client,server}; crypto/x509, crypto/rsa, crypto/ecdsa. Kernel: /sys/kernel/security/tpm0/binary_bios_measurements, /dev/tpmrm0.

Phased delivery

  • MVP: Linux TPM 2.0, TPM2_Quote over PCRs [0,1,7,10] with nonce binding; quote-signature + event-log-replay verification; predicate + unit tests with a mock TPM; RegoV0 gate (nonce + signature + replay).
  • P2: full AK→EK→manufacturer-root chain validation + embedded root store; multi-bank (SHA-256/384/512); vTPM cert retrieval (Nitro/GCP/Azure); signed golden-PCR baselines + drift policy.
  • P3: Secure Boot (PCR-7) policy; SEV-SNP / TDX quote support; event-log confidentiality filtering; freshness timeout.

Open questions

  • Mandatory vs optional PCRs, and how golden values are indexed (platform × env × PCR) vs fuzzy-matched.
  • Manufacturer-root trust: embed frozen roots (offline verify) vs fetch (rotation).
  • AK lifecycle: persistent pinned AK (theft risk) vs ephemeral per-build AK (TPM storage/perf).
  • Event-log confidentiality (proprietary firmware measurements) before shipping the predicate.

Part of the hardware-root-of-trust track. Closes the BuildEnv L2/L3 gap noted in Judge's SLSA posture analysis. Spec refs: SLSA Build-Environment track (draft).

Filed by an AI agent at Cole's request; design researched against the SLSA draft + TPM 2.0 / go-attestation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ai-agentAuthored or edited by an AI agentenhancementNew feature or requestrelease-hardeningSupply-chain integrity hardening for cilock releasessecuritySecurity hardening / vulnerability mitigation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions