@@ -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-
300219fn 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+
556496fn 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 ! ( "\n Category 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