@@ -5150,6 +5150,117 @@ static void wp11_Token_Final(WP11_Token* token)
51505150static int HashPIN (char * pin , int pinLen , byte * seed , int seedLen , byte * hash ,
51515151 int hashLen , WP11_Slot * slot );
51525152
5153+ #ifdef WOLFSSL_STM32U5_DHUK
5154+ /* DHUK seed storage: IV (16) + AES-CBC ciphertext of seed (16).
5155+ * Uses AES-CBC with DHUK so the decrypted seed is placed in token->seed
5156+ * for use by AES-GCM and other operations. */
5157+ #define WP11_SEED_DHUK_IV_SZ 16
5158+ #define WP11_SEED_WRAPPED_SZ (WP11_SEED_DHUK_IV_SZ + PIN_SEED_SZ)
5159+
5160+ #if defined(HAVE_AES_CBC )
5161+ /* Dummy key for wc_AesSetKey when using DHUK; hardware uses DHUK. */
5162+ static const byte wp11_dhuk_dummy_key [32 ] = {0 };
5163+
5164+ static int wp11_token_write_seed_dhuk (void * storage , WP11_Token * token )
5165+ {
5166+ int ret ;
5167+ Aes aes ;
5168+ byte iv [WP11_SEED_DHUK_IV_SZ ];
5169+ byte wrappedSeed [PIN_SEED_SZ ];
5170+
5171+ WP11_Lock_LockRW (& token -> rngLock );
5172+ ret = wc_RNG_GenerateBlock (& token -> rng , iv , sizeof (iv ));
5173+ WP11_Lock_UnlockRW (& token -> rngLock );
5174+ if (ret != 0 )
5175+ return ret ;
5176+
5177+ ret = wc_AesInit (& aes , NULL , WOLFSSL_STM32U5_DHUK_DEVID );
5178+ if (ret != 0 )
5179+ return ret ;
5180+ ret = wc_AesSetKey (& aes , wp11_dhuk_dummy_key , sizeof (wp11_dhuk_dummy_key ),
5181+ iv , AES_ENCRYPTION );
5182+ if (ret != 0 ) {
5183+ wc_AesFree (& aes );
5184+ return ret ;
5185+ }
5186+ ret = wc_AesCbcEncrypt (& aes , wrappedSeed , (const byte * )token -> seed ,
5187+ (word32 )PIN_SEED_SZ );
5188+ wc_AesFree (& aes );
5189+ if (ret != 0 )
5190+ return ret ;
5191+
5192+ ret = wp11_storage_write_word32 (storage , WP11_SEED_WRAPPED_SZ );
5193+ if (ret == 0 )
5194+ ret = wp11_storage_write_fixed_array (storage , iv , WP11_SEED_DHUK_IV_SZ );
5195+ if (ret == 0 )
5196+ ret = wp11_storage_write (storage , wrappedSeed , (int )WP11_SEED_WRAPPED_SZ );
5197+ return ret ;
5198+ }
5199+
5200+ static int wp11_token_read_seed_dhuk (void * storage , WP11_Token * token )
5201+ {
5202+ int ret ;
5203+ Aes aes ;
5204+ byte iv [WP11_SEED_DHUK_IV_SZ ];
5205+ word32 wrappedLen ;
5206+ byte wrappedSeed [PIN_SEED_SZ ];
5207+
5208+ ret = wp11_storage_read_word32 (storage , & wrappedLen );
5209+ if (ret != 0 )
5210+ return ret ;
5211+ if (wrappedLen != WP11_SEED_WRAPPED_SZ )
5212+ return BUFFER_E ;
5213+ ret = wp11_storage_read_fixed_array (storage , iv , WP11_SEED_DHUK_IV_SZ );
5214+ if (ret != 0 )
5215+ return ret ;
5216+ ret = wp11_storage_read (storage , wrappedSeed , PIN_SEED_SZ );
5217+ if (ret != 0 )
5218+ return ret ;
5219+
5220+ ret = wc_AesInit (& aes , NULL , WOLFSSL_STM32U5_DHUK_DEVID );
5221+ if (ret != 0 )
5222+ return ret ;
5223+ ret = wc_AesSetKey (& aes , wp11_dhuk_dummy_key , sizeof (wp11_dhuk_dummy_key ),
5224+ iv , AES_DECRYPTION );
5225+ if (ret != 0 ) {
5226+ wc_AesFree (& aes );
5227+ return ret ;
5228+ }
5229+ ret = wc_AesCbcDecrypt (& aes , token -> seed , wrappedSeed , PIN_SEED_SZ );
5230+ wc_AesFree (& aes );
5231+ return ret ;
5232+ }
5233+ #else /* !HAVE_AES_CBC */
5234+ #error WOLFSSL_STM32U5_DHUK token seed storage requires HAVE_AES_CBC
5235+ #endif /* HAVE_AES_CBC */
5236+ #endif /* WOLFSSL_STM32U5_DHUK */
5237+
5238+ /**
5239+ * Read token seed from storage.
5240+ */
5241+ static int wp11_token_read_seed (void * storage , WP11_Token * token )
5242+ {
5243+ #ifdef WOLFSSL_STM32U5_DHUK
5244+ return wp11_token_read_seed_dhuk (storage , token );
5245+ #else
5246+ return wp11_storage_read_fixed_array (storage , token -> seed ,
5247+ sizeof (token -> seed ));
5248+ #endif
5249+ }
5250+
5251+ /**
5252+ * Write token seed to storage.
5253+ */
5254+ static int wp11_token_write_seed (void * storage , WP11_Token * token )
5255+ {
5256+ #ifdef WOLFSSL_STM32U5_DHUK
5257+ return wp11_token_write_seed_dhuk (storage , token );
5258+ #else
5259+ return wp11_storage_write_fixed_array (storage , token -> seed ,
5260+ sizeof (token -> seed ));
5261+ #endif
5262+ }
5263+
51535264/**
51545265 * Load a token from storage.
51555266 *
@@ -5225,9 +5336,8 @@ static int wp11_Token_Load(WP11_Slot* slot, int tokenId, WP11_Token* token)
52255336 ret = wp11_storage_read_time (storage , & token -> userFailLoginTimeout );
52265337 }
52275338 if (ret == 0 ) {
5228- /* Read seed used to calculate key. (16) */
5229- ret = wp11_storage_read_fixed_array (storage , token -> seed ,
5230- sizeof (token -> seed ));
5339+ /* Read seed used to calculate key. */
5340+ ret = wp11_token_read_seed (storage , token );
52315341 }
52325342 if (ret == 0 ) {
52335343 /* Read count of object on token. (4) */
@@ -5426,9 +5536,8 @@ static int wp11_Token_Store(WP11_Token* token, int tokenId)
54265536 ret = wp11_storage_write_time (storage , token -> userFailLoginTimeout );
54275537 }
54285538 if (ret == 0 ) {
5429- /* Write seed used to calculate key. (16) */
5430- ret = wp11_storage_write_fixed_array (storage , token -> seed ,
5431- sizeof (token -> seed ));
5539+ /* Write seed used to calculate key. */
5540+ ret = wp11_token_write_seed (storage , token );
54325541 }
54335542
54345543 if (ret == 0 ) {
@@ -6304,6 +6413,7 @@ int WP11_Slot_UserLogin(WP11_Slot* slot, char* pin, int pinLen)
63046413 if (ret == 0 ) {
63056414 ret = WP11_Slot_CheckUserPin (slot , pin , pinLen );
63066415 #ifndef WOLFPKCS11_NO_STORE
6416+ /* Re-create token->key from PIN + token->seed (HashPIN) on load. */
63076417 if (ret == 0 ) {
63086418 ret = HashPIN (pin , pinLen , token -> seed , sizeof (token -> seed ),
63096419 token -> key , sizeof (token -> key ), slot );
0 commit comments