@@ -57,9 +57,9 @@ use caliptra_drivers::{
5757 hand_off:: DataStore ,
5858 pcr_log:: { PCR_ID_STASH_MEASUREMENT , RT_FW_CURRENT_PCR , RT_FW_JOURNEY_PCR } ,
5959 sha2_512_384:: Sha2DigestOpTrait ,
60- Aes , Array4x12 , CaliptraError , CaliptraResult , Ecc384 , Hmac , KeyId , KeyVault , Lms , Mldsa87 ,
61- Mldsa87PubKey , PcrBank , PersistentDataAccessor , Pic , ResetReason , Sha1 , Sha256 , Sha256Alg ,
62- Sha2_512_384 , Sha2_512_384Acc , SocIfc , Trng ,
60+ Aes , Array4x12 , CaliptraError , CaliptraManagedDpeContextIndices , CaliptraResult , Ecc384 , Hmac ,
61+ KeyId , KeyVault , Lms , Mldsa87 , Mldsa87PubKey , PcrBank , PersistentDataAccessor , Pic ,
62+ ResetReason , Sha1 , Sha256 , Sha256Alg , Sha2_512_384 , Sha2_512_384Acc , SocIfc , Trng ,
6363} ;
6464use caliptra_drivers:: { Dma , DmaMmio } ;
6565use caliptra_image_types:: ImageManifest ;
@@ -98,6 +98,21 @@ impl From<McuResetReason> for u32 {
9898 }
9999}
100100
101+ #[ derive( Clone , Copy ) ]
102+ pub ( crate ) enum CaliptraManagedDpeContext {
103+ Cciv ,
104+ McuRt ,
105+ }
106+
107+ impl CaliptraManagedDpeContext {
108+ fn tci_type ( self ) -> u32 {
109+ match self {
110+ Self :: Cciv => Drivers :: CCIV_TCI_TYPE ,
111+ Self :: McuRt => Drivers :: MCU_RT_TCI_TYPE ,
112+ }
113+ }
114+ }
115+
101116#[ derive( Debug , Copy , Clone ) ]
102117pub enum McuFwStatus {
103118 NotLoaded ,
@@ -229,21 +244,22 @@ impl Drivers {
229244 match reset_reason {
230245 ResetReason :: ColdReset => {
231246 cfi_assert_eq ( self . soc_ifc . reset_reason ( ) , ResetReason :: ColdReset ) ;
247+ self . persistent_data
248+ . get_mut ( )
249+ . caliptra_managed_dpe_context_indices
250+ . invalidate ( ) ;
232251 Self :: initialize_dpe ( self ) ?;
233252 if self . soc_ifc . subsystem_mode ( ) {
234253 RecoveryFlow :: recovery_flow ( self ) ?;
235254 }
236- self . cache_caliptra_managed_dpe_context_indices ( ) ?;
237255 }
238256 ResetReason :: UpdateReset => {
239257 cfi_assert_eq ( self . soc_ifc . reset_reason ( ) , ResetReason :: UpdateReset ) ;
240258 Self :: validate_dpe_structure ( self ) ?;
241259 Self :: validate_context_tags ( self ) ?;
260+ self . init_dpe_index_cache ( ) ?;
242261 Self :: update_dpe_rt_tci ( self ) ?;
243262 Self :: update_dpe_cciv ( self ) ?;
244- // Repopulate appended context-index cache for hitless updates
245- // from older runtimes that did not have these persistent fields.
246- self . cache_caliptra_managed_dpe_context_indices ( ) ?;
247263 }
248264 ResetReason :: WarmReset => {
249265 cfi_assert_eq ( self . soc_ifc . reset_reason ( ) , ResetReason :: WarmReset ) ;
@@ -321,22 +337,39 @@ impl Drivers {
321337 }
322338
323339 #[ inline( always) ]
324- fn get_caliptra_managed_dpe_context_index ( & self , tci_type : u32 ) -> CaliptraResult < usize > {
340+ fn get_caliptra_managed_dpe_context_index (
341+ & self ,
342+ context : CaliptraManagedDpeContext ,
343+ ) -> Option < usize > {
325344 let indices = self
326345 . persistent_data
327346 . get ( )
328347 . caliptra_managed_dpe_context_indices ;
329- let idx = match tci_type {
330- Self :: CCIV_TCI_TYPE => indices. cciv ,
331- Self :: MCU_RT_TCI_TYPE => indices. mcu_rt ,
332- _ => return Err ( CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ,
348+
349+ if !indices. is_initialized ( ) {
350+ return None ;
351+ }
352+
353+ let idx = match context {
354+ CaliptraManagedDpeContext :: Cciv => indices. cciv ,
355+ CaliptraManagedDpeContext :: McuRt => indices. mcu_rt ,
333356 } ;
334357
335- Ok ( idx as usize )
358+ if idx == CaliptraManagedDpeContextIndices :: INVALID_INDEX {
359+ None
360+ } else {
361+ Some ( idx as usize )
362+ }
336363 }
337364
338- fn cache_caliptra_managed_dpe_context_indices ( & mut self ) -> CaliptraResult < ( ) > {
339- if self . persistent_data . get ( ) . attestation_disabled . get ( ) {
365+ fn init_dpe_index_cache ( & mut self ) -> CaliptraResult < ( ) > {
366+ if self . persistent_data . get ( ) . attestation_disabled . get ( )
367+ || self
368+ . persistent_data
369+ . get ( )
370+ . caliptra_managed_dpe_context_indices
371+ . is_initialized ( )
372+ {
340373 return Ok ( ( ) ) ;
341374 }
342375
@@ -364,11 +397,14 @@ impl Drivers {
364397 . persistent_data
365398 . get_mut ( )
366399 . caliptra_managed_dpe_context_indices ;
367- indices. cciv =
368- u8:: try_from ( cciv_idx) . map_err ( |_| CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ?;
400+ indices. set_cciv (
401+ u8:: try_from ( cciv_idx) . map_err ( |_| CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ?,
402+ ) ;
369403 if let Some ( mcu_rt_idx) = mcu_rt_idx {
370- indices. mcu_rt = u8:: try_from ( mcu_rt_idx)
371- . map_err ( |_| CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ?;
404+ indices. set_mcu_rt (
405+ u8:: try_from ( mcu_rt_idx)
406+ . map_err ( |_| CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ?,
407+ ) ;
372408 }
373409
374410 Ok ( ( ) )
@@ -378,32 +414,34 @@ impl Drivers {
378414 #[ inline( never) ]
379415 pub ( crate ) fn update_caliptra_managed_measurement (
380416 & mut self ,
381- tci_type : u32 ,
417+ caliptra_managed_context : CaliptraManagedDpeContext ,
382418 measurement : & [ u8 ; 48 ] ,
383419 locality : Option < u32 > ,
384420 ) -> CaliptraResult < ( ) > {
385- let persistent_data = self . persistent_data . get ( ) ;
386- let idx = self . get_caliptra_managed_dpe_context_index ( tci_type) ?;
387- let ctx = persistent_data
388- . state
389- . contexts
390- . get ( idx)
391- . ok_or ( CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ?;
392- if ctx. state == ContextState :: Inactive
393- || ctx. context_type != ContextType :: Normal
394- || ctx. tci . tci_type != tci_type
395- || locality. is_some_and ( |locality| ctx. locality != locality)
396- {
397- return Err ( CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ;
398- }
399- let prev_journey = persistent_data
400- . state
401- . contexts
402- . get ( idx)
403- . ok_or ( CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ?
404- . tci
405- . tci_cumulative
406- . 0 ;
421+ let tci_type = caliptra_managed_context. tci_type ( ) ;
422+ let ( idx, prev_journey) = {
423+ let persistent_data = self . persistent_data . get ( ) ;
424+ let Some ( idx) = self . get_caliptra_managed_dpe_context_index ( caliptra_managed_context)
425+ else {
426+ return Ok ( ( ) ) ;
427+ } ;
428+ let ctx = persistent_data
429+ . state
430+ . contexts
431+ . get ( idx)
432+ . ok_or ( CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ?;
433+ if ctx. state == ContextState :: Inactive
434+ || ctx. context_type != ContextType :: Normal
435+ || ctx. tci . tci_type != tci_type
436+ || locality. is_some_and ( |locality| ctx. locality != locality)
437+ {
438+ return Err ( CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ;
439+ }
440+ if ctx. tci . tci_current . 0 == * measurement {
441+ return Ok ( ( ) ) ;
442+ }
443+ ( idx, ctx. tci . tci_cumulative . 0 )
444+ } ;
407445
408446 let mut digest_op = self . sha2_512_384 . sha384_digest_init ( ) ?;
409447 digest_op. update ( & prev_journey) ?;
@@ -509,31 +547,8 @@ impl Drivers {
509547 }
510548 let initialization_values_hash: [ u8 ; 48 ] =
511549 <[ u8 ; 48 ] >:: from ( Self :: compute_initialization_values_hash ( drivers) ?) ;
512- // Only update if changed
513- let dpe = & drivers. persistent_data . get ( ) . state ;
514- let root_idx = Self :: get_dpe_root_context_idx ( dpe) ? as u8 ;
515- let cciv_idx =
516- Self :: get_dpe_context_idx_by_tci_type ( dpe, Self :: CCIV_TCI_TYPE , None , Some ( root_idx) ) ?;
517- let cciv_ctx = drivers
518- . persistent_data
519- . get ( )
520- . state
521- . contexts
522- . get ( cciv_idx)
523- . ok_or ( CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ?;
524- if cciv_ctx. state == ContextState :: Inactive
525- || cciv_ctx. context_type != ContextType :: Normal
526- || cciv_ctx. tci . tci_type != Self :: CCIV_TCI_TYPE
527- {
528- return Err ( CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ;
529- }
530- let prev_current: [ u8 ; 48 ] = cciv_ctx. tci . tci_current . 0 ;
531- if prev_current == initialization_values_hash {
532- return Ok ( ( ) ) ;
533- }
534-
535550 drivers. update_caliptra_managed_measurement (
536- Self :: CCIV_TCI_TYPE ,
551+ CaliptraManagedDpeContext :: Cciv ,
537552 & initialization_values_hash,
538553 None ,
539554 )
@@ -759,12 +774,15 @@ impl Drivers {
759774 }
760775 Err ( CaliptraError :: RUNTIME_ADD_CCIV_MEASUREMENT_TO_DPE_FAILED ) ?
761776 }
762- pdata . caliptra_managed_dpe_context_indices . cciv = u8:: try_from (
777+ let cciv_idx = u8:: try_from (
763778 env. state
764779 . get_active_context_pos ( & ContextHandle :: default ( ) , pl0_pauser_locality)
765780 . map_err ( |_| CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ?,
766781 )
767782 . map_err ( |_| CaliptraError :: RUNTIME_DPE_CONTEXT_NOT_FOUND ) ?;
783+ pdata
784+ . caliptra_managed_dpe_context_indices
785+ . set_cciv ( cciv_idx) ;
768786
769787 // Call DeriveContext to create TCIs for each measurement added in ROM
770788 let num_measurements = pdata. fht . meas_log_index as usize ;
0 commit comments