@@ -176,7 +176,8 @@ static int init_token(const char* module_path, Pkcs11Dev* dev,
176176 Pkcs11Token * token , CK_SLOT_ID * slot_id )
177177{
178178 CK_UTF8CHAR so_pin [] = "password123456" ;
179- CK_UTF8CHAR user_pin_l [] = "interop-user" ;
179+ /* Static: token->userPin retains the pointer past init_token. */
180+ static CK_UTF8CHAR user_pin_l [] = "interop-user" ;
180181 static const char token_label_text [] = "wolfPKCS11-Interop" ;
181182 CK_UTF8CHAR label [32 ];
182183 CK_RV rv ;
@@ -409,6 +410,84 @@ static int test_hmac_sha256(Pkcs11Token* token, int dev_id)
409410 return ret ;
410411}
411412
413+ /* Multi-call HMAC must run on the same PKCS#11 session; the default
414+ * token-wide session masks the bug, so clear it for this test. */
415+ static int test_hmac_sha256_per_call_session (Pkcs11Token * token , int dev_id )
416+ {
417+ /* wolfPKCS11 enforces ulMinKeySize=32 for CKM_SHA256_HMAC. */
418+ static const byte key [32 ] = {
419+ 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
420+ 0x08 , 0x09 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f ,
421+ 0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 ,
422+ 0x18 , 0x19 , 0x1a , 0x1b , 0x1c , 0x1d , 0x1e , 0x1f
423+ };
424+ static const byte msg [] = "wolfPKCS11 multi-call HMAC dispatch" ;
425+ CK_SESSION_HANDLE saved_handle = token -> handle ;
426+ CK_UTF8CHAR_PTR saved_userPin = token -> userPin ;
427+ byte saved_userPinLogin = token -> userPinLogin ;
428+ Hmac hmac ;
429+ Hmac swHmac ;
430+ byte digest [WC_SHA256_DIGEST_SIZE ];
431+ byte ref [WC_SHA256_DIGEST_SIZE ];
432+ int hmacInited = 0 ;
433+ int swInited = 0 ;
434+ int ret ;
435+
436+ ret = wc_HmacInit (& swHmac , NULL , INVALID_DEVID );
437+ if (ret != 0 )
438+ return ret ;
439+ swInited = 1 ;
440+ ret = wc_HmacSetKey (& swHmac , WC_SHA256 , key , (word32 )sizeof (key ));
441+ if (ret == 0 )
442+ ret = wc_HmacUpdate (& swHmac , msg , (word32 )(sizeof (msg ) - 1 ));
443+ if (ret == 0 )
444+ ret = wc_HmacFinal (& swHmac , ref );
445+ if (ret != 0 )
446+ goto done ;
447+
448+ /* Force per-dispatch sessions; skip Login/Logout (slot already
449+ * logged in) so subsequent tests aren't affected. */
450+ token -> handle = CK_INVALID_HANDLE ;
451+ token -> userPin = NULL ;
452+ token -> userPinLogin = 0 ;
453+
454+ ret = wc_HmacInit (& hmac , NULL , dev_id );
455+ if (ret != 0 )
456+ goto restore ;
457+ hmacInited = 1 ;
458+
459+ ret = wc_HmacSetKey (& hmac , WC_SHA256 , key , (word32 )sizeof (key ));
460+ if (ret != 0 )
461+ goto restore ;
462+
463+ ret = wc_HmacUpdate (& hmac , msg , (word32 )(sizeof (msg ) - 1 ));
464+ if (ret != 0 )
465+ goto restore ;
466+
467+ ret = wc_HmacFinal (& hmac , digest );
468+ if (ret != 0 )
469+ goto restore ;
470+
471+ if (compare_bytes (digest , ref , sizeof (digest )) != 0 ) {
472+ dump_buffer ("hmac" , digest , sizeof (digest ));
473+ dump_buffer ("hmac-ref" , ref , sizeof (ref ));
474+ ret = WC_HW_E ;
475+ }
476+
477+ restore :
478+ /* Free Hmac before restore so cleanup runs without triggering
479+ * Logout via the now-restored userPin. */
480+ if (hmacInited )
481+ wc_HmacFree (& hmac );
482+ token -> handle = saved_handle ;
483+ token -> userPin = saved_userPin ;
484+ token -> userPinLogin = saved_userPinLogin ;
485+ done :
486+ if (swInited )
487+ wc_HmacFree (& swHmac );
488+ return ret ;
489+ }
490+
412491#ifdef WOLFSSL_SHA224
413492static int test_sha224_digest (int dev_id )
414493{
@@ -1117,6 +1196,15 @@ int main(int argc, char** argv)
11171196 printf ("HMAC-SHA256 test_passed!\n" );
11181197 }
11191198
1199+ ret = test_hmac_sha256_per_call_session (& token , dev_id );
1200+ if (ret != 0 ) {
1201+ fprintf (stderr , "HMAC-SHA256 per-call session test failed: %d (%s)\n" ,
1202+ ret , error_to_string (ret ));
1203+ failures ++ ;
1204+ } else {
1205+ printf ("HMAC-SHA256 per-call session test_passed!\n" );
1206+ }
1207+
11201208#ifdef WOLFSSL_SHA224
11211209 ret = test_sha224_digest (dev_id );
11221210 if (ret != 0 ) {
0 commit comments