@@ -14,6 +14,8 @@ use ring::rand::{SecureRandom, SystemRandom};
1414use tdx_tdcall:: tdx:: { tdcall_servtd_rebind_approve, tdcall_vm_write} ;
1515
1616use crate :: migration:: servtd_ext:: read_servtd_ext;
17+ #[ cfg( feature = "spdm_attestation" ) ]
18+ use crate :: spdm;
1719use crate :: { event_log, migration:: transport:: * } ;
1820use crypto:: hash:: digest_sha384;
1921
@@ -392,6 +394,22 @@ pub async fn start_rebinding(
392394 MIGTD_REBIND_OP_FINALIZE => rebinding_old_finalize ( info, data) . await ?,
393395 _ => return Err ( MigrationResult :: InvalidParameter ) ,
394396 }
397+
398+ #[ cfg( feature = "spdm_attestation" ) ]
399+ match info. operation {
400+ MIGTD_REBIND_OP_PREPARE => {
401+ rebinding_old_spdm (
402+ transport,
403+ info,
404+ data,
405+ #[ cfg( feature = "policy_v2" ) ]
406+ remote_policy,
407+ )
408+ . await ?
409+ }
410+ MIGTD_REBIND_OP_FINALIZE => rebinding_old_finalize ( info, data) . await ?,
411+ _ => return Err ( MigrationResult :: InvalidParameter ) ,
412+ }
395413 } else {
396414 let pre_session_data = Box :: pin ( with_timeout (
397415 PRE_SESSION_TIMEOUT ,
@@ -421,8 +439,23 @@ pub async fn start_rebinding(
421439 MIGTD_REBIND_OP_FINALIZE => rebinding_new_finalize ( info, data) . await ?,
422440 _ => return Err ( MigrationResult :: InvalidParameter ) ,
423441 }
424- }
425442
443+ #[ cfg( feature = "spdm_attestation" ) ]
444+ match info. operation {
445+ MIGTD_REBIND_OP_PREPARE => {
446+ rebinding_new_spdm (
447+ transport,
448+ info,
449+ data,
450+ #[ cfg( feature = "policy_v2" ) ]
451+ pre_session_data,
452+ )
453+ . await ?
454+ }
455+ MIGTD_REBIND_OP_FINALIZE => rebinding_new_finalize ( info, data) . await ?,
456+ _ => return Err ( MigrationResult :: InvalidParameter ) ,
457+ }
458+ }
426459 #[ cfg( feature = "vmcall-raw" ) ]
427460 {
428461 use crate :: migration:: logging:: entrylog;
@@ -437,6 +470,87 @@ pub async fn start_rebinding(
437470 Ok ( ( ) )
438471}
439472
473+ #[ cfg( feature = "spdm_attestation" ) ]
474+ pub async fn rebinding_old_spdm (
475+ transport : TransportType ,
476+ info : & RebindingInfo < ' _ > ,
477+ _data : & mut Vec < u8 > ,
478+ #[ cfg( feature = "policy_v2" ) ] remote_policy : Vec < u8 > ,
479+ ) -> Result < ( ) , MigrationResult > {
480+ const SPDM_TIMEOUT : Duration = Duration :: from_secs ( 60 ) ; // 60 seconds
481+ let mut spdm_requester = spdm:: spdm_requester ( transport) . map_err ( |_e| {
482+ log:: error!(
483+ "rebinding: Failed in spdm_requester transport. Migration ID: {}\n " ,
484+ info. mig_request_id
485+ ) ;
486+ MigrationResult :: SecureSessionError
487+ } ) ?;
488+ with_timeout (
489+ SPDM_TIMEOUT ,
490+ spdm:: spdm_requester_rebind_old (
491+ & mut spdm_requester,
492+ info,
493+ #[ cfg( feature = "policy_v2" ) ]
494+ remote_policy,
495+ ) ,
496+ )
497+ . await
498+ . map_err ( |e| {
499+ log:: error!(
500+ "rebinding: spdm_requester_rebind_old timeout error: {:?}\n " ,
501+ e
502+ ) ;
503+ e
504+ } ) ?
505+ . map_err ( |e| {
506+ log:: error!( "rebinding: spdm_requester_rebind_old error: {:?}\n " , e) ;
507+ e
508+ } ) ?;
509+ log:: info!( "Rebind completed\n " ) ;
510+ Ok ( ( ) )
511+ }
512+
513+ #[ cfg( feature = "spdm_attestation" ) ]
514+ pub async fn rebinding_new_spdm (
515+ transport : TransportType ,
516+ info : & RebindingInfo < ' _ > ,
517+ _data : & mut Vec < u8 > ,
518+ #[ cfg( feature = "policy_v2" ) ] remote_policy : Vec < u8 > ,
519+ ) -> Result < ( ) , MigrationResult > {
520+ const SPDM_TIMEOUT : Duration = Duration :: from_secs ( 60 ) ; // 60 seconds
521+ let mut spdm_responder = spdm:: spdm_responder ( transport) . map_err ( |_e| {
522+ log:: error!(
523+ "rebinding: Failed in spdm_responder transport. Migration ID: {}\n " ,
524+ info. mig_request_id
525+ ) ;
526+ MigrationResult :: SecureSessionError
527+ } ) ?;
528+
529+ with_timeout (
530+ SPDM_TIMEOUT ,
531+ spdm:: spdm_responder_rebind_new (
532+ & mut spdm_responder,
533+ info,
534+ #[ cfg( feature = "policy_v2" ) ]
535+ remote_policy,
536+ ) ,
537+ )
538+ . await
539+ . map_err ( |e| {
540+ log:: error!(
541+ "rebinding: spdm_responder_rebind_new timeout error: {:?}\n " ,
542+ e
543+ ) ;
544+ e
545+ } ) ?
546+ . map_err ( |e| {
547+ log:: error!( "rebinding: spdm_responder_rebind_new error: {:?}\n " , e) ;
548+ e
549+ } ) ?;
550+ log:: info!( "Rebind completed\n " ) ;
551+ Ok ( ( ) )
552+ }
553+
440554pub async fn rebinding_old_prepare (
441555 transport : TransportType ,
442556 info : & RebindingInfo < ' _ > ,
@@ -594,7 +708,7 @@ fn get_servtd_ext_from_cert(certs: &Option<Vec<&[u8]>>) -> Result<ServtdExt, Mig
594708 }
595709}
596710
597- fn create_rebind_token ( info : & RebindingInfo ) -> Result < RebindingToken , MigrationResult > {
711+ pub fn create_rebind_token ( info : & RebindingInfo ) -> Result < RebindingToken , MigrationResult > {
598712 let mut token = [ 0u8 ; 32 ] ;
599713 let rng = SystemRandom :: new ( ) ;
600714 rng. fill ( & mut token)
0 commit comments