Skip to content

Commit

Permalink
AS/Verifier: add support for TDX Quote v5
Browse files Browse the repository at this point in the history
Close #352

Signed-off-by: Xynnn007 <[email protected]>
  • Loading branch information
Xynnn007 committed Mar 28, 2024
1 parent 1070686 commit 83b73b7
Show file tree
Hide file tree
Showing 5 changed files with 372 additions and 68 deletions.
2 changes: 1 addition & 1 deletion attestation-service/verifier/src/az_tdx_vtpm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl Verifier for AzTdxVtpm {

fn verify_hcl_var_data(hcl_report: &HclReport, td_quote: &TdQuote) -> Result<()> {
let var_data_hash = hcl_report.var_data_sha256();
if var_data_hash != td_quote.report_body.report_data[..32] {
if var_data_hash != td_quote.report_data()[..32] {
bail!("TDX Quote report data mismatch");
}
debug!("Report data verification completed successfully.");
Expand Down
129 changes: 91 additions & 38 deletions attestation-service/verifier/src/tdx/claims.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ use byteorder::{LittleEndian, ReadBytesExt};
use log::{debug, warn};
use serde_json::{Map, Value};

use crate::TeeEvidenceParsedClaim;
use crate::{tdx::quote::QuoteV5Body, TeeEvidenceParsedClaim};

use super::{
eventlog::{CcEventLog, MeasuredEntity},
Expand All @@ -76,41 +76,94 @@ pub fn generate_parsed_claim(
let mut quote_map = Map::new();
let mut quote_body = Map::new();
let mut quote_header = Map::new();
// Claims from TD Quote Header.
parse_claim!(quote_header, "version", quote.header.version);
parse_claim!(quote_header, "att_key_type", quote.header.att_key_type);
parse_claim!(quote_header, "tee_type", quote.header.tee_type);
parse_claim!(quote_header, "reserved", quote.header.reserved);
parse_claim!(quote_header, "vendor_id", quote.header.vendor_id);
parse_claim!(quote_header, "user_data", quote.header.user_data);
// Claims from TD Quote Body. We ignore RTMRs because when verifying the integrity of
// the eventlog (CCEL), they have already been consumed.
parse_claim!(quote_body, "tcb_svn", quote.report_body.tcb_svn);
parse_claim!(quote_body, "mr_seam", quote.report_body.mr_seam);
parse_claim!(quote_body, "mrsigner_seam", quote.report_body.mrsigner_seam);
parse_claim!(
quote_body,
"seam_attributes",
quote.report_body.seam_attributes
);
parse_claim!(quote_body, "td_attributes", quote.report_body.td_attributes);
parse_claim!(quote_body, "xfam", quote.report_body.xfam);
parse_claim!(quote_body, "mr_td", quote.report_body.mr_td);
parse_claim!(quote_body, "mr_config_id", quote.report_body.mr_config_id);
parse_claim!(quote_body, "mr_owner", quote.report_body.mr_owner);
parse_claim!(
quote_body,
"mr_owner_config",
quote.report_body.mr_owner_config
);
parse_claim!(quote_body, "rtmr_0", quote.report_body.rtmr_0);
parse_claim!(quote_body, "rtmr_1", quote.report_body.rtmr_1);
parse_claim!(quote_body, "rtmr_2", quote.report_body.rtmr_2);
parse_claim!(quote_body, "rtmr_3", quote.report_body.rtmr_3);
parse_claim!(quote_body, "report_data", quote.report_body.report_data);

parse_claim!(quote_map, "header", quote_header);
parse_claim!(quote_map, "body", quote_body);

match &quote {
Quote::V4 { header, body } => {
parse_claim!(quote_header, "version", b"\x04\x00");
parse_claim!(quote_header, "att_key_type", header.att_key_type);
parse_claim!(quote_header, "tee_type", header.tee_type);
parse_claim!(quote_header, "reserved", header.reserved);
parse_claim!(quote_header, "vendor_id", header.vendor_id);
parse_claim!(quote_header, "user_data", header.user_data);
parse_claim!(quote_body, "tcb_svn", body.tcb_svn);
parse_claim!(quote_body, "mr_seam", body.mr_seam);
parse_claim!(quote_body, "mrsigner_seam", body.mrsigner_seam);
parse_claim!(quote_body, "seam_attributes", body.seam_attributes);
parse_claim!(quote_body, "td_attributes", body.td_attributes);
parse_claim!(quote_body, "xfam", body.xfam);
parse_claim!(quote_body, "mr_td", body.mr_td);
parse_claim!(quote_body, "mr_config_id", body.mr_config_id);
parse_claim!(quote_body, "mr_owner", body.mr_owner);
parse_claim!(quote_body, "mr_owner_config", body.mr_owner_config);
parse_claim!(quote_body, "rtmr_0", body.rtmr_0);
parse_claim!(quote_body, "rtmr_1", body.rtmr_1);
parse_claim!(quote_body, "rtmr_2", body.rtmr_2);
parse_claim!(quote_body, "rtmr_3", body.rtmr_3);
parse_claim!(quote_body, "report_data", body.report_data);

parse_claim!(quote_map, "header", quote_header);
parse_claim!(quote_map, "body", quote_body);
}
Quote::V5 {
header,
r#type,
size,
body,
} => {
parse_claim!(quote_header, "version", b"\x05\x00");
parse_claim!(quote_header, "att_key_type", header.att_key_type);
parse_claim!(quote_header, "tee_type", header.tee_type);
parse_claim!(quote_header, "reserved", header.reserved);
parse_claim!(quote_header, "vendor_id", header.vendor_id);
parse_claim!(quote_header, "user_data", header.user_data);
parse_claim!(quote_map, "type", r#type.as_bytes());
parse_claim!(quote_map, "size", &size[..]);
match body {
QuoteV5Body::Tdx10(body) => {
parse_claim!(quote_body, "tcb_svn", body.tcb_svn);
parse_claim!(quote_body, "mr_seam", body.mr_seam);
parse_claim!(quote_body, "mrsigner_seam", body.mrsigner_seam);
parse_claim!(quote_body, "seam_attributes", body.seam_attributes);
parse_claim!(quote_body, "td_attributes", body.td_attributes);
parse_claim!(quote_body, "xfam", body.xfam);
parse_claim!(quote_body, "mr_td", body.mr_td);
parse_claim!(quote_body, "mr_config_id", body.mr_config_id);
parse_claim!(quote_body, "mr_owner", body.mr_owner);
parse_claim!(quote_body, "mr_owner_config", body.mr_owner_config);
parse_claim!(quote_body, "rtmr_0", body.rtmr_0);
parse_claim!(quote_body, "rtmr_1", body.rtmr_1);
parse_claim!(quote_body, "rtmr_2", body.rtmr_2);
parse_claim!(quote_body, "rtmr_3", body.rtmr_3);
parse_claim!(quote_body, "report_data", body.report_data);

parse_claim!(quote_map, "header", quote_header);
parse_claim!(quote_map, "body", quote_body);
}
QuoteV5Body::Tdx15(body) => {
parse_claim!(quote_body, "tcb_svn", body.tcb_svn);
parse_claim!(quote_body, "mr_seam", body.mr_seam);
parse_claim!(quote_body, "mrsigner_seam", body.mrsigner_seam);
parse_claim!(quote_body, "seam_attributes", body.seam_attributes);
parse_claim!(quote_body, "td_attributes", body.td_attributes);
parse_claim!(quote_body, "xfam", body.xfam);
parse_claim!(quote_body, "mr_td", body.mr_td);
parse_claim!(quote_body, "mr_config_id", body.mr_config_id);
parse_claim!(quote_body, "mr_owner", body.mr_owner);
parse_claim!(quote_body, "mr_owner_config", body.mr_owner_config);
parse_claim!(quote_body, "rtmr_0", body.rtmr_0);
parse_claim!(quote_body, "rtmr_1", body.rtmr_1);
parse_claim!(quote_body, "rtmr_2", body.rtmr_2);
parse_claim!(quote_body, "rtmr_3", body.rtmr_3);
parse_claim!(quote_body, "report_data", body.report_data);

parse_claim!(quote_body, "tee_tcb_svn2", body.tee_tcb_svn2);
parse_claim!(quote_body, "mr_servicetd", body.mr_servicetd);
parse_claim!(quote_map, "header", quote_header);
parse_claim!(quote_map, "body", quote_body);
}
}
}
}

// Claims from CC EventLog.
let mut ccel_map = Map::new();
Expand All @@ -124,8 +177,8 @@ pub fn generate_parsed_claim(
parse_claim!(claims, "quote", quote_map);
parse_claim!(claims, "ccel", ccel_map);

parse_claim!(claims, "report_data", quote.report_body.report_data);
parse_claim!(claims, "init_data", quote.report_body.mr_config_id);
parse_claim!(claims, "report_data", quote.report_data());
parse_claim!(claims, "init_data", quote.mr_config_id());

log::info!("\nParsed Evidence claims map: \n{:?}\n", &claims);

Expand Down
12 changes: 6 additions & 6 deletions attestation-service/verifier/src/tdx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ async fn verify_evidence(
if let ReportData::Value(expected_report_data) = expected_report_data {
debug!("Check the binding of REPORT_DATA.");
let expected_report_data = regularize_data(expected_report_data, 64, "REPORT_DATA", "TDX");
if expected_report_data != quote.report_body.report_data {
if expected_report_data != quote.report_data() {
bail!("REPORT_DATA is different from that in TDX Quote");
}
}
Expand All @@ -69,7 +69,7 @@ async fn verify_evidence(
debug!("Check the binding of MRCONFIGID.");
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 {
if expected_init_data_hash != quote.mr_config_id() {
bail!("MRCONFIGID is different from that in TDX Quote");
}
}
Expand All @@ -86,10 +86,10 @@ async fn verify_evidence(
log::debug!("Get CC Eventlog. \n{}\n", &ccel.cc_events);

let rtmr_from_quote = Rtmr {
rtmr0: quote.report_body.rtmr_0,
rtmr1: quote.report_body.rtmr_1,
rtmr2: quote.report_body.rtmr_2,
rtmr3: quote.report_body.rtmr_3,
rtmr0: quote.rtmr_0().try_into().expect("must be 48 bytes"),
rtmr1: quote.rtmr_1().try_into().expect("must be 48 bytes"),
rtmr2: quote.rtmr_2().try_into().expect("must be 48 bytes"),
rtmr3: quote.rtmr_3().try_into().expect("must be 48 bytes"),
};

ccel.integrity_check(rtmr_from_quote)?;
Expand Down
Loading

0 comments on commit 83b73b7

Please sign in to comment.