From fd07a8433da9a09c2b877696b1d6629b587e550e Mon Sep 17 00:00:00 2001 From: Xynnn007 Date: Thu, 1 Feb 2024 22:40:47 +0800 Subject: [PATCH] AA: add runtime measurement for TDX Signed-off-by: Xynnn007 --- attestation-agent/attester/Cargo.toml | 3 +- attestation-agent/attester/src/tdx/mod.rs | 39 +++++++---- attestation-agent/attester/src/tdx/rtmr.rs | 76 ++++++++++++++++++++++ attestation-agent/lib/src/lib.rs | 21 +++--- 4 files changed, 114 insertions(+), 25 deletions(-) create mode 100644 attestation-agent/attester/src/tdx/rtmr.rs diff --git a/attestation-agent/attester/Cargo.toml b/attestation-agent/attester/Cargo.toml index 6dd1e98db..dc20e6f52 100644 --- a/attestation-agent/attester/Cargo.toml +++ b/attestation-agent/attester/Cargo.toml @@ -24,6 +24,7 @@ serde_json.workspace = true sev = { version = "1.2.0", default-features = false, features = [ "snp", ], optional = true } +sha2 = { workspace = true, optional = true } strum.workspace = true tdx-attest-rs = { git = "https://github.com/intel/SGXDataCenterAttestationPrimitives", tag = "DCAP_1.16", optional = true } # TODO: change it to "0.1", once released. @@ -52,7 +53,7 @@ all-attesters = [ "cca-attester", ] -tdx-attester = ["tdx-attest-rs"] +tdx-attester = ["sha2", "tdx-attest-rs"] sgx-attester = ["occlum_dcap"] az-snp-vtpm-attester = ["az-snp-vtpm"] az-tdx-vtpm-attester = ["az-tdx-vtpm"] diff --git a/attestation-agent/attester/src/tdx/mod.rs b/attestation-agent/attester/src/tdx/mod.rs index aa0d1cf15..264337cf4 100644 --- a/attestation-agent/attester/src/tdx/mod.rs +++ b/attestation-agent/attester/src/tdx/mod.rs @@ -3,12 +3,16 @@ // SPDX-License-Identifier: Apache-2.0 // +use self::rtmr::TdxRtmrEvent; + use super::Attester; use anyhow::*; use base64::Engine; use serde::{Deserialize, Serialize}; +use sha2::Digest; use std::path::Path; -use tdx_attest_rs; + +mod rtmr; const TDX_REPORT_DATA_SIZE: usize = 64; const CCEL_PATH: &str = "/sys/firmware/acpi/tables/data/CCEL"; @@ -72,19 +76,28 @@ impl Attester for TdxAttester { async fn extend_runtime_measurement( &self, events: Vec>, - _register_index: Option, + register_index: Option, ) -> Result<()> { - for event in events { - match tdx_attest_rs::tdx_att_extend(&event) { - tdx_attest_rs::tdx_attest_error_t::TDX_ATTEST_SUCCESS => { - log::debug!("TDX extend runtime measurement succeeded.") - } - error_code => { - bail!( - "TDX Attester: Failed to extend RTMR. Error code: {:?}", - error_code - ); - } + let register_index = register_index.unwrap_or(2); + let extend_data: Vec = events.into_iter().flatten().collect(); + let mut hasher = sha2::Sha384::new(); + hasher.update(extend_data); + let extend_data = hasher.finalize().into(); + + let event: Vec = TdxRtmrEvent::default() + .with_extend_data(extend_data) + .with_rtmr_index(register_index) + .into(); + + match tdx_attest_rs::tdx_att_extend(&event) { + tdx_attest_rs::tdx_attest_error_t::TDX_ATTEST_SUCCESS => { + log::debug!("TDX extend runtime measurement succeeded.") + } + error_code => { + bail!( + "TDX Attester: Failed to extend RTMR. Error code: {:?}", + error_code + ); } } diff --git a/attestation-agent/attester/src/tdx/rtmr.rs b/attestation-agent/attester/src/tdx/rtmr.rs new file mode 100644 index 000000000..628c3a9b5 --- /dev/null +++ b/attestation-agent/attester/src/tdx/rtmr.rs @@ -0,0 +1,76 @@ +// Copyright (c) 2024 Alibaba Cloud +// +// SPDX-License-Identifier: Apache-2.0 +// + +/// The actual rtmr event data handled in DCAP +#[repr(C, packed)] +pub struct TdxRtmrEvent { + /// Always 1 + version: u32, + + /// The RTMR that will be extended. + /// As defined in https://github.com/confidential-containers/td-shim/blob/main/doc/tdshim_spec.md#td-measurement + /// we will use RTMR 2 for guest application code and configuration. + rtmr_index: u64, + + /// Data that will be used to extend RTMR + extend_data: [u8; 48usize], + + /// Not used in DCAP + event_type: u32, + + /// Always 0 + event_data_size: u32, + + /// Not used in DCAP + event_data: Vec, +} + +impl Default for TdxRtmrEvent { + fn default() -> Self { + Self { + extend_data: [0; 48], + version: 1, + rtmr_index: 2, + event_type: 0, + event_data_size: 0, + event_data: Vec::new(), + } + } +} + +impl TdxRtmrEvent { + pub fn with_extend_data(mut self, extend_data: [u8; 48]) -> Self { + self.extend_data = extend_data; + self + } + + pub fn with_rtmr_index(mut self, rtmr_index: u64) -> Self { + self.rtmr_index = rtmr_index; + self + } +} + +impl Into> for TdxRtmrEvent { + fn into(self) -> Vec { + let event_ptr = &self as *const TdxRtmrEvent as *const u8; + let event_data_size = std::mem::size_of::() * self.event_data_size as usize; + let res_size = std::mem::size_of::() * 3 + + std::mem::size_of::() + + std::mem::size_of::<[u8; 48]>() + + event_data_size; + let mut res = vec![0; res_size]; + unsafe { + for i in 0..res_size - event_data_size { + res[i] = *event_ptr.add(i); + } + } + let event_data = Vec::from(self.event_data); + for i in 0..event_data_size { + res[i + res_size - event_data_size] = event_data[i]; + } + + return res; + } +} diff --git a/attestation-agent/lib/src/lib.rs b/attestation-agent/lib/src/lib.rs index 882f36cb3..ce4e4b8b3 100644 --- a/attestation-agent/lib/src/lib.rs +++ b/attestation-agent/lib/src/lib.rs @@ -86,11 +86,7 @@ pub trait AttestationAPIs { async fn get_evidence(&mut self, runtime_data: &[u8]) -> Result>; /// Extend runtime measurement register - async fn extend_runtime_measurement( - &mut self, - events: Vec>, - register_index: Option, - ) -> Result<()>; + async fn extend_runtime_measurement(&mut self, event: &[u8]) -> Result<()>; } /// Attestation agent to provide attestation service. @@ -210,16 +206,19 @@ impl AttestationAPIs for AttestationAgent { } /// Extend runtime measurement register - async fn extend_runtime_measurement( - &mut self, - events: Vec>, - register_index: Option, - ) -> Result<()> { + async fn extend_runtime_measurement(&mut self, event: &[u8]) -> Result<()> { let tee_type = detect_tee_type(); let attester = TryInto::::try_into(tee_type)?; + + let coco_event = CoCoEvent::from_bytes(event)?; + + // Update runtime measurement registers. attester - .extend_runtime_measurement(events, register_index) + .extend_runtime_measurement(vec![event.to_vec()], None) .await?; + + // Record inside the Eventlog + self.eventlog_writer.write_event_entry(coco_event).await?; Ok(()) } }