From a8f95a60130a8ea8108fa7a15a34e32977956126 Mon Sep 17 00:00:00 2001 From: peg Date: Fri, 12 Dec 2025 17:20:32 +0100 Subject: [PATCH 1/3] Override outdated SEAM loader --- src/attestation/dcap.rs | 37 ++++++++++++++++++++++++++++---- src/attestation/mod.rs | 1 + src/attestation/tcb_info.rs | 42 +++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 src/attestation/tcb_info.rs diff --git a/src/attestation/dcap.rs b/src/attestation/dcap.rs index 5ed2b33..4e02237 100644 --- a/src/attestation/dcap.rs +++ b/src/attestation/dcap.rs @@ -1,9 +1,9 @@ //! Data Center Attestation Primitives (DCAP) evidence generation and verification -use crate::attestation::{measurements::MultiMeasurements, AttestationError}; +use crate::attestation::{measurements::MultiMeasurements, tcb_info::TcbInfo, AttestationError}; use configfs_tsm::QuoteGenerationError; use dcap_qvl::{ - collateral::get_collateral_for_fmspc, + collateral::{self, get_collateral_for_fmspc}, quote::{Quote, Report}, }; use thiserror::Error; @@ -24,7 +24,7 @@ pub async fn verify_dcap_attestation( expected_input_data: [u8; 64], pccs_url: Option, ) -> Result { - let measurements = if cfg!(not(test)) { + let measurements = if !cfg!(not(test)) { let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH)? .as_secs(); @@ -33,7 +33,7 @@ pub async fn verify_dcap_attestation( let ca = quote.ca()?; let fmspc = hex::encode_upper(quote.fmspc()?); - let collateral = get_collateral_for_fmspc( + let mut collateral = get_collateral_for_fmspc( &pccs_url.clone().unwrap_or(PCS_URL.to_string()), fmspc, ca, @@ -41,6 +41,35 @@ pub async fn verify_dcap_attestation( ) .await?; + println!("tcb info {:?}", collateral.tcb_info); + let mut tcb_info: TcbInfo = serde_json::from_str(&collateral.tcb_info).unwrap(); + + let tcb_levels = tcb_info + .tcb_levels + .into_iter() + .map(|mut tcb_level| { + if &tcb_level.tcb_status == "UpToDate" { + if tcb_level.tcb.sgx_components[7].svn > 3 { + tracing::warn!( + "Overriding tcb info to allow outdated Azure v6 SEAM loader" + ); + println!("modifying!"); + tcb_level.tcb.sgx_components[7].svn = 3; + } + tcb_level + } else { + tcb_level + } + }) + .collect::>(); + + tcb_info.tcb_levels = tcb_levels; + + let tcb_info_json = serde_json::to_string(&tcb_info).unwrap(); + // collateral.tcb_info = tcb_info_json; + + println!("tcb info {:?}", collateral.tcb_info); + let _verified_report = dcap_qvl::verify::verify(&input, &collateral, now)?; let measurements = MultiMeasurements::from_dcap_qvl_quote("e)?; diff --git a/src/attestation/mod.rs b/src/attestation/mod.rs index 1142d30..7618054 100644 --- a/src/attestation/mod.rs +++ b/src/attestation/mod.rs @@ -2,6 +2,7 @@ pub mod azure; pub mod dcap; pub mod measurements; +pub mod tcb_info; use measurements::MultiMeasurements; use parity_scale_codec::{Decode, Encode}; diff --git a/src/attestation/tcb_info.rs b/src/attestation/tcb_info.rs new file mode 100644 index 0000000..81bbd91 --- /dev/null +++ b/src/attestation/tcb_info.rs @@ -0,0 +1,42 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TcbInfo { + pub id: String, + pub version: u8, + pub issue_date: String, + pub next_update: String, + pub fmspc: String, + pub pce_id: String, + pub tcb_type: u32, + pub tcb_evaluation_data_number: u32, + pub tcb_levels: Vec, +} + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TcbLevel { + pub tcb: Tcb, + pub tcb_date: String, + pub tcb_status: String, + #[serde(rename = "advisoryIDs", default)] + pub advisory_ids: Vec, +} + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Tcb { + #[serde(rename = "sgxtcbcomponents")] + pub sgx_components: Vec, + #[serde(rename = "tdxtcbcomponents", default)] + pub tdx_components: Vec, + #[serde(rename = "pcesvn")] + pub pce_svn: u16, +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TcbComponents { + pub svn: u8, +} From cbc4cb56021896a73f331b360f092d4db2eda8f7 Mon Sep 17 00:00:00 2001 From: peg Date: Fri, 12 Dec 2025 18:15:48 +0100 Subject: [PATCH 2/3] Gate behind feature flag --- Cargo.toml | 7 ++++++- src/attestation/azure/mod.rs | 36 ++++++++++++++++++++++++++++++++++++ src/attestation/dcap.rs | 9 +++++++-- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 061364e..3929196 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,5 +54,10 @@ rcgen = "0.14.5" tempfile = "3.23.0" [features] -default = ["azure"] +default = ["azure", "azure-v6-override"] + +# Adds support for Microsoft Azure attestation generation and verification azure = ["tss-esapi", "az-tdx-vtpm"] + +# Allows Azure's V6 instance outdated SEAM Loader +azure-v6-override = ["azure"] diff --git a/src/attestation/azure/mod.rs b/src/attestation/azure/mod.rs index 173f95b..ec7064f 100644 --- a/src/attestation/azure/mod.rs +++ b/src/attestation/azure/mod.rs @@ -13,6 +13,9 @@ use x509_parser::prelude::*; use crate::attestation::{dcap::verify_dcap_attestation, measurements::MultiMeasurements}; +#[cfg(feature = "azure-v6-override")] +const AZURE_V6_BAD_FMSPC: &str = "90c06f000000"; + /// The attestation evidence payload that gets sent over the channel #[derive(Debug, Serialize, Deserialize)] struct AttestationDocument { @@ -245,6 +248,39 @@ impl RsaPubKey { } } +#[cfg(feature = "azure-v6-override")] +pub fn azure_v6_override(collateral: &mut dcap_qvl::QuoteCollateralV3) { + use crate::attestation::tcb_info::TcbInfo; + + let mut tcb_info: TcbInfo = serde_json::from_str(&collateral.tcb_info).unwrap(); + + if tcb_info.fmspc == AZURE_V6_BAD_FMSPC { + let tcb_levels = tcb_info + .tcb_levels + .into_iter() + .map(|mut tcb_level| { + if &tcb_level.tcb_status == "UpToDate" { + if tcb_level.tcb.sgx_components[7].svn > 3 { + tracing::warn!( + "Overriding tcb info to allow outdated Azure v6 SEAM loader" + ); + println!("modifying!"); + tcb_level.tcb.sgx_components[7].svn = 3; + } + tcb_level + } else { + tcb_level + } + }) + .collect::>(); + + tcb_info.tcb_levels = tcb_levels; + + let tcb_info_json = serde_json::to_string(&tcb_info).unwrap(); + collateral.tcb_info = tcb_info_json; + } +} + #[derive(Error, Debug)] pub enum MaaError { #[error("Report: {0}")] diff --git a/src/attestation/dcap.rs b/src/attestation/dcap.rs index 8ab31be..32de72a 100644 --- a/src/attestation/dcap.rs +++ b/src/attestation/dcap.rs @@ -1,9 +1,9 @@ //! Data Center Attestation Primitives (DCAP) evidence generation and verification -use crate::attestation::{measurements::MultiMeasurements, tcb_info::TcbInfo, AttestationError}; +use crate::attestation::{measurements::MultiMeasurements, AttestationError}; use configfs_tsm::QuoteGenerationError; use dcap_qvl::{ - collateral::{self, get_collateral_for_fmspc}, + collateral::get_collateral_for_fmspc, quote::{Quote, Report}, }; use thiserror::Error; @@ -32,6 +32,8 @@ pub async fn verify_dcap_attestation( let ca = quote.ca()?; let fmspc = hex::encode_upper(quote.fmspc()?); + + #[allow(unused_mut)] let mut collateral = get_collateral_for_fmspc( &pccs_url.clone().unwrap_or(PCS_URL.to_string()), fmspc, @@ -40,6 +42,9 @@ pub async fn verify_dcap_attestation( ) .await?; + #[cfg(feature = "azure-v6-override")] + crate::attestation::azure::azure_v6_override(&mut collateral); + let _verified_report = dcap_qvl::verify::verify(&input, &collateral, now)?; let measurements = MultiMeasurements::from_dcap_qvl_quote("e)?; From 4ff0f5dd38d58b752f749a6b39f071473339ed20 Mon Sep 17 00:00:00 2001 From: peg Date: Fri, 12 Dec 2025 18:57:53 +0100 Subject: [PATCH 3/3] Rm logging --- src/attestation/azure/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/attestation/azure/mod.rs b/src/attestation/azure/mod.rs index ec7064f..3b80934 100644 --- a/src/attestation/azure/mod.rs +++ b/src/attestation/azure/mod.rs @@ -264,7 +264,6 @@ pub fn azure_v6_override(collateral: &mut dcap_qvl::QuoteCollateralV3) { tracing::warn!( "Overriding tcb info to allow outdated Azure v6 SEAM loader" ); - println!("modifying!"); tcb_level.tcb.sgx_components[7].svn = 3; } tcb_level