diff --git a/kernel/src/device/misc/tdxguest.rs b/kernel/src/device/misc/tdxguest.rs index 05f2112a8..f99737193 100644 --- a/kernel/src/device/misc/tdxguest.rs +++ b/kernel/src/device/misc/tdxguest.rs @@ -16,7 +16,7 @@ use ostd::{ use spin::Once; use tdx_guest::{ SHARED_MASK, - tdcall::{TdCallError, get_report}, + tdcall::{TdCallError, extend_rtmr, get_report}, tdvmcall::{TdVmcallError, get_quote}, }; @@ -278,6 +278,27 @@ pub fn tdx_get_mr(reg: MeasurementReg) -> Result<[u8; SHA384_DIGEST_SIZE]> { Ok(blob) } +/// Extends the measurement register in the TDX report. +pub fn tdx_extend_mr(reg: MeasurementReg, data: &[u8]) -> Result<()> { + if data.len() != SHA384_DIGEST_SIZE { + return_errno_with_message!(Errno::EINVAL, "Invalid data length for extending MR"); + } + + let index = match reg { + MeasurementReg::Rtmr0 => 0, + MeasurementReg::Rtmr1 => 1, + MeasurementReg::Rtmr2 => 2, + MeasurementReg::Rtmr3 => 3, + _ => return_errno_with_message!(Errno::EINVAL, "Only RTMR can be extended"), + }; + + let segment: USegment = FrameAllocOptions::new().alloc_segment(1)?.into(); + segment.write_bytes(0, data).unwrap(); + + extend_rtmr(segment.paddr() as u64, index)?; + Ok(()) +} + pub(super) fn init() -> Result<()> { TDX_REPORT.call_once(|| { let report = FrameAllocOptions::new() diff --git a/kernel/src/security/tsm_mr.rs b/kernel/src/security/tsm_mr.rs index 83bba9bb7..20f508371 100644 --- a/kernel/src/security/tsm_mr.rs +++ b/kernel/src/security/tsm_mr.rs @@ -8,11 +8,11 @@ use aster_systree::{ }; use inherit_methods_macro::inherit_methods; use ostd::{ - mm::{FallibleVmWrite, VmReader, VmWriter}, + mm::{FallibleVmRead, FallibleVmWrite, VmReader, VmWriter}, sync::RwMutex, }; -use crate::device::misc::tdxguest::{MeasurementReg, tdx_get_mr, tdx_get_report}; +use crate::device::misc::tdxguest::{MeasurementReg, tdx_extend_mr, tdx_get_mr, tdx_get_report}; pub(super) fn init() { let node = { @@ -189,7 +189,38 @@ inherit_sys_leaf_node!(Measurement, fields, { } fn write_attr(&self, name: &str, reader: &mut VmReader) -> Result { - Err(Error::AttributeError) + match name { + "rtmr0:sha384" | "rtmr1:sha384" | "rtmr2:sha384" | "rtmr3:sha384" => { + let attr = MEASUREMENT_ATTRS + .iter() + .find(|attr| attr.name == name) + .unwrap(); + + let data = { + let mut buf = [0u8; 48]; + let mut writer = VmWriter::from(&mut buf[..]); + let bytes_read = reader + .read_fallible(&mut writer) + .map_err(|_| Error::AttributeError)?; + if bytes_read != buf.len() { + return Err(Error::InvalidOperation); + } + + buf + }; + + let mut in_sync = self.in_sync.write(); + + tdx_extend_mr(attr.reg, &data).map_err(|_| Error::AttributeError)?; + + if attr.refresh_on_read() { + *in_sync = false; + } + + Ok(data.len()) + } + _ => Err(Error::AttributeError), + } } });