Skip to content

Commit c7de221

Browse files
refactor(rebinding): use init_tdinfo in rebind handshake
Adapt rebinding handshake to use init_tdinfo instead of init_policy: - rebinding.rs: rename params in pre_session_data_exchange functions - server_client.rs: rename init_td_report -> init_tdinfo in RATLS cert creation/verification, update pre_session_data parsing with init_tdinfo naming, compare mrowner at TDINFO offset 112..160 directly instead of digest_sha384(init_policy) - spdm_rsp.rs: rename pre_session_data parsing, compare mrowner directly Co-authored-by: Grams, Stanislaw <stanislaw.grams@intel.com>
1 parent c35e102 commit c7de221

3 files changed

Lines changed: 35 additions & 29 deletions

File tree

src/migtd/src/migration/rebinding.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ impl<'a> MigtdDataEntry<'a> {
235235

236236
pub(super) async fn rebinding_old_pre_session_data_exchange(
237237
transport: &mut TransportType,
238-
init_policy: &[u8],
238+
init_tdinfo: &[u8],
239239
) -> Result<Vec<u8>, MigrationResult> {
240240
let version = exchange_hello_packet(transport).await.map_err(|e| {
241241
log::error!(
@@ -271,7 +271,7 @@ pub(super) async fn rebinding_old_pre_session_data_exchange(
271271
e
272272
})?;
273273

274-
send_pre_session_data_packet(init_policy, transport)
274+
send_pre_session_data_packet(init_tdinfo, transport)
275275
.await
276276
.map_err(|e| {
277277
log::error!(
@@ -336,11 +336,11 @@ pub(super) async fn rebinding_new_pre_session_data_exchange(
336336
e
337337
})?;
338338

339-
let init_policy = receive_pre_session_data_packet(transport)
339+
let init_tdinfo = receive_pre_session_data_packet(transport)
340340
.await
341341
.map_err(|e| {
342342
log::error!(
343-
"pre_session_data_exchange: send_pre_session_data_packet error: {:?}\n",
343+
"pre_session_data_exchange: receive init_tdinfo error: {:?}\n",
344344
e
345345
);
346346
e
@@ -365,8 +365,8 @@ pub(super) async fn rebinding_new_pre_session_data_exchange(
365365
let mut policy_buffer = Vec::new();
366366
policy_buffer.extend_from_slice(&(remote_policy.len() as u32).to_le_bytes());
367367
policy_buffer.extend_from_slice(&remote_policy);
368-
policy_buffer.extend_from_slice(&(init_policy.len() as u32).to_le_bytes());
369-
policy_buffer.extend_from_slice(&init_policy);
368+
policy_buffer.extend_from_slice(&(init_tdinfo.len() as u32).to_le_bytes());
369+
policy_buffer.extend_from_slice(&init_tdinfo);
370370

371371
Ok(policy_buffer)
372372
}

src/migtd/src/ratls/server_client.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ pub fn client_rebinding<T: AsyncRead + AsyncWrite + Unpin>(
184184
stream: T,
185185
remote_policy: Vec<u8>,
186186
init_policy_hash: &[u8],
187-
init_td_report: &[u8],
187+
init_tdinfo: &[u8],
188188
init_event_log: &[u8],
189189
servtd_ext: &ServtdExt,
190190
) -> Result<SecureChannel<T>> {
@@ -198,7 +198,7 @@ pub fn client_rebinding<T: AsyncRead + AsyncWrite + Unpin>(
198198
let certs = create_certificate_for_rebinding_old(
199199
&signing_key,
200200
init_policy_hash,
201-
init_td_report,
201+
init_tdinfo,
202202
init_event_log,
203203
servtd_ext,
204204
)
@@ -409,7 +409,7 @@ fn create_certificate_for_client(signing_key: &EcdsaPk) -> Result<(Vec<u8>, Vec<
409409
fn create_certificate_for_rebinding_old(
410410
signing_key: &EcdsaPk,
411411
init_policy_hash: &[u8],
412-
init_tdreport: &[u8],
412+
init_tdinfo: &[u8],
413413
init_event_log: &[u8],
414414
servtd_ext: &ServtdExt,
415415
) -> Result<Vec<u8>> {
@@ -508,7 +508,7 @@ fn create_certificate_for_rebinding_old(
508508
Extension::new(
509509
EXTNID_MIGTD_TDREPORT_INIT,
510510
Some(false),
511-
Some(&init_tdreport),
511+
Some(&init_tdinfo),
512512
)
513513
.map_err(|e| {
514514
log::error!(
@@ -992,16 +992,18 @@ mod verify {
992992
log::error!("Failed to find expected policy hash extension.\n");
993993
CryptoError::ParseCertificate
994994
})?;
995-
let init_td_report =
995+
// Per GHCI 1.5: init extension now carries TDINFO_STRUCT instead of full TDREPORT
996+
let init_tdinfo =
996997
find_extension(extensions, &EXTNID_MIGTD_TDREPORT_INIT).ok_or_else(|| {
997-
log::error!("Failed to find init tdreport extension.\n");
998+
log::error!("Failed to find init tdinfo extension.\n");
998999
CryptoError::ParseCertificate
9991000
})?;
10001001
let init_event_log =
10011002
find_extension(extensions, &EXTNID_MIGTD_EVENT_LOG_INIT).ok_or_else(|| {
10021003
log::error!("Failed to find init event log extension.\n");
10031004
CryptoError::ParseCertificate
10041005
})?;
1006+
// Per GHCI 1.5: init_policy_hash is now mrowner from the initial TDINFO_STRUCT
10051007
let init_policy_hash = find_extension(extensions, &EXTNID_MIGTD_INIT_POLICY_HASH)
10061008
.ok_or_else(|| {
10071009
log::error!("Failed to find init policy hash extension.\n");
@@ -1012,6 +1014,7 @@ mod verify {
10121014
CryptoError::ParseCertificate
10131015
})?;
10141016

1017+
// Parse pre_session_data: [remote_policy_size(4) | remote_policy | init_tdinfo_size(4) | init_tdinfo]
10151018
let remote_policy_size = u32::from_le_bytes(
10161019
pre_session_data
10171020
.get(..4)
@@ -1024,18 +1027,19 @@ mod verify {
10241027
let remote_policy = pre_session_data.get(4..4 + remote_policy_size).ok_or(
10251028
CryptoError::TlsVerifyPeerCert(INVALID_MIG_POLICY_ERROR.to_string()),
10261029
)?;
1027-
let init_policy_offset = 4 + remote_policy_size;
1028-
let init_policy_size = u32::from_le_bytes(
1030+
// Per GHCI 1.5: second item is init_tdinfo (was init_policy)
1031+
let init_tdinfo_offset = 4 + remote_policy_size;
1032+
let init_tdinfo_size = u32::from_le_bytes(
10291033
pre_session_data
1030-
.get(init_policy_offset..4 + init_policy_offset)
1034+
.get(init_tdinfo_offset..4 + init_tdinfo_offset)
10311035
.ok_or(CryptoError::TlsVerifyPeerCert(
10321036
INVALID_MIG_POLICY_ERROR.to_string(),
10331037
))?
10341038
.try_into()
10351039
.unwrap(),
10361040
) as usize;
1037-
let init_policy = pre_session_data
1038-
.get(init_policy_offset + 4..init_policy_offset + 4 + init_policy_size)
1041+
let _init_tdinfo_from_pre_session = pre_session_data
1042+
.get(init_tdinfo_offset + 4..init_tdinfo_offset + 4 + init_tdinfo_size)
10391043
.ok_or(CryptoError::TlsVerifyPeerCert(
10401044
INVALID_MIG_POLICY_ERROR.to_string(),
10411045
))?;
@@ -1046,9 +1050,10 @@ mod verify {
10461050
INVALID_MIG_POLICY_ERROR.to_string(),
10471051
));
10481052
}
1049-
let exact_init_policy_hash = digest_sha384(init_policy)?;
1050-
if init_policy_hash != exact_init_policy_hash.as_slice() {
1051-
log::error!("Invalid init rebinding policy.\n");
1053+
// Per GHCI 1.5: init_policy_hash is mrowner from TDINFO — compare directly
1054+
// (no longer a hash of a policy blob)
1055+
if init_policy_hash != init_tdinfo.get(112..160).unwrap_or(&[]) {
1056+
log::error!("Invalid init policy hash (mrowner mismatch).\n");
10521057
return Err(CryptoError::TlsVerifyPeerCert(
10531058
INVALID_MIG_POLICY_ERROR.to_string(),
10541059
));

src/migtd/src/spdm/spdm_rsp.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,16 +1052,17 @@ pub fn handle_exchange_rebind_attest_info_req(
10521052
let remote_policy = pre_session_data
10531053
.get(4..4 + remote_policy_size)
10541054
.ok_or(MigrationResult::InvalidPolicyError)?;
1055-
let init_policy_offset = 4 + remote_policy_size;
1056-
let init_policy_size = u32::from_le_bytes(
1055+
// Per GHCI 1.5: second item in pre_session_data is init_tdinfo (was init_policy)
1056+
let init_tdinfo_offset = 4 + remote_policy_size;
1057+
let init_tdinfo_size = u32::from_le_bytes(
10571058
pre_session_data
1058-
.get(init_policy_offset..4 + init_policy_offset)
1059+
.get(init_tdinfo_offset..4 + init_tdinfo_offset)
10591060
.ok_or(MigrationResult::InvalidPolicyError)?
10601061
.try_into()
10611062
.unwrap(),
10621063
) as usize;
1063-
let init_policy = pre_session_data
1064-
.get(init_policy_offset + 4..init_policy_offset + 4 + init_policy_size)
1064+
let _init_tdinfo_from_pre_session = pre_session_data
1065+
.get(init_tdinfo_offset + 4..init_tdinfo_offset + 4 + init_tdinfo_size)
10651066
.ok_or(MigrationResult::InvalidPolicyError)?;
10661067

10671068
let remote_policy_hash =
@@ -1073,11 +1074,11 @@ pub fn handle_exchange_rebind_attest_info_req(
10731074
return Err(SPDM_STATUS_INVALID_MSG_FIELD);
10741075
}
10751076

1076-
let mig_policy_init_hash =
1077-
digest_sha384(init_policy).map_err(|_| SPDM_STATUS_CRYPTO_ERROR)?;
1078-
if mig_policy_init_hash_src != mig_policy_init_hash.as_slice() {
1077+
// Per GHCI 1.5: init_policy_hash is mrowner from TDINFO — compare directly
1078+
let mrowner = td_report_init_vec.get(112..160).ok_or(SPDM_STATUS_INVALID_MSG_SIZE)?;
1079+
if mig_policy_init_hash_src != mrowner {
10791080
error!(
1080-
"The received mig policy init hash does not match the expected init policy hash!\n"
1081+
"The received mig policy init hash does not match mrowner from init tdinfo!\n"
10811082
);
10821083
return Err(SPDM_STATUS_INVALID_MSG_FIELD);
10831084
}

0 commit comments

Comments
 (0)