//! Verify a sealed run's TEE evidence as a third party (SPEC ยง7.6): from the //! attestation, the challenge the verifier issued, and the platform's anchor, //! with nothing from the host that sealed it. //! //! ```text //! verify_run //! ``` //! //! For SEV-SNP evidence, `anchor.der` is the chip's VCEK, as AMD's KDS issues //! it. For TDX evidence, it is Intel's root CA certificate: the PCK anchor is //! derived from the chain the quote carries, checked to that root. The run is verified //! against the challenge, and must be refused against any other challenge and //! against none. Exits non-zero unless all three hold. use sandbox_attest::{Attestation, TeeKind}; use sandbox_runtime::verify_run_evidence; use sandbox_tee::policy::{TeeAnchor, TeePolicy}; fn main() { let args: Vec = std::env::args().collect(); let (Some(path), Some(challenge_hex), Some(vcek_path)) = (args.get(1), args.get(2), args.get(3)) else { eprintln!("usage: verify_run "); std::process::exit(2); }; let attestation: Attestation = serde_json::from_str(&std::fs::read_to_string(path).expect("read the attestation")).expect("an attestation"); let challenge: [u8; 32] = hex::decode(challenge_hex.trim()).ok().and_then(|v| v.try_into().ok()).expect("a 32-byte hex challenge"); let der = std::fs::read(vcek_path).expect("read the anchor"); let tee = attestation.tee.as_ref().expect("TEE evidence to verify"); let (anchor, policy) = match tee.kind { TeeKind::SevSnp => { let at = der.windows(4).position(|w| w == [0x03, 0x62, 0x00, 0x04]).expect("a P-384 point in the VCEK"); let vcek = p384::ecdsa::VerifyingKey::from_sec1_bytes(&der[at + 3..at + 3 + 97]).expect("a P-384 key"); (TeeAnchor::SevSnp(vcek), TeePolicy::sev_snp_baseline()) } TeeKind::Tdx => { let quote = hex::decode(tee.report_hex.as_ref().expect("the quote")).expect("a hex quote"); let now = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).expect("a clock").as_secs(); let pck = sandbox_tee::intel_pcs::pck_from_quote("e, &der, now).expect("a PCK chain to Intel's root"); (TeeAnchor::Tdx(pck), TeePolicy::tdx_baseline()) } TeeKind::ArmCca => panic!("no ArmCca verifier"), }; let verified = verify_run_evidence(&attestation, Some(&challenge), &policy, &anchor); let mut other = challenge; other[31] ^= 0x80; let refused_other = verify_run_evidence(&attestation, Some(&other), &policy, &anchor).is_err(); let refused_none = verify_run_evidence(&attestation, None, &policy, &anchor).is_err(); match &verified { Ok(v) => println!("verified: {:?} run, measurement {}", v.kind, hex::encode(v.measurement)), Err(e) => println!("NOT verified: {e}"), } println!("refused for another challenge: {refused_other}"); println!("refused without a challenge: {refused_none}"); if verified.is_err() || !refused_other || !refused_none { std::process::exit(1); } }