From 8947c758b4ee8c5ec08b99c22c4936311ee25af0 Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Thu, 21 Sep 2023 15:13:27 -0700 Subject: [PATCH] Add `Digest` implemtation to `prost::DcapEvidence` (#3573) --- attest/verifier/types/build.rs | 9 +++- .../types/src/convert/dcap_evidence.rs | 48 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/attest/verifier/types/build.rs b/attest/verifier/types/build.rs index 59e8969ef8..d2f9425718 100644 --- a/attest/verifier/types/build.rs +++ b/attest/verifier/types/build.rs @@ -13,7 +13,14 @@ fn main() -> Result<(), Box> { // `Digestible` should be stable. There are tests in each of the // `convert/.rs` files that help ensure the `Digestible` field // order stability. - for t in ["EnclaveReportDataContents", "Quote3", "Collateral"].iter() { + for t in [ + "EnclaveReportDataContents", + "Quote3", + "Collateral", + "DcapEvidence", + ] + .iter() + { config.type_attribute( t, "#[derive(serde::Serialize, serde::Deserialize, Digestible, Eq)]", diff --git a/attest/verifier/types/src/convert/dcap_evidence.rs b/attest/verifier/types/src/convert/dcap_evidence.rs index b9aced11c7..cb4f7ec8f7 100644 --- a/attest/verifier/types/src/convert/dcap_evidence.rs +++ b/attest/verifier/types/src/convert/dcap_evidence.rs @@ -45,6 +45,7 @@ mod test { use ::prost::Message; use assert_matches::assert_matches; use mc_attest_untrusted::DcapQuotingEnclave; + use mc_crypto_digestible::{DigestTranscript, Digestible, MerlinTranscript}; use mc_sgx_core_types::Report; fn evidence() -> DcapEvidence { @@ -171,4 +172,51 @@ mod test { assert_matches!(error, Err(ConversionError::LengthMismatch { .. })); } + + #[test] + fn digestible() { + let evidence = evidence(); + let prost_evidence = + prost::DcapEvidence::try_from(&evidence).expect("Failed to convert evidence to prost"); + + // We manually build up the digest here, to help ensure that the digest + // order of fields is maintained in the future. + let context = b"history sticks to your feet"; + + // The `digestible` byte string is used in the `DigestTranscript` + // implementation for `MerlinTranscript`. It shouldn't change or else + // historical digests would fail to be reproduced. + let mut transcript = MerlinTranscript::new(b"digestible"); + transcript.append_agg_header(context, b"DcapEvidence"); + + // As mentioned above the order of these calls should not change after + // release. Only items added or removed. This is because the digest + // will be stored on the block chain and someone will need to be able + // to reproduce it. Note that prost will order the fields in generated + // code based on tag numbers. This test also helps ensure the order + // of the prost generated fields. + prost_evidence + .quote + .clone() + .expect("Quote should be set") + .append_to_transcript(b"quote", &mut transcript); + prost_evidence + .collateral + .clone() + .expect("Collateral should be set") + .append_to_transcript(b"collateral", &mut transcript); + prost_evidence + .report_data + .clone() + .expect("Report data should be set") + .append_to_transcript(b"report_data", &mut transcript); + + transcript.append_agg_closer(context, b"DcapEvidence"); + + let mut expected_digest = [0u8; 32]; + transcript.extract_digest(&mut expected_digest); + + let evidence_digest = prost_evidence.digest32::(context); + assert_eq!(evidence_digest, expected_digest); + } }