@@ -269,6 +269,9 @@ typedef enum {
269269 KEYMGR_KEY_SINK_COUNT
270270} OtKeyMgrKeySink ;
271271
272+ static_assert (KEYMGR_KEY_SINK_COUNT < 32 ,
273+ "Sideload clear bitmasking logic needs < 32 key sinks" );
274+
272275#define KEY_SINK_OFFSET 1
273276
274277typedef enum {
@@ -445,6 +448,7 @@ typedef struct OtKeyMgrState {
445448 OtRomCtrlState * rom_ctrl ;
446449 DeviceState * key_sinks [KEYMGR_KEY_SINK_COUNT ];
447450 char * seed_xstrs [KEYMGR_SEED_COUNT ];
451+ bool use_default_entropy_seed ; /* flag to seed PRNG with default seed */
448452} OtKeyMgrState ;
449453
450454struct OtKeyMgrClass {
@@ -832,16 +836,14 @@ static void ot_keymgr_request_entropy(OtKeyMgrState *s)
832836 }
833837}
834838
835- static void ot_keymgr_wipe_key_states (OtKeyMgrState * s )
839+ /* Returns true if 'data' is not all zeros or all ones */
840+ static bool ot_keymgr_valid_data_check (const uint8_t * data , size_t len )
836841{
837- /* @todo: should wipe with random entropy, but just zero for now */
838- for (unsigned cdi = 0u ; cdi < NUM_CDIS ; cdi ++ ) {
839- memset (s -> key_states [cdi ].share0 , 0u , KEYMGR_KEY_BYTES );
840- memset (s -> key_states [cdi ].share1 , 0u , KEYMGR_KEY_BYTES );
841- s -> key_states [cdi ].valid = false;
842- }
843- memset (s -> sw_out_key -> share0 , 0u , KEYMGR_KEY_BYTES );
844- memset (s -> sw_out_key -> share1 , 0u , KEYMGR_KEY_BYTES );
842+ size_t popcount = 0u ;
843+ for (unsigned ix = 0u ; ix < len ; ix ++ ) {
844+ popcount += __builtin_popcount (data [ix ]);
845+ }
846+ return (popcount && popcount != (len * BITS_PER_BYTE ));
845847}
846848
847849static void ot_keymgr_push_key (
@@ -855,12 +857,14 @@ static void ot_keymgr_push_key(
855857
856858 g_assert (sink );
857859
860+ g_assert (key_share0 );
861+ g_assert (key_share1 );
862+
858863 /*
859864 * Save the latest KMAC sideloading key, as it needs to be restored after
860865 * any keymgr operations that load the KMAC KDF key to offload KDF.
861866 */
862- if (key_share0 && key_share1 && sideload_key &&
863- key_sink == KEYMGR_KEY_SINK_KMAC ) {
867+ if (sideload_key && key_sink == KEYMGR_KEY_SINK_KMAC ) {
864868 memcpy (s -> saved_kmac_key -> share0 , key_share0 , key_size );
865869 memcpy (s -> saved_kmac_key -> share1 , key_share1 , key_size );
866870 s -> saved_kmac_key -> valid = valid ;
@@ -898,23 +902,65 @@ static void ot_keymgr_push_kdf_key(OtKeyMgrState *s, const uint8_t *key_share0,
898902 trace_ot_keymgr_push_kdf_key (s -> ot_id , valid );
899903
900904 /*
901- * @todo: when key invalidating/wiping with entropy is implemented,
902- * pushing a new KDF key should perform a validity check for all 0s
903- * or all 1s, and set R_DEBUG_INVALID_KEY_MASK if so, i.e.:
904- *
905- * if (!ot_keymgr_valid_data_check(key_share0, OT_KMAC_KEY_SIZE)) {
906- * s->regs[R_DEBUG] |= R_DEBUG_INVALID_KEY_MASK;
907- * s->op_state.valid_inputs = false;
908- * }
909- *
910905 * @todo: when KMAC masking is introduced, this should check both key
911906 * shares and not just key share 0 for validity.
912907 */
908+ if (!ot_keymgr_valid_data_check (key_share0 , OT_KMAC_KEY_SIZE )) {
909+ s -> regs [R_DEBUG ] |= R_DEBUG_INVALID_KEY_MASK ;
910+ s -> op_state .valid_inputs = false;
911+ }
913912
914913 ot_keymgr_push_key (s , KEYMGR_KEY_SINK_KMAC , key_share0 , key_share1 , valid ,
915914 false);
916915}
917916
917+ static void ot_keymgr_wipe_keys (OtKeyMgrState * s , bool key_states ,
918+ bool sw_outputs , uint32_t key_sink_bm )
919+ {
920+ trace_ot_keymgr_wipe_keys (s -> ot_id , key_states , sw_outputs , key_sink_bm );
921+
922+ uint8_t sideload_share0 [KEYMGR_KEY_SIZE_MAX ];
923+ uint8_t sideload_share1 [KEYMGR_KEY_SIZE_MAX ];
924+
925+ /* all keys (CDIs, shares etc.) are wiped with the same entropy */
926+ for (unsigned ix = 0 ; ix < KEYMGR_KEY_SIZE_MAX ; ix += sizeof (uint32_t )) {
927+ /* @todo: use reseed_cnt and reseed if > RESEED_INTERVAL_SHADOWED */
928+ uint32_t randval = ot_prng_random_u32 (s -> prng .state );
929+
930+ if (key_states && ix < KEYMGR_KEY_BYTES ) {
931+ for (unsigned cdi = 0u ; cdi < NUM_CDIS ; cdi ++ ) {
932+ stl_le_p (& s -> key_states [cdi ].share0 [ix ], randval );
933+ stl_le_p (& s -> key_states [cdi ].share1 [ix ], randval );
934+ }
935+ }
936+
937+ if (sw_outputs && ix < KEYMGR_KEY_BYTES ) {
938+ stl_le_p (& s -> sw_out_key -> share0 [ix ], randval );
939+ stl_le_p (& s -> sw_out_key -> share1 [ix ], randval );
940+ }
941+
942+ if (key_sink_bm ) {
943+ stl_le_p (& sideload_share0 [ix ], randval );
944+ stl_le_p (& sideload_share1 [ix ], randval );
945+ }
946+ }
947+
948+ for (unsigned ix = 0 ; key_sink_bm && ix < KEYMGR_KEY_SINK_COUNT ; ix ++ ) {
949+ uint32_t key_sink_mask = (1u << ix );
950+ if (key_sink_bm & key_sink_mask ) {
951+ key_sink_bm &= ~key_sink_mask ;
952+ ot_keymgr_push_key (s , (OtKeyMgrKeySink )ix , sideload_share0 ,
953+ sideload_share1 , false, true);
954+ }
955+ }
956+ }
957+
958+ static void ot_keymgr_wipe_all_keys (OtKeyMgrState * s )
959+ {
960+ uint32_t all_keys_bm = (1u << KEYMGR_KEY_SINK_COUNT ) - 1u ;
961+ ot_keymgr_wipe_keys (s , true, true, all_keys_bm );
962+ }
963+
918964static void ot_keymgr_sideload_clear (OtKeyMgrState * s )
919965{
920966 int sideload_clear =
@@ -924,38 +970,22 @@ static void ot_keymgr_sideload_clear(OtKeyMgrState *s)
924970 SIDELOAD_CLEAR_NAME (sideload_clear ),
925971 sideload_clear );
926972
927- /* @todo: this should use random dummy data instead */
928- uint8_t share0 [KEYMGR_KEY_SIZE_MAX ] = { 0 };
929- uint8_t share1 [KEYMGR_KEY_SIZE_MAX ] = { 0 };
930-
973+ uint32_t sideload_clear_bm ;
931974 switch (sideload_clear ) {
932975 case KEYMGR_SIDELOAD_CLEAR_NONE :
933- break ;
976+ return ;
934977 case KEYMGR_SIDELOAD_CLEAR_AES :
935978 case KEYMGR_SIDELOAD_CLEAR_OTBN :
936- case KEYMGR_SIDELOAD_CLEAR_KMAC : {
937- OtKeyMgrKeySink sink =
938- (OtKeyMgrKeySink )(sideload_clear - KEY_SINK_OFFSET );
939- ot_keymgr_push_key (s , sink , share0 , share1 , false, true);
979+ case KEYMGR_SIDELOAD_CLEAR_KMAC :
980+ sideload_clear_bm = 1u << (sideload_clear - KEY_SINK_OFFSET );
940981 break ;
941- }
942982 default :
943983 /* continuously clear ALL slots if a non-enumerated value is written */
944- for (unsigned ix = 0 ; ix < KEYMGR_KEY_SINK_COUNT ; ix ++ ) {
945- ot_keymgr_push_key (s , (OtKeyMgrKeySink )ix , share0 , share1 , false,
946- true);
947- }
984+ sideload_clear_bm = (1u << KEYMGR_KEY_SINK_COUNT ) - 1u ;
985+ break ;
948986 }
949- }
950987
951- /* check that 'data' is not all zeros or all ones */
952- static bool ot_keymgr_valid_data_check (const uint8_t * data , size_t len )
953- {
954- size_t popcount = 0u ;
955- for (unsigned ix = 0u ; ix < len ; ix ++ ) {
956- popcount += __builtin_popcount (data [ix ]);
957- }
958- return (popcount && popcount != (len * BITS_PER_BYTE ));
988+ ot_keymgr_wipe_keys (s , false, false, sideload_clear_bm );
959989}
960990
961991static void ot_keymgr_reset_kdf_buffer (OtKeyMgrState * s )
@@ -1204,7 +1234,7 @@ static void ot_keymgr_send_kmac_req(OtKeyMgrState *s)
12041234
12051235static void ot_keymgr_operation_disable (OtKeyMgrState * s )
12061236{
1207- ot_keymgr_wipe_key_states (s );
1237+ ot_keymgr_wipe_all_keys (s );
12081238 ot_keymgr_change_main_fsm_state (s , KEYMGR_ST_DISABLED );
12091239 s -> op_state .op_ack = true;
12101240 ot_keymgr_schedule_fsm (s );
@@ -1739,7 +1769,7 @@ static bool ot_keymgr_main_fsm_tick(OtKeyMgrState *s)
17391769 break ;
17401770 case KEYMGR_ST_WIPE :
17411771 /* whilst wiping, keymgr retains the previous working state */
1742- ot_keymgr_wipe_key_states (s );
1772+ ot_keymgr_wipe_all_keys (s );
17431773 /* see OT keymgr_ctrl.sv RTL: maintain & complete ongoing ops */
17441774 if (op_start ) {
17451775 s -> regs [R_ERR_CODE ] |= R_ERR_CODE_INVALID_OP_MASK ;
@@ -2050,6 +2080,11 @@ static void ot_keymgr_write(void *opaque, hwaddr addr, uint64_t val64,
20502080 val32 &= R_RESEED_INTERVAL_SHADOWED_VAL_MASK ;
20512081 switch (ot_shadow_reg_write (& s -> reseed_interval , val32 )) {
20522082 case OT_SHADOW_REG_STAGED :
2083+ /* @todo: implement entropy reseeding & better entropy modelling */
2084+ qemu_log_mask (LOG_UNIMP ,
2085+ "%s: %s: Entropy reseeding not implemented.\n" ,
2086+ __func__ , s -> ot_id );
2087+ break ;
20532088 case OT_SHADOW_REG_COMMITTED :
20542089 break ;
20552090 case OT_SHADOW_REG_ERROR :
@@ -2285,6 +2320,8 @@ static Property ot_keymgr_properties[] = {
22852320 DEFINE_PROP_STRING ("cdi_seed" , OtKeyMgrState , seed_xstrs [KEYMGR_SEED_CDI ]),
22862321 DEFINE_PROP_STRING ("none_seed" , OtKeyMgrState ,
22872322 seed_xstrs [KEYMGR_SEED_NONE ]),
2323+ DEFINE_PROP_BOOL ("use-default-entropy-seed" , OtKeyMgrState ,
2324+ use_default_entropy_seed , false),
22882325 DEFINE_PROP_END_OF_LIST (),
22892326};
22902327
@@ -2341,17 +2378,20 @@ static void ot_keymgr_reset_enter(Object *obj, ResetType type)
23412378 s -> prng .reseed_req = false;
23422379 s -> prng .reseed_ack = false;
23432380 s -> prng .reseed_cnt = 0u ;
2381+ if (s -> use_default_entropy_seed ) {
2382+ const uint8_t * default_prng_seed = s -> seeds [KEYMGR_SEED_LFSR ];
2383+ for (unsigned ix = 0 ; ix < KEYMGR_SEED_BYTES ; ix += sizeof (uint32_t )) {
2384+ uint32_t seed = ldl_le_p (& default_prng_seed [ix ]);
2385+ ot_prng_reseed (s -> prng .state , seed );
2386+ }
2387+ }
23442388 s -> op_state .op_req = false;
23452389 s -> op_state .op_ack = false;
23462390 s -> op_state .valid_inputs = true;
23472391 s -> op_state .stage = KEYMGR_STAGE_DISABLE ;
23482392 s -> op_state .adv_cdi_cnt = 0u ;
23492393 ot_keymgr_reset_kdf_buffer (s );
23502394
2351- /* reset key state */
2352- memset (s -> key_states , 0u , NUM_CDIS * sizeof (OtKeyMgrKey ));
2353- memset (s -> saved_kmac_key , 0u , sizeof (OtKeyMgrKey ));
2354-
23552395 /* reset output keys */
23562396 memset (s -> sw_out_key , 0u , sizeof (OtKeyMgrKey ));
23572397
@@ -2376,11 +2416,9 @@ static void ot_keymgr_reset_exit(Object *obj, ResetType type)
23762416 c -> parent_phases .exit (obj , type );
23772417 }
23782418
2379- /* invalidate all sideloaded keys when exiting reset */
2380- for (unsigned ix = 0u ; ix < KEYMGR_KEY_SINK_COUNT ; ix ++ ) {
2381- OtKeyMgrKeySink key_sink = (OtKeyMgrKeySink )ix ;
2382- ot_keymgr_push_key (s , key_sink , NULL , NULL , false, true);
2383- }
2419+ /* invalidate internal key state & sideloaded keys when exiting reset */
2420+ uint32_t all_keys_bm = (1u << KEYMGR_KEY_SINK_COUNT ) - 1u ;
2421+ ot_keymgr_wipe_keys (s , true, false, all_keys_bm );
23842422}
23852423
23862424static void ot_keymgr_realize (DeviceState * dev , Error * * errp )
0 commit comments