Skip to content

Commit d2e2ea5

Browse files
committed
refactor Quote v4 verifier
Signed-off-by: Jun Kimura <jun.kimura@datachain.jp>
1 parent 8d6bd10 commit d2e2ea5

File tree

6 files changed

+158
-158
lines changed

6 files changed

+158
-158
lines changed

crates/quote-verifier/src/cert.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,30 +75,38 @@ pub fn get_x509_issuer_cn(cert: &X509Certificate) -> String {
7575
cn.as_str().unwrap().to_string()
7676
}
7777

78+
/// Get the TCB status of the SGX and TDX corresponding to the given SVN from the TCB Info V3.
79+
/// This function returns the TCB status of the SGX and TDX, and the advisory IDs.
7880
/// ref. <https://github.com/intel/SGX-TDX-DCAP-QuoteVerificationLibrary/blob/7e5b2a13ca5472de8d97dd7d7024c2ea5af9a6ba/Src/AttestationLibrary/src/Verifiers/Checks/TcbLevelCheck.cpp#L129-L181>
79-
pub fn get_sgx_tdx_fmspc_tcbstatus_v3(
81+
///
82+
/// # Arguments
83+
/// * `tee_type` - The type of TEE (SGX or TDX)
84+
/// * `tee_tcb_svn` - The TCB SVN of the TEE (only for TDX)
85+
/// * `sgx_extensions` - The SGX Extensions from the PCK Certificate
86+
/// * `tcbinfov3` - The TCB Info V3
87+
/// # Returns
88+
/// * `(sgx_tcb_status, tdx_tcb_status, advisory_ids)` - The TCB status of the SGX and TDX, and the advisory IDs
89+
pub fn get_sgx_tdx_tcb_status_v3(
8090
tee_type: u32,
8191
tee_tcb_svn: Option<[u8; 16]>,
82-
// SGX Extensions from the PCK Certificate
8392
sgx_extensions: &SgxExtensions,
8493
tcbinfov3: &TcbInfoV3,
8594
) -> crate::Result<(TcbInfoV3TcbStatus, Option<TcbInfoV3TcbStatus>, Vec<String>)> {
86-
let is_tdx = tee_type == TDX_TEE_TYPE && tcbinfov3.tcb_info.id == "TDX";
87-
if !is_tdx {
88-
// check if tee_type and tcb_info.id are consistent
89-
assert!(tee_type == SGX_TEE_TYPE && tcbinfov3.tcb_info.id == "SGX");
90-
}
91-
92-
let is_tdx = if tee_type == SGX_TEE_TYPE {
93-
false
95+
if tee_type == SGX_TEE_TYPE {
96+
if tcbinfov3.tcb_info.id != "SGX" {
97+
bail!("Invalid TCB Info ID for SGX TEE Type");
98+
} else if tee_tcb_svn.is_some() {
99+
bail!("SGX TCB SVN is not needed");
100+
}
94101
} else if tee_type == TDX_TEE_TYPE {
95-
if tee_tcb_svn.is_none() {
102+
if tcbinfov3.tcb_info.id != "TDX" {
103+
bail!("Invalid TCB Info ID for TDX TEE Type");
104+
} else if tee_tcb_svn.is_none() {
96105
bail!("TDX TCB SVN is missing");
97106
}
98-
true
99107
} else {
100108
bail!("Unsupported TEE type: {}", tee_type);
101-
};
109+
}
102110

103111
// ref. https://github.com/intel/SGX-TDX-DCAP-QuoteVerificationLibrary/blob/7e5b2a13ca5472de8d97dd7d7024c2ea5af9a6ba/Src/AttestationLibrary/src/Verifiers/QuoteVerifier.cpp#L117
104112
if sgx_extensions.fmspc != tcbinfov3.tcb_info.fmspc()? {
@@ -125,15 +133,16 @@ pub fn get_sgx_tdx_fmspc_tcbstatus_v3(
125133
&& extension_pcesvn >= tcb_level.tcb.pcesvn
126134
{
127135
sgx_tcb_status = Some(TcbInfoV3TcbStatus::from_str(tcb_level.tcb_status.as_str())?);
128-
if !is_tdx {
136+
if tee_type == SGX_TEE_TYPE {
129137
return Ok((
130138
sgx_tcb_status.unwrap(),
131139
None,
132140
tcb_level.advisory_ids.clone().unwrap_or_default(),
133141
));
134142
}
135143
}
136-
if is_tdx && sgx_tcb_status.is_some() {
144+
145+
if tee_type == TDX_TEE_TYPE && sgx_tcb_status.is_some() {
137146
let tdxtcbcomponents = match &tcb_level.tcb.tdxtcbcomponents {
138147
Some(cmps) => cmps,
139148
None => bail!("TDX TCB Components are missing"),

crates/quote-verifier/src/quotes/version_3.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::{check_quote_header, converge_tcb_status_with_qe_tcb, verify_quote_common, Result};
22
use crate::{
3-
cert::{get_sgx_tdx_fmspc_tcbstatus_v3, merge_advisory_ids},
3+
cert::{get_sgx_tdx_tcb_status_v3, merge_advisory_ids},
44
collaterals::IntelCollateral,
55
crypto::keccak256sum,
66
verifier::QuoteVerificationOutput,
@@ -41,7 +41,7 @@ pub fn verify_quote_v3(
4141
)?;
4242
let TcbInfo::V3(tcb_info_v3) = tcb_info;
4343
let (tcb_status, _, tcb_advisory_ids) =
44-
get_sgx_tdx_fmspc_tcbstatus_v3(quote.header.tee_type, None, &sgx_extensions, &tcb_info_v3)?;
44+
get_sgx_tdx_tcb_status_v3(quote.header.tee_type, None, &sgx_extensions, &tcb_info_v3)?;
4545

4646
Ok(QuoteVerificationOutput {
4747
version: VERIFIER_VERSION,

crates/quote-verifier/src/quotes/version_4.rs

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use super::{check_quote_header, converge_tcb_status_with_qe_tcb, verify_quote_common, Result};
22
use crate::{
3-
cert::{get_sgx_tdx_fmspc_tcbstatus_v3, merge_advisory_ids},
3+
cert::{get_sgx_tdx_tcb_status_v3, merge_advisory_ids},
44
collaterals::IntelCollateral,
55
crypto::sha256sum,
6-
tdx_module::{converge_tcb_status_with_tdx_module_tcb, get_tdx_module_identity_and_tcb},
6+
tdx_module::{check_tdx_module_tcb_status, converge_tcb_status_with_tdx_module_tcb},
77
verifier::QuoteVerificationOutput,
88
VERIFIER_VERSION,
99
};
@@ -12,7 +12,7 @@ use core::cmp::min;
1212
use dcap_types::{
1313
quotes::{body::QuoteBody, version_4::QuoteV4, CertDataType},
1414
tcbinfo::TcbInfo,
15-
TcbInfoV3TcbStatus, TdxModuleTcbValidationStatus, SGX_TEE_TYPE,
15+
TdxModuleTcbValidationStatus, SGX_TEE_TYPE, TDX_TEE_TYPE,
1616
};
1717

1818
/// Verify the given DCAP quote v4 and return the verification output.
@@ -58,61 +58,63 @@ pub fn verify_quote_v4(
5858

5959
let TcbInfo::V3(tcb_info_v3) = tcb_info;
6060
let (quote_tdx_body, tee_tcb_svn) = if let QuoteBody::TD10QuoteBody(body) = &quote.quote_body {
61-
(Some(body), body.tee_tcb_svn)
61+
(Some(body), Some(body.tee_tcb_svn))
6262
} else {
63-
// SGX does not produce tee_tcb_svns
64-
(None, [0; 16])
63+
// SGX does not produce tee_tcb_svn
64+
(None, None)
6565
};
6666

67-
// check TCB level
68-
6967
let tee_type = quote.header.tee_type;
7068
let (sgx_tcb_status, tdx_tcb_status, tcb_advisory_ids) =
71-
get_sgx_tdx_fmspc_tcbstatus_v3(tee_type, Some(tee_tcb_svn), &sgx_extensions, &tcb_info_v3)?;
69+
get_sgx_tdx_tcb_status_v3(tee_type, tee_tcb_svn, &sgx_extensions, &tcb_info_v3)?;
7270

73-
let mut advisory_ids = merge_advisory_ids(tcb_advisory_ids, qe_tcb.advisory_ids);
74-
let mut tcb_status: TcbInfoV3TcbStatus;
75-
if quote.header.tee_type == SGX_TEE_TYPE {
76-
tcb_status = sgx_tcb_status;
77-
} else {
78-
tcb_status = tdx_tcb_status.context("TDX TCB Status not found")?;
71+
let advisory_ids = merge_advisory_ids(tcb_advisory_ids, qe_tcb.advisory_ids);
72+
73+
let (tcb_status, advisory_ids) = if tee_type == TDX_TEE_TYPE {
74+
let tdx_tcb_status = tdx_tcb_status.context("TDX TCB Status not found")?;
7975

8076
// Fetch TDXModule TCB and TDXModule Identity
8177
let (
8278
tdx_module_tcb_status,
8379
tdx_module_advisory_ids,
8480
tdx_module_mrsigner,
8581
tdx_module_attributes,
86-
) = get_tdx_module_identity_and_tcb(&tee_tcb_svn, &tcb_info_v3)?;
82+
) = check_tdx_module_tcb_status(&tee_tcb_svn.unwrap_or_default(), &tcb_info_v3)?;
8783
if tdx_module_tcb_status == TdxModuleTcbValidationStatus::TcbNotSupported
8884
|| tdx_module_tcb_status == TdxModuleTcbValidationStatus::TdxModuleMismatch
8985
{
90-
// NOTE: early return - modify from the original
86+
// NOTE: early return - different from the original code
9187
bail!("TDX Module TCB not supported or out of date");
9288
}
9389

9490
// check TDX module
95-
let (tdx_report_mrsigner, tdx_report_attributes) = if let Some(tdx_body) = quote_tdx_body {
96-
(tdx_body.mrsignerseam, tdx_body.seam_attributes)
97-
} else {
98-
unreachable!();
99-
};
91+
let (tdx_report_mrsigner, tdx_report_attributes) = quote_tdx_body
92+
.map(|tdx_body| (tdx_body.mrsignerseam, tdx_body.seam_attributes))
93+
.context("TDX Quote Body not found")?;
10094

101-
// TODO check if these validations are correct
102-
let mr_signer_matched = tdx_module_mrsigner == tdx_report_mrsigner;
103-
let attributes_matched = tdx_module_attributes == tdx_report_attributes;
104-
if !mr_signer_matched || !attributes_matched {
105-
bail!("TDX module values mismatch");
95+
// ref. https://github.com/intel/SGX-TDX-DCAP-QuoteVerificationLibrary/blob/7e5b2a13ca5472de8d97dd7d7024c2ea5af9a6ba/Src/AttestationLibrary/src/Verifiers/QuoteVerifier.cpp#L181
96+
if tdx_module_mrsigner != tdx_report_mrsigner {
97+
bail!("TDX module mrsigner mismatch");
98+
}
99+
// ref. https://github.com/intel/SGX-TDX-DCAP-QuoteVerificationLibrary/blob/7e5b2a13ca5472de8d97dd7d7024c2ea5af9a6ba/Src/AttestationLibrary/src/Verifiers/QuoteVerifier.cpp#L200
100+
if tdx_module_attributes != tdx_report_attributes {
101+
bail!("TDX module attributes mismatch");
106102
}
107103

108-
tcb_status = converge_tcb_status_with_tdx_module_tcb(tcb_status, tdx_module_tcb_status);
109-
advisory_ids = merge_advisory_ids(advisory_ids, tdx_module_advisory_ids);
110-
}
104+
(
105+
converge_tcb_status_with_tdx_module_tcb(tdx_tcb_status, tdx_module_tcb_status),
106+
merge_advisory_ids(advisory_ids, tdx_module_advisory_ids),
107+
)
108+
} else if tee_type == SGX_TEE_TYPE {
109+
(sgx_tcb_status, advisory_ids)
110+
} else {
111+
bail!("Unsupported TEE type: {}", tee_type);
112+
};
111113

112114
Ok(QuoteVerificationOutput {
113115
version: VERIFIER_VERSION,
114116
quote_version: quote.header.version,
115-
tee_type: quote.header.tee_type,
117+
tee_type,
116118
tcb_status: converge_tcb_status_with_qe_tcb(tcb_status, qe_tcb.tcb_status),
117119
min_tcb_evaluation_data_number: min(
118120
qe_tcb.tcb_evaluation_data_number,
Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,53 @@
11
use crate::Result;
2-
use anyhow::bail;
2+
use anyhow::Context;
33
use dcap_types::tcbinfo::TcbInfoV3;
44
use dcap_types::{TcbInfoV3TcbStatus, TdxModuleTcbStatus, TdxModuleTcbValidationStatus};
55
use std::str::FromStr;
66

7-
// https://github.com/intel/SGX-TDX-DCAP-QuoteVerificationLibrary/blob/7e5b2a13ca5472de8d97dd7d7024c2ea5af9a6ba/Src/AttestationLibrary/src/Verifiers/Checks/TdxModuleCheck.cpp#L62-L97
8-
pub fn get_tdx_module_identity_and_tcb(
7+
/// Get the TCB status of the TDX module corresponding to the given SVN.
8+
/// ref. <https://github.com/intel/SGX-TDX-DCAP-QuoteVerificationLibrary/blob/7e5b2a13ca5472de8d97dd7d7024c2ea5af9a6ba/Src/AttestationLibrary/src/Verifiers/Checks/TdxModuleCheck.cpp#L62-L97>
9+
///
10+
/// # Arguments
11+
/// - `tee_tcb_svn`: The SVN of the TEE TCB extracted from the `TD10ReportBody::tee_tcb_svn`
12+
/// - `tcb_info_v3`: The TDX TCB Info V3
13+
/// # Returns
14+
/// - The TCB status of the TDX module
15+
pub fn check_tdx_module_tcb_status(
916
tee_tcb_svn: &[u8; 16],
1017
tcb_info_v3: &TcbInfoV3,
1118
) -> Result<(TdxModuleTcbValidationStatus, Vec<String>, [u8; 48], u64)> {
12-
let tdx_module = if let Some(tdx_module_obj) = &tcb_info_v3.tcb_info.tdx_module {
13-
tdx_module_obj
14-
} else {
15-
bail!("TDX module not found");
16-
};
19+
let tdx_module = tcb_info_v3
20+
.tcb_info
21+
.tdx_module
22+
.as_ref()
23+
.context("TDX module not found")?;
1724

1825
let tdx_module_isv_svn = tee_tcb_svn[0];
1926
let tdx_module_version = tee_tcb_svn[1];
2027

2128
if tdx_module_version == 0 {
2229
// we assume the quote header version is greater than 3
23-
let mut mrsigner: [u8; 48] = [0; 48];
24-
mrsigner.copy_from_slice(&hex::decode(&tdx_module.mrsigner)?);
25-
2630
return Ok((
2731
TdxModuleTcbValidationStatus::Ok,
2832
Default::default(),
29-
mrsigner,
30-
from_str_to_u64(tdx_module.attributes.as_str())?,
33+
tdx_module.mrsigner()?,
34+
tdx_module.attributes()?,
3135
));
3236
}
3337

34-
let id = format!("TDX_{:02x}", tdx_module_version);
38+
let tdx_module_identity_id = format!("TDX_{:02x}", tdx_module_version);
3539
if let Some(tdx_module_identities) = &tcb_info_v3.tcb_info.tdx_module_identities {
36-
for tdx_module_identity in tdx_module_identities.iter().filter(|m| m.id == id) {
40+
for tdx_module_identity in tdx_module_identities
41+
.iter()
42+
.filter(|m| m.id == tdx_module_identity_id)
43+
{
3744
for tcb_level in &tdx_module_identity.tcb_levels {
3845
if tdx_module_isv_svn >= tcb_level.tcb.isvsvn {
39-
let mut mrsigner: [u8; 48] = [0; 48];
40-
mrsigner.copy_from_slice(&hex::decode(&tdx_module_identity.mrsigner)?);
4146
return Ok((
4247
TdxModuleTcbStatus::from_str(tcb_level.tcb_status.as_str())?.into(),
4348
tcb_level.advisory_ids.clone().unwrap_or_default(),
44-
mrsigner,
45-
from_str_to_u64(tdx_module_identity.attributes.as_str())?,
49+
tdx_module_identity.mrsigner()?,
50+
tdx_module_identity.attributes()?,
4651
));
4752
}
4853
}
@@ -63,7 +68,8 @@ pub fn get_tdx_module_identity_and_tcb(
6368
}
6469
}
6570

66-
// https://github.com/intel/SGX-TDX-DCAP-QuoteVerificationLibrary/blob/7e5b2a13ca5472de8d97dd7d7024c2ea5af9a6ba/Src/AttestationLibrary/src/Verifiers/Checks/TdxModuleCheck.cpp#L99-L137
71+
/// Converge TCB status with TDX module TCB status
72+
/// ref. <https://github.com/intel/SGX-TDX-DCAP-QuoteVerificationLibrary/blob/7e5b2a13ca5472de8d97dd7d7024c2ea5af9a6ba/Src/AttestationLibrary/src/Verifiers/Checks/TdxModuleCheck.cpp#L99-L137>
6773
pub fn converge_tcb_status_with_tdx_module_tcb(
6874
tcb_status: TcbInfoV3TcbStatus,
6975
tdx_module_tcb_status: TdxModuleTcbValidationStatus,
@@ -83,14 +89,3 @@ pub fn converge_tcb_status_with_tdx_module_tcb(
8389
_ => tcb_status,
8490
}
8591
}
86-
87-
fn from_str_to_u64(str: &str) -> Result<u64> {
88-
if str.len() != 16 {
89-
bail!("Invalid u64 str length");
90-
}
91-
92-
match u64::from_str_radix(str, 16) {
93-
Ok(ret) => Ok(ret),
94-
Err(_) => bail!("Invalid hex character found"),
95-
}
96-
}

0 commit comments

Comments
 (0)