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..3b80934 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,38 @@ 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" + ); + 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 e448f95..32de72a 100644 --- a/src/attestation/dcap.rs +++ b/src/attestation/dcap.rs @@ -32,7 +32,9 @@ pub async fn verify_dcap_attestation( let ca = quote.ca()?; let fmspc = hex::encode_upper(quote.fmspc()?); - let collateral = get_collateral_for_fmspc( + + #[allow(unused_mut)] + let mut collateral = get_collateral_for_fmspc( &pccs_url.clone().unwrap_or(PCS_URL.to_string()), fmspc, ca, @@ -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)?; diff --git a/src/attestation/mod.rs b/src/attestation/mod.rs index 7d87577..0e6ea27 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, +}