diff --git a/fuzz-target/pass_context/src/pass_requester.rs b/fuzz-target/pass_context/src/pass_requester.rs index 01d3237d..4621dfff 100644 --- a/fuzz-target/pass_context/src/pass_requester.rs +++ b/fuzz-target/pass_context/src/pass_requester.rs @@ -46,7 +46,12 @@ pub async fn fuzz_total_requesters() { req_provision_info, ); - if requester.init_connection().await.is_err() { + let mut transcript_vca = None; + if requester + .init_connection(&mut transcript_vca) + .await + .is_err() + { return; } diff --git a/fuzz-target/random_requester/src/main.rs b/fuzz-target/random_requester/src/main.rs index c1707b90..aabfee34 100644 --- a/fuzz-target/random_requester/src/main.rs +++ b/fuzz-target/random_requester/src/main.rs @@ -100,6 +100,8 @@ async fn run_spdm(spdm: Vec) { let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let mut content_changed = None; + let mut transcript_meas = None; + if requester .send_receive_spdm_measurement( None, @@ -109,6 +111,7 @@ async fn run_spdm(spdm: Vec) { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await .is_err() diff --git a/fuzz-target/requester/measurement_req/src/main.rs b/fuzz-target/requester/measurement_req/src/main.rs index 51a18253..8538391b 100644 --- a/fuzz-target/requester/measurement_req/src/main.rs +++ b/fuzz-target/requester/measurement_req/src/main.rs @@ -68,6 +68,8 @@ async fn fuzz_send_receive_spdm_measurement(fuzzdata: Arc>) { let mut total_number = 0; let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let mut content_changed = None; + let mut transcript_meas = None; + let _ = requester .send_receive_spdm_measurement( None, @@ -77,6 +79,7 @@ async fn fuzz_send_receive_spdm_measurement(fuzzdata: Arc>) { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await; } @@ -123,6 +126,8 @@ async fn fuzz_send_receive_spdm_measurement(fuzzdata: Arc>) { let mut total_number = 0; let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let mut content_changed = None; + let mut transcript_meas = None; + let _ = requester .send_receive_spdm_measurement( None, @@ -132,6 +137,7 @@ async fn fuzz_send_receive_spdm_measurement(fuzzdata: Arc>) { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await; } @@ -179,6 +185,8 @@ async fn fuzz_send_receive_spdm_measurement(fuzzdata: Arc>) { let mut total_number = 0; let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let mut content_changed = None; + let mut transcript_meas = None; + let _ = requester .send_receive_spdm_measurement( None, @@ -188,6 +196,7 @@ async fn fuzz_send_receive_spdm_measurement(fuzzdata: Arc>) { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await; } @@ -235,6 +244,8 @@ async fn fuzz_send_receive_spdm_measurement(fuzzdata: Arc>) { let mut total_number = 0; let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let mut content_changed = None; + let mut transcript_meas = None; + let _ = requester .send_receive_spdm_measurement( None, @@ -244,6 +255,7 @@ async fn fuzz_send_receive_spdm_measurement(fuzzdata: Arc>) { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await; } @@ -319,6 +331,8 @@ async fn fuzz_send_receive_spdm_measurement(fuzzdata: Arc>) { let mut total_number = 0; let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let mut content_changed = None; + let mut transcript_meas = None; + let _ = requester .send_receive_spdm_measurement( Some(4294836221), @@ -328,6 +342,7 @@ async fn fuzz_send_receive_spdm_measurement(fuzzdata: Arc>) { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await; } diff --git a/spdmlib/src/requester/context.rs b/spdmlib/src/requester/context.rs index fded7df6..f2f2dd46 100644 --- a/spdmlib/src/requester/context.rs +++ b/spdmlib/src/requester/context.rs @@ -2,8 +2,8 @@ // // SPDX-License-Identifier: Apache-2.0 -use crate::common::ST1; use crate::common::{self, SpdmDeviceIo, SpdmTransportEncap}; +use crate::common::{ManagedBufferA, ST1}; use crate::config; use crate::error::{SpdmResult, SPDM_STATUS_RECEIVE_FAIL, SPDM_STATUS_SEND_FAIL}; use crate::protocol::*; @@ -34,10 +34,16 @@ impl RequesterContext { } } - pub async fn init_connection(&mut self) -> SpdmResult { + pub async fn init_connection( + &mut self, + transcript_vca: &mut Option, + ) -> SpdmResult { + *transcript_vca = None; self.send_receive_spdm_version().await?; self.send_receive_spdm_capability().await?; - self.send_receive_spdm_algorithm().await + self.send_receive_spdm_algorithm().await?; + *transcript_vca = Some(self.common.runtime_info.message_a.clone()); + Ok(()) } pub async fn start_session( diff --git a/spdmlib/src/requester/get_measurements_req.rs b/spdmlib/src/requester/get_measurements_req.rs index d6a9a0b5..1ac5eaf9 100644 --- a/spdmlib/src/requester/get_measurements_req.rs +++ b/spdmlib/src/requester/get_measurements_req.rs @@ -15,6 +15,7 @@ use crate::protocol::*; use crate::requester::*; impl RequesterContext { + #[allow(clippy::too_many_arguments)] async fn send_receive_spdm_measurement_record( &mut self, session_id: Option, @@ -22,8 +23,13 @@ impl RequesterContext { measurement_operation: SpdmMeasurementOperation, content_changed: &mut Option, spdm_measurement_record_structure: &mut SpdmMeasurementRecordStructure, + transcript_meas: &mut Option, slot_id: u8, ) -> SpdmResult { + if transcript_meas.is_none() { + *transcript_meas = Some(ManagedBufferM::default()); + } + let result = self .delegate_send_receive_spdm_measurement_record( session_id, @@ -31,6 +37,7 @@ impl RequesterContext { measurement_operation, content_changed, spdm_measurement_record_structure, + transcript_meas, slot_id, ) .await; @@ -38,12 +45,14 @@ impl RequesterContext { if let Err(e) = result { if e != SPDM_STATUS_NOT_READY_PEER { self.common.reset_message_m(session_id); + *transcript_meas = None; } } result } + #[allow(clippy::too_many_arguments)] async fn delegate_send_receive_spdm_measurement_record( &mut self, session_id: Option, @@ -51,6 +60,7 @@ impl RequesterContext { measurement_operation: SpdmMeasurementOperation, content_changed: &mut Option, spdm_measurement_record_structure: &mut SpdmMeasurementRecordStructure, + transcript_meas: &mut Option, slot_id: u8, ) -> SpdmResult { info!("send spdm measurement\n"); @@ -89,6 +99,7 @@ impl RequesterContext { spdm_measurement_record_structure, &send_buffer[..send_used], &receive_buffer[..used], + transcript_meas, ) } @@ -131,6 +142,7 @@ impl RequesterContext { spdm_measurement_record_structure: &mut SpdmMeasurementRecordStructure, send_buffer: &[u8], receive_buffer: &[u8], + transcript_meas: &mut Option, ) -> SpdmResult { self.common.runtime_info.need_measurement_signature = measurement_attributes.contains(SpdmMeasurementAttributes::SIGNATURE_REQUESTED); @@ -181,6 +193,26 @@ impl RequesterContext { self.common.append_message_m(session_id, send_buffer)?; self.common .append_message_m(session_id, &receive_buffer[..temp_used])?; + if let Some(ret_message_m) = transcript_meas { + ret_message_m + .append_message(send_buffer) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + ret_message_m + .append_message(&receive_buffer[..temp_used]) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + if measurement_attributes + .contains(SpdmMeasurementAttributes::SIGNATURE_REQUESTED) + { + if measurements.signature.as_ref().is_empty() { + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } else { + ret_message_m + .append_message(measurements.signature.as_ref()) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + } + } + } // verify signature if measurement_attributes @@ -247,6 +279,7 @@ impl RequesterContext { out_total_number: &mut u8, // out, total number when measurement_operation = SpdmMeasurementQueryTotalNumber // number of blocks got measured. spdm_measurement_record_structure: &mut SpdmMeasurementRecordStructure, // out + transcript_meas: &mut Option, // out ) -> SpdmResult { *out_total_number = self .send_receive_spdm_measurement_record( @@ -255,6 +288,7 @@ impl RequesterContext { measurement_operation, content_changed, spdm_measurement_record_structure, + transcript_meas, slot_id, ) .await?; diff --git a/test/spdm-requester-emu/src/main.rs b/test/spdm-requester-emu/src/main.rs index b8dac66d..6cafd62e 100644 --- a/test/spdm-requester-emu/src/main.rs +++ b/test/spdm-requester-emu/src/main.rs @@ -239,7 +239,8 @@ async fn test_spdm( provision_info, ); - if context.init_connection().await.is_err() { + let mut transcript_vca = None; + if context.init_connection(&mut transcript_vca).await.is_err() { panic!("init_connection failed!"); } @@ -269,6 +270,8 @@ async fn test_spdm( let mut total_number: u8 = 0; let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let mut content_changed = None; + let mut transcript_meas = None; + if context .send_receive_spdm_measurement( None, @@ -278,6 +281,7 @@ async fn test_spdm( &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await .is_err() @@ -285,6 +289,10 @@ async fn test_spdm( panic!("send_receive_spdm_measurement failed!"); } + if transcript_meas.is_none() { + panic!("get message_m from send_receive_spdm_measurement failed!"); + } + let result = context .start_session( false, @@ -332,6 +340,8 @@ async fn test_spdm( } let mut content_changed = None; + let mut transcript_meas = None; + if context .send_receive_spdm_measurement( Some(session_id), @@ -341,6 +351,7 @@ async fn test_spdm( &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await .is_err() @@ -348,6 +359,10 @@ async fn test_spdm( panic!("send_receive_spdm_measurement failed"); } + if transcript_vca.is_none() || transcript_meas.is_none() { + panic!("get VCA + message_m from send_receive_spdm_measurement failed!"); + } + if context .send_receive_spdm_digest(Some(session_id)) .await @@ -517,7 +532,8 @@ async fn test_idekm( provision_info, ); - if context.init_connection().await.is_err() { + let mut transcript_vca = None; + if context.init_connection(&mut transcript_vca).await.is_err() { panic!("init_connection failed!"); } @@ -547,6 +563,8 @@ async fn test_idekm( let mut total_number: u8 = 0; let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let mut content_changed = None; + let mut transcript_meas = None; + if context .send_receive_spdm_measurement( None, @@ -556,6 +574,7 @@ async fn test_idekm( &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await .is_err() diff --git a/test/spdmlib-test/src/requester_tests/context.rs b/test/spdmlib-test/src/requester_tests/context.rs index 3022ff2b..77f8e95c 100644 --- a/test/spdmlib-test/src/requester_tests/context.rs +++ b/test/spdmlib-test/src/requester_tests/context.rs @@ -56,7 +56,8 @@ fn test_case0_start_session() { req_provision_info, ); - let status = requester.init_connection().await.is_ok(); + let mut transcript_vca = None; + let status = requester.init_connection(&mut transcript_vca).await.is_ok(); assert!(status); let status = requester.send_receive_spdm_digest(None).await.is_ok(); @@ -142,7 +143,8 @@ fn test_case0_get_next_half_session() { req_provision_info, ); - let status = requester.init_connection().await.is_ok(); + let mut transcript_vca = None; + let status = requester.init_connection(&mut transcript_vca).await.is_ok(); assert!(status); let status = requester.send_receive_spdm_digest(None).await.is_ok(); diff --git a/test/spdmlib-test/src/requester_tests/get_digests_req.rs b/test/spdmlib-test/src/requester_tests/get_digests_req.rs index 853635f2..971478b5 100644 --- a/test/spdmlib-test/src/requester_tests/get_digests_req.rs +++ b/test/spdmlib-test/src/requester_tests/get_digests_req.rs @@ -288,6 +288,8 @@ fn issue_other_request_before_vca_negotiated() { let mut total_number: u8 = 0; let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let mut content_changed = None; + let mut transcript_meas = None; + let result = requester .send_receive_spdm_measurement( None, @@ -297,6 +299,7 @@ fn issue_other_request_before_vca_negotiated() { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await; assert!( diff --git a/test/spdmlib-test/src/requester_tests/get_measurements_req.rs b/test/spdmlib-test/src/requester_tests/get_measurements_req.rs index bdba284f..6e0e974c 100644 --- a/test/spdmlib-test/src/requester_tests/get_measurements_req.rs +++ b/test/spdmlib-test/src/requester_tests/get_measurements_req.rs @@ -6,13 +6,14 @@ use crate::common::device_io::{FakeSpdmDeviceIo, FakeSpdmDeviceIoReceve, SharedB use crate::common::secret_callback::*; use crate::common::transport::PciDoeTransportEncap; use crate::common::util::{create_info, get_rsp_cert_chain_buff}; -use spdmlib::common::SpdmConnectionState; +use ring::signature; +use spdmlib::common::{ManagedBufferL1L2, SpdmConnectionState}; use spdmlib::config::MAX_SPDM_MSG_SIZE; use spdmlib::error::{SpdmResult, SPDM_STATUS_INVALID_MSG_FIELD}; use spdmlib::message::{SpdmMeasurementAttributes, SpdmMeasurementOperation}; -use spdmlib::protocol::*; use spdmlib::requester::RequesterContext; use spdmlib::{config, responder, secret}; +use spdmlib::{crypto, protocol::*}; use spin::Mutex; extern crate alloc; use alloc::sync::Arc; @@ -121,6 +122,8 @@ fn test_case0_send_receive_spdm_measurement() { let mut total_number: u8 = 0; let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let mut content_changed = None; + let mut transcript_meas = None; + let status = requester .send_receive_spdm_measurement( None, @@ -130,6 +133,7 @@ fn test_case0_send_receive_spdm_measurement() { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await .is_ok(); @@ -137,6 +141,8 @@ fn test_case0_send_receive_spdm_measurement() { let measurement_operation = SpdmMeasurementOperation::SpdmMeasurementRequestAll; let mut content_changed = None; + let mut transcript_meas = None; + let status = requester .send_receive_spdm_measurement( None, @@ -146,6 +152,7 @@ fn test_case0_send_receive_spdm_measurement() { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await .is_ok(); @@ -153,6 +160,8 @@ fn test_case0_send_receive_spdm_measurement() { let measurement_operation = SpdmMeasurementOperation::Unknown(1); let mut content_changed = None; + let mut transcript_meas = None; + let status = requester .send_receive_spdm_measurement( None, @@ -162,6 +171,7 @@ fn test_case0_send_receive_spdm_measurement() { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await .is_ok(); @@ -169,6 +179,8 @@ fn test_case0_send_receive_spdm_measurement() { let measurement_operation = SpdmMeasurementOperation::Unknown(5); let mut content_changed = None; + let mut transcript_meas = None; + let status = requester .send_receive_spdm_measurement( None, @@ -178,6 +190,7 @@ fn test_case0_send_receive_spdm_measurement() { &mut content_changed, &mut total_number, &mut spdm_measurement_record_structure, + &mut transcript_meas, ) .await .is_err(); @@ -361,6 +374,7 @@ fn test_handle_spdm_measurement_record_response() { let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); let send_buffer = [0u8; MAX_SPDM_MSG_SIZE]; let mut content_changed = None; + let mut transcript_meas = None; let result = requester.handle_spdm_measurement_record_response( session_id, tc.request_slot_id, @@ -370,6 +384,7 @@ fn test_handle_spdm_measurement_record_response() { &mut spdm_measurement_record_structure, &send_buffer, &*tc.receive_buffer, + &mut transcript_meas, ); assert!( result == tc.expected_result, @@ -382,3 +397,420 @@ fn test_handle_spdm_measurement_record_response() { } executor::poll_tasks(); } + +#[test] +fn test_case1_send_receive_spdm_measurement() { + let future = async { + let (rsp_config_info, rsp_provision_info) = create_info(); + let (req_config_info, req_provision_info) = create_info(); + + let shared_buffer = SharedBuffer::new(); + let device_io_responder = Arc::new(Mutex::new(FakeSpdmDeviceIoReceve::new(Arc::new( + shared_buffer, + )))); + let pcidoe_transport_encap = Arc::new(Mutex::new(PciDoeTransportEncap {})); + + secret::asym_sign::register(SECRET_ASYM_IMPL_INSTANCE.clone()); + secret::measurement::register(SECRET_MEASUREMENT_IMPL_INSTANCE.clone()); + + let mut responder = responder::ResponderContext::new( + device_io_responder, + pcidoe_transport_encap, + rsp_config_info, + rsp_provision_info, + ); + + responder.common.negotiate_info.req_ct_exponent_sel = 0; + responder.common.negotiate_info.req_capabilities_sel = SpdmRequestCapabilityFlags::CERT_CAP; + + responder.common.negotiate_info.rsp_ct_exponent_sel = 0; + responder.common.negotiate_info.rsp_capabilities_sel = + SpdmResponseCapabilityFlags::CERT_CAP; + + responder + .common + .negotiate_info + .measurement_specification_sel = SpdmMeasurementSpecification::DMTF; + + responder.common.negotiate_info.base_hash_sel = SpdmBaseHashAlgo::TPM_ALG_SHA_384; + responder.common.negotiate_info.base_asym_sel = + SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384; + responder.common.negotiate_info.measurement_hash_sel = + SpdmMeasurementHashAlgo::TPM_ALG_SHA_384; + #[cfg(not(feature = "hashed-transcript-data"))] + let message_m = &[0]; + #[cfg(not(feature = "hashed-transcript-data"))] + responder + .common + .runtime_info + .message_m + .append_message(message_m); + responder.common.reset_runtime_info(); + responder.common.provision_info.my_cert_chain = [ + Some(SpdmCertChainBuffer { + data_size: 512u16, + data: [0u8; 4 + SPDM_MAX_HASH_SIZE + config::MAX_SPDM_CERT_CHAIN_DATA_SIZE], + }), + None, + None, + None, + None, + None, + None, + None, + ]; + responder.common.negotiate_info.spdm_version_sel = SpdmVersion::SpdmVersion12; + responder + .common + .runtime_info + .set_connection_state(SpdmConnectionState::SpdmConnectionNegotiated); + responder + .common + .append_message_a(b"transcript_vca") + .unwrap(); + + let pcidoe_transport_encap2 = Arc::new(Mutex::new(PciDoeTransportEncap {})); + let shared_buffer = SharedBuffer::new(); + let device_io_requester = Arc::new(Mutex::new(FakeSpdmDeviceIo::new( + Arc::new(shared_buffer), + Arc::new(Mutex::new(responder)), + ))); + + let mut requester = RequesterContext::new( + device_io_requester, + pcidoe_transport_encap2, + req_config_info, + req_provision_info, + ); + + requester.common.negotiate_info.req_ct_exponent_sel = 0; + requester.common.negotiate_info.req_capabilities_sel = SpdmRequestCapabilityFlags::CERT_CAP; + + requester.common.negotiate_info.rsp_ct_exponent_sel = 0; + requester.common.negotiate_info.rsp_capabilities_sel = + SpdmResponseCapabilityFlags::CERT_CAP; + requester + .common + .negotiate_info + .measurement_specification_sel = SpdmMeasurementSpecification::DMTF; + requester.common.negotiate_info.base_hash_sel = SpdmBaseHashAlgo::TPM_ALG_SHA_384; + requester.common.negotiate_info.base_asym_sel = + SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384; + requester.common.negotiate_info.measurement_hash_sel = + SpdmMeasurementHashAlgo::TPM_ALG_SHA_384; + requester.common.peer_info.peer_cert_chain[0] = Some(get_rsp_cert_chain_buff()); + requester.common.negotiate_info.spdm_version_sel = SpdmVersion::SpdmVersion12; + requester.common.reset_runtime_info(); + requester + .common + .append_message_a(b"transcript_vca") + .unwrap(); + + let measurement_operation = SpdmMeasurementOperation::SpdmMeasurementQueryTotalNumber; + let mut total_number: u8 = 0; + let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); + let mut content_changed = None; + let mut transcript_meas = None; + + let status = requester + .send_receive_spdm_measurement( + None, + 0, + SpdmMeasurementAttributes::SIGNATURE_REQUESTED, + measurement_operation, + &mut content_changed, + &mut total_number, + &mut spdm_measurement_record_structure, + &mut transcript_meas, + ) + .await + .is_ok(); + assert!(status); + + let measurement_operation = SpdmMeasurementOperation::SpdmMeasurementRequestAll; + let mut content_changed = None; + let mut transcript_meas = None; + + let status = requester + .send_receive_spdm_measurement( + None, + 0, + SpdmMeasurementAttributes::SIGNATURE_REQUESTED, + measurement_operation, + &mut content_changed, + &mut total_number, + &mut spdm_measurement_record_structure, + &mut transcript_meas, + ) + .await + .is_ok(); + assert!(status); + + let transcript_meas = transcript_meas.unwrap(); + let transcript_meas_len = transcript_meas.as_ref().len(); + let mut message_l1l2 = ManagedBufferL1L2::default(); + message_l1l2.append_message(b"transcript_vca").unwrap(); + message_l1l2 + .append_message(&transcript_meas.as_ref()[..transcript_meas_len - 96]) + .unwrap(); + let mut spdm_signature_struct = SpdmSignatureStruct::default(); + spdm_signature_struct.data_size = 96; + spdm_signature_struct.data[..96] + .copy_from_slice(&transcript_meas.as_ref()[transcript_meas_len - 96..]); + let message_l1l2_hash = + crypto::hash::hash_all(SpdmBaseHashAlgo::TPM_ALG_SHA_384, message_l1l2.as_ref()) + .unwrap(); + message_l1l2.reset_message(); + message_l1l2 + .append_message(&SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT) + .unwrap(); + message_l1l2 + .append_message(&SPDM_VERSION_1_2_SIGNING_CONTEXT_ZEROPAD_6) + .unwrap(); + message_l1l2 + .append_message(&SPDM_MEASUREMENTS_SIGN_CONTEXT) + .unwrap(); + message_l1l2 + .append_message(message_l1l2_hash.as_ref()) + .unwrap(); + + let cert_chain_data = &requester.common.peer_info.peer_cert_chain[0 as usize] + .as_ref() + .unwrap() + .data[(4usize + + requester.common.negotiate_info.base_hash_sel.get_size() as usize) + ..(requester.common.peer_info.peer_cert_chain[0 as usize] + .as_ref() + .unwrap() + .data_size as usize)]; + + let result = crypto::asym_verify::verify( + requester.common.negotiate_info.base_hash_sel, + requester.common.negotiate_info.base_asym_sel, + cert_chain_data, + message_l1l2.as_ref(), + &spdm_signature_struct, + ); + + assert!(result.is_ok()); + }; + executor::block_on(future); +} + +#[test] +fn test_case3_send_receive_spdm_measurement() { + let future = async { + let (rsp_config_info, rsp_provision_info) = create_info(); + let (req_config_info, req_provision_info) = create_info(); + + let shared_buffer = SharedBuffer::new(); + let device_io_responder = Arc::new(Mutex::new(FakeSpdmDeviceIoReceve::new(Arc::new( + shared_buffer, + )))); + let pcidoe_transport_encap = Arc::new(Mutex::new(PciDoeTransportEncap {})); + + secret::asym_sign::register(SECRET_ASYM_IMPL_INSTANCE.clone()); + secret::measurement::register(SECRET_MEASUREMENT_IMPL_INSTANCE.clone()); + + let mut responder = responder::ResponderContext::new( + device_io_responder, + pcidoe_transport_encap, + rsp_config_info, + rsp_provision_info, + ); + + responder.common.negotiate_info.req_ct_exponent_sel = 0; + responder.common.negotiate_info.req_capabilities_sel = SpdmRequestCapabilityFlags::CERT_CAP; + + responder.common.negotiate_info.rsp_ct_exponent_sel = 0; + responder.common.negotiate_info.rsp_capabilities_sel = + SpdmResponseCapabilityFlags::CERT_CAP; + + responder + .common + .negotiate_info + .measurement_specification_sel = SpdmMeasurementSpecification::DMTF; + + responder.common.negotiate_info.base_hash_sel = SpdmBaseHashAlgo::TPM_ALG_SHA_384; + responder.common.negotiate_info.base_asym_sel = + SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384; + responder.common.negotiate_info.measurement_hash_sel = + SpdmMeasurementHashAlgo::TPM_ALG_SHA_384; + #[cfg(not(feature = "hashed-transcript-data"))] + let message_m = &[0]; + #[cfg(not(feature = "hashed-transcript-data"))] + responder + .common + .runtime_info + .message_m + .append_message(message_m); + responder.common.reset_runtime_info(); + responder.common.provision_info.my_cert_chain = [ + Some(SpdmCertChainBuffer { + data_size: 512u16, + data: [0u8; 4 + SPDM_MAX_HASH_SIZE + config::MAX_SPDM_CERT_CHAIN_DATA_SIZE], + }), + None, + None, + None, + None, + None, + None, + None, + ]; + responder.common.negotiate_info.spdm_version_sel = SpdmVersion::SpdmVersion12; + responder + .common + .runtime_info + .set_connection_state(SpdmConnectionState::SpdmConnectionNegotiated); + responder + .common + .append_message_a(b"transcript_vca") + .unwrap(); + + let pcidoe_transport_encap2 = Arc::new(Mutex::new(PciDoeTransportEncap {})); + let shared_buffer = SharedBuffer::new(); + let device_io_requester = Arc::new(Mutex::new(FakeSpdmDeviceIo::new( + Arc::new(shared_buffer), + Arc::new(Mutex::new(responder)), + ))); + + let mut requester = RequesterContext::new( + device_io_requester, + pcidoe_transport_encap2, + req_config_info, + req_provision_info, + ); + + requester.common.negotiate_info.req_ct_exponent_sel = 0; + requester.common.negotiate_info.req_capabilities_sel = SpdmRequestCapabilityFlags::CERT_CAP; + + requester.common.negotiate_info.rsp_ct_exponent_sel = 0; + requester.common.negotiate_info.rsp_capabilities_sel = + SpdmResponseCapabilityFlags::CERT_CAP; + requester + .common + .negotiate_info + .measurement_specification_sel = SpdmMeasurementSpecification::DMTF; + requester.common.negotiate_info.base_hash_sel = SpdmBaseHashAlgo::TPM_ALG_SHA_384; + requester.common.negotiate_info.base_asym_sel = + SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384; + requester.common.negotiate_info.measurement_hash_sel = + SpdmMeasurementHashAlgo::TPM_ALG_SHA_384; + requester.common.peer_info.peer_cert_chain[0] = Some(get_rsp_cert_chain_buff()); + requester.common.negotiate_info.spdm_version_sel = SpdmVersion::SpdmVersion12; + requester.common.reset_runtime_info(); + requester + .common + .append_message_a(b"transcript_vca") + .unwrap(); + + let measurement_operation = SpdmMeasurementOperation::SpdmMeasurementQueryTotalNumber; + let mut total_number: u8 = 0; + let mut spdm_measurement_record_structure = SpdmMeasurementRecordStructure::default(); + let mut content_changed = None; + let mut transcript_meas = None; + + let status = requester + .send_receive_spdm_measurement( + None, + 0, + SpdmMeasurementAttributes::SIGNATURE_REQUESTED, + measurement_operation, + &mut content_changed, + &mut total_number, + &mut spdm_measurement_record_structure, + &mut transcript_meas, + ) + .await + .is_ok(); + assert!(status); + + let mut content_changed = None; + let mut transcript_meas = None; + let mut dummy_total_number = 0; + + let mut counter = 0; + for i in 0..255 { + let status = requester + .send_receive_spdm_measurement( + None, + 0, + if counter == total_number - 1 { + SpdmMeasurementAttributes::SIGNATURE_REQUESTED + } else { + SpdmMeasurementAttributes::empty() + }, + SpdmMeasurementOperation::Unknown(i), + &mut content_changed, + &mut dummy_total_number, + &mut spdm_measurement_record_structure, + &mut transcript_meas, + ) + .await + .is_ok(); + + if status { + counter += 1; + } else { + continue; + } + + if counter == total_number { + let transcript_meas = transcript_meas.clone().unwrap(); + let transcript_meas_len = transcript_meas.as_ref().len(); + let mut message_l1l2 = ManagedBufferL1L2::default(); + message_l1l2.append_message(b"transcript_vca").unwrap(); + message_l1l2 + .append_message(&transcript_meas.as_ref()[..transcript_meas_len - 96]) + .unwrap(); + let mut spdm_signature_struct = SpdmSignatureStruct::default(); + spdm_signature_struct.data_size = 96; + spdm_signature_struct.data[..96] + .copy_from_slice(&transcript_meas.as_ref()[transcript_meas_len - 96..]); + let message_l1l2_hash = crypto::hash::hash_all( + SpdmBaseHashAlgo::TPM_ALG_SHA_384, + message_l1l2.as_ref(), + ) + .unwrap(); + message_l1l2.reset_message(); + message_l1l2 + .append_message(&SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT) + .unwrap(); + message_l1l2 + .append_message(&SPDM_VERSION_1_2_SIGNING_CONTEXT_ZEROPAD_6) + .unwrap(); + message_l1l2 + .append_message(&SPDM_MEASUREMENTS_SIGN_CONTEXT) + .unwrap(); + message_l1l2 + .append_message(message_l1l2_hash.as_ref()) + .unwrap(); + + let cert_chain_data = &requester.common.peer_info.peer_cert_chain[0 as usize] + .as_ref() + .unwrap() + .data[(4usize + + requester.common.negotiate_info.base_hash_sel.get_size() as usize) + ..(requester.common.peer_info.peer_cert_chain[0 as usize] + .as_ref() + .unwrap() + .data_size as usize)]; + + let result = crypto::asym_verify::verify( + requester.common.negotiate_info.base_hash_sel, + requester.common.negotiate_info.base_asym_sel, + cert_chain_data, + message_l1l2.as_ref(), + &spdm_signature_struct, + ); + + assert!(result.is_ok()); + break; + } else { + continue; + } + } + }; + executor::block_on(future); +} diff --git a/test/spdmlib-test/src/test_client_server.rs b/test/spdmlib-test/src/test_client_server.rs index ad12914f..06fd54ea 100644 --- a/test/spdmlib-test/src/test_client_server.rs +++ b/test/spdmlib-test/src/test_client_server.rs @@ -60,7 +60,11 @@ fn intergration_client_server() { provision_info, ); - assert!(!requester_context.init_connection().await.is_err()); + let mut transcript_vca = None; + assert!(!requester_context + .init_connection(&mut transcript_vca) + .await + .is_err()); assert!(!requester_context .send_receive_spdm_digest(None)