Skip to content

Harden SEV-SNP verifier: verify VCEK->ASK->ARK chain and make report_data binding fatal (port approach from ca2a) #384

Description

@imran-siddique

Summary

cmcp's SEV-SNP verifier (src/cmcp_verify/sev_snp.py) lags the equivalent in ca2a (src/ca2a_verify/sev_snp.py). ca2a already verifies the full VCEK -> ASK -> ARK chain to the AMD root, verifies the report signature with the VCEK key, and treats a report_data mismatch as fatal. cmcp does none of these. This is the same "verify-the-trust-anchor" class we care about: without chain verification the "measurement matches" check is self-referential, and a non-fatal report_data check means the confirmation-key binding / freshness is not enforced.

Current behavior (cmcp)

verify_sev_snp_measurement in src/cmcp_verify/sev_snp.py:

  1. report_data mismatch is non-fatal. Docstring: "report_data (nonce) if provided (mismatch is not fatal)." On mismatch the code simply omits report_data from verified_fields instead of failing. report_data carries the confirmation-key binding / freshness nonce, so when a value is expected a mismatch should fail closed.
  2. VCEK/VLEK cert-chain verification is not implemented (explicitly out of scope; always placed in unverified_fields). The report signature is never checked against the AMD root, so the "measurement matches" comparison hashes the report's own measurement field and compares it to the claim's own measurement string, both attacker-supplied.

Requested changes

  1. When report_data_hex is supplied and does not equal the report's report_data, set verified = False with PUBLIC_KEY_NOT_BOUND (binding) or ATTESTATION_STALE (freshness), as appropriate.
  2. Port ca2a's chain verification: fetch VCEK by chip_id + reported_tcb from AMD KDS, verify VCEK -> ASK -> ARK against a trusted AMD root, then verify the report signature over the report body with the VCEK key. ca2a/src/ca2a_verify/sev_snp.py is the reference implementation.
  3. Apply the same treatment to the TDX (Intel PCS/DCAP) and TPM paths.
  4. Guardrail: ensure the dispatcher can never return VERIFIED while vcek_cert_chain (or the TDX/TPM equivalent) is in unverified_fields -- only PARTIALLY_VERIFIED.

Notes

  • Keep the "software-only scope" language for dev-mode records; this is about not over-claiming on the hardware path.
  • Internal security-review finding; suggested triage: security / high for item 1 (quick fix), feature for item 2.

Metadata

Metadata

Assignees

No one assigned

    Labels

    securityThreat model, attack surface, OWASP

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions