Current behavior
verify_attestation_chain() documents platform-specific hardware-signature dispatch. At current main (eb747f5fd610a8d7fa360e52faaea5db578e6b34) the dispatch is:
platform = getattr(report, "platform", "") or ""
if platform == "intel-tdx":
signature = _verify_tdx_signature_step(...)
elif platform in ("tpm", "aws-nitro"):
signature = _verify_tpm_signature_step(...)
else:
signature = _verify_snp_signature_step(...)
The else is therefore not "SEV-SNP"; it is every other string, including typos, unsupported future values, opaque, and an empty/unknown label.
That matters because the backend does not independently re-check the report's platform label. Given otherwise valid SNP report bytes, VCEK material, matching report_data, and no rejecting measurement policy, changing only AttestationReport.platform from "amd-sev-snp" to an unsupported value still selects the SNP verification path.
The existing full-pass SNP test provides a direct mutation control: its cryptographic evidence does not depend on the Python platform string, so the label and the verification backend are currently separable.
Why this is security-relevant
The result object reports one overall passed boolean and signature status. A caller can therefore receive a successful SNP cryptographic appraisal attached to a report whose declared platform says something else.
This is a platform-dispatch/binding problem, not a claim that the SNP signature itself can be forged.
It is also inconsistent with the repository's own provider boundary:
SEVSNPProvider emits platform="amd-sev-snp";
TDXProvider emits platform="intel-tdx";
- Azure has its own
azure-cvm-sev-snp path because its manifest binding is vTPM-rooted rather than direct guest-controlled SNP REPORT_DATA;
OPAQUEProvider is documented as not implemented and fail-closed at construction.
An unsupported platform label should not silently inherit the SNP verifier merely by falling through the dispatch.
Expected invariant
The selected verification procedure must be authorized by the declared platform/profile. Unknown or unsupported platform values must fail closed rather than be interpreted as a known backend.
I am intentionally not choosing whether the result should use FAILED, NOT_IMPLEMENTED, or a distinct unsupported-platform status. That result vocabulary is a maintainer decision.
Suggested narrow direction
Use explicit platform-to-verifier dispatch for every supported platform and an explicit fail-closed branch for everything else. Keep Azure's distinct binding model distinct from direct SEV-SNP rather than folding it into the same default.
Also update the AttestationReport.platform field comment, whose current illustrative values ("tpm" | "sev-snp" | "tdx" | "opaque") no longer match the concrete labels emitted by the providers.
Regression matrix
- valid
amd-sev-snp + valid SNP evidence -> existing result;
- same exact evidence with
platform="opaque" -> must not pass as SNP;
- same with unknown/empty/future platform label -> fail closed;
- valid
intel-tdx -> existing TDX path unchanged;
- valid TPM/AWS Nitro -> existing TPM path unchanged;
- Azure label remains governed by its vTPM-rooted verification semantics rather than direct SNP fallback.
No hardware signature algorithm, certificate chain, manifest hash pre-image, or platform trust root is changed by this issue. The correction is explicit backend selection and platform/evidence binding.
Current behavior
verify_attestation_chain()documents platform-specific hardware-signature dispatch. At currentmain(eb747f5fd610a8d7fa360e52faaea5db578e6b34) the dispatch is:The
elseis therefore not "SEV-SNP"; it is every other string, including typos, unsupported future values,opaque, and an empty/unknown label.That matters because the backend does not independently re-check the report's platform label. Given otherwise valid SNP report bytes, VCEK material, matching
report_data, and no rejecting measurement policy, changing onlyAttestationReport.platformfrom"amd-sev-snp"to an unsupported value still selects the SNP verification path.The existing full-pass SNP test provides a direct mutation control: its cryptographic evidence does not depend on the Python
platformstring, so the label and the verification backend are currently separable.Why this is security-relevant
The result object reports one overall
passedboolean and signature status. A caller can therefore receive a successful SNP cryptographic appraisal attached to a report whose declared platform says something else.This is a platform-dispatch/binding problem, not a claim that the SNP signature itself can be forged.
It is also inconsistent with the repository's own provider boundary:
SEVSNPProvideremitsplatform="amd-sev-snp";TDXProvideremitsplatform="intel-tdx";azure-cvm-sev-snppath because its manifest binding is vTPM-rooted rather than direct guest-controlled SNPREPORT_DATA;OPAQUEProvideris documented as not implemented and fail-closed at construction.An unsupported platform label should not silently inherit the SNP verifier merely by falling through the dispatch.
Expected invariant
The selected verification procedure must be authorized by the declared platform/profile. Unknown or unsupported platform values must fail closed rather than be interpreted as a known backend.
I am intentionally not choosing whether the result should use
FAILED,NOT_IMPLEMENTED, or a distinct unsupported-platform status. That result vocabulary is a maintainer decision.Suggested narrow direction
Use explicit platform-to-verifier dispatch for every supported platform and an explicit fail-closed branch for everything else. Keep Azure's distinct binding model distinct from direct SEV-SNP rather than folding it into the same default.
Also update the
AttestationReport.platformfield comment, whose current illustrative values ("tpm" | "sev-snp" | "tdx" | "opaque") no longer match the concrete labels emitted by the providers.Regression matrix
amd-sev-snp+ valid SNP evidence -> existing result;platform="opaque"-> must not pass as SNP;intel-tdx-> existing TDX path unchanged;No hardware signature algorithm, certificate chain, manifest hash pre-image, or platform trust root is changed by this issue. The correction is explicit backend selection and platform/evidence binding.