Skip to content

Commit b5c9d05

Browse files
committed
Enforce some more minor checks
1 parent befd2df commit b5c9d05

File tree

4 files changed

+333
-128
lines changed

4 files changed

+333
-128
lines changed

cli/src/bin/generate_all_samples.rs

Lines changed: 158 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -216,87 +216,6 @@ fn generate_base_quote(version: u16, key_type: u16, debug: bool) -> Result<Vec<u
216216
Ok(quote.encode())
217217
}
218218

219-
fn generate_sgx_v5_quote() -> Result<Vec<u8>> {
220-
// Quote v5 uses Body structure and v4 auth data
221-
let header = create_sgx_header(5, 2, 0);
222-
let report = create_sgx_report(false);
223-
224-
// Create Body for v5
225-
let body = Body {
226-
body_type: 1, // BODY_SGX_ENCLAVE_REPORT_TYPE
227-
size: 384, // Size of EnclaveReport
228-
};
229-
230-
let pck_cert = fs::read_to_string(format!("{}/pck.pem", CERT_DIR))?;
231-
let root_cert = fs::read_to_string(format!("{}/root_ca.pem", CERT_DIR))?;
232-
let pck_chain_for_quote = format!("{}{}", pck_cert, root_cert);
233-
234-
let pck_key_path = &format!("{}/pck.pkcs8.key", CERT_DIR);
235-
let pck_key_pair = load_private_key(pck_key_path)?;
236-
237-
let rng = SystemRandom::new();
238-
let attestation_pkcs8 =
239-
ring::signature::EcdsaKeyPair::generate_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, &rng)?;
240-
let attestation_key_pair = EcdsaKeyPair::from_pkcs8(
241-
&ECDSA_P256_SHA256_FIXED_SIGNING,
242-
attestation_pkcs8.as_ref(),
243-
&rng,
244-
)?;
245-
246-
let attestation_public_key = attestation_key_pair.public_key().as_ref();
247-
let mut ecdsa_attestation_key = [0u8; 64];
248-
ecdsa_attestation_key.copy_from_slice(&attestation_public_key[1..65]);
249-
250-
let qe_auth_data = vec![0u8; 32];
251-
let mut qe_hash_data = [0u8; 96];
252-
qe_hash_data[0..64].copy_from_slice(&ecdsa_attestation_key);
253-
qe_hash_data[64..].copy_from_slice(&qe_auth_data);
254-
let qe_hash = ring::digest::digest(&ring::digest::SHA256, &qe_hash_data);
255-
256-
let mut qe_report_data = create_sgx_report(false);
257-
qe_report_data.report_data[0..32].copy_from_slice(qe_hash.as_ref());
258-
let qe_report_bytes = qe_report_data.encode();
259-
let mut qe_report = [0u8; 384];
260-
qe_report[..qe_report_bytes.len()].copy_from_slice(&qe_report_bytes);
261-
262-
let qe_report_signature = sign_data(&pck_key_pair, &qe_report)?;
263-
264-
// Sign quote (header + body + report)
265-
let mut signed_data = header.encode();
266-
signed_data.extend_from_slice(&body.encode());
267-
signed_data.extend_from_slice(&report.encode());
268-
let ecdsa_signature = sign_data(&attestation_key_pair, &signed_data)?;
269-
270-
// Use v4 auth data for v5 quote
271-
let qe_report_data = QEReportCertificationData {
272-
qe_report,
273-
qe_report_signature,
274-
qe_auth_data: Data::<u16>::new(qe_auth_data.clone()),
275-
certification_data: CertificationData {
276-
cert_type: 5,
277-
body: Data::<u32>::new(pck_chain_for_quote.into_bytes()),
278-
},
279-
};
280-
281-
let auth_data = AuthData::V4(AuthDataV4 {
282-
ecdsa_signature,
283-
ecdsa_attestation_key,
284-
certification_data: CertificationData {
285-
cert_type: 5,
286-
body: Data::<u32>::new(vec![]),
287-
},
288-
qe_report_data,
289-
});
290-
291-
let quote = Quote {
292-
header,
293-
report: Report::SgxEnclave(report),
294-
auth_data,
295-
};
296-
297-
Ok(quote.encode())
298-
}
299-
300219
fn generate_tdx_quote_v4() -> Result<Vec<u8>> {
301220
let header = create_sgx_header(4, 2, 0x00000081); // TEE_TYPE_TDX = 0x81
302221
let report = create_tdx_report();
@@ -553,6 +472,27 @@ fn generate_base_collateral() -> Result<serde_json::Value> {
553472
}))
554473
}
555474

475+
fn update_qe_identity(
476+
collateral: &mut serde_json::Value,
477+
id: &str,
478+
version: u8,
479+
) -> Result<()> {
480+
if let Some(qe_str) = collateral["qe_identity"].as_str() {
481+
let mut qe_identity = serde_json::from_str::<serde_json::Value>(qe_str)?;
482+
qe_identity["id"] = json!(id);
483+
qe_identity["version"] = json!(version);
484+
let new_qe_identity = serde_json::to_string(&qe_identity)?;
485+
486+
let key_path = &format!("{}/tcb_signing.pkcs8.key", CERT_DIR);
487+
let key_pair = load_private_key(key_path)?;
488+
let qe_identity_signature = sign_data(&key_pair, new_qe_identity.as_bytes())?;
489+
490+
collateral["qe_identity"] = json!(new_qe_identity);
491+
collateral["qe_identity_signature"] = json!(hex::encode(qe_identity_signature));
492+
}
493+
Ok(())
494+
}
495+
556496
fn create_sample_directory(name: &str) -> Result<PathBuf> {
557497
let dir = Path::new(SAMPLES_DIR).join(name);
558498
fs::create_dir_all(&dir)?;
@@ -620,10 +560,10 @@ fn main() -> Result<()> {
620560
});
621561

622562
samples.push(TestSample {
623-
name: "valid_sgx_v4".to_string(),
624-
description: "Valid SGX quote v4".to_string(),
625-
should_succeed: true,
626-
expected_error: None,
563+
name: "invalid_sgx_v4".to_string(),
564+
description: "Invalid SGX quote v4 (v4/v5 are TDX only)".to_string(),
565+
should_succeed: false,
566+
expected_error: Some("SGX TEE quote must have version 3".to_string()),
627567
quote_generator: Box::new(|| generate_base_quote(4, 2, false)),
628568
collateral_modifier: None,
629569
});
@@ -669,19 +609,11 @@ fn main() -> Result<()> {
669609
collateral["tcb_info_signature"] = json!(hex::encode(tcb_signature));
670610
}
671611
}
612+
update_qe_identity(collateral, "TD_QE", 2)?;
672613
Ok(())
673614
})),
674615
});
675616

676-
samples.push(TestSample {
677-
name: "valid_sgx_v5".to_string(),
678-
description: "Valid SGX quote v5 (uses v4 auth data)".to_string(),
679-
should_succeed: true,
680-
expected_error: None,
681-
quote_generator: Box::new(generate_sgx_v5_quote),
682-
collateral_modifier: None,
683-
});
684-
685617
samples.push(TestSample {
686618
name: "invalid_quote_v5".to_string(),
687619
description: "Invalid SGX quote v5 format (v5 header with v3 auth data)".to_string(),
@@ -718,6 +650,49 @@ fn main() -> Result<()> {
718650
collateral["tcb_info_signature"] = json!(hex::encode(tcb_signature));
719651
}
720652
}
653+
update_qe_identity(collateral, "TD_QE", 2)?;
654+
Ok(())
655+
})),
656+
});
657+
658+
samples.push(TestSample {
659+
name: "tdx_qe_identity_id_mismatch".to_string(),
660+
description: "TDX quote with SGX QE Identity".to_string(),
661+
should_succeed: false,
662+
expected_error: Some("Unsupported QE Identity id/version for the quote TEE type".to_string()),
663+
quote_generator: Box::new(generate_tdx_quote_v4),
664+
collateral_modifier: Some(Box::new(|collateral| {
665+
// Ensure TDX TCB info has TDX components
666+
if let Some(tcb_str) = collateral["tcb_info"].as_str() {
667+
if let Ok(mut tcb) = serde_json::from_str::<serde_json::Value>(tcb_str) {
668+
tcb["version"] = json!(3);
669+
tcb["id"] = json!("TDX");
670+
if let Some(tcb_levels) = tcb["tcbLevels"].as_array_mut() {
671+
for level in tcb_levels.iter_mut() {
672+
if let Some(tcb_obj) = level["tcb"].as_object_mut() {
673+
tcb_obj.insert(
674+
"tdxtcbcomponents".to_string(),
675+
json!([
676+
{"svn": 1}, {"svn": 1}, {"svn": 1}, {"svn": 1},
677+
{"svn": 1}, {"svn": 1}, {"svn": 1}, {"svn": 1},
678+
{"svn": 1}, {"svn": 1}, {"svn": 1}, {"svn": 1},
679+
{"svn": 1}, {"svn": 1}, {"svn": 1}, {"svn": 1}
680+
]),
681+
);
682+
}
683+
}
684+
}
685+
let new_tcb_info = serde_json::to_string(&tcb)?;
686+
let key_path = &format!("{}/tcb_signing.pkcs8.key", CERT_DIR);
687+
let key_pair = load_private_key(key_path)?;
688+
let tcb_signature = sign_data(&key_pair, new_tcb_info.as_bytes())?;
689+
collateral["tcb_info"] = json!(new_tcb_info);
690+
collateral["tcb_info_signature"] = json!(hex::encode(tcb_signature));
691+
}
692+
}
693+
694+
// Force QE identity to SGX QE for a TDX quote
695+
update_qe_identity(collateral, "QE", 2)?;
721696
Ok(())
722697
})),
723698
});
@@ -832,6 +807,7 @@ fn main() -> Result<()> {
832807
collateral["tcb_info_signature"] = json!(hex::encode(tcb_signature));
833808
}
834809
}
810+
update_qe_identity(collateral, "TD_QE", 2)?;
835811
Ok(())
836812
})),
837813
});
@@ -933,6 +909,7 @@ fn main() -> Result<()> {
933909
collateral["tcb_info_signature"] = json!(hex::encode(tcb_signature));
934910
}
935911
}
912+
update_qe_identity(collateral, "TD_QE", 2)?;
936913
Ok(())
937914
})),
938915
});
@@ -1033,6 +1010,7 @@ fn main() -> Result<()> {
10331010
collateral["tcb_info_signature"] = json!(hex::encode(tcb_signature));
10341011
}
10351012
}
1013+
update_qe_identity(collateral, "TD_QE", 2)?;
10361014
Ok(())
10371015
})),
10381016
});
@@ -1133,6 +1111,7 @@ fn main() -> Result<()> {
11331111
collateral["tcb_info_signature"] = json!(hex::encode(tcb_signature));
11341112
}
11351113
}
1114+
update_qe_identity(collateral, "TD_QE", 2)?;
11361115
Ok(())
11371116
})),
11381117
});
@@ -1233,6 +1212,7 @@ fn main() -> Result<()> {
12331212
collateral["tcb_info_signature"] = json!(hex::encode(tcb_signature));
12341213
}
12351214
}
1215+
update_qe_identity(collateral, "TD_QE", 2)?;
12361216
Ok(())
12371217
})),
12381218
});
@@ -1248,15 +1228,6 @@ fn main() -> Result<()> {
12481228
collateral_modifier: None,
12491229
});
12501230

1251-
samples.push(TestSample {
1252-
name: "debug_sgx_v4".to_string(),
1253-
description: "SGX v4 in debug mode".to_string(),
1254-
should_succeed: false,
1255-
expected_error: Some("Debug mode is enabled".to_string()),
1256-
quote_generator: Box::new(|| generate_base_quote(4, 2, true)),
1257-
collateral_modifier: None,
1258-
});
1259-
12601231
// Category 3: Decode errors
12611232
println!("\nCategory 3: Decode errors");
12621233
samples.push(TestSample {
@@ -1332,6 +1303,52 @@ fn main() -> Result<()> {
13321303
})),
13331304
});
13341305

1306+
samples.push(TestSample {
1307+
name: "tcb_issue_date_future".to_string(),
1308+
description: "TCB info issue date in the future".to_string(),
1309+
should_succeed: false,
1310+
expected_error: Some("TCBInfo issue date is in the future".to_string()),
1311+
quote_generator: Box::new(|| generate_base_quote(3, 2, false)),
1312+
collateral_modifier: Some(Box::new(|collateral| {
1313+
if let Some(tcb_str) = collateral["tcb_info"].as_str() {
1314+
if let Ok(mut tcb) = serde_json::from_str::<serde_json::Value>(tcb_str) {
1315+
tcb["issueDate"] = json!("2999-01-01T00:00:00Z");
1316+
tcb["nextUpdate"] = json!("2999-12-31T23:59:59Z");
1317+
let new_tcb_info = serde_json::to_string(&tcb)?;
1318+
let key_path = &format!("{}/tcb_signing.pkcs8.key", CERT_DIR);
1319+
let key_pair = load_private_key(key_path)?;
1320+
let tcb_signature = sign_data(&key_pair, new_tcb_info.as_bytes())?;
1321+
collateral["tcb_info"] = json!(new_tcb_info);
1322+
collateral["tcb_info_signature"] = json!(hex::encode(tcb_signature));
1323+
}
1324+
}
1325+
Ok(())
1326+
})),
1327+
});
1328+
1329+
samples.push(TestSample {
1330+
name: "sgx_tcb_id_mismatch".to_string(),
1331+
description: "SGX quote with non-SGX TCB info".to_string(),
1332+
should_succeed: false,
1333+
expected_error: Some("SGX quote with non-SGX TCB info in the collateral".to_string()),
1334+
quote_generator: Box::new(|| generate_base_quote(3, 2, false)),
1335+
collateral_modifier: Some(Box::new(|collateral| {
1336+
if let Some(tcb_str) = collateral["tcb_info"].as_str() {
1337+
if let Ok(mut tcb) = serde_json::from_str::<serde_json::Value>(tcb_str) {
1338+
tcb["id"] = json!("TDX");
1339+
tcb["version"] = json!(3);
1340+
let new_tcb_info = serde_json::to_string(&tcb)?;
1341+
let key_path = &format!("{}/tcb_signing.pkcs8.key", CERT_DIR);
1342+
let key_pair = load_private_key(key_path)?;
1343+
let tcb_signature = sign_data(&key_pair, new_tcb_info.as_bytes())?;
1344+
collateral["tcb_info"] = json!(new_tcb_info);
1345+
collateral["tcb_info_signature"] = json!(hex::encode(tcb_signature));
1346+
}
1347+
}
1348+
Ok(())
1349+
})),
1350+
});
1351+
13351352
samples.push(TestSample {
13361353
name: "invalid_tcb_json".to_string(),
13371354
description: "Invalid TCB JSON format".to_string(),
@@ -1679,6 +1696,44 @@ fn main() -> Result<()> {
16791696
})),
16801697
});
16811698

1699+
samples.push(TestSample {
1700+
name: "qe_identity_issue_date_future".to_string(),
1701+
description: "QE Identity issue date in the future".to_string(),
1702+
should_succeed: false,
1703+
expected_error: Some("QE Identity issue date is in the future".to_string()),
1704+
quote_generator: Box::new(|| generate_base_quote(3, 2, false)),
1705+
collateral_modifier: Some(Box::new(|collateral| {
1706+
let qe_identity = json!({
1707+
"id": "QE",
1708+
"version": 2,
1709+
"issueDate": "2999-01-01T00:00:00Z",
1710+
"nextUpdate": "2999-12-31T23:59:59Z",
1711+
"tcbEvaluationDataNumber": 17,
1712+
"miscselect": "00000000",
1713+
"miscselectMask": "FFFFFFFF",
1714+
"attributes": "00000000000000000000000000000000",
1715+
"attributesMask": "00000000000000000000000000000000",
1716+
"mrsigner": "0000000000000000000000000000000000000000000000000000000000000000",
1717+
"isvprodid": 0,
1718+
"tcbLevels": [{
1719+
"tcb": { "isvsvn": 0 },
1720+
"tcbDate": "2024-01-01T00:00:00Z",
1721+
"tcbStatus": "UpToDate",
1722+
"advisoryIDs": []
1723+
}]
1724+
});
1725+
let qe_identity_json = serde_json::to_string(&qe_identity)?;
1726+
1727+
let key_path = &format!("{}/tcb_signing.pkcs8.key", CERT_DIR);
1728+
let key_pair = load_private_key(key_path)?;
1729+
let qe_identity_signature = sign_data(&key_pair, qe_identity_json.as_bytes())?;
1730+
1731+
collateral["qe_identity"] = json!(qe_identity_json);
1732+
collateral["qe_identity_signature"] = json!(hex::encode(qe_identity_signature));
1733+
Ok(())
1734+
})),
1735+
});
1736+
16821737
samples.push(TestSample {
16831738
name: "invalid_qe_identity_json".to_string(),
16841739
description: "Invalid QE Identity JSON format".to_string(),

0 commit comments

Comments
 (0)