diff --git a/oak_attestation/src/dice.rs b/oak_attestation/src/dice.rs index ddeed936ae1..e626751ac79 100644 --- a/oak_attestation/src/dice.rs +++ b/oak_attestation/src/dice.rs @@ -210,9 +210,10 @@ pub fn stage0_dice_data_to_proto(value: Stage0DiceData) -> anyhow::Result TeePlatform { match src { + oak_dice::evidence::TeePlatform::Unspecified => TeePlatform::Unspecified, oak_dice::evidence::TeePlatform::AmdSevSnp => TeePlatform::AmdSevSnp, oak_dice::evidence::TeePlatform::IntelTdx => TeePlatform::IntelTdx, - oak_dice::evidence::TeePlatform::Unspecified => TeePlatform::Unspecified, + oak_dice::evidence::TeePlatform::None => TeePlatform::None, } } diff --git a/oak_attestation_verification/src/verifier.rs b/oak_attestation_verification/src/verifier.rs index 003ff770a00..8f69200b525 100644 --- a/oak_attestation_verification/src/verifier.rs +++ b/oak_attestation_verification/src/verifier.rs @@ -37,7 +37,8 @@ use oak_proto_rust::oak::{ ApplicationLayerEndorsements, ApplicationLayerReferenceValues, AttestationResults, BinaryReferenceValue, CbData, CbEndorsements, CbReferenceValues, ContainerLayerData, ContainerLayerEndorsements, ContainerLayerReferenceValues, Endorsements, Evidence, - ExtractedEvidence, IntelTdxAttestationReport, IntelTdxReferenceValues, KernelLayerData, + ExtractedEvidence, FakeAttestationReport, InsecureReferenceValues, + IntelTdxAttestationReport, IntelTdxReferenceValues, KernelLayerData, KernelLayerEndorsements, KernelLayerReferenceValues, OakContainersData, OakContainersEndorsements, OakContainersReferenceValues, OakRestrictedKernelData, OakRestrictedKernelEndorsements, OakRestrictedKernelReferenceValues, ReferenceValues, @@ -142,6 +143,7 @@ pub fn verify( { Report::SevSnp(values) => values.report_data.as_ref(), Report::Tdx(values) => values.report_data.as_ref(), + Report::Fake(values) => values.report_data.as_ref(), }; // The report data contains 64 bytes by default, but we only use the first 32 bytes at the // moment. @@ -403,6 +405,14 @@ fn verify_intel_tdx_attestation_report( anyhow::bail!("needs implementation") } +/// Verifies a fake attestation report. +fn verify_fake_attestation_report( + _attestation_report_values: &FakeAttestationReport, + _reference_values: &InsecureReferenceValues, +) -> anyhow::Result<()> { + Ok(()) +} + /// Verifies the signature chain for the attestation report included in the root. fn verify_root_attestation_signature( _now_utc_millis: i64, @@ -431,6 +441,7 @@ fn verify_root_attestation_signature( verify_attestation_report_signature(&vcek, report) } TeePlatform::IntelTdx => anyhow::bail!("not supported"), + TeePlatform::None => Ok(()), } } @@ -456,6 +467,13 @@ fn verify_root_layer( .as_ref() .context("Intel TDX reference values not found")?, ), + Some(Report::Fake(report_values)) => verify_fake_attestation_report( + report_values, + reference_values + .insecure + .as_ref() + .context("insecure reference values not found")?, + ), None => Err(anyhow::anyhow!("no attestation report")), } } @@ -822,6 +840,20 @@ fn extract_root_values(root_layer: &RootLayerEvidence) -> anyhow::Result Err(anyhow::anyhow!("not supported")), + TeePlatform::None => { + // We use an unsigned, mostly empty AMD SEV-SNP attestation report as a fake when not + // running in a TEE. + let report = AttestationReport::ref_from(&root_layer.remote_attestation_report) + .context("invalid fake attestation report")?; + + report.validate().map_err(|msg| anyhow::anyhow!(msg))?; + + let report_data = report.data.report_data.as_ref().to_vec(); + + Ok(RootLayerData { + report: Some(Report::Fake(FakeAttestationReport { report_data })), + }) + } } } diff --git a/oak_attestation_verification/testdata/fake_evidence.binarypb b/oak_attestation_verification/testdata/fake_evidence.binarypb new file mode 100644 index 00000000000..83452e61088 Binary files /dev/null and b/oak_attestation_verification/testdata/fake_evidence.binarypb differ diff --git a/oak_attestation_verification/testdata/fake_evidence.textproto b/oak_attestation_verification/testdata/fake_evidence.textproto new file mode 100644 index 00000000000..68ab6a63c3d --- /dev/null +++ b/oak_attestation_verification/testdata/fake_evidence.textproto @@ -0,0 +1,21 @@ +# proto-file: proto/attestation/evidence.proto +# proto-message: oak.attestaton.v1.Evidence +# +# Attestation evidence generated when not running on a TEE. +# Generated on 9 Feb 2024. `fake_evidence.binarypb` is the same instance in +# serialized binary format. +root_layer { + platform: TEE_PLATFORM_NONE + remote_attestation_report: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000l\025\313\320C\030T\201i\347\024\300\363\023\241\306\' \003\317f\341\231\"\330D\306D2\r\336\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + eca_public_key: "\247\001\002\002T\355\215\321Z\334ux&\262\214\370*\232L\217\023\307\010.\007\0038.\004\201\002 \001!X \024\221\3475\317u\245\372\226\236uTX\307\323l\336\242y\206\305\357\r\244\036)(\036HZ\330\004\"X \023=\367r@\000\177\334\331<\014\034\345\336\006\223w\343\3125\335\263\243\201UFx\241\346n\030\036" +} +layers { + eca_certificate: "\204D\241\0018.\241\004RAsymmetricECDSA256Y\001\341\245\001x(ed8dd15adc757826b28cf82a9a4c8f13c7082e07\002x(2c315ded0740742804d1056ecca0a472feb87fc2:\000GDWXg\247\001\002\002T,1]\355\007@t(\004\321\005n\314\240\244r\376\270\177\302\0038.\004\201\002 \001!X \240Uo\306\246*;\275\357\340\033h\367\252\026\313\362\227\037\246\000\037\344\234g3b\351\343B\276\264\"X R\251\233+\363\340;\250\317Q-GD\005;y\263\327c\332\022\343e\013XQ\251l\2716\020\224:\000GDXB \000:\000GDZ\246:\000GD`\241:\000GDkX \223\004R\310\222\320\027gg\215ky^\312\302[\344\2152x\363[XQ)\024\353\362`]\371c:\000GDa\241:\000GDkX \215c\241+\037t\"\023\367\360\222\\\226\tZx\363\\\371JL\221\274\'\221\236D\252\312\311\026\035:\000GDb\241:\000GDkX \002\263\372yk\225:\363\271D\200\207p\260*\207\255\227\323w9\320\215\346\001m\"\203(8T<:\000GDc\241:\000GDkX *\247\3275\275\031\370-\0069\254A\334\207\r\342$\217\003=\005\231d\010}7\310\\,\2126\023:\000GDd\241:\000GDkX \001u>\274BEU\250\r5\255\252!\365\310\305\360\tH.\213\\\305\332\360I\274\033\277\376\274{:\000GDe\241:\000GDkX Z\200J\367\351\007t\222\332\302\342\333g\020\246\315\246\207\331]A\\rA\225\321\2051\010\"\261\260X@\251\022:\344\324\314o%\246\024-\373\274\331M\357\312{\325S\3153\261rch9\177\010J\027#\007\235\221q\253\005\2034\035:\233\\~\344\347$\'\265\271\\eYrg\263N\022\337\227\314\304W" +} +layers { + eca_certificate: "\204D\241\0018.\241\004RAsymmetricECDSA256Y\001\000\245\001x(2c315ded0740742804d1056ecca0a472feb87fc2\002x(824798eb43ead4d88ebc68ce6cdb52cfe1546b84:\000GDWXg\247\001\002\002T\202G\230\353C\352\324\330\216\274h\316l\333R\317\341Tk\204\0038.\004\201\002 \001!X \253\3322?Xq\375`^\214p\207\267\233\324Y\253F\216Kh\273\232\0363\\-\312\323\365\'A\"X M\032>?7\317\233A9\024\240$\376[\370\264\3118j{D\243?1\023\260\004\276\232 \306\016:\000GDXB \000:\000GD\\\241:\000GDf\241:\000GDkX \277u\264\344\262\306).\327s\244\347\372P\303\253\252\210\tf\315~V\257\220*\217\261\030\273\214}X@\375\334\177ks?\213\230n\321\222\007\331\"\225qk\210*\276|\343bg\214N\215\'\277\200\350\2325\362.t\t\002c\360Y\247BH\016\300\014s\205Z\r\007\375v\314q\234\347\013\240\006\243T\302" +} +application_keys { + encryption_public_key_certificate: "\204D\241\0018.\241\004RAsymmetricECDSA256Y\001\n\245\001x(824798eb43ead4d88ebc68ce6cdb52cfe1546b84\002x(d98d5083465d75e56b9554149efc002903a17cfb:\000GDWXD\246\001\001\002T\331\215P\203F]u\345k\225T\024\236\374\000)\003\241|\373\0038\036\004\201\005 \004!X \321\257x\257)\311e\365}\323R\202\033\'0\336YS\024\203\016G\200;\357\252\272\206FY\237d:\000GDXB \000:\000GD^\242:\000GDh\241:\000GDkX P>\323\307\242=\3354U_\227?Q\255~<.\301[\362aSv{\377\211j\260\024\301l\200:\000GDi\241:\000GDkX \033\336\262\213\304\362\020\333\233B\2421`\370\027\307\005\357\371\210\334g\302\342\350\356O\216\345\223RzX@\301\246?y\361\036G\321\013\232?\313;/\177\343\202C:\325$\016\221\270\031A\377\204pZ|+\371\345\304\320\363\343M\216P\026\242\373\344<\037;/\332.\311\321#%\344\006!\006\t\316\306.\360" + signing_public_key_certificate: "\204D\241\0018.\241\004RAsymmetricECDSA256Y\001-\245\001x(824798eb43ead4d88ebc68ce6cdb52cfe1546b84\002x(8c69d3a14ea82ad66acc603e141b13282e1dc173:\000GDWXg\247\001\002\002T\214i\323\241N\250*\326j\314`>\024\033\023(.\035\301s\0038.\004\201\002 \001!X \351\345G?\306\355\366\347\020y\211\344~b\3077Z\303\036[Kf\377\311Z\317\3432:(\361K\"X \335w\353[\0070\353\3569\207@\231\001\342\031\3738\023Tp\360>\215\377&\357w.\262\341\'\334:\000GDXB \000:\000GD^\242:\000GDh\241:\000GDkX P>\323\307\242=\3354U_\227?Q\255~<.\301[\362aSv{\377\211j\260\024\301l\200:\000GDi\241:\000GDkX \033\336\262\213\304\362\020\333\233B\2421`\370\027\307\005\357\371\210\334g\302\342\350\356O\216\345\223RzX@\253+\222V\206n?_r\207\337\270\037\325\2108\340M\357%8L\376&\310\247\347\337\203\230\02729\204\210\302\276\027\236\r\315\347\376LU\316\214}AU\376\032\333k\255\370&\323\016\352\304B\177_" +} diff --git a/oak_attestation_verification/tests/verifier_tests.rs b/oak_attestation_verification/tests/verifier_tests.rs index 01005203b19..e3a19608dbd 100644 --- a/oak_attestation_verification/tests/verifier_tests.rs +++ b/oak_attestation_verification/tests/verifier_tests.rs @@ -21,12 +21,13 @@ use oak_attestation_verification::{ verifier::{to_attestation_results, verify}, }; use oak_proto_rust::oak::attestation::v1::{ - attestation_results::Status, AmdSevReferenceValues, BinaryReferenceValue, - ContainerLayerEndorsements, ContainerLayerReferenceValues, EndorsementReferenceValue, - Endorsements, Evidence, KernelLayerEndorsements, KernelLayerReferenceValues, - OakContainersEndorsements, OakContainersReferenceValues, ReferenceValues, - RootLayerEndorsements, RootLayerReferenceValues, SkipVerification, StringReferenceValue, - SystemLayerEndorsements, SystemLayerReferenceValues, TransparentReleaseEndorsement, + attestation_results::Status, binary_reference_value, reference_values, AmdSevReferenceValues, + BinaryReferenceValue, ContainerLayerEndorsements, ContainerLayerReferenceValues, + EndorsementReferenceValue, Endorsements, Evidence, InsecureReferenceValues, + KernelLayerEndorsements, KernelLayerReferenceValues, OakContainersEndorsements, + OakContainersReferenceValues, ReferenceValues, RootLayerEndorsements, RootLayerReferenceValues, + SkipVerification, StringReferenceValue, SystemLayerEndorsements, SystemLayerReferenceValues, + TransparentReleaseEndorsement, }; use prost::Message; @@ -37,16 +38,23 @@ const VCEK_MILAN_CERT_DER: &str = "testdata/vcek_milan.der"; const ENDORSER_PUBLIC_KEY_PATH: &str = "testdata/oak-development.pem"; const REKOR_PUBLIC_KEY_PATH: &str = "testdata/rekor_public_key.pem"; const EVIDENCE_PATH: &str = "testdata/evidence.binarypb"; +const FAKE_EVIDENCE_PATH: &str = "testdata/fake_evidence.binarypb"; // Pretend the tests run at this time: 1 Nov 2023, 9:00 UTC const NOW_UTC_MILLIS: i64 = 1698829200000; -// Creates a valid evidence instance. +// Creates a valid AMD SEV-SNP evidence instance. fn create_evidence() -> Evidence { let serialized = fs::read(EVIDENCE_PATH).expect("could not read evidence"); Evidence::decode(serialized.as_slice()).expect("could not decode evidence") } +// Creates a valid fake evidence instance. +fn create_fake_evidence() -> Evidence { + let serialized = fs::read(FAKE_EVIDENCE_PATH).expect("could not read fake evidence"); + Evidence::decode(serialized.as_slice()).expect("could not decode fake evidence") +} + // Creates valid endorsements for an Oak Containers chain. fn create_endorsements() -> Endorsements { let endorsement = fs::read(ENDORSEMENT_PATH).expect("couldn't read endorsement"); @@ -109,11 +117,7 @@ fn create_reference_values() -> ReferenceValues { rekor_public_key, }; let skip = BinaryReferenceValue { - r#type: Some( - oak_proto_rust::oak::attestation::v1::binary_reference_value::Type::Skip( - SkipVerification {}, - ), - ), + r#type: Some(binary_reference_value::Type::Skip(SkipVerification {})), }; let brv = BinaryReferenceValue { r#type: Some( @@ -133,7 +137,7 @@ fn create_reference_values() -> ReferenceValues { let root_layer = RootLayerReferenceValues { amd_sev: Some(amd_sev), - intel_tdx: None, + ..Default::default() }; let kernel_layer = KernelLayerReferenceValues { kernel_image: Some(skip.clone()), @@ -157,9 +161,7 @@ fn create_reference_values() -> ReferenceValues { container_layer: Some(container_layer), }; ReferenceValues { - r#type: Some( - oak_proto_rust::oak::attestation::v1::reference_values::Type::OakContainers(vs), - ), + r#type: Some(reference_values::Type::OakContainers(vs)), } } @@ -179,6 +181,31 @@ fn verify_succeeds() { assert!(p.status() == Status::Success); } +#[test] +fn verify_fake_evidence() { + let evidence = create_fake_evidence(); + let endorsements = create_endorsements(); + let mut reference_values = create_reference_values(); + if let Some(reference_values::Type::OakContainers(reference)) = reference_values.r#type.as_mut() + { + reference.root_layer = Some(RootLayerReferenceValues { + insecure: Some(InsecureReferenceValues {}), + ..Default::default() + }); + } else { + panic!("invalid reference value type"); + } + + let r = verify(NOW_UTC_MILLIS, &evidence, &endorsements, &reference_values); + let p = to_attestation_results(&r); + + eprintln!("======================================"); + eprintln!("code={} reason={}", p.status as i32, p.reason); + eprintln!("======================================"); + assert!(r.is_ok()); + assert!(p.status() == Status::Success); +} + #[test] fn verify_fails_with_manipulated_root_public_key() { let mut evidence = create_evidence(); diff --git a/oak_dice/src/evidence.rs b/oak_dice/src/evidence.rs index ccdde532bdf..13d2c220c81 100644 --- a/oak_dice/src/evidence.rs +++ b/oak_dice/src/evidence.rs @@ -72,6 +72,8 @@ pub enum TeePlatform { AmdSevSnp = 1, /// Intel TDX. IntelTdx = 2, + /// None. + None = 3, } /// Attestation evidence generated by Stage 0. @@ -99,10 +101,16 @@ impl RootLayerEvidence { pub fn get_remote_attestation_report(&self) -> Result<&[u8], &'static str> { match self.get_tee_platform()? { + TeePlatform::None => { + // We use a mock attestation report based on the AMD SEV-SNP report when we run + // without a TEE. + Ok(&self.remote_attestation_report[..AMD_SEV_SNP_ATTESTATION_REPORT_SIZE]) + } TeePlatform::AmdSevSnp => { Ok(&self.remote_attestation_report[..AMD_SEV_SNP_ATTESTATION_REPORT_SIZE]) } - _ => Ok(&self.remote_attestation_report), + TeePlatform::IntelTdx => Ok(&self.remote_attestation_report), + TeePlatform::Unspecified => Err("TEE platform not specified"), } } diff --git a/oak_restricted_kernel_sdk/src/mock_attestation.rs b/oak_restricted_kernel_sdk/src/mock_attestation.rs index cbb5cdb6c00..3f9379cf9b7 100644 --- a/oak_restricted_kernel_sdk/src/mock_attestation.rs +++ b/oak_restricted_kernel_sdk/src/mock_attestation.rs @@ -21,7 +21,7 @@ use oak_crypto::{ encryptor::{EncryptionKeyHandle, EncryptionKeyProvider}, hpke::RecipientContext, }; -use oak_dice::evidence::{Evidence, RestrictedKernelDiceData}; +use oak_dice::evidence::{Evidence, RestrictedKernelDiceData, TeePlatform}; use p256::ecdsa::SigningKey; use crate::{DiceWrapper, EvidenceProvider, Signer}; @@ -40,6 +40,7 @@ fn get_mock_dice_data() -> RestrictedKernelDiceData { &oak_stage0_dice::Measurements::default(), oak_stage0_dice::mock_attestation_report, oak_stage0_dice::mock_derived_key, + TeePlatform::None, ); oak_restricted_kernel_dice::generate_dice_data( diff --git a/proto/attestation/endorsement.proto b/proto/attestation/endorsement.proto index 217de8b580e..6cdbd3b5422 100644 --- a/proto/attestation/endorsement.proto +++ b/proto/attestation/endorsement.proto @@ -42,7 +42,9 @@ message RootLayerEndorsements { // certificate(s) are encoded into this byte array are implementation // specific. In case of AMD-SEV-SNP, as described in // https://www.amd.com/system/files/TechDocs/57230.pdf, there are three - // different certificates packaged in two different files. + // different certificates packaged in two different files. We only include + // the machine-specific VCEK certificate since the AMD Root Key (ARK) and + // AMD SEV Key (ASK) are long-lived. bytes tee_certificate = 1; // Endorsement of the Stage0 binary. diff --git a/proto/attestation/evidence.proto b/proto/attestation/evidence.proto index 621b2adfce0..cf5e88beaf4 100644 --- a/proto/attestation/evidence.proto +++ b/proto/attestation/evidence.proto @@ -37,6 +37,7 @@ enum TeePlatform { TEE_PLATFORM_UNSPECIFIED = 0; AMD_SEV_SNP = 1; INTEL_TDX = 2; + TEE_PLATFORM_NONE = 3; } // Evidence generated by the Layer0. diff --git a/proto/attestation/reference_value.proto b/proto/attestation/reference_value.proto index abf97ac2792..a04eef33a78 100644 --- a/proto/attestation/reference_value.proto +++ b/proto/attestation/reference_value.proto @@ -70,9 +70,11 @@ message StringReferenceValue { } message RootLayerReferenceValues { - // Switches between AMD and Intel based on TeePlatform value. + // Switches between AMD SEV-SNP and Intel TDX based on TeePlatform value. + // Verification is skipped when not running in a TEE. AmdSevReferenceValues amd_sev = 1; IntelTdxReferenceValues intel_tdx = 2; + InsecureReferenceValues insecure = 3; } message AmdSevReferenceValues { @@ -89,9 +91,9 @@ message AmdSevReferenceValues { BinaryReferenceValue stage0 = 4; } -message IntelTdxReferenceValues { - // TBD -} +message IntelTdxReferenceValues {} + +message InsecureReferenceValues {} // Verifies that the field contains at least one of the given digests. // No checks are performed if this is empty. A match in at least one diff --git a/proto/attestation/verification.proto b/proto/attestation/verification.proto index 591186995be..b3473b5d45e 100644 --- a/proto/attestation/verification.proto +++ b/proto/attestation/verification.proto @@ -74,6 +74,8 @@ message RootLayerData { AmdAttestationReport sev_snp = 1; // Values extracted from an Intel TDX attestation report. IntelTdxAttestationReport tdx = 2; + // Values extracted from a fake report when not running in a TEE. + FakeAttestationReport fake = 3; } } @@ -104,6 +106,12 @@ message IntelTdxAttestationReport { bytes report_data = 1; } +// Values extracted from a fake attestation report when not running in a TEE. +message FakeAttestationReport { + // The custom bytes that were passed to the report when it was requested. + bytes report_data = 1; +} + // The versions of the components in the AMD SEV-SNP platform Trusted Compute // Base (TCB). message TcbVersion { diff --git a/stage0/src/lib.rs b/stage0/src/lib.rs index dcae8e423cc..19bca94eaad 100644 --- a/stage0/src/lib.rs +++ b/stage0/src/lib.rs @@ -26,7 +26,7 @@ use core::{arch::asm, ffi::c_void, mem::MaybeUninit, panic::PanicInfo}; use linked_list_allocator::LockedHeap; use oak_core::sync::OnceCell; -use oak_dice::evidence::DICE_DATA_CMDLINE_PARAM; +use oak_dice::evidence::{TeePlatform, DICE_DATA_CMDLINE_PARAM}; use oak_linux_boot_params::{BootE820Entry, E820EntryType}; use oak_sev_guest::{io::PortFactoryWrapper, msr::SevStatus}; use sha2::{Digest, Sha256}; @@ -335,11 +335,18 @@ pub fn rust64_start(encrypted: u64) -> ! { memory_map_sha2_256_digest, }; + let tee_platform = if sev_status().contains(SevStatus::SNP_ACTIVE) { + TeePlatform::AmdSevSnp + } else { + TeePlatform::None + }; + let dice_data = Box::leak(Box::new_in( oak_stage0_dice::generate_dice_data( &measurements, dice_attestation::get_attestation, dice_attestation::get_derived_key, + tee_platform, ), &crate::BOOT_ALLOC, )); diff --git a/stage0_dice/src/lib.rs b/stage0_dice/src/lib.rs index e0a86883a7b..fa9ebb29403 100644 --- a/stage0_dice/src/lib.rs +++ b/stage0_dice/src/lib.rs @@ -137,6 +137,7 @@ pub fn generate_dice_data< measurements: &Measurements, get_attestation: F, get_derived_key: G, + tee_platform: TeePlatform, ) -> Stage0DiceData { let mut result = Stage0DiceData::new_zeroed(); // Generate ECA Stage0 key pair. This key will be used to sign Stage1 ECA certificate. @@ -182,7 +183,7 @@ pub fn generate_dice_data< let hkdf = Hkdf::::new(Some(&salt), &ikm[..]); result.magic = STAGE0_MAGIC; - result.root_layer_evidence.tee_platform = TeePlatform::AmdSevSnp as u64; + result.root_layer_evidence.tee_platform = tee_platform as u64; result .root_layer_evidence .set_remote_attestation_report(report_bytes)