From a7473b5207c1b5d0c0d9e26d1478e3f286cc84ef Mon Sep 17 00:00:00 2001 From: Jiaqi Gao Date: Tue, 9 Apr 2024 08:33:05 -0400 Subject: [PATCH] migtd: mask the `xfam` and `attribute` MigTD may have different features on different platforms. Mask the attribute and xfam bits that is not required for migtd. Signed-off-by: Jiaqi Gao --- src/policy/src/verify.rs | 156 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/src/policy/src/verify.rs b/src/policy/src/verify.rs index dfd08a06..4f62f01e 100644 --- a/src/policy/src/verify.rs +++ b/src/policy/src/verify.rs @@ -24,6 +24,40 @@ const EV_EVENT_TAG: u32 = 0x00000006; const TAGGED_EVENT_ID_POLICY: u32 = 0x1; const TAGGED_EVENT_ID_ROOT_CA: u32 = 0x2; +// Attributes Mask: +// Bits Feature Masked or Not Notes +// 3:0 TD Under Debug Not masked Always 0 +// 15:4 TD Under Profiling Not masked Always 0 +// 26:16 Reserved Masked Always 0 +// 27 LASS Masked Feature not required +// 28 SEPT_VE_DISABLE Not masked Always 0 +// 29 MIGRATABLE Not masked Always 0 +// 30 PKS Masked Feature not required +// 31 KL (Key Locker) Masked Feature not required +// 61:32 Reserved Masked Always 0 +// 62 TPA Not masked Always 0 +// 63 PERFMON Masked Feature not required +const MIGTD_ATTRIBUTES_MASK: [u8; 8] = [0xff, 0xff, 0x00, 0x30, 0x00, 0x00, 0x00, 0x40]; + +// XFAM Mask: +// Bits Feature Masked or Not Notes +// 0 FP Not masked Always enabled +// 1 SSE Not masked Always enabled +// 2 AVX Masked Feature not required +// 4:3 MPX Masked Feature not required (MPX is being deprecated.) +// 7:5 AVX512 Masked Feature not required +// 8 PT (RTIT) Masked Feature not required +// 9 PK Masked Feature not required +// 10 ENQCMD Masked Feature not required +// 12:11 CET Not masked Feature required +// 13 HDC Masked Feature not required +// 14 ULI Masked Feature not required +// 15 LBR Masked Feature not required +// 16 HWP Masked Feature not required +// 18:17 AMX Masked Feature not required +// 19 APX Masked Feature not required +const MIGTD_XFAM_MASK: [u8; 8] = [0x03, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + struct Report<'a> { platform_info: BTreeMap, qe_info: BTreeMap, @@ -478,11 +512,33 @@ fn verify_migtd_info( local_report: &Report, peer_report: &Report, ) -> Result<(), PolicyError> { + let mut masked_local = [0u8; 8]; + let mut masked_remote = [0u8; 8]; + for (name, action) in &policy.migtd.td_info { let property = MigTdInfoProperty::from(name.as_str()); let local = local_report.get_migtd_info_property(&property)?; let remote = peer_report.get_migtd_info_property(&property)?; + let (local, remote) = match property { + // Mask the Attributes and XFAM + MigTdInfoProperty::Attributes => { + masked_local[..8].copy_from_slice(local); + masked_remote[..8].copy_from_slice(remote); + mask_bytes_array(&mut masked_local, &MIGTD_ATTRIBUTES_MASK); + mask_bytes_array(&mut masked_remote, &MIGTD_ATTRIBUTES_MASK); + (masked_local.as_slice(), masked_remote.as_slice()) + } + MigTdInfoProperty::Xfam => { + masked_local[..8].copy_from_slice(local); + masked_remote[..8].copy_from_slice(remote); + mask_bytes_array(&mut masked_local, &MIGTD_XFAM_MASK); + mask_bytes_array(&mut masked_remote, &MIGTD_XFAM_MASK); + (masked_local.as_slice(), masked_remote.as_slice()) + } + _ => (local, remote), + }; + let verify_result = action.verify(is_src, local, remote); if !verify_result { @@ -504,6 +560,12 @@ fn verify_migtd_info( Ok(()) } +fn mask_bytes_array(data: &mut [u8], mask: &[u8]) { + for (x, mask) in data.iter_mut().zip(mask.iter()) { + *x &= mask; + } +} + fn verify_event_log( is_src: bool, policy: &BTreeMap, @@ -988,6 +1050,33 @@ mod tests { // different attributes, not equal report_peer[Report::R_ATTR_TD].copy_from_slice(&[1u8; 8]); + let verify_result = verify_policy( + true, + policy_bytes, + template, + &[0u8; 8], + &report_peer, + &[0u8; 8], + ); + assert!(matches!( + verify_result, + Err(PolicyError::UnqulifiedMigTdInfo) + )); + + // verify the attributes mask, set masked bits + report_peer[Report::R_ATTR_TD].copy_from_slice(&[0, 0, 0, 0x8, 0x1, 0, 0, 0]); + let verify_result = verify_policy( + true, + policy_bytes, + template, + &[0u8; 8], + &report_peer, + &[0u8; 8], + ); + assert!(verify_result.is_ok()); + + // verify the attributes mask, set bits that will not be masked but must be zero + report_peer[Report::R_ATTR_TD].copy_from_slice(&[0, 0x1, 0, 0x3, 0, 0, 0, 0]); let verify_result = verify_policy( true, policy_bytes, @@ -1004,6 +1093,33 @@ mod tests { // different xfam, not equal report_peer[Report::R_XFAM].copy_from_slice(&[1u8; 8]); + let verify_result = verify_policy( + true, + policy_bytes, + template, + &[0u8; 8], + &report_peer, + &[0u8; 8], + ); + assert!(matches!( + verify_result, + Err(PolicyError::UnqulifiedMigTdInfo) + )); + + // verify xfam mask, set masked bits and required bits + report_peer[Report::R_XFAM].copy_from_slice(&[0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0]); + let verify_result = verify_policy( + true, + policy_bytes, + template, + &[0u8; 8], + &report_peer, + &[0u8; 8], + ); + assert!(verify_result.is_ok()); + + // verify xfam mask, unset bits that is not masked but required + report_peer[Report::R_XFAM].copy_from_slice(&[0x3, 0x08, 0, 0, 0, 0, 0, 0]); let verify_result = verify_policy( true, @@ -1484,4 +1600,44 @@ mod tests { ) .is_err()); } + + #[test] + fn test_xfam_mask() { + let mut xfam = [0u8; 8]; + + xfam.copy_from_slice(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); + mask_bytes_array(&mut xfam, &MIGTD_XFAM_MASK); + assert_eq!(&xfam, &[0x3, 0x18, 0x0, 0, 0, 0, 0, 0]); + + xfam.copy_from_slice(&[0x3, 0x18, 0x0, 0, 0, 0, 0, 0]); + mask_bytes_array(&mut xfam, &MIGTD_XFAM_MASK); + assert_eq!(&xfam, &[0x3, 0x18, 0x0, 0, 0, 0, 0, 0]); + + xfam.copy_from_slice(&[0xe7, 0x1a, 0x6, 0, 0, 0, 0, 0]); + mask_bytes_array(&mut xfam, &MIGTD_XFAM_MASK); + assert_eq!(&xfam, &[0x3, 0x18, 0x0, 0, 0, 0, 0, 0]) + } + + #[test] + fn test_attribute_mask() { + let mut attributes = [0u8; 8]; + + attributes.copy_from_slice(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); + mask_bytes_array(&mut attributes, &MIGTD_ATTRIBUTES_MASK); + assert_eq!( + &attributes, + &[0xff, 0xff, 0x00, 0x30, 0x00, 0x00, 0x00, 0x40] + ); + + attributes.copy_from_slice(&[0xff, 0xff, 0x00, 0x30, 0x00, 0x00, 0x00, 0x40]); + mask_bytes_array(&mut attributes, &MIGTD_ATTRIBUTES_MASK); + assert_eq!( + &attributes, + &[0xff, 0xff, 0x00, 0x30, 0x00, 0x00, 0x00, 0x40] + ); + + attributes.copy_from_slice(&[0, 0, 0, 0x8, 0, 0, 0, 0]); + mask_bytes_array(&mut attributes, &MIGTD_ATTRIBUTES_MASK); + assert_eq!(&attributes, &[0, 0, 0, 0, 0, 0, 0, 0]); + } }