Skip to content

Commit e6fd9cf

Browse files
committed
add min_tcb_evaluation_data_number to VerifiedOutput
Signed-off-by: Jun Kimura <jun.kimura@datachain.jp>
1 parent add8a70 commit e6fd9cf

File tree

9 files changed

+100
-80
lines changed

9 files changed

+100
-80
lines changed

crates/collaterals/src/enclave_identity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl EnclaveIdentityV2Builder {
8585
}
8686
}
8787

88-
pub fn tcb_evaluation_data_number(self, tcb_evaluation_data_number: u64) -> Self {
88+
pub fn tcb_evaluation_data_number(self, tcb_evaluation_data_number: u32) -> Self {
8989
Self {
9090
obj: EnclaveIdentityV2Inner {
9191
tcb_evaluation_data_number,

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

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ use dcap_types::{EnclaveIdentityV2TcbStatus, Status, TcbInfoV3TcbStatus};
2727
use dcap_types::{ECDSA_256_WITH_P256_CURVE, INTEL_QE_VENDOR_ID};
2828
use x509_parser::certificate::X509Certificate;
2929

30+
/// The TCB info of the QE
31+
#[derive(Debug, Clone, PartialEq, Eq)]
32+
pub struct QETCB {
33+
pub tcb_evaluation_data_number: u32,
34+
pub tcb_status: EnclaveIdentityV2TcbStatus,
35+
pub advisory_ids: Vec<String>,
36+
}
37+
3038
/// common_verify_and_fetch_tcb is a common function that verifies the quote and fetches the TCB info
3139
///
3240
/// # Arguments
@@ -46,7 +54,6 @@ use x509_parser::certificate::X509Certificate;
4654
///
4755
/// * A tuple containing:
4856
/// * The TCB status of the QE
49-
/// * The advisory IDs of the QE
5057
/// * The SGX extensions from the PCK leaf certificate
5158
/// * The TCB info
5259
/// * The validity intersection of all collaterals
@@ -62,13 +69,7 @@ fn common_verify_and_fetch_tcb(
6269
qe_cert_data: &CertData,
6370
collaterals: &IntelCollateral,
6471
current_time: u64,
65-
) -> Result<(
66-
EnclaveIdentityV2TcbStatus,
67-
Vec<String>,
68-
SgxExtensions,
69-
TcbInfo,
70-
ValidityIntersection,
71-
)> {
72+
) -> Result<(QETCB, SgxExtensions, TcbInfo, ValidityIntersection)> {
7273
// get the certchain embedded in the ecda quote signature data
7374
// this can be one of 5 types, and we only support type 5
7475
// https://github.com/intel/SGXDataCenterAttestationPrimitives/blob/aa239d25a437a28f3f4de92c38f5b6809faac842/QuoteGeneration/quote_wrapper/common/inc/sgx_quote_3.h#L63C4-L63C112
@@ -143,41 +144,28 @@ fn common_verify_and_fetch_tcb(
143144
};
144145

145146
// validate QE Report and Quote Body
146-
let (qe_tcb_status, advisory_ids, pck_cert_sgx_extensions) = {
147-
let (qe_tcb_status, advisory_ids) = verify_qe_report(
148-
qe_report,
149-
ecdsa_attestation_pubkey,
150-
qe_auth_data,
151-
&qeidentityv2,
152-
&pck_leaf_cert,
153-
qe_report_signature,
154-
)?;
155-
verify_quote_attestation(
156-
quote_header,
157-
quote_body,
158-
ecdsa_attestation_pubkey,
159-
ecdsa_attestation_signature,
160-
)
161-
.context("Invalid quote attestation")?;
162-
163-
(
164-
qe_tcb_status,
165-
advisory_ids,
166-
extract_sgx_extensions(&pck_leaf_cert)?,
167-
)
168-
};
147+
let qe_tcb = verify_qe_report(
148+
qe_report,
149+
ecdsa_attestation_pubkey,
150+
qe_auth_data,
151+
&qeidentityv2,
152+
&pck_leaf_cert,
153+
qe_report_signature,
154+
)?;
155+
verify_quote_attestation(
156+
quote_header,
157+
quote_body,
158+
ecdsa_attestation_pubkey,
159+
ecdsa_attestation_signature,
160+
)
161+
.context("Invalid quote attestation")?;
162+
let pck_cert_sgx_extensions = extract_sgx_extensions(&pck_leaf_cert)?;
169163

170164
if !validity.validate() {
171165
bail!("Validity intersection provided from collaterals is invalid");
172166
}
173167

174-
Ok((
175-
qe_tcb_status,
176-
advisory_ids,
177-
pck_cert_sgx_extensions,
178-
tcb_info,
179-
validity,
180-
))
168+
Ok((qe_tcb, pck_cert_sgx_extensions, tcb_info, validity))
181169
}
182170

183171
fn check_quote_header(quote_header: &QuoteHeader, expected_quote_version: u16) -> Result<()> {
@@ -206,7 +194,7 @@ fn verify_qe_report(
206194
qeidentityv2: &EnclaveIdentityV2,
207195
pck_leaf_cert: &X509Certificate,
208196
qe_report_signature: &[u8; 64],
209-
) -> Result<(EnclaveIdentityV2TcbStatus, Vec<String>)> {
197+
) -> Result<QETCB> {
210198
// validate QEReport then get TCB Status
211199
if !validate_qe_report_data(
212200
&qe_report.report_data,
@@ -228,7 +216,14 @@ fn verify_qe_report(
228216

229217
// https://github.com/intel/SGX-TDX-DCAP-QuoteVerificationLibrary/blob/29bd3b0a3b46c1159907d656b45f378f97e7e686/Src/AttestationLibrary/src/Verifiers/EnclaveReportVerifier.cpp#L92
230218
// https://github.com/intel/SGX-TDX-DCAP-QuoteVerificationLibrary/blob/7e5b2a13ca5472de8d97dd7d7024c2ea5af9a6ba/Src/AttestationLibrary/src/Verifiers/QuoteVerifier.cpp#L286
231-
get_qe_tcbstatus(qe_report.isv_svn, &qeidentityv2.enclave_identity.tcb_levels)
219+
let (tcb_status, advisory_ids) =
220+
get_qe_tcbstatus(qe_report.isv_svn, &qeidentityv2.enclave_identity.tcb_levels)?;
221+
222+
Ok(QETCB {
223+
tcb_evaluation_data_number: qeidentityv2.enclave_identity.tcb_evaluation_data_number,
224+
tcb_status,
225+
advisory_ids,
226+
})
232227
}
233228

234229
/// Verify the attestation signature for the quote (header + body) using the attestation public key

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

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::{
99
VERIFIER_VERSION,
1010
};
1111
use anyhow::{bail, Context};
12+
use core::cmp::min;
1213
use dcap_types::{
1314
quotes::{body::QuoteBody, version_3::QuoteV3},
1415
tcbinfo::TcbInfo,
@@ -22,19 +23,18 @@ pub fn verify_quote_dcapv3(
2223
check_quote_header(&quote.header, 3).context("invalid quote header")?;
2324

2425
let quote_body = QuoteBody::SGXQuoteBody(quote.isv_enclave_report);
25-
let (qe_tcb_status, qe_advisory_ids, sgx_extensions, tcb_info, validity) =
26-
common_verify_and_fetch_tcb(
27-
&quote.header,
28-
&quote_body,
29-
&quote.signature.isv_enclave_report_signature,
30-
&quote.signature.ecdsa_attestation_key,
31-
&quote.signature.qe_report,
32-
&quote.signature.qe_report_signature,
33-
&quote.signature.qe_auth_data.data,
34-
&quote.signature.qe_cert_data,
35-
collaterals,
36-
current_time,
37-
)?;
26+
let (qe_status, sgx_extensions, tcb_info, validity) = common_verify_and_fetch_tcb(
27+
&quote.header,
28+
&quote_body,
29+
&quote.signature.isv_enclave_report_signature,
30+
&quote.signature.ecdsa_attestation_key,
31+
&quote.signature.qe_report,
32+
&quote.signature.qe_report_signature,
33+
&quote.signature.qe_auth_data.data,
34+
&quote.signature.qe_cert_data,
35+
collaterals,
36+
current_time,
37+
)?;
3838
if !validity.validate_time(current_time) {
3939
bail!(
4040
"certificates are expired: validity={} current_time={}",
@@ -50,12 +50,16 @@ pub fn verify_quote_dcapv3(
5050
version: VERIFIER_VERSION,
5151
quote_version: quote.header.version,
5252
tee_type: quote.header.tee_type,
53-
tcb_status: converge_tcb_status_with_qe_tcb(tcb_status, qe_tcb_status),
53+
tcb_status: converge_tcb_status_with_qe_tcb(tcb_status, qe_status.tcb_status),
54+
min_tcb_evaluation_data_number: min(
55+
qe_status.tcb_evaluation_data_number,
56+
tcb_info_v3.tcb_info.tcb_evaluation_data_number,
57+
),
5458
fmspc: sgx_extensions.fmspc,
5559
sgx_intel_root_ca_hash: keccak256sum(collaterals.sgx_intel_root_ca_der.as_ref()),
5660
validity,
5761
quote_body,
58-
advisory_ids: merge_advisory_ids(tcb_advisory_ids, qe_advisory_ids),
62+
advisory_ids: merge_advisory_ids(tcb_advisory_ids, qe_status.advisory_ids),
5963
})
6064
}
6165

@@ -143,11 +147,13 @@ mod tests {
143147
// fmspc and tcb_levels must be consistent with the sgx extensions in the pck cert
144148
let tcb_info = TcbInfoV3Builder::new(true)
145149
.fmspc([0, 96, 106, 0, 0, 0])
150+
.tcb_evaluation_data_number(2)
146151
.tcb_levels(target_tcb_levels)
147152
.build_and_sign(&tcb_certchain.key)
148153
.unwrap();
149154

150155
let qe_identity = EnclaveIdentityV2Builder::new(EnclaveIdentityId::QE)
156+
.tcb_evaluation_data_number(1)
151157
.tcb_levels_json(json!([
152158
{
153159
"tcb": {
@@ -172,5 +178,7 @@ mod tests {
172178
let current_time = 1730000000;
173179
let res = verify_quote_dcapv3(&quote, &collateral, current_time);
174180
assert!(res.is_ok(), "{:?}", res);
181+
let output = res.unwrap();
182+
assert_eq!(output.min_tcb_evaluation_data_number, 1);
175183
}
176184
}

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

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
VERIFIER_VERSION,
1111
};
1212
use anyhow::{bail, Context};
13+
use core::cmp::min;
1314
use dcap_types::{
1415
quotes::{body::QuoteBody, version_4::QuoteV4, CertDataType},
1516
tcbinfo::TcbInfo,
@@ -38,19 +39,18 @@ pub fn verify_quote_dcapv4(
3839
);
3940
};
4041

41-
let (qe_tcb_status, qe_advisory_ids, sgx_extensions, tcb_info, validity) =
42-
common_verify_and_fetch_tcb(
43-
&quote.header,
44-
&quote.quote_body,
45-
&quote.signature.quote_signature,
46-
&quote.signature.ecdsa_attestation_key,
47-
&qe_report_cert_data.qe_report,
48-
&qe_report_cert_data.qe_report_signature,
49-
&qe_report_cert_data.qe_auth_data.data,
50-
&qe_report_cert_data.qe_cert_data,
51-
collaterals,
52-
current_time,
53-
)?;
42+
let (qe_tcb, sgx_extensions, tcb_info, validity) = common_verify_and_fetch_tcb(
43+
&quote.header,
44+
&quote.quote_body,
45+
&quote.signature.quote_signature,
46+
&quote.signature.ecdsa_attestation_key,
47+
&qe_report_cert_data.qe_report,
48+
&qe_report_cert_data.qe_report_signature,
49+
&qe_report_cert_data.qe_auth_data.data,
50+
&qe_report_cert_data.qe_cert_data,
51+
collaterals,
52+
current_time,
53+
)?;
5454

5555
if !validity.validate_time(current_time) {
5656
bail!(
@@ -73,7 +73,7 @@ pub fn verify_quote_dcapv4(
7373
let (sgx_tcb_status, tdx_tcb_status, tcb_advisory_ids) =
7474
get_sgx_tdx_fmspc_tcbstatus_v3(tee_type, Some(tee_tcb_svn), &sgx_extensions, &tcb_info_v3)?;
7575

76-
let mut advisory_ids = merge_advisory_ids(tcb_advisory_ids, qe_advisory_ids);
76+
let mut advisory_ids = merge_advisory_ids(tcb_advisory_ids, qe_tcb.advisory_ids);
7777
let mut tcb_status: TcbInfoV3TcbStatus;
7878
if quote.header.tee_type == SGX_TEE_TYPE {
7979
tcb_status = sgx_tcb_status;
@@ -116,7 +116,11 @@ pub fn verify_quote_dcapv4(
116116
version: VERIFIER_VERSION,
117117
quote_version: quote.header.version,
118118
tee_type: quote.header.tee_type,
119-
tcb_status: converge_tcb_status_with_qe_tcb(tcb_status, qe_tcb_status),
119+
tcb_status: converge_tcb_status_with_qe_tcb(tcb_status, qe_tcb.tcb_status),
120+
min_tcb_evaluation_data_number: min(
121+
qe_tcb.tcb_evaluation_data_number,
122+
tcb_info_v3.tcb_info.tcb_evaluation_data_number,
123+
),
120124
fmspc: sgx_extensions.fmspc,
121125
sgx_intel_root_ca_hash: sha256sum(collaterals.sgx_intel_root_ca_der.as_ref()),
122126
validity,

crates/quote-verifier/src/verifier.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ pub struct VerifiedOutput {
116116
/// TCB status
117117
/// length: 1 byte
118118
pub tcb_status: Status,
119+
/// Minimum TCB evaluation data number
120+
/// length: 4 bytes
121+
pub min_tcb_evaluation_data_number: u32,
119122
/// FMSPC
120123
/// length: 6 bytes
121124
pub fmspc: [u8; 6],
@@ -145,6 +148,7 @@ impl VerifiedOutput {
145148
output_vec.extend_from_slice(&self.quote_version.to_be_bytes());
146149
output_vec.extend_from_slice(&self.tee_type.to_be_bytes());
147150
output_vec.push(self.tcb_status.as_u8());
151+
output_vec.extend_from_slice(&self.min_tcb_evaluation_data_number.to_be_bytes());
148152
output_vec.extend_from_slice(&self.fmspc);
149153
output_vec.extend_from_slice(&self.sgx_intel_root_ca_hash);
150154
output_vec.extend_from_slice(&self.validity.not_before_max.to_be_bytes());
@@ -176,18 +180,20 @@ impl VerifiedOutput {
176180
let mut tee_type = [0; 4];
177181
tee_type.copy_from_slice(&slice[4..8]);
178182
let tcb_status = Status::from_u8(slice[8])?;
183+
let mut min_tcb_evaluation_data_number = [0; 4];
184+
min_tcb_evaluation_data_number.copy_from_slice(&slice[9..13]);
179185
let mut fmspc = [0; 6];
180-
fmspc.copy_from_slice(&slice[9..15]);
186+
fmspc.copy_from_slice(&slice[13..19]);
181187

182188
let mut sgx_intel_root_ca_hash = [0; 32];
183-
sgx_intel_root_ca_hash.copy_from_slice(&slice[15..47]);
189+
sgx_intel_root_ca_hash.copy_from_slice(&slice[19..51]);
184190

185191
let mut not_before_max = [0; 8];
186-
not_before_max.copy_from_slice(&slice[47..55]);
192+
not_before_max.copy_from_slice(&slice[51..59]);
187193
let mut not_after_min = [0; 8];
188-
not_after_min.copy_from_slice(&slice[55..63]);
194+
not_after_min.copy_from_slice(&slice[59..67]);
189195

190-
const QUOTE_BODY_OFFSET: usize = 63;
196+
const QUOTE_BODY_OFFSET: usize = 67;
191197
let (quote_body, advisory_ids_offset) = match u32::from_be_bytes(tee_type) {
192198
SGX_TEE_TYPE => {
193199
let raw_quote_body =
@@ -214,6 +220,7 @@ impl VerifiedOutput {
214220
quote_version: u16::from_be_bytes(quote_version),
215221
tee_type: u32::from_be_bytes(tee_type),
216222
tcb_status,
223+
min_tcb_evaluation_data_number: u32::from_be_bytes(min_tcb_evaluation_data_number),
217224
fmspc,
218225
sgx_intel_root_ca_hash,
219226
validity: ValidityIntersection {

crates/types/src/enclave_identity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ pub struct EnclaveIdentityV2Inner {
144144
pub version: u64,
145145
pub issue_date: String,
146146
pub next_update: String,
147-
pub tcb_evaluation_data_number: u64,
147+
pub tcb_evaluation_data_number: u32,
148148
pub miscselect: String,
149149
pub miscselect_mask: String,
150150
pub attributes: String,

zkvm/risc0/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ edition = "2021"
66
[package.metadata.risc0]
77
methods = ["guest"]
88

9+
[dependencies]
10+
risc0-zkvm = { version = "=1.2.2", default-features = false, optional = true }
11+
912
[build-dependencies]
1013
risc0-build = { version = "=1.2.2", features = ["docker", "unstable"] }
1114
risc0-binfmt = { version = "=1.2.2", default-features = false }
1215

1316
[dev-dependencies]
1417
risc0-zkvm = { version = "=1.2.2", default-features = false, features = ["prove"] }
1518
hex = { version = "0.4", default-features = false, features = ["alloc"] }
16-
dcap-quote-verifier = { path = "../../crates/quote-verifier" }
19+
dcap-quote-verifier = { path = "../../crates/quote-verifier" }
20+
21+
[features]
22+
cuda = ["risc0-zkvm?/cuda"]
36 Bytes
Binary file not shown.

zkvm/risc0/src/methods.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11

2-
pub const DCAP_QUOTE_VERIFIER_ID: [u32; 8] = [1310702660, 1468422329, 87586300, 1252053983, 3549838645, 1249629134, 1412581844, 922648141];
3-
pub const DCAP_QUOTE_VERIFIER_ID_STR: &str = "44bc1f4eb9588657fc753805dfd3a04a353d96d3ced37b4ad44932544d7efe36";
2+
pub const DCAP_QUOTE_VERIFIER_ID: [u32; 8] = [927428042, 1559589155, 2728204900, 3879470470, 2705950934, 683452413, 3440644992, 2443300394];
3+
pub const DCAP_QUOTE_VERIFIER_ID_STR: &str = "ca6d47372371f55c641a9da286053ce7d68849a1fda7bc28801314cd2acea191";
44
pub const DCAP_QUOTE_VERIFIER_ELF: &[u8] = include_bytes!("../artifacts/dcap-quote-verifier");

0 commit comments

Comments
 (0)