From 41ad4ca1737debfc6139c76b603991df119d890e Mon Sep 17 00:00:00 2001 From: Xynnn007 Date: Wed, 3 Jan 2024 11:52:27 +0800 Subject: [PATCH] AS/Verifier: fix the report/init data comparation We used to compare the runtime/init data without caring about the length of each other. This commit resize the input expected data by trim or append '\0' to the equal length with the actual value from the one in evidence. In this way we can avoid unexpected failures. Signed-off-by: Xynnn007 --- .../verifier/src/az_snp_vtpm/mod.rs | 7 +++++-- attestation-service/verifier/src/cca/mod.rs | 16 ++------------ attestation-service/verifier/src/csv/mod.rs | 4 +++- attestation-service/verifier/src/lib.rs | 21 +++++++++++++++++++ attestation-service/verifier/src/sgx/mod.rs | 11 ++++++---- attestation-service/verifier/src/snp/mod.rs | 7 +++++-- attestation-service/verifier/src/tdx/mod.rs | 7 +++++-- 7 files changed, 48 insertions(+), 25 deletions(-) diff --git a/attestation-service/verifier/src/az_snp_vtpm/mod.rs b/attestation-service/verifier/src/az_snp_vtpm/mod.rs index 3c306db1e..080ce08d9 100644 --- a/attestation-service/verifier/src/az_snp_vtpm/mod.rs +++ b/attestation-service/verifier/src/az_snp_vtpm/mod.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 // -use crate::{InitDataHash, ReportData}; +use crate::{regularize_data, InitDataHash, ReportData}; use super::{TeeEvidenceParsedClaim, Verifier}; use crate::snp::{ @@ -61,6 +61,9 @@ impl Verifier for AzSnpVtpm { bail!("unexpected empty report data"); }; + let expected_report_data = + regularize_data(expected_report_data, 64, "REPORT_DATA", "Azure SNP vTPM"); + if let InitDataHash::Value(_) = expected_init_data_hash { warn!("Azure SNP vTPM verifier does not support verify init data hash, will ignore the input `init_data_hash`."); } @@ -69,7 +72,7 @@ impl Verifier for AzSnpVtpm { .context("Failed to deserialize Azure vTPM SEV-SNP evidence")?; let hcl_report = HclReport::new(evidence.report)?; - verify_quote(&evidence.quote, &hcl_report, expected_report_data)?; + verify_quote(&evidence.quote, &hcl_report, &expected_report_data)?; let var_data_hash = hcl_report.var_data_sha256(); let snp_report = hcl_report.try_into()?; diff --git a/attestation-service/verifier/src/cca/mod.rs b/attestation-service/verifier/src/cca/mod.rs index f7b244bfa..bccd95c84 100644 --- a/attestation-service/verifier/src/cca/mod.rs +++ b/attestation-service/verifier/src/cca/mod.rs @@ -10,7 +10,7 @@ use base64::Engine; use core::result::Result::Ok; use ear::{Ear, RawValue}; use jsonwebtoken::{self as jwt}; -use log::{debug, error, info, warn}; +use log::{debug, error, info}; use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, str}; use veraison_apiclient::*; @@ -83,19 +83,7 @@ impl Verifier for CCA { bail!("CCA verifier must provide report data field!"); }; - let mut expected_report_data = expected_report_data.to_vec(); - - match expected_report_data.len() { - 0..=63 => { - warn!("The input report_data of CCA is shorter than 64 bytes, will be padded with '\\0'."); - expected_report_data.resize(64, b'\0'); - } - 64 => {} - _ => { - warn!("The input report_data of CCA is longer than 64 bytes, will be truncated to 64 bytes."); - expected_report_data.truncate(64); - } - }; + let expected_report_data = regularize_data(expected_report_data, 64, "REPORT_DATA", "CCA"); let evidence = serde_json::from_slice::(evidence) .context("Deserialize CCA Evidence failed.")?; diff --git a/attestation-service/verifier/src/csv/mod.rs b/attestation-service/verifier/src/csv/mod.rs index 249eb97c3..5756dd654 100644 --- a/attestation-service/verifier/src/csv/mod.rs +++ b/attestation-service/verifier/src/csv/mod.rs @@ -53,7 +53,9 @@ impl Verifier for CsvVerifier { if let ReportData::Value(expected_report_data) = expected_report_data { debug!("Check the binding of REPORT_DATA."); - if *expected_report_data != report_raw.body.report_data { + let expected_report_data = + regularize_data(expected_report_data, 64, "REPORT_DATA", "CSV"); + if expected_report_data != report_raw.body.report_data { bail!("REPORT_DATA is different from that in CSV Quote"); } } diff --git a/attestation-service/verifier/src/lib.rs b/attestation-service/verifier/src/lib.rs index b82e7cceb..67658734e 100644 --- a/attestation-service/verifier/src/lib.rs +++ b/attestation-service/verifier/src/lib.rs @@ -1,6 +1,9 @@ +use std::cmp::Ordering; + use anyhow::*; use async_trait::async_trait; use kbs_types::Tee; +use log::warn; pub mod sample; @@ -139,3 +142,21 @@ pub trait Verifier { expected_init_data_hash: &InitDataHash, ) -> Result; } + +/// Padding or truncate the given data slice to the given `len` bytes. +fn regularize_data(data: &[u8], len: usize, data_name: &str, arch: &str) -> Vec { + let data_len = data.len(); + match data_len.cmp(&len) { + Ordering::Less => { + warn!("The input {data_name} of {arch} is shorter than {len} bytes, will be padded with '\\0'."); + let mut data = data.to_vec(); + data.resize(len, b'\0'); + data + } + Ordering::Equal => data.to_vec(), + Ordering::Greater => { + warn!("The input {data_name} of {arch} is longer than {len} bytes, will be truncated to {len} bytes."); + data[..len].to_vec() + } + } +} diff --git a/attestation-service/verifier/src/sgx/mod.rs b/attestation-service/verifier/src/sgx/mod.rs index c94f9b820..6a355e592 100644 --- a/attestation-service/verifier/src/sgx/mod.rs +++ b/attestation-service/verifier/src/sgx/mod.rs @@ -19,7 +19,7 @@ use sgx_dcap_quoteverify_rs::{ tee_qv_get_collateral, tee_supp_data_descriptor_t, tee_verify_quote, }; -use crate::{InitDataHash, ReportData}; +use crate::{regularize_data, InitDataHash, ReportData}; use self::types::sgx_quote3_t; @@ -81,15 +81,18 @@ async fn verify_evidence( let quote = parse_sgx_quote("e_bin)?; if let ReportData::Value(expected_report_data) = expected_report_data { debug!("Check the binding of REPORT_DATA."); - if *expected_report_data != quote.report_body.report_data { + let expected_report_data = regularize_data(expected_report_data, 64, "REPORT_DATA", "SGX"); + if expected_report_data != quote.report_body.report_data { bail!("REPORT_DATA is different from that in SGX Quote"); } } if let InitDataHash::Value(expected_init_data_hash) = expected_init_data_hash { debug!("Check the binding of CONFIGID."); - if *expected_init_data_hash != quote.report_body.config_id { - bail!("MRCONFIGID is different from that in SGX Quote"); + let expected_init_data_hash = + regularize_data(expected_init_data_hash, 64, "CONFIGID", "SGX"); + if expected_init_data_hash != quote.report_body.config_id { + bail!("CONFIGID is different from that in SGX Quote"); } } diff --git a/attestation-service/verifier/src/snp/mod.rs b/attestation-service/verifier/src/snp/mod.rs index 17f7903e7..a282e13d2 100644 --- a/attestation-service/verifier/src/snp/mod.rs +++ b/attestation-service/verifier/src/snp/mod.rs @@ -97,14 +97,17 @@ impl Verifier for Snp { }; debug!("Check the binding of REPORT_DATA."); + let expected_report_data = regularize_data(expected_report_data, 64, "REPORT_DATA", "SNP"); - if *expected_report_data != report.report_data { + if expected_report_data != report.report_data { bail!("Report Data Mismatch"); } if let InitDataHash::Value(expected_init_data_hash) = expected_init_data_hash { debug!("Check the binding of HOST_DATA."); - if *expected_init_data_hash != report.host_data { + let expected_init_data_hash = + regularize_data(expected_init_data_hash, 32, "HOST_DATA", "SNP"); + if expected_init_data_hash != report.host_data { bail!("Host Data Mismatch"); } } diff --git a/attestation-service/verifier/src/tdx/mod.rs b/attestation-service/verifier/src/tdx/mod.rs index a6bc70b42..2b73e23a5 100644 --- a/attestation-service/verifier/src/tdx/mod.rs +++ b/attestation-service/verifier/src/tdx/mod.rs @@ -59,14 +59,17 @@ async fn verify_evidence( if let ReportData::Value(expected_report_data) = expected_report_data { debug!("Check the binding of REPORT_DATA."); - if *expected_report_data != quote.report_body.report_data { + let expected_report_data = regularize_data(expected_report_data, 64, "REPORT_DATA", "TDX"); + if expected_report_data != quote.report_body.report_data { bail!("REPORT_DATA is different from that in TDX Quote"); } } if let InitDataHash::Value(expected_init_data_hash) = expected_init_data_hash { debug!("Check the binding of MRCONFIGID."); - if *expected_init_data_hash != quote.report_body.mr_config_id { + let expected_init_data_hash = + regularize_data(expected_init_data_hash, 48, "MRCONFIGID", "TDX"); + if expected_init_data_hash != quote.report_body.mr_config_id { bail!("MRCONFIGID is different from that in TDX Quote"); } }