From 146395ed8a7d7d8b5498a22b525df2d271adacc6 Mon Sep 17 00:00:00 2001 From: siweicai Date: Mon, 9 Feb 2026 10:22:19 +0800 Subject: [PATCH 1/3] Add spdm attestation initial flow for rebinding --- src/migtd/src/migration/rebinding.rs | 132 ++++++- src/migtd/src/migration/servtd_ext.rs | 1 + src/migtd/src/ratls/server_client.rs | 2 +- src/migtd/src/spdm/mod.rs | 6 + src/migtd/src/spdm/spdm_rebind.rs | 85 +++++ src/migtd/src/spdm/spdm_req.rs | 466 +++++++++++++++++++++++- src/migtd/src/spdm/spdm_rsp.rs | 490 +++++++++++++++++++++++++- src/migtd/src/spdm/spdm_vdm.rs | 49 ++- 8 files changed, 1197 insertions(+), 34 deletions(-) create mode 100644 src/migtd/src/spdm/spdm_rebind.rs diff --git a/src/migtd/src/migration/rebinding.rs b/src/migtd/src/migration/rebinding.rs index 51e2b71b..73b000ab 100644 --- a/src/migtd/src/migration/rebinding.rs +++ b/src/migtd/src/migration/rebinding.rs @@ -14,6 +14,8 @@ use ring::rand::{SecureRandom, SystemRandom}; use tdx_tdcall::tdx::{tdcall_servtd_rebind_approve, tdcall_vm_write}; use crate::migration::servtd_ext::read_servtd_ext; +#[cfg(feature = "spdm_attestation")] +use crate::spdm; use crate::{event_log, migration::transport::*}; use crypto::hash::digest_sha384; @@ -421,6 +423,22 @@ pub async fn start_rebinding( MIGTD_REBIND_OP_FINALIZE => rebinding_old_finalize(info, data).await?, _ => return Err(MigrationResult::InvalidParameter), } + + #[cfg(feature = "spdm_attestation")] + match info.operation { + MIGTD_REBIND_OP_PREPARE => { + rebinding_old_prepare( + transport, + info, + data, + #[cfg(feature = "policy_v2")] + remote_policy, + ) + .await? + } + MIGTD_REBIND_OP_FINALIZE => rebinding_old_finalize(info, data).await?, + _ => return Err(MigrationResult::InvalidParameter), + } } else { let pre_session_data = Box::pin(with_timeout( PRE_SESSION_TIMEOUT, @@ -450,8 +468,23 @@ pub async fn start_rebinding( MIGTD_REBIND_OP_FINALIZE => rebinding_new_finalize(info, data).await?, _ => return Err(MigrationResult::InvalidParameter), } - } + #[cfg(feature = "spdm_attestation")] + match info.operation { + MIGTD_REBIND_OP_PREPARE => { + rebinding_new_prepare( + transport, + info, + data, + #[cfg(feature = "policy_v2")] + pre_session_data, + ) + .await? + } + MIGTD_REBIND_OP_FINALIZE => rebinding_new_finalize(info, data).await?, + _ => return Err(MigrationResult::InvalidParameter), + } + } #[cfg(feature = "vmcall-raw")] { use crate::migration::logging::entrylog; @@ -466,7 +499,101 @@ pub async fn start_rebinding( Ok(()) } +#[cfg(feature = "spdm_attestation")] pub async fn rebinding_old_prepare( + transport: TransportType, + info: &RebindingInfo, + _data: &mut Vec, + #[cfg(feature = "policy_v2")] remote_policy: Vec, +) -> Result<(), MigrationResult> { + use core::ops::DerefMut; + + const SPDM_TIMEOUT: Duration = Duration::from_secs(60); // 60 seconds + let (mut spdm_requester, device_io_ref) = spdm::spdm_requester(transport).map_err(|_e| { + log::error!( + "rebinding: Failed in spdm_requester transport. Migration ID: {}\n", + info.mig_request_id + ); + MigrationResult::SecureSessionError + })?; + with_timeout( + SPDM_TIMEOUT, + spdm::spdm_requester_rebind_old( + &mut spdm_requester, + info, + #[cfg(feature = "policy_v2")] + remote_policy, + ), + ) + .await + .map_err(|e| { + log::error!( + "rebinding: spdm_requester_rebind_old timeout error: {:?}\n", + e + ); + e + })? + .map_err(|e| { + log::error!("rebinding: spdm_requester_rebind_old error: {:?}\n", e); + e + })?; + log::info!("Rebind completed\n"); + + let mut transport_lock = device_io_ref.lock(); + let transport = transport_lock.deref_mut(); + shutdown_transport(&mut transport.transport, info.mig_request_id).await?; + Ok(()) +} + +#[cfg(feature = "spdm_attestation")] +pub async fn rebinding_new_prepare( + transport: TransportType, + info: &RebindingInfo, + _data: &mut Vec, + #[cfg(feature = "policy_v2")] remote_policy: Vec, +) -> Result<(), MigrationResult> { + use core::ops::DerefMut; + + const SPDM_TIMEOUT: Duration = Duration::from_secs(60); // 60 seconds + let (mut spdm_responder, device_io_ref) = spdm::spdm_responder(transport).map_err(|_e| { + log::error!( + "rebinding: Failed in spdm_responder transport. Migration ID: {}\n", + info.mig_request_id + ); + MigrationResult::SecureSessionError + })?; + + with_timeout( + SPDM_TIMEOUT, + spdm::spdm_responder_rebind_new( + &mut spdm_responder, + info, + #[cfg(feature = "policy_v2")] + remote_policy, + ), + ) + .await + .map_err(|e| { + log::error!( + "rebinding: spdm_responder_rebind_new timeout error: {:?}\n", + e + ); + e + })? + .map_err(|e| { + log::error!("rebinding: spdm_responder_rebind_new error: {:?}\n", e); + e + })?; + log::info!("Rebind completed\n"); + + let mut transport_lock = device_io_ref.lock(); + let transport = transport_lock.deref_mut(); + shutdown_transport(&mut transport.transport, info.mig_request_id).await?; + Ok(()) +} + +#[cfg(not(feature = "spdm_attestation"))] +async fn rebinding_old_prepare( transport: TransportType, info: &RebindingInfo, init_migtd_data: &InitData, @@ -517,6 +644,7 @@ pub async fn rebinding_old_finalize( Ok(()) } +#[cfg(not(feature = "spdm_attestation"))] async fn rebinding_new_prepare( transport: TransportType, info: &RebindingInfo, @@ -623,7 +751,7 @@ fn get_servtd_ext_from_cert(certs: &Option>) -> Result Result { +pub fn create_rebind_token(info: &RebindingInfo) -> Result { let mut token = [0u8; 32]; let rng = SystemRandom::new(); rng.fill(&mut token) diff --git a/src/migtd/src/migration/servtd_ext.rs b/src/migtd/src/migration/servtd_ext.rs index 8ef77482..9e0833ae 100644 --- a/src/migtd/src/migration/servtd_ext.rs +++ b/src/migtd/src/migration/servtd_ext.rs @@ -24,6 +24,7 @@ pub const TDCS_FIELD_SERVTD_ATTR: u64 = 0x1910000300000202; pub const TDCS_FIELD_SERVTD_ACCEPT_SERVTD_EXT_HASH: u64 = 0x1910000300000214; #[repr(C)] +#[derive(Clone, Copy)] pub struct ServtdExt { pub init_servtd_info_hash: [u8; 48], pub init_attr: [u8; 8], diff --git a/src/migtd/src/ratls/server_client.rs b/src/migtd/src/ratls/server_client.rs index 4f1d05f3..5759348e 100644 --- a/src/migtd/src/ratls/server_client.rs +++ b/src/migtd/src/ratls/server_client.rs @@ -231,7 +231,7 @@ fn gen_quote(public_key: &[u8]) -> Result> { }) } -fn gen_tdreport(public_key: &[u8]) -> Result { +pub fn gen_tdreport(public_key: &[u8]) -> Result { let hash = digest_sha384(public_key).map_err(|e| { log::error!("Failed to compute SHA384 digest: {:?}\n", e); e diff --git a/src/migtd/src/spdm/mod.rs b/src/migtd/src/spdm/mod.rs index 291fb07d..560ac371 100644 --- a/src/migtd/src/spdm/mod.rs +++ b/src/migtd/src/spdm/mod.rs @@ -4,6 +4,8 @@ #![cfg(feature = "spdm_attestation")] +#[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] +mod spdm_rebind; mod spdm_req; mod spdm_rsp; mod spdm_vdm; @@ -25,6 +27,10 @@ use zeroize::ZeroizeOnDrop; use async_io::AsyncRead; use async_io::AsyncWrite; use crypto::hash::digest_sha384; +#[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] +pub use spdm_rebind::spdm_requester_rebind_old; +#[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] +pub use spdm_rebind::spdm_responder_rebind_new; pub use spdm_req::spdm_requester; pub use spdm_req::spdm_requester_transfer_msk; pub use spdm_rsp::spdm_responder; diff --git a/src/migtd/src/spdm/spdm_rebind.rs b/src/migtd/src/spdm/spdm_rebind.rs new file mode 100644 index 00000000..7bd757fd --- /dev/null +++ b/src/migtd/src/spdm/spdm_rebind.rs @@ -0,0 +1,85 @@ +// Copyright (c) 2026 Intel Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +use crate::{ + migration::{rebinding::RebindingInfo, MigtdMigrationInformation}, + spdm::{ + spdm_req::{ + send_and_receive_pub_key, send_and_receive_sdm_rebind_attest_info, + send_and_receive_sdm_rebind_info, + }, + spdm_rsp::{rsp_handle_message, ResponderContextEx, ResponderContextExInfo}, + PrivateKeyDer, SpdmAppContextData, + }, +}; +use alloc::boxed::Box; +use alloc::vec::Vec; +use codec::{Codec, Writer}; +use spdmlib::{ + error::{SpdmStatus, SPDM_STATUS_BUFFER_FULL}, + protocol::SpdmMeasurementSummaryHashType, + requester::RequesterContext, +}; +use zeroize::Zeroize; + +pub async fn spdm_requester_rebind_old( + spdm_requester: &mut RequesterContext, + rebind_info: &RebindingInfo, + remote_policy: Vec, +) -> Result<(), SpdmStatus> { + Box::pin(spdm_requester.send_receive_spdm_version()).await?; + Box::pin(spdm_requester.send_receive_spdm_capability()).await?; + Box::pin(spdm_requester.send_receive_spdm_algorithm()).await?; + + Box::pin(send_and_receive_pub_key(spdm_requester)).await?; + let session_id = Box::pin(spdm_requester.send_receive_spdm_key_exchange( + 0xff, + SpdmMeasurementSummaryHashType::SpdmMeasurementSummaryHashTypeNone, + )) + .await?; + + Box::pin(send_and_receive_sdm_rebind_attest_info( + spdm_requester, + rebind_info, + session_id, + remote_policy, + )) + .await?; + + Box::pin(spdm_requester.send_receive_spdm_finish(Some(0xff), session_id)).await?; + + Box::pin(send_and_receive_sdm_rebind_info( + spdm_requester, + rebind_info, + Some(session_id), + )) + .await?; + + Box::pin(spdm_requester.send_receive_spdm_end_session(session_id)).await?; + Ok(()) +} + +pub async fn spdm_responder_rebind_new<'a>( + spdm_responder_ex: &mut ResponderContextEx<'a>, + rebind_info: &'a RebindingInfo, + remote_policy: Vec, +) -> Result<(), SpdmStatus> { + spdm_responder_ex.remote_policy = remote_policy; + spdm_responder_ex.info = ResponderContextExInfo::RebindInformation(rebind_info); + + let spdm_responder = &mut spdm_responder_ex.responder_context; + let mut writer = Writer::init(&mut spdm_responder.common.app_context_data_buffer); + + let responder_app_context = SpdmAppContextData { + migration_info: MigtdMigrationInformation::default(), + private_key: PrivateKeyDer::default(), + }; + responder_app_context + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + + Box::pin(rsp_handle_message(spdm_responder)).await?; + spdm_responder.common.app_context_data_buffer.zeroize(); + + Ok(()) +} diff --git a/src/migtd/src/spdm/spdm_req.rs b/src/migtd/src/spdm/spdm_req.rs index c1c6c5e5..f4370af0 100644 --- a/src/migtd/src/spdm/spdm_req.rs +++ b/src/migtd/src/spdm/spdm_req.rs @@ -2,6 +2,8 @@ // // SPDX-License-Identifier: BSD-2-Clause-Patent use crate::mig_policy; +#[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] +use crate::migration::rebinding::RebindingInfo; use crate::{ migration::{ data::MigrationSessionKey, @@ -23,12 +25,11 @@ use spdmlib::{ }; use spin::Mutex; extern crate alloc; -use alloc::sync::Arc; -use log::error; - use crate::{ config::get_policy, event_log::get_event_log, migration::session::ExchangeInformation, }; +use alloc::sync::Arc; +use log::error; pub fn spdm_requester( stream: T, @@ -119,7 +120,7 @@ pub async fn spdm_requester_transfer_msk( Ok(()) } -async fn send_and_receive_pub_key(spdm_requester: &mut RequesterContext) -> SpdmResult { +pub async fn send_and_receive_pub_key(spdm_requester: &mut RequesterContext) -> SpdmResult { let signing_key = EcdsaPk::new().map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; let my_pub_key = signing_key.public_key_spki(); @@ -307,7 +308,7 @@ pub async fn send_and_receive_sdm_migration_attest_info( major_version: VDM_MESSAGE_MAJOR_VERSION, minor_version: VDM_MESSAGE_MINOR_VERSION, op_code: VdmMessageOpCode::ExchangeMigrationAttestInfoReq, - element_count: VDM_MESSAGE_EXCHANGE_MIG_ATTEST_INFO_ELEMENT_COUNT, + element_count: VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT, }; cnt += vdm_exchange_attest_info @@ -461,7 +462,7 @@ pub async fn send_and_receive_sdm_migration_attest_info( error!("Invalid VDM message op_code: {:x?}\n", vdm_message.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_MIG_ATTEST_INFO_ELEMENT_COUNT { + if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", vdm_message.element_count @@ -609,7 +610,7 @@ async fn send_and_receive_sdm_exchange_migration_info( vendor_id[..VDM_MESSAGE_VENDOR_ID_LEN].copy_from_slice(&VDM_MESSAGE_VENDOR_ID); let vendor_id = VendorIDStruct { len: 4, vendor_id }; - let mut exchange_information = exchange_info(mig_info, false)?; + let exchange_information = exchange_info(mig_info, false)?; let mut payload = vec![0u8; MAX_SPDM_VENDOR_DEFINED_PAYLOAD_SIZE]; let mut writer = Writer::init(&mut payload); @@ -761,7 +762,7 @@ async fn send_and_receive_sdm_exchange_migration_info( return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - let mut remote_information = ExchangeInformation { + let remote_information = ExchangeInformation { min_ver: min_import_version, max_ver: max_import_version, key: MigrationSessionKey { @@ -776,3 +777,452 @@ async fn send_and_receive_sdm_exchange_migration_info( Ok(()) } + +#[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] +pub async fn send_and_receive_sdm_rebind_attest_info( + spdm_requester: &mut RequesterContext, + rebind_info: &RebindingInfo, + session_id: u32, + remote_policy: Vec, +) -> SpdmResult { + use crate::{migration::servtd_ext::read_servtd_ext, ratls::gen_tdreport}; + + if spdm_requester.common.provision_info.my_pub_key.is_none() + || spdm_requester.common.provision_info.peer_pub_key.is_none() + { + error!("Cannot transfer attestation info without provisioning my_pub_key.\n"); + return Err(SPDM_STATUS_UNSUPPORTED_CAP); + } + + let mut vendor_id = [0u8; MAX_SPDM_VENDOR_DEFINED_VENDOR_ID_LEN]; + vendor_id[..VDM_MESSAGE_VENDOR_ID_LEN].copy_from_slice(&VDM_MESSAGE_VENDOR_ID); + let vendor_id = VendorIDStruct { len: 4, vendor_id }; + + let mut payload = vec![0u8; MAX_SPDM_VENDOR_DEFINED_PAYLOAD_SIZE]; + let mut writer = Writer::init(&mut payload); + let mut cnt = 0; + + let vdm_exchange_attest_info = VdmMessage { + major_version: VDM_MESSAGE_MAJOR_VERSION, + minor_version: VDM_MESSAGE_MINOR_VERSION, + op_code: VdmMessageOpCode::ExchangeRebindAttestInfoReq, + element_count: VDM_MESSAGE_EXCHANGE_ATTEST_INFO_WITH_HISTORY_INFO_ELEMENT_COUNT, + }; + + cnt += vdm_exchange_attest_info + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + + let th1 = if let Some(s) = spdm_requester.common.get_session_via_id(session_id) { + s.get_th1() + } else { + error!("Cannot get session id. Attestation failed.\n"); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + }; + + let report_data_prefix = "MigTDReq".as_bytes(); + let report_data_prefix_len = report_data_prefix.len(); + // Build concatenated slice: "MigTDReq" || th1 + let th1_len = th1.data_size as usize; + // th1 for SHA-384 should be 48 bytes; 8 (prefix) + 48 digest = 56 bytes needed. + if th1_len > SPDM_MAX_HASH_SIZE { + error!("th1 length is too large: {}\n", th1_len); + return Err(SPDM_STATUS_BUFFER_FULL); + } + let mut report_data = [0u8; "MigTDReq".len() + SPDM_MAX_HASH_SIZE]; + // Copy prefix + report_data[..report_data_prefix_len].copy_from_slice(report_data_prefix); + report_data[report_data_prefix_len..report_data_prefix_len + th1_len] + .copy_from_slice(&th1.data[..th1_len]); + + //TD report src + let td_report_src = gen_tdreport(&report_data[..report_data_prefix_len + th1_len]) + .map_err(|_| SPDM_STATUS_INVALID_STATE_LOCAL)?; + let td_report_src_bytes = td_report_src.as_bytes(); + + if td_report_src_bytes.len() > u16::MAX as usize { + error!( + "Td report src size is too large: {}\n", + td_report_src_bytes.len() + ); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + } + let tdreport_element = VdmMessageElement { + element_type: VdmMessageElementType::TdReportMy, + length: td_report_src_bytes.len() as u16, + }; + cnt += tdreport_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(td_report_src_bytes) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + //event log src + let event_log_src = get_event_log().ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; + if event_log_src.len() > u16::MAX as usize { + error!("Event log size is too large: {}\n", event_log_src.len()); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + } + let event_log_element = VdmMessageElement { + element_type: VdmMessageElementType::EventLogMy, + length: event_log_src.len() as u16, + }; + cnt += event_log_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(event_log_src) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + //mig policy src + let mig_policy_src = get_policy().ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; + let mig_policy_src_hash = + digest_sha384(mig_policy_src).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; + + let mig_policy_element = VdmMessageElement { + element_type: VdmMessageElementType::MigPolicyMy, + length: mig_policy_src_hash.len() as u16, + }; + cnt += mig_policy_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(&mig_policy_src_hash) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + //SERVTD_EXT + let binding_handle = rebind_info.binding_handle; + let target_td_uuid = &rebind_info.target_td_uuid; + if rebind_info.init_migtd_data.is_none() { + error!("RebindingInfo.init_migtd_data is None!\n"); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + } + let init_migtd_data = rebind_info.init_migtd_data.as_ref().unwrap(); + + let servtd_ext = read_servtd_ext(binding_handle, target_td_uuid) + .map_err(|_| SPDM_STATUS_INVALID_STATE_LOCAL)?; + + let servtd_ext_element = VdmMessageElement { + element_type: VdmMessageElementType::SerVtdExt, + length: servtd_ext.as_bytes().len() as u16, + }; + cnt += servtd_ext_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(servtd_ext.as_bytes()) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + //TD report init + let tdreport_init = &init_migtd_data.init_report; + let tdreport_init_element = VdmMessageElement { + element_type: VdmMessageElementType::TdReportInit, + length: tdreport_init.len() as u16, + }; + cnt += tdreport_init_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(tdreport_init) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + //event log init + let event_log_init = &init_migtd_data.init_event_log; + let event_log_init_element = VdmMessageElement { + element_type: VdmMessageElementType::EventLogInit, + length: event_log_init.len() as u16, + }; + cnt += event_log_init_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(&event_log_init) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + //mig policy init hash + let mig_policy_init = &init_migtd_data.init_policy; + let mig_policy_init_hash = + digest_sha384(mig_policy_init).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; + let mig_policy_init_element = VdmMessageElement { + element_type: VdmMessageElementType::MigPolicyInit, + length: mig_policy_init_hash.len() as u16, + }; + cnt += mig_policy_init_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(&mig_policy_init_hash) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + spdm_requester.common.reset_buffer_via_request_code( + SpdmRequestResponseCode::SpdmRequestVendorDefinedRequest, + None, + ); + + let mut send_buffer = [0u8; config::MAX_SPDM_MSG_SIZE]; + let mut writer = Writer::init(&mut send_buffer); + let request_header = SpdmMessageHeader { + version: spdm_requester.common.negotiate_info.spdm_version_sel, + request_response_code: SpdmRequestResponseCode::SpdmRequestVendorDefinedRequest, + }; + let request_payload = SpdmVdmRequestPayload { + standard_id: RegistryOrStandardsBodyID::IANA, + vendor_id, + req_length: cnt as u32, + req_payload: payload, + }; + let mut send_used = 0; + send_used += request_header + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + send_used += request_payload.spdm_encode(&mut spdm_requester.common, &mut writer)?; + + let mut receive_buffer = [0u8; config::MAX_SPDM_MSG_SIZE]; + let response = spdm_requester + .send_spdm_vendor_defined_request_ex(None, &send_buffer[..send_used], &mut receive_buffer) + .await?; + + //Format checks + let mut reader = Reader::init(response); + let _response_header = + SpdmMessageHeader::read(&mut reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + let response_payload = + SpdmVdmResponsePayload::spdm_read(&mut spdm_requester.common, &mut reader) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + + let reader = + &mut Reader::init(&response_payload.rsp_payload[..response_payload.rsp_length as usize]); + let vdm_message = VdmMessage::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_message.major_version != VDM_MESSAGE_MAJOR_VERSION { + error!( + "Invalid VDM message major_version: {:x?}\n", + vdm_message.major_version + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_message.minor_version != VDM_MESSAGE_MINOR_VERSION { + error!( + "Invalid VDM message minor_version: {:x?}\n", + vdm_message.minor_version + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_message.op_code != VdmMessageOpCode::ExchangeRebindAttestInfoRsp { + error!("Invalid VDM message op_code: {:x?}\n", vdm_message.op_code); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT { + error!( + "Invalid VDM message element_count: {:x?}\n", + vdm_message.element_count + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + + //td report dst + let vdm_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_element.element_type != VdmMessageElementType::TdReportMy { + error!( + "Invalid VDM message element_type: {:x?}\n", + vdm_element.element_type + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + let td_report_dst = reader + .take(vdm_element.length as usize) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + let td_report_dst_vec = td_report_dst.to_vec(); + + //event log dst + let vdm_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_element.element_type != VdmMessageElementType::EventLogMy { + error!( + "Invalid VDM message element_type: {:x?}\n", + vdm_element.element_type + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + let event_log_dst = reader + .take(vdm_element.length as usize) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + let event_log_dst_vec = event_log_dst.to_vec(); + + //mig policy dst + let vdm_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_element.element_type != VdmMessageElementType::MigPolicyMy { + error!( + "Invalid VDM message element_type: {:x?}\n", + vdm_element.element_type + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + let mig_policy_hash_dst = reader + .take(vdm_element.length as usize) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + + #[cfg(not(feature = "test_disable_ra_and_accept_all"))] + { + let remote_policy_hash = + digest_sha384(&remote_policy).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; + if mig_policy_hash_dst != remote_policy_hash.as_slice() { + error!( + "The received mig policy hash does not match the expected remote policy hash!\n" + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + + let policy_check_result = mig_policy::authenticate_rebinding_new( + &td_report_dst_vec, + &event_log_dst_vec, + &remote_policy, + ); + + if let Err(e) = &policy_check_result { + error!("Policy v2 check failed, below is the detail information:\n"); + error!("{:x?}\n", e); + let session = spdm_requester + .common + .get_session_via_id(session_id) + .ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; + session.teardown(); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + } + + let vdm_attest_info_src_hash = + digest_sha384(&send_buffer[..send_used]).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; + let vdm_attest_info_dst_hash = digest_sha384(response).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; + let mut transcript_before_finish = ManagedVdmBuffer::default(); + transcript_before_finish + .append_message(vdm_attest_info_src_hash.as_slice()) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + transcript_before_finish + .append_message(vdm_attest_info_dst_hash.as_slice()) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + if let Some(s) = spdm_requester.common.get_session_via_id(session_id) { + s.runtime_info.vdm_message_transcript_before_finish = Some(transcript_before_finish); + } else { + error!("Cannot get session id. Attestation failed.\n"); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + } + + Ok(()) +} + +#[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] +pub async fn send_and_receive_sdm_rebind_info( + spdm_requester: &mut RequesterContext, + rebind_info: &RebindingInfo, + session_id: Option, +) -> SpdmResult { + use crate::migration::rebinding::{approve_rebinding, create_rebind_token}; + + let mut vendor_id = [0u8; MAX_SPDM_VENDOR_DEFINED_VENDOR_ID_LEN]; + vendor_id[..VDM_MESSAGE_VENDOR_ID_LEN].copy_from_slice(&VDM_MESSAGE_VENDOR_ID); + let vendor_id = VendorIDStruct { len: 4, vendor_id }; + + let rebind_token = create_rebind_token(rebind_info)?; + let token = rebind_token.token; + + let mut payload = vec![0u8; MAX_SPDM_VENDOR_DEFINED_PAYLOAD_SIZE]; + let mut writer = Writer::init(&mut payload); + let mut cnt = 0; + + let vdm_exchange_migration_info = VdmMessage { + major_version: VDM_MESSAGE_MAJOR_VERSION, + minor_version: VDM_MESSAGE_MINOR_VERSION, + op_code: VdmMessageOpCode::ExchangeRebindInfoReq, + element_count: VDM_MESSAGE_EXCHANGE_REBIND_INFO_ELEMENT_REQ_COUNT, + }; + + cnt += vdm_exchange_migration_info + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + + // Rebind session token + let rebind_session_token_element = VdmMessageElement { + element_type: VdmMessageElementType::RebindSessionToken, + length: token.len() as u16, + }; + cnt += rebind_session_token_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(&token) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + spdm_requester.common.reset_buffer_via_request_code( + SpdmRequestResponseCode::SpdmRequestVendorDefinedRequest, + None, + ); + + let mut send_buffer = [0u8; config::MAX_SPDM_MSG_SIZE]; + let mut writer = Writer::init(&mut send_buffer); + + let request_header = SpdmMessageHeader { + version: spdm_requester.common.negotiate_info.spdm_version_sel, + request_response_code: SpdmRequestResponseCode::SpdmRequestVendorDefinedRequest, + }; + let request_payload = SpdmVdmRequestPayload { + standard_id: RegistryOrStandardsBodyID::IANA, + vendor_id, + req_length: cnt as u32, + req_payload: payload, + }; + let mut send_used = 0; + send_used += request_header + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + send_used += request_payload.spdm_encode(&mut spdm_requester.common, &mut writer)?; + + let mut receive_buffer = [0u8; config::MAX_SPDM_MSG_SIZE]; + let response = spdm_requester + .send_spdm_vendor_defined_request_ex( + session_id, + &send_buffer[..send_used], + &mut receive_buffer, + ) + .await?; + + // Format checks + let mut reader = Reader::init(response); + let _response_header = + SpdmMessageHeader::read(&mut reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + let response_payload = + SpdmVdmResponsePayload::spdm_read(&mut spdm_requester.common, &mut reader) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + + let reader = + &mut Reader::init(&response_payload.rsp_payload[..response_payload.rsp_length as usize]); + let vdm_message = VdmMessage::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_message.major_version != VDM_MESSAGE_MAJOR_VERSION { + error!( + "Invalid VDM message major_version: {:x?}\n", + vdm_message.major_version + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_message.minor_version != VDM_MESSAGE_MINOR_VERSION { + error!( + "Invalid VDM message minor_version: {:x?}\n", + vdm_message.minor_version + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_message.op_code != VdmMessageOpCode::ExchangeRebindInfoRsp { + error!("Invalid VDM message op_code: {:x?}\n", vdm_message.op_code); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_REBIND_INFO_ELEMENT_RSP_COUNT { + error!( + "Invalid VDM message element_count: {:x?}\n", + vdm_message.element_count + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + + approve_rebinding(rebind_info, &rebind_token).map_err(|_| SPDM_STATUS_INVALID_STATE_LOCAL)?; + + Ok(()) +} diff --git a/src/migtd/src/spdm/spdm_rsp.rs b/src/migtd/src/spdm/spdm_rsp.rs index 9eaae0ca..61bde179 100644 --- a/src/migtd/src/spdm/spdm_rsp.rs +++ b/src/migtd/src/spdm/spdm_rsp.rs @@ -3,6 +3,12 @@ // SPDX-License-Identifier: BSD-2-Clause-Patent use crate::mig_policy; +#[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] +use crate::migration::rebinding::{ + write_rebinding_session_token, write_servtd_rebind_attr, RebindingInfo, +}; +#[cfg(feature = "policy_v2")] +use crate::migration::servtd_ext::{write_approved_servtd_ext_hash, ServtdExt}; use crate::{ config::get_policy, event_log::get_event_log, @@ -38,12 +44,22 @@ use zeroize::Zeroize; extern crate alloc; #[repr(C)] -pub struct ResponderContextEx { +pub struct ResponderContextEx<'a> { pub responder_context: ResponderContext, pub remote_policy: Vec, + pub info: ResponderContextExInfo<'a>, + #[cfg(feature = "policy_v2")] + pub servtd_ext: Option, } -impl ResponderContextEx { +pub enum ResponderContextExInfo<'a> { + MigrationInformation(&'a MigtdMigrationInformation), + #[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] + RebindInformation(&'a RebindingInfo), + None, +} + +impl ResponderContextEx<'_> { pub fn inner(&self) -> &ResponderContext { &self.responder_context } @@ -59,9 +75,9 @@ pub unsafe fn upcast_mut(inner: &mut ResponderContext) -> &mut ResponderContextE &mut *outer_ptr } -pub fn spdm_responder( +pub fn spdm_responder<'a, T: AsyncRead + AsyncWrite + Unpin + Send + Sync + 'static>( stream: T, -) -> Result<(ResponderContextEx, SpdmDeviceIoArc), SpdmStatus> { +) -> Result<(ResponderContextEx<'a>, SpdmDeviceIoArc), SpdmStatus> { let transport = MigtdTransport { transport: stream }; let device_io = Arc::new(Mutex::new(transport)); let device_io_ref = device_io.clone(); @@ -119,13 +135,16 @@ pub fn spdm_responder let responder_context_ex = ResponderContextEx { responder_context, remote_policy: Vec::new(), + info: ResponderContextExInfo::None, + #[cfg(feature = "policy_v2")] + servtd_ext: None, }; Ok((responder_context_ex, device_io_ref)) } pub async fn spdm_responder_transfer_msk( - spdm_responder_ex: &mut ResponderContextEx, + spdm_responder_ex: &mut ResponderContextEx<'_>, mig_info: &MigtdMigrationInformation, #[cfg(feature = "policy_v2")] remote_policy: Vec, ) -> Result<(), SpdmStatus> { @@ -388,7 +407,7 @@ pub fn handle_exchange_mig_attest_info_req( error!("Invalid VDM message op_code: {:x?}\n", vdm_request.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_MIG_ATTEST_INFO_ELEMENT_COUNT { + if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", vdm_request.element_count @@ -563,7 +582,7 @@ pub fn handle_exchange_mig_attest_info_req( major_version: VDM_MESSAGE_MAJOR_VERSION, minor_version: VDM_MESSAGE_MINOR_VERSION, op_code: VdmMessageOpCode::ExchangeMigrationAttestInfoRsp, - element_count: VDM_MESSAGE_EXCHANGE_MIG_ATTEST_INFO_ELEMENT_COUNT, + element_count: VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT, }; cnt += vdm_exchange_attest_info @@ -698,7 +717,7 @@ pub fn handle_exchange_mig_info_req( return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - let mut remote_information = ExchangeInformation { + let remote_information = ExchangeInformation { min_ver: min_export_version, max_ver: max_export_version, key: MigrationSessionKey { @@ -709,7 +728,7 @@ pub fn handle_exchange_mig_info_req( let mut reader = Reader::init(responder_context.common.app_context_data_buffer.as_ref()); let responder_app_context = SpdmAppContextData::read(&mut reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; - let mut exchange_information = exchange_info(&responder_app_context.migration_info, false)?; + let exchange_information = exchange_info(&responder_app_context.migration_info, false)?; let mig_ver = cal_mig_version(false, &exchange_information, &remote_information)?; set_mig_version(&responder_app_context.migration_info, mig_ver)?; @@ -761,6 +780,459 @@ pub fn handle_exchange_mig_info_req( Ok(cnt) } +#[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] +pub fn handle_exchange_rebind_attest_info_req( + responder_context: &mut ResponderContext, + session_id: Option, + vdm_request: &VdmMessage, + reader: &mut Reader<'_>, + vendor_defined_rsp_payload: &mut [u8], +) -> SpdmResult { + use crate::ratls::gen_tdreport; + // Rebinding messages must be handled only when rebinding info is set. + let spdm_responder_ex = unsafe { upcast_mut(responder_context) }; + if !matches!( + &spdm_responder_ex.info, + ResponderContextExInfo::RebindInformation(_) + ) { + error!("Rebinding info is not set in responder context.\n"); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + + let session_id = if session_id.is_some() { + session_id + } else { + responder_context.common.runtime_info.get_last_session_id() + }; + if session_id.is_none() { + error!("Cannot transfer attestation info before key exchange.\n"); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + } + let session_id = session_id.unwrap(); + + let session = responder_context + .common + .get_session_via_id(session_id) + .ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; + if session + .runtime_info + .vdm_message_transcript_before_finish + .is_some() + { + error!("Attestation info has already been exchanged.\n"); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + } + + if responder_context.common.provision_info.my_pub_key.is_none() + || responder_context + .common + .provision_info + .peer_pub_key + .is_none() + { + error!("Cannot transfer attestation info without provisioning pub_key.\n"); + return Err(SPDM_STATUS_UNSUPPORTED_CAP); + } + + if vdm_request.major_version != VDM_MESSAGE_MAJOR_VERSION { + error!( + "Invalid VDM message major_version: {:x?}\n", + vdm_request.major_version + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_request.minor_version != VDM_MESSAGE_MINOR_VERSION { + error!( + "Invalid VDM message minor_version: {:x?}\n", + vdm_request.minor_version + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_request.op_code != VdmMessageOpCode::ExchangeRebindAttestInfoReq { + error!("Invalid VDM message op_code: {:x?}\n", vdm_request.op_code); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_ATTEST_INFO_WITH_HISTORY_INFO_ELEMENT_COUNT + { + error!( + "Invalid VDM message element_count: {:x?}\n", + vdm_request.element_count + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + + let th1 = if let Some(s) = responder_context.common.get_session_via_id(session_id) { + s.get_th1() + } else { + error!("Cannot get TH1 from session.\n"); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + }; + + let report_data_prefix = "MigTDRsp".as_bytes(); + let report_data_prefix_len = report_data_prefix.len(); + // Build concatenated slice: "MigTDRsp" || th1 + let th1_len = th1.data_size as usize; + // th1 for SHA-384 should be 48 bytes; 8 (prefix) + 48 digest = 56 bytes needed. + if th1_len > SPDM_MAX_HASH_SIZE { + error!("th1 length is too large: {}\n", th1_len); + return Err(SPDM_STATUS_BUFFER_FULL); + } + let mut report_data = [0u8; "MigTDRsp".len() + SPDM_MAX_HASH_SIZE]; + // Copy prefix + report_data[..report_data_prefix_len].copy_from_slice(report_data_prefix); + report_data[report_data_prefix_len..report_data_prefix_len + th1_len] + .copy_from_slice(&th1.data[..th1_len]); + + //TD report src + let vdm_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_element.element_type != VdmMessageElementType::TdReportMy { + error!( + "Invalid VDM message element_type: {:x?}\n", + vdm_element.element_type + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + let td_report_src = reader + .take(vdm_element.length as usize) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + let td_report_src_vec = td_report_src.to_vec(); + + //event log src + let vdm_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_element.element_type != VdmMessageElementType::EventLogMy { + error!( + "Invalid VDM message element_type: {:x?}\n", + vdm_element.element_type + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + let event_log_src = reader + .take(vdm_element.length as usize) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + let event_log_src_vec = event_log_src.to_vec(); + + //mig policy src + let vdm_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_element.element_type != VdmMessageElementType::MigPolicyMy { + error!( + "Invalid VDM message element_type: {:x?}\n", + vdm_element.element_type + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + let mig_policy_hash_src = reader + .take(vdm_element.length as usize) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + let mig_policy_hash_src_vec = mig_policy_hash_src.to_vec(); + + // SERVTD_EXT + let vdm_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_element.element_type != VdmMessageElementType::SerVtdExt { + error!( + "Invalid VDM message element_type: {:x?}\n", + vdm_element.element_type + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + }; + let servtd_ext = reader + .take(vdm_element.length as usize) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + let servtd_ext_vec = servtd_ext.to_vec(); + + // TD report init + let vdm_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_element.element_type != VdmMessageElementType::TdReportInit { + error!( + "Invalid VDM message element_type: {:x?}\n", + vdm_element.element_type + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + }; + let td_report_init = reader + .take(vdm_element.length as usize) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + let td_report_init_vec = td_report_init.to_vec(); + + // event log init + let vdm_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_element.element_type != VdmMessageElementType::EventLogInit { + error!( + "Invalid VDM message element_type: {:x?}\n", + vdm_element.element_type + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + }; + let event_log_init = reader + .take(vdm_element.length as usize) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + let event_log_init_vec = event_log_init.to_vec(); + + // mig policy init hash + let vdm_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if vdm_element.element_type != VdmMessageElementType::MigPolicyInit { + error!( + "Invalid VDM message element_type: {:x?}\n", + vdm_element.element_type + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + }; + let mig_policy_init_hash_src = reader + .take(vdm_element.length as usize) + .ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + + // attestation verification + #[cfg(not(feature = "test_disable_ra_and_accept_all"))] + { + let pre_session_data = unsafe { + let spdm_responder_ex = upcast_mut(responder_context); + spdm_responder_ex.remote_policy.as_slice() + }; + + //FIXME: Enable easier access to pre-session data, aligned to tls fixme. + let remote_policy_size = u32::from_le_bytes( + pre_session_data + .get(..4) + .ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)? + .try_into() + .unwrap(), + ) as usize; + let remote_policy = pre_session_data + .get(4..4 + remote_policy_size) + .ok_or(MigrationResult::InvalidPolicyError)?; + let init_policy_offset = 4 + remote_policy_size; + let init_policy_size = u32::from_le_bytes( + pre_session_data + .get(init_policy_offset..4 + init_policy_offset) + .ok_or(MigrationResult::InvalidPolicyError)? + .try_into() + .unwrap(), + ) as usize; + let init_policy = pre_session_data + .get(init_policy_offset + 4..init_policy_offset + 4 + init_policy_size) + .ok_or(MigrationResult::InvalidPolicyError)?; + + let remote_policy_hash = + digest_sha384(remote_policy).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; + if mig_policy_hash_src_vec != remote_policy_hash { + error!( + "The received mig policy hash does not match the expected remote policy hash!\n" + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + + let mig_policy_init_hash = + digest_sha384(init_policy).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; + if mig_policy_init_hash_src != mig_policy_init_hash.as_slice() { + error!( + "The received mig policy init hash does not match the expected init policy hash!\n" + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + + let policy_check_result = mig_policy::authenticate_rebinding_old( + &td_report_src_vec, + &event_log_src_vec, + remote_policy, + init_policy, + &event_log_init_vec, + &td_report_init_vec, + &servtd_ext_vec, + ); + if let Err(e) = &policy_check_result { + error!("Policy v2 check failed, below is the detail information:\n"); + error!("{:x?}\n", e); + let session = responder_context + .common + .get_session_via_id(session_id) + .ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; + session.teardown(); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + } + + unsafe { + let spdm_responder_ex = upcast_mut(responder_context); + spdm_responder_ex.servtd_ext = ServtdExt::read_from_bytes(&servtd_ext_vec); + }; + + let mut writer = Writer::init(vendor_defined_rsp_payload); + let mut cnt = 0; + + let vdm_exchange_attest_info = VdmMessage { + major_version: VDM_MESSAGE_MAJOR_VERSION, + minor_version: VDM_MESSAGE_MINOR_VERSION, + op_code: VdmMessageOpCode::ExchangeRebindAttestInfoRsp, + element_count: VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT, + }; + + cnt += vdm_exchange_attest_info + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + + //TD report dst + let td_report_dst = gen_tdreport(&report_data[..report_data_prefix_len + th1_len]) + .map_err(|_| SPDM_STATUS_INVALID_STATE_LOCAL)?; + let td_report_dst_bytes = td_report_dst.as_bytes(); + + if td_report_dst_bytes.len() > u16::MAX as usize { + error!( + "Td report size is too large: {}\n", + td_report_dst_bytes.len() + ); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + } + let tdreport_element = VdmMessageElement { + element_type: VdmMessageElementType::TdReportMy, + length: td_report_dst_bytes.len() as u16, + }; + cnt += tdreport_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(td_report_dst_bytes) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + //event log dst + let event_log_dst = get_event_log().ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; + if event_log_dst.len() > u16::MAX as usize { + error!("Event log size is too large: {}\n", event_log_dst.len()); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + } + let event_log_element = VdmMessageElement { + element_type: VdmMessageElementType::EventLogMy, + length: event_log_dst.len() as u16, + }; + cnt += event_log_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(event_log_dst) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + //mig policy dst + let mig_policy_dst = get_policy().ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; + let mig_policy_dst_hash = + digest_sha384(mig_policy_dst).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; + let mig_policy_element = VdmMessageElement { + element_type: VdmMessageElementType::MigPolicyMy, + length: mig_policy_dst_hash.len() as u16, + }; + cnt += mig_policy_element + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + cnt += writer + .extend_from_slice(&mig_policy_dst_hash) + .ok_or(SPDM_STATUS_BUFFER_FULL)?; + + Ok(cnt) +} + +#[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] +pub fn handle_exchange_rebind_info_req( + responder_context: &mut ResponderContext, + session_id: Option, + vdm_request: &VdmMessage, + reader: &mut Reader<'_>, + vendor_defined_rsp_payload: &mut [u8], +) -> SpdmResult { + // Rebinding messages must be handled only when rebinding info is set. + let spdm_responder_ex = unsafe { upcast_mut(responder_context) }; + if !matches!( + &spdm_responder_ex.info, + ResponderContextExInfo::RebindInformation(_) + ) { + error!("Rebinding info is not set in responder context.\n"); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + + // The VDM message for secret migration info exchange MUST be sent after mutual attested session establishment. + let session_id = if let Some(sid) = session_id { + sid + } else { + return Err(SPDM_STATUS_INVALID_PARAMETER); + }; + + let session = responder_context + .common + .get_session_via_id(session_id) + .ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; + if session.get_session_state() + != spdmlib::common::session::SpdmSessionState::SpdmSessionEstablished + || session + .runtime_info + .vdm_message_transcript_before_finish + .is_none() + { + error!("Migration info received while session is not established!\n"); + session.teardown(); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + } + + if vdm_request.major_version != VDM_MESSAGE_MAJOR_VERSION { + error!( + "Invalid VDM message major_version: {:x?}\n", + vdm_request.major_version + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_request.minor_version != VDM_MESSAGE_MINOR_VERSION { + error!( + "Invalid VDM message minor_version: {:x?}\n", + vdm_request.minor_version + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_request.op_code != VdmMessageOpCode::ExchangeRebindInfoReq { + error!("Invalid VDM message op_code: {:x?}\n", vdm_request.op_code); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_REBIND_INFO_ELEMENT_REQ_COUNT { + error!( + "Invalid VDM message element_count: {:x?}\n", + vdm_request.element_count + ); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + + let rebind_session_token_element = + VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + if rebind_session_token_element.element_type != VdmMessageElementType::RebindSessionToken + || rebind_session_token_element.length + != VDM_MESSAGE_EXCHANGE_REBIND_INFO_SESSION_TOKEN_SIZE + { + error!("invalid rebind session token!\n"); + return Err(SPDM_STATUS_INVALID_MSG_FIELD); + } + + let mut token = <[u8; 32]>::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; + + let servtd_ext = unsafe { + let spdm_responder_ex = upcast_mut(responder_context); + spdm_responder_ex + .servtd_ext + .ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)? + }; + + write_rebinding_session_token(&token)?; + write_approved_servtd_ext_hash(&servtd_ext.calculate_approved_servtd_ext_hash()?)?; + write_servtd_rebind_attr(&servtd_ext.cur_servtd_attr)?; + token.zeroize(); + + let mut writer = Writer::init(vendor_defined_rsp_payload); + let mut cnt = 0; + let vdm_exchange_mig_info = VdmMessage { + major_version: VDM_MESSAGE_MAJOR_VERSION, + minor_version: VDM_MESSAGE_MINOR_VERSION, + op_code: VdmMessageOpCode::ExchangeRebindInfoRsp, + element_count: VDM_MESSAGE_EXCHANGE_REBIND_INFO_ELEMENT_RSP_COUNT, + }; + cnt += vdm_exchange_mig_info + .encode(&mut writer) + .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + + Ok(cnt) +} + pub static SECRET_ASYM_IMPL_INSTANCE: SpdmSecretAsymSign = SpdmSecretAsymSign { sign_cb: asym_sign }; diff --git a/src/migtd/src/spdm/spdm_vdm.rs b/src/migtd/src/spdm/spdm_vdm.rs index cb86b0e7..7c4d7396 100644 --- a/src/migtd/src/spdm/spdm_vdm.rs +++ b/src/migtd/src/spdm/spdm_vdm.rs @@ -24,11 +24,15 @@ pub const VDM_MESSAGE_MAJOR_VERSION: u8 = 0; pub const VDM_MESSAGE_MINOR_VERSION: u8 = 0; pub const VDM_MESSAGE_EXCHANGE_PUB_KEY_ELEMENT_COUNT: u8 = 1; -pub const VDM_MESSAGE_EXCHANGE_MIG_ATTEST_INFO_ELEMENT_COUNT: u8 = 3; +pub const VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT: u8 = 3; +pub const VDM_MESSAGE_EXCHANGE_ATTEST_INFO_WITH_HISTORY_INFO_ELEMENT_COUNT: u8 = 7; pub const VDM_MESSAGE_EXCHANGE_MIG_INFO_ELEMENT_COUNT: u8 = 2; +pub const VDM_MESSAGE_EXCHANGE_REBIND_INFO_ELEMENT_REQ_COUNT: u8 = 1; +pub const VDM_MESSAGE_EXCHANGE_REBIND_INFO_ELEMENT_RSP_COUNT: u8 = 0; pub const VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_VERSION_SIZE: u16 = 4; pub const VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_SESSION_KEY_SIZE: u16 = 32; +pub const VDM_MESSAGE_EXCHANGE_REBIND_INFO_SESSION_TOKEN_SIZE: u16 = 32; enum_builder! { @U8 @@ -40,11 +44,11 @@ enum_builder! { ExchangeMigrationAttestInfoReq => 0x03, ExchangeMigrationAttestInfoRsp => 0x04, ExchangeMigrationInfoReq => 0x05, - ExchangeMigrationInfoRsp => 0x06 -// ExchangeRebindAttestInfoReq => 0x07, -// ExchangeRebindAttestInfoRsp => 0x08, -// ExchangeRebindInfoReq => 0x09, -// ExchangeRebindInfoRsp => 0x0A + ExchangeMigrationInfoRsp => 0x06, + ExchangeRebindAttestInfoReq => 0x07, + ExchangeRebindAttestInfoRsp => 0x08, + ExchangeRebindInfoReq => 0x09, + ExchangeRebindInfoRsp => 0x0A } } @@ -97,15 +101,15 @@ enum_builder! { QuoteMy => 0x03, EventLogMy => 0x04, MigPolicyMy => 0x05, -// SerVtdExt => 0x10, -// TdReportInit => 0x12, -// EventLogInit => 0x14, -// MigPolicyInit => 0x15, + SerVtdExt => 0x10, + TdReportInit => 0x12, + EventLogInit => 0x14, + MigPolicyInit => 0x15, MigrationExportVersion => 0x81, MigrationImportVersion => 0x82, ForwardMigrationSessionKey => 0x83, - BackwardMigrationSessionKey => 0x84 -// RebindSessionToken => 0x85, + BackwardMigrationSessionKey => 0x84, + RebindSessionToken => 0x85 } } @@ -459,6 +463,22 @@ pub fn migtd_vdm_msg_rsp_dispatcher_ex<'a>( &mut reader, &mut vdm_rsp_payload.rsp_payload, ), + #[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] + VdmMessageOpCode::ExchangeRebindAttestInfoReq => handle_exchange_rebind_attest_info_req( + responder_context, + session_id, + &vdm_request, + &mut reader, + &mut vdm_rsp_payload.rsp_payload, + ), + #[cfg(all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"))] + VdmMessageOpCode::ExchangeRebindInfoReq => handle_exchange_rebind_info_req( + responder_context, + session_id, + &vdm_request, + &mut reader, + &mut vdm_rsp_payload.rsp_payload, + ), _ => Err(SPDM_STATUS_INVALID_MSG_FIELD), }; if let Ok(vdm_payload_size) = vdm_payload_size { @@ -544,7 +564,8 @@ pub fn migtd_vdm_msg_rsp_dispatcher_ex<'a>( .runtime_info .vdm_message_transcript_before_key_exchange = Some(transcript_before_key_exchange); } - VdmMessageOpCode::ExchangeMigrationAttestInfoReq => { + VdmMessageOpCode::ExchangeMigrationAttestInfoReq + | VdmMessageOpCode::ExchangeRebindAttestInfoReq => { let vdm_attest_info_src_hash = match digest_sha384(req_bytes) { Ok(hash) => hash, Err(_) => { @@ -594,7 +615,7 @@ pub fn migtd_vdm_msg_rsp_dispatcher_ex<'a>( } } } - VdmMessageOpCode::ExchangeMigrationInfoReq => {} + VdmMessageOpCode::ExchangeMigrationInfoReq | VdmMessageOpCode::ExchangeRebindInfoReq => {} _ => {} }; From a8b35c8d036dc6576e086df29ed17b8894d02da6 Mon Sep 17 00:00:00 2001 From: siweicai Date: Thu, 5 Feb 2026 17:25:26 +0800 Subject: [PATCH 2/3] Modify names of definitions and variables to align with spec --- src/migtd/src/spdm/spdm_req.rs | 53 +++++++++++++++++++--------------- src/migtd/src/spdm/spdm_rsp.rs | 40 +++++++++++++------------ src/migtd/src/spdm/spdm_vdm.rs | 21 +++++++++----- 3 files changed, 66 insertions(+), 48 deletions(-) diff --git a/src/migtd/src/spdm/spdm_req.rs b/src/migtd/src/spdm/spdm_req.rs index f4370af0..73f4c74a 100644 --- a/src/migtd/src/spdm/spdm_req.rs +++ b/src/migtd/src/spdm/spdm_req.rs @@ -147,7 +147,7 @@ pub async fn send_and_receive_pub_key(spdm_requester: &mut RequesterContext) -> major_version: VDM_MESSAGE_MAJOR_VERSION, minor_version: VDM_MESSAGE_MINOR_VERSION, op_code: VdmMessageOpCode::ExchangePubKeyReq, - element_count: VDM_MESSAGE_EXCHANGE_PUB_KEY_ELEMENT_COUNT, + element_count: VDM_MESSAGE_EXCHANGE_PUB_KEY_REQ_ELEMENT_COUNT, }; cnt += vdm_exchange_pub_key .encode(&mut writer) @@ -216,7 +216,7 @@ pub async fn send_and_receive_pub_key(spdm_requester: &mut RequesterContext) -> error!("Invalid VDM message op_code: {:x?}\n", vdm_message.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_PUB_KEY_ELEMENT_COUNT { + if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_PUB_KEY_RSP_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", vdm_message.element_count @@ -308,7 +308,7 @@ pub async fn send_and_receive_sdm_migration_attest_info( major_version: VDM_MESSAGE_MAJOR_VERSION, minor_version: VDM_MESSAGE_MINOR_VERSION, op_code: VdmMessageOpCode::ExchangeMigrationAttestInfoReq, - element_count: VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT, + element_count: VDM_MESSAGE_EXCHANGE_MIGRATION_ATTEST_INFO_REQ_ELEMENT_COUNT, }; cnt += vdm_exchange_attest_info @@ -462,7 +462,7 @@ pub async fn send_and_receive_sdm_migration_attest_info( error!("Invalid VDM message op_code: {:x?}\n", vdm_message.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT { + if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_MIGRATION_ATTEST_INFO_RSP_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", vdm_message.element_count @@ -620,7 +620,7 @@ async fn send_and_receive_sdm_exchange_migration_info( major_version: VDM_MESSAGE_MAJOR_VERSION, minor_version: VDM_MESSAGE_MINOR_VERSION, op_code: VdmMessageOpCode::ExchangeMigrationInfoReq, - element_count: VDM_MESSAGE_EXCHANGE_MIG_INFO_ELEMENT_COUNT, + element_count: VDM_MESSAGE_EXCHANGE_MIGRATION_INFO_REQ_ELEMENT_COUNT, }; cnt += vdm_exchange_migration_info @@ -630,7 +630,7 @@ async fn send_and_receive_sdm_exchange_migration_info( //Migration Export Version let mig_export_version_element = VdmMessageElement { element_type: VdmMessageElementType::MigrationExportVersion, - length: VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_VERSION_SIZE, + length: VDM_MESSAGE_MIGRATION_EXPORT_VERSION_SIZE, }; cnt += mig_export_version_element .encode(&mut writer) @@ -645,11 +645,11 @@ async fn send_and_receive_sdm_exchange_migration_info( .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; //Forward Migration Session Key - let mig_session_key_element = VdmMessageElement { + let forward_mig_session_key_element = VdmMessageElement { element_type: VdmMessageElementType::ForwardMigrationSessionKey, - length: VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_SESSION_KEY_SIZE, + length: VDM_MESSAGE_FORWARD_MIGRATION_SESSION_KEY_SIZE, }; - cnt += mig_session_key_element + cnt += forward_mig_session_key_element .encode(&mut writer) .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; cnt += exchange_information @@ -720,44 +720,44 @@ async fn send_and_receive_sdm_exchange_migration_info( error!("Invalid VDM message op_code: {:x?}\n", vdm_message.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_MIG_INFO_ELEMENT_COUNT { + if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_MIGRATION_INFO_RSP_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", vdm_message.element_count ); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - let mig_export_version_element = + let mig_import_version_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; - if mig_export_version_element.element_type != VdmMessageElementType::MigrationImportVersion { + if mig_import_version_element.element_type != VdmMessageElementType::MigrationImportVersion { error!( "Invalid VDM message element_type: {:x?}\n", - mig_export_version_element.element_type + mig_import_version_element.element_type ); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if mig_export_version_element.length != VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_VERSION_SIZE { + if mig_import_version_element.length != VDM_MESSAGE_MIGRATION_IMPORT_VERSION_SIZE { error!( "Invalid VDM message element length: {:x?}\n", - mig_export_version_element.length + mig_import_version_element.length ); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } let min_import_version = u16::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; let max_import_version = u16::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; - let mig_session_key_element = + let backward_mig_session_key_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; - if mig_session_key_element.element_type != VdmMessageElementType::BackwardMigrationSessionKey { + if backward_mig_session_key_element.element_type != VdmMessageElementType::BackwardMigrationSessionKey { error!( "Invalid VDM message element_type: {:x?}\n", - mig_session_key_element.element_type + backward_mig_session_key_element.element_type ); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if mig_session_key_element.length != VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_SESSION_KEY_SIZE { + if backward_mig_session_key_element.length != VDM_MESSAGE_BACKWARD_MIGRATION_SESSION_KEY_SIZE { error!( "Invalid VDM message element length: {:x?}\n", - mig_session_key_element.length + backward_mig_session_key_element.length ); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } @@ -806,7 +806,7 @@ pub async fn send_and_receive_sdm_rebind_attest_info( major_version: VDM_MESSAGE_MAJOR_VERSION, minor_version: VDM_MESSAGE_MINOR_VERSION, op_code: VdmMessageOpCode::ExchangeRebindAttestInfoReq, - element_count: VDM_MESSAGE_EXCHANGE_ATTEST_INFO_WITH_HISTORY_INFO_ELEMENT_COUNT, + element_count: VDM_MESSAGE_EXCHANGE_REBIND_ATTEST_INFO_REQ_WITH_HISTORY_INFO_ELEMENT_COUNT, }; cnt += vdm_exchange_attest_info @@ -1012,7 +1012,7 @@ pub async fn send_and_receive_sdm_rebind_attest_info( error!("Invalid VDM message op_code: {:x?}\n", vdm_message.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT { + if vdm_message.element_count != VDM_MESSAGE_EXCHANGE_REBIND_ATTEST_INFO_RSP_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", vdm_message.element_count @@ -1124,6 +1124,13 @@ pub async fn send_and_receive_sdm_rebind_info( let rebind_token = create_rebind_token(rebind_info)?; let token = rebind_token.token; + if token.len() as u16 != VDM_MESSAGE_REBIND_SESSION_TOKEN_SIZE { + error!( + "Rebind token size is invalid: {}\n", + token.len() + ); + return Err(SPDM_STATUS_INVALID_STATE_LOCAL); + } let mut payload = vec![0u8; MAX_SPDM_VENDOR_DEFINED_PAYLOAD_SIZE]; let mut writer = Writer::init(&mut payload); @@ -1143,7 +1150,7 @@ pub async fn send_and_receive_sdm_rebind_info( // Rebind session token let rebind_session_token_element = VdmMessageElement { element_type: VdmMessageElementType::RebindSessionToken, - length: token.len() as u16, + length: VDM_MESSAGE_REBIND_SESSION_TOKEN_SIZE, }; cnt += rebind_session_token_element .encode(&mut writer) diff --git a/src/migtd/src/spdm/spdm_rsp.rs b/src/migtd/src/spdm/spdm_rsp.rs index 61bde179..f06de77e 100644 --- a/src/migtd/src/spdm/spdm_rsp.rs +++ b/src/migtd/src/spdm/spdm_rsp.rs @@ -253,7 +253,7 @@ pub fn handle_exchange_pub_key_req( error!("Invalid VDM message op_code: {:x?}\n", vdm_request.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_PUB_KEY_ELEMENT_COUNT { + if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_PUB_KEY_REQ_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", vdm_request.element_count @@ -303,7 +303,7 @@ pub fn handle_exchange_pub_key_req( major_version: VDM_MESSAGE_MAJOR_VERSION, minor_version: VDM_MESSAGE_MINOR_VERSION, op_code: VdmMessageOpCode::ExchangePubKeyRsp, - element_count: VDM_MESSAGE_EXCHANGE_PUB_KEY_ELEMENT_COUNT, + element_count: VDM_MESSAGE_EXCHANGE_PUB_KEY_RSP_ELEMENT_COUNT, }; cnt += vdm_exchange_pub_key @@ -407,7 +407,7 @@ pub fn handle_exchange_mig_attest_info_req( error!("Invalid VDM message op_code: {:x?}\n", vdm_request.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT { + if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_MIGRATION_ATTEST_INFO_REQ_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", vdm_request.element_count @@ -582,7 +582,7 @@ pub fn handle_exchange_mig_attest_info_req( major_version: VDM_MESSAGE_MAJOR_VERSION, minor_version: VDM_MESSAGE_MINOR_VERSION, op_code: VdmMessageOpCode::ExchangeMigrationAttestInfoRsp, - element_count: VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT, + element_count: VDM_MESSAGE_EXCHANGE_MIGRATION_ATTEST_INFO_RSP_ELEMENT_COUNT, }; cnt += vdm_exchange_attest_info @@ -688,7 +688,7 @@ pub fn handle_exchange_mig_info_req( error!("Invalid VDM message op_code: {:x?}\n", vdm_request.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_MIG_INFO_ELEMENT_COUNT { + if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_MIGRATION_INFO_REQ_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", vdm_request.element_count @@ -699,7 +699,7 @@ pub fn handle_exchange_mig_info_req( let mig_export_version_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; if mig_export_version_element.element_type != VdmMessageElementType::MigrationExportVersion - || mig_export_version_element.length != VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_VERSION_SIZE + || mig_export_version_element.length != VDM_MESSAGE_MIGRATION_EXPORT_VERSION_SIZE { error!("invalid migration info payload!\n"); return Err(SPDM_STATUS_INVALID_MSG_FIELD); @@ -707,11 +707,11 @@ pub fn handle_exchange_mig_info_req( let min_export_version = u16::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; let max_export_version = u16::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; - let mig_session_key_element = + let forward_mig_session_key_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; - if mig_session_key_element.element_type != VdmMessageElementType::ForwardMigrationSessionKey - || mig_session_key_element.length - != VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_SESSION_KEY_SIZE + if forward_mig_session_key_element.element_type != VdmMessageElementType::ForwardMigrationSessionKey + || forward_mig_session_key_element.length + != VDM_MESSAGE_FORWARD_MIGRATION_SESSION_KEY_SIZE { error!("invalid forward migration session key!\n"); return Err(SPDM_STATUS_INVALID_MSG_FIELD); @@ -748,14 +748,16 @@ pub fn handle_exchange_mig_info_req( major_version: VDM_MESSAGE_MAJOR_VERSION, minor_version: VDM_MESSAGE_MINOR_VERSION, op_code: VdmMessageOpCode::ExchangeMigrationInfoRsp, - element_count: VDM_MESSAGE_EXCHANGE_MIG_INFO_ELEMENT_COUNT, + element_count: VDM_MESSAGE_EXCHANGE_MIGRATION_INFO_RSP_ELEMENT_COUNT, }; cnt += vdm_exchange_mig_info .encode(&mut writer) .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; + + //Migration Import Version let mig_import_version_element = VdmMessageElement { element_type: VdmMessageElementType::MigrationImportVersion, - length: VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_VERSION_SIZE, + length: VDM_MESSAGE_MIGRATION_IMPORT_VERSION_SIZE, }; cnt += mig_import_version_element .encode(&mut writer) @@ -766,11 +768,13 @@ pub fn handle_exchange_mig_info_req( cnt += max_import_version .encode(&mut writer) .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; - let mig_session_key_element = VdmMessageElement { + + //Backward Migration Session Key + let backward_mig_session_key_element = VdmMessageElement { element_type: VdmMessageElementType::BackwardMigrationSessionKey, - length: VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_SESSION_KEY_SIZE, + length: VDM_MESSAGE_BACKWARD_MIGRATION_SESSION_KEY_SIZE, }; - cnt += mig_session_key_element + cnt += backward_mig_session_key_element .encode(&mut writer) .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; cnt += writer @@ -852,7 +856,7 @@ pub fn handle_exchange_rebind_attest_info_req( error!("Invalid VDM message op_code: {:x?}\n", vdm_request.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_ATTEST_INFO_WITH_HISTORY_INFO_ELEMENT_COUNT + if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_REBIND_ATTEST_INFO_REQ_WITH_HISTORY_INFO_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", @@ -1062,7 +1066,7 @@ pub fn handle_exchange_rebind_attest_info_req( major_version: VDM_MESSAGE_MAJOR_VERSION, minor_version: VDM_MESSAGE_MINOR_VERSION, op_code: VdmMessageOpCode::ExchangeRebindAttestInfoRsp, - element_count: VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT, + element_count: VDM_MESSAGE_EXCHANGE_REBIND_ATTEST_INFO_RSP_ELEMENT_COUNT, }; cnt += vdm_exchange_attest_info @@ -1198,7 +1202,7 @@ pub fn handle_exchange_rebind_info_req( VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; if rebind_session_token_element.element_type != VdmMessageElementType::RebindSessionToken || rebind_session_token_element.length - != VDM_MESSAGE_EXCHANGE_REBIND_INFO_SESSION_TOKEN_SIZE + != VDM_MESSAGE_REBIND_SESSION_TOKEN_SIZE { error!("invalid rebind session token!\n"); return Err(SPDM_STATUS_INVALID_MSG_FIELD); diff --git a/src/migtd/src/spdm/spdm_vdm.rs b/src/migtd/src/spdm/spdm_vdm.rs index 7c4d7396..38c3cf94 100644 --- a/src/migtd/src/spdm/spdm_vdm.rs +++ b/src/migtd/src/spdm/spdm_vdm.rs @@ -23,16 +23,23 @@ pub const VDM_MESSAGE_VENDOR_ID_LEN: usize = 4; pub const VDM_MESSAGE_MAJOR_VERSION: u8 = 0; pub const VDM_MESSAGE_MINOR_VERSION: u8 = 0; -pub const VDM_MESSAGE_EXCHANGE_PUB_KEY_ELEMENT_COUNT: u8 = 1; -pub const VDM_MESSAGE_EXCHANGE_ATTEST_INFO_ELEMENT_COUNT: u8 = 3; -pub const VDM_MESSAGE_EXCHANGE_ATTEST_INFO_WITH_HISTORY_INFO_ELEMENT_COUNT: u8 = 7; -pub const VDM_MESSAGE_EXCHANGE_MIG_INFO_ELEMENT_COUNT: u8 = 2; +pub const VDM_MESSAGE_EXCHANGE_PUB_KEY_REQ_ELEMENT_COUNT: u8 = 1; +pub const VDM_MESSAGE_EXCHANGE_PUB_KEY_RSP_ELEMENT_COUNT: u8 = 1; +pub const VDM_MESSAGE_EXCHANGE_MIGRATION_ATTEST_INFO_REQ_ELEMENT_COUNT: u8 = 3; +//pub const VDM_MESSAGE_EXCHANGE_MIGRATION_ATTEST_INFO_REQ_WITH_HISTORY_INFO_ELEMENT_COUNT: u8 = 7; Migration with History Info is not supported yet. +pub const VDM_MESSAGE_EXCHANGE_MIGRATION_ATTEST_INFO_RSP_ELEMENT_COUNT: u8 = 3; +pub const VDM_MESSAGE_EXCHANGE_MIGRATION_INFO_REQ_ELEMENT_COUNT: u8 = 2; +pub const VDM_MESSAGE_EXCHANGE_MIGRATION_INFO_RSP_ELEMENT_COUNT: u8 = 2; +pub const VDM_MESSAGE_EXCHANGE_REBIND_ATTEST_INFO_REQ_WITH_HISTORY_INFO_ELEMENT_COUNT: u8 = 7; +pub const VDM_MESSAGE_EXCHANGE_REBIND_ATTEST_INFO_RSP_ELEMENT_COUNT: u8 = 3; pub const VDM_MESSAGE_EXCHANGE_REBIND_INFO_ELEMENT_REQ_COUNT: u8 = 1; pub const VDM_MESSAGE_EXCHANGE_REBIND_INFO_ELEMENT_RSP_COUNT: u8 = 0; -pub const VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_VERSION_SIZE: u16 = 4; -pub const VDM_MESSAGE_EXCHANGE_MIG_INFO_MIGRATION_SESSION_KEY_SIZE: u16 = 32; -pub const VDM_MESSAGE_EXCHANGE_REBIND_INFO_SESSION_TOKEN_SIZE: u16 = 32; +pub const VDM_MESSAGE_MIGRATION_EXPORT_VERSION_SIZE: u16 = 4; +pub const VDM_MESSAGE_FORWARD_MIGRATION_SESSION_KEY_SIZE: u16 = 32; +pub const VDM_MESSAGE_MIGRATION_IMPORT_VERSION_SIZE: u16 = 4; +pub const VDM_MESSAGE_BACKWARD_MIGRATION_SESSION_KEY_SIZE: u16 = 32; +pub const VDM_MESSAGE_REBIND_SESSION_TOKEN_SIZE: u16 = 32; enum_builder! { @U8 From 384f768d565ac2c297f6348d470b473ead41dc04 Mon Sep 17 00:00:00 2001 From: siweicai Date: Thu, 5 Feb 2026 17:33:40 +0800 Subject: [PATCH 3/3] Change Spdm vdm elements Length field length to 4 --- src/migtd/src/spdm/spdm_req.rs | 54 +++++++++++----------------------- src/migtd/src/spdm/spdm_rsp.rs | 45 ++++++++-------------------- src/migtd/src/spdm/spdm_vdm.rs | 14 ++++----- 3 files changed, 37 insertions(+), 76 deletions(-) diff --git a/src/migtd/src/spdm/spdm_req.rs b/src/migtd/src/spdm/spdm_req.rs index 73f4c74a..7232b695 100644 --- a/src/migtd/src/spdm/spdm_req.rs +++ b/src/migtd/src/spdm/spdm_req.rs @@ -155,7 +155,7 @@ pub async fn send_and_receive_pub_key(spdm_requester: &mut RequesterContext) -> let pub_key_element = VdmMessageElement { element_type: VdmMessageElementType::PubKeyMy, - length: my_pub_key.len() as u16, + length: my_pub_key.len() as u32, }; cnt += pub_key_element .encode(&mut writer) @@ -357,13 +357,10 @@ pub async fn send_and_receive_sdm_migration_attest_info( #[cfg(not(feature = "policy_v2"))] let verified_report_local = res.unwrap(); - if quote_src.len() > u16::MAX as usize { - error!("Quote size is too large: {}\n", quote_src.len()); - return Err(SPDM_STATUS_INVALID_STATE_LOCAL); - } + //quote src let quote_element = VdmMessageElement { element_type: VdmMessageElementType::QuoteMy, - length: quote_src.len() as u16, + length: quote_src.len() as u32, }; cnt += quote_element .encode(&mut writer) @@ -374,13 +371,9 @@ pub async fn send_and_receive_sdm_migration_attest_info( //event log src let event_log_src = get_event_log().ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; - if event_log_src.len() > u16::MAX as usize { - error!("Event log size is too large: {}\n", event_log_src.len()); - return Err(SPDM_STATUS_INVALID_STATE_LOCAL); - } let event_log_element = VdmMessageElement { element_type: VdmMessageElementType::EventLogMy, - length: event_log_src.len() as u16, + length: event_log_src.len() as u32, }; cnt += event_log_element .encode(&mut writer) @@ -396,7 +389,7 @@ pub async fn send_and_receive_sdm_migration_attest_info( let mig_policy_element = VdmMessageElement { element_type: VdmMessageElementType::MigPolicyMy, - length: mig_policy_src_hash.len() as u16, + length: mig_policy_src_hash.len() as u32, }; cnt += mig_policy_element .encode(&mut writer) @@ -747,7 +740,9 @@ async fn send_and_receive_sdm_exchange_migration_info( let max_import_version = u16::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; let backward_mig_session_key_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; - if backward_mig_session_key_element.element_type != VdmMessageElementType::BackwardMigrationSessionKey { + if backward_mig_session_key_element.element_type + != VdmMessageElementType::BackwardMigrationSessionKey + { error!( "Invalid VDM message element_type: {:x?}\n", backward_mig_session_key_element.element_type @@ -839,17 +834,9 @@ pub async fn send_and_receive_sdm_rebind_attest_info( let td_report_src = gen_tdreport(&report_data[..report_data_prefix_len + th1_len]) .map_err(|_| SPDM_STATUS_INVALID_STATE_LOCAL)?; let td_report_src_bytes = td_report_src.as_bytes(); - - if td_report_src_bytes.len() > u16::MAX as usize { - error!( - "Td report src size is too large: {}\n", - td_report_src_bytes.len() - ); - return Err(SPDM_STATUS_INVALID_STATE_LOCAL); - } let tdreport_element = VdmMessageElement { element_type: VdmMessageElementType::TdReportMy, - length: td_report_src_bytes.len() as u16, + length: td_report_src_bytes.len() as u32, }; cnt += tdreport_element .encode(&mut writer) @@ -860,13 +847,9 @@ pub async fn send_and_receive_sdm_rebind_attest_info( //event log src let event_log_src = get_event_log().ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; - if event_log_src.len() > u16::MAX as usize { - error!("Event log size is too large: {}\n", event_log_src.len()); - return Err(SPDM_STATUS_INVALID_STATE_LOCAL); - } let event_log_element = VdmMessageElement { element_type: VdmMessageElementType::EventLogMy, - length: event_log_src.len() as u16, + length: event_log_src.len() as u32, }; cnt += event_log_element .encode(&mut writer) @@ -882,7 +865,7 @@ pub async fn send_and_receive_sdm_rebind_attest_info( let mig_policy_element = VdmMessageElement { element_type: VdmMessageElementType::MigPolicyMy, - length: mig_policy_src_hash.len() as u16, + length: mig_policy_src_hash.len() as u32, }; cnt += mig_policy_element .encode(&mut writer) @@ -905,7 +888,7 @@ pub async fn send_and_receive_sdm_rebind_attest_info( let servtd_ext_element = VdmMessageElement { element_type: VdmMessageElementType::SerVtdExt, - length: servtd_ext.as_bytes().len() as u16, + length: servtd_ext.as_bytes().len() as u32, }; cnt += servtd_ext_element .encode(&mut writer) @@ -918,7 +901,7 @@ pub async fn send_and_receive_sdm_rebind_attest_info( let tdreport_init = &init_migtd_data.init_report; let tdreport_init_element = VdmMessageElement { element_type: VdmMessageElementType::TdReportInit, - length: tdreport_init.len() as u16, + length: tdreport_init.len() as u32, }; cnt += tdreport_init_element .encode(&mut writer) @@ -931,7 +914,7 @@ pub async fn send_and_receive_sdm_rebind_attest_info( let event_log_init = &init_migtd_data.init_event_log; let event_log_init_element = VdmMessageElement { element_type: VdmMessageElementType::EventLogInit, - length: event_log_init.len() as u16, + length: event_log_init.len() as u32, }; cnt += event_log_init_element .encode(&mut writer) @@ -946,7 +929,7 @@ pub async fn send_and_receive_sdm_rebind_attest_info( digest_sha384(mig_policy_init).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; let mig_policy_init_element = VdmMessageElement { element_type: VdmMessageElementType::MigPolicyInit, - length: mig_policy_init_hash.len() as u16, + length: mig_policy_init_hash.len() as u32, }; cnt += mig_policy_init_element .encode(&mut writer) @@ -1124,11 +1107,8 @@ pub async fn send_and_receive_sdm_rebind_info( let rebind_token = create_rebind_token(rebind_info)?; let token = rebind_token.token; - if token.len() as u16 != VDM_MESSAGE_REBIND_SESSION_TOKEN_SIZE { - error!( - "Rebind token size is invalid: {}\n", - token.len() - ); + if token.len() as u32 != VDM_MESSAGE_REBIND_SESSION_TOKEN_SIZE { + error!("Rebind token size is invalid: {}\n", token.len()); return Err(SPDM_STATUS_INVALID_STATE_LOCAL); } diff --git a/src/migtd/src/spdm/spdm_rsp.rs b/src/migtd/src/spdm/spdm_rsp.rs index f06de77e..a69ec2c9 100644 --- a/src/migtd/src/spdm/spdm_rsp.rs +++ b/src/migtd/src/spdm/spdm_rsp.rs @@ -312,7 +312,7 @@ pub fn handle_exchange_pub_key_req( let pub_key_element = VdmMessageElement { element_type: VdmMessageElementType::PubKeyMy, - length: my_pub_key.len() as u16, + length: my_pub_key.len() as u32, }; cnt += pub_key_element @@ -590,13 +590,9 @@ pub fn handle_exchange_mig_attest_info_req( .map_err(|_| SPDM_STATUS_BUFFER_FULL)?; //quote dst - if quote_dst.len() > u16::MAX as usize { - error!("Quote size is too large: {}\n", quote_dst.len()); - return Err(SPDM_STATUS_INVALID_STATE_LOCAL); - } let quote_element = VdmMessageElement { element_type: VdmMessageElementType::QuoteMy, - length: quote_dst.len() as u16, + length: quote_dst.len() as u32, }; cnt += quote_element .encode(&mut writer) @@ -607,13 +603,9 @@ pub fn handle_exchange_mig_attest_info_req( //event log dst let event_log_dst = get_event_log().ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; - if event_log_dst.len() > u16::MAX as usize { - error!("Event log size is too large: {}\n", event_log_dst.len()); - return Err(SPDM_STATUS_INVALID_STATE_LOCAL); - } let event_log_element = VdmMessageElement { element_type: VdmMessageElementType::EventLogMy, - length: event_log_dst.len() as u16, + length: event_log_dst.len() as u32, }; cnt += event_log_element .encode(&mut writer) @@ -628,7 +620,7 @@ pub fn handle_exchange_mig_attest_info_req( digest_sha384(mig_policy_dst).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; let mig_policy_element = VdmMessageElement { element_type: VdmMessageElementType::MigPolicyMy, - length: mig_policy_dst_hash.len() as u16, + length: mig_policy_dst_hash.len() as u32, }; cnt += mig_policy_element .encode(&mut writer) @@ -709,9 +701,9 @@ pub fn handle_exchange_mig_info_req( let forward_mig_session_key_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; - if forward_mig_session_key_element.element_type != VdmMessageElementType::ForwardMigrationSessionKey - || forward_mig_session_key_element.length - != VDM_MESSAGE_FORWARD_MIGRATION_SESSION_KEY_SIZE + if forward_mig_session_key_element.element_type + != VdmMessageElementType::ForwardMigrationSessionKey + || forward_mig_session_key_element.length != VDM_MESSAGE_FORWARD_MIGRATION_SESSION_KEY_SIZE { error!("invalid forward migration session key!\n"); return Err(SPDM_STATUS_INVALID_MSG_FIELD); @@ -856,7 +848,8 @@ pub fn handle_exchange_rebind_attest_info_req( error!("Invalid VDM message op_code: {:x?}\n", vdm_request.op_code); return Err(SPDM_STATUS_INVALID_MSG_FIELD); } - if vdm_request.element_count != VDM_MESSAGE_EXCHANGE_REBIND_ATTEST_INFO_REQ_WITH_HISTORY_INFO_ELEMENT_COUNT + if vdm_request.element_count + != VDM_MESSAGE_EXCHANGE_REBIND_ATTEST_INFO_REQ_WITH_HISTORY_INFO_ELEMENT_COUNT { error!( "Invalid VDM message element_count: {:x?}\n", @@ -1078,16 +1071,9 @@ pub fn handle_exchange_rebind_attest_info_req( .map_err(|_| SPDM_STATUS_INVALID_STATE_LOCAL)?; let td_report_dst_bytes = td_report_dst.as_bytes(); - if td_report_dst_bytes.len() > u16::MAX as usize { - error!( - "Td report size is too large: {}\n", - td_report_dst_bytes.len() - ); - return Err(SPDM_STATUS_INVALID_STATE_LOCAL); - } let tdreport_element = VdmMessageElement { element_type: VdmMessageElementType::TdReportMy, - length: td_report_dst_bytes.len() as u16, + length: td_report_dst_bytes.len() as u32, }; cnt += tdreport_element .encode(&mut writer) @@ -1098,13 +1084,9 @@ pub fn handle_exchange_rebind_attest_info_req( //event log dst let event_log_dst = get_event_log().ok_or(SPDM_STATUS_INVALID_STATE_LOCAL)?; - if event_log_dst.len() > u16::MAX as usize { - error!("Event log size is too large: {}\n", event_log_dst.len()); - return Err(SPDM_STATUS_INVALID_STATE_LOCAL); - } let event_log_element = VdmMessageElement { element_type: VdmMessageElementType::EventLogMy, - length: event_log_dst.len() as u16, + length: event_log_dst.len() as u32, }; cnt += event_log_element .encode(&mut writer) @@ -1119,7 +1101,7 @@ pub fn handle_exchange_rebind_attest_info_req( digest_sha384(mig_policy_dst).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?; let mig_policy_element = VdmMessageElement { element_type: VdmMessageElementType::MigPolicyMy, - length: mig_policy_dst_hash.len() as u16, + length: mig_policy_dst_hash.len() as u32, }; cnt += mig_policy_element .encode(&mut writer) @@ -1201,8 +1183,7 @@ pub fn handle_exchange_rebind_info_req( let rebind_session_token_element = VdmMessageElement::read(reader).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?; if rebind_session_token_element.element_type != VdmMessageElementType::RebindSessionToken - || rebind_session_token_element.length - != VDM_MESSAGE_REBIND_SESSION_TOKEN_SIZE + || rebind_session_token_element.length != VDM_MESSAGE_REBIND_SESSION_TOKEN_SIZE { error!("invalid rebind session token!\n"); return Err(SPDM_STATUS_INVALID_MSG_FIELD); diff --git a/src/migtd/src/spdm/spdm_vdm.rs b/src/migtd/src/spdm/spdm_vdm.rs index 38c3cf94..23f145b5 100644 --- a/src/migtd/src/spdm/spdm_vdm.rs +++ b/src/migtd/src/spdm/spdm_vdm.rs @@ -35,11 +35,11 @@ pub const VDM_MESSAGE_EXCHANGE_REBIND_ATTEST_INFO_RSP_ELEMENT_COUNT: u8 = 3; pub const VDM_MESSAGE_EXCHANGE_REBIND_INFO_ELEMENT_REQ_COUNT: u8 = 1; pub const VDM_MESSAGE_EXCHANGE_REBIND_INFO_ELEMENT_RSP_COUNT: u8 = 0; -pub const VDM_MESSAGE_MIGRATION_EXPORT_VERSION_SIZE: u16 = 4; -pub const VDM_MESSAGE_FORWARD_MIGRATION_SESSION_KEY_SIZE: u16 = 32; -pub const VDM_MESSAGE_MIGRATION_IMPORT_VERSION_SIZE: u16 = 4; -pub const VDM_MESSAGE_BACKWARD_MIGRATION_SESSION_KEY_SIZE: u16 = 32; -pub const VDM_MESSAGE_REBIND_SESSION_TOKEN_SIZE: u16 = 32; +pub const VDM_MESSAGE_MIGRATION_EXPORT_VERSION_SIZE: u32 = 4; +pub const VDM_MESSAGE_FORWARD_MIGRATION_SESSION_KEY_SIZE: u32 = 32; +pub const VDM_MESSAGE_MIGRATION_IMPORT_VERSION_SIZE: u32 = 4; +pub const VDM_MESSAGE_BACKWARD_MIGRATION_SESSION_KEY_SIZE: u32 = 32; +pub const VDM_MESSAGE_REBIND_SESSION_TOKEN_SIZE: u32 = 32; enum_builder! { @U8 @@ -130,7 +130,7 @@ impl Default for VdmMessageElementType { #[derive(Debug)] pub struct VdmMessageElement { pub element_type: VdmMessageElementType, - pub length: u16, + pub length: u32, } impl Codec for VdmMessageElement { @@ -143,7 +143,7 @@ impl Codec for VdmMessageElement { fn read(r: &mut Reader<'_>) -> Option { let element_type = VdmMessageElementType::read(r)?; - let length = u16::read(r)?; + let length = u32::read(r)?; Some(VdmMessageElement { element_type, length,