diff --git a/attestation-agent/attester/src/tdx/mod.rs b/attestation-agent/attester/src/tdx/mod.rs index 231644911..ddd8ebf17 100644 --- a/attestation-agent/attester/src/tdx/mod.rs +++ b/attestation-agent/attester/src/tdx/mod.rs @@ -3,6 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 // +use self::rtmr::TdxRtmrEvent; + use super::tsm_report::*; use super::Attester; use crate::utils::pad; @@ -11,16 +13,14 @@ use anyhow::*; use base64::Engine; use scroll::Pread; use serde::{Deserialize, Serialize}; -use sha2::{Digest, Sha384}; -use std::mem; use std::path::Path; use tdx_attest_rs::tdx_report_t; mod report; +mod rtmr; const TDX_REPORT_DATA_SIZE: usize = 64; const CCEL_PATH: &str = "/sys/firmware/acpi/tables/data/CCEL"; -const RUNTIME_MEASUREMENT_RTMR_INDEX: u64 = 2; pub fn detect_platform() -> bool { TsmReportPath::new(TsmReportProvider::Tdx).is_ok() || Path::new("/dev/tdx_guest").exists() @@ -104,34 +104,36 @@ impl Attester for TdxAttester { async fn extend_runtime_measurement( &self, - events: Vec>, - _register_index: Option, + event_digest: Vec, + register_index: u64, ) -> Result<()> { if !runtime_measurement_extend_available() { bail!("TDX Attester: Cannot extend runtime measurement on this system"); } - for event in events { - let mut event_buffer = [0u8; mem::size_of::()]; - let mut hasher = Sha384::new(); - hasher.update(&event); - let hash = hasher.finalize().to_vec(); - let rtmr_event = unsafe { - &mut *(event_buffer.as_mut_ptr() as *mut tdx_attest_rs::tdx_rtmr_event_t) - }; - rtmr_event.version = 1; - rtmr_event.rtmr_index = RUNTIME_MEASUREMENT_RTMR_INDEX; - rtmr_event.extend_data.copy_from_slice(&hash); - match tdx_attest_rs::tdx_att_extend(&event_buffer) { - 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 - ); - } + // The match follows https://github.com/confidential-containers/td-shim/blob/main/doc/tdshim_spec.md#td-event-log + let rtmr_index = match register_index { + 1 | 7 => 0, + 2..=6 => 1, + 8..=15 => 2, + _ => 3, + }; + + let extend_data: [u8; 48] = pad(&event_digest); + let event: Vec = TdxRtmrEvent::default() + .with_extend_data(extend_data) + .with_rtmr_index(rtmr_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..8d9be076d --- /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 3 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 From for Vec { + fn from(val: TdxRtmrEvent) -> Self { + let event_ptr = &val as *const TdxRtmrEvent as *const u8; + let event_data_size = std::mem::size_of::() * val.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, chunk) in res.iter_mut().enumerate().take(res_size - event_data_size) { + *chunk = *event_ptr.add(i); + } + } + let event_data = val.event_data; + for i in 0..event_data_size { + res[i + res_size - event_data_size] = event_data[i]; + } + + res + } +}