@@ -3598,17 +3598,25 @@ int wh_Client_Cmac(whClientContext* ctx, Cmac* cmac, CmacType type,
35983598 uint32_t mac_len =
35993599 ((outMac == NULL ) || (outMacLen == NULL )) ? 0 : * outMacLen ;
36003600
3601+ /* For non-HSM keys on subsequent calls (no key provided), send the
3602+ * stored key bytes so the server can reconstruct the CMAC context */
3603+ if (key == NULL && keyLen == 0 && WH_KEYID_ISERASED (key_id ) &&
3604+ (inLen != 0 || mac_len != 0 )) {
3605+ key = (const uint8_t * )cmac -> aes .devKey ;
3606+ keyLen = cmac -> aes .keylen ;
3607+ }
3608+
36013609 /* Return success for a call with NULL params, or 0 len's */
36023610 if ((inLen == 0 ) && (keyLen == 0 ) && (mac_len == 0 )) {
36033611 /* Update the type */
36043612 cmac -> type = type ;
36053613 return WH_ERROR_OK ;
36063614 }
36073615
3608- WH_DEBUG_CLIENT_VERBOSE ("cmac key:%p key_len:%d in:%p in_len:%d out:%p out_len:%d "
3609- "keyId:%x\n" ,
3610- key , ( int ) keyLen , in , ( int ) inLen , outMac , ( int ) mac_len , key_id );
3611-
3616+ WH_DEBUG_CLIENT_VERBOSE (
3617+ "cmac key:%p key_len:%d in:%p in_len:%d out:%p out_len:%d "
3618+ "keyId:%x\n" ,
3619+ key , ( int ) keyLen , in , ( int ) inLen , outMac , ( int ) mac_len , key_id );
36123620
36133621 /* Get data pointer */
36143622 dataPtr = (uint8_t * )wh_CommClient_GetDataPtr (ctx -> comm );
@@ -3642,6 +3650,13 @@ int wh_Client_Cmac(whClientContext* ctx, Cmac* cmac, CmacType type,
36423650 req -> keyId = key_id ;
36433651 req -> keySz = keyLen ;
36443652 req -> outSz = mac_len ;
3653+
3654+ /* Pack non-sensitive CMAC state into request */
3655+ memcpy (req -> resumeState .buffer , cmac -> buffer , AES_BLOCK_SIZE );
3656+ memcpy (req -> resumeState .digest , cmac -> digest , AES_BLOCK_SIZE );
3657+ req -> resumeState .bufferSz = cmac -> bufferSz ;
3658+ req -> resumeState .totalSz = cmac -> totalSz ;
3659+
36453660 /* multiple modes are possible so we need to set zero size if buffers
36463661 * are NULL */
36473662 if ((in != NULL ) && (inLen > 0 )) {
@@ -3656,6 +3671,13 @@ int wh_Client_Cmac(whClientContext* ctx, Cmac* cmac, CmacType type,
36563671 if (ret == WH_ERROR_OK ) {
36573672 /* Update the local type since call succeeded */
36583673 cmac -> type = type ;
3674+
3675+ /* Store key bytes locally for future calls (non-HSM keys) */
3676+ if (key != NULL && keyLen > 0 && WH_KEYID_ISERASED (key_id )) {
3677+ memcpy ((void * )cmac -> aes .devKey , key , keyLen );
3678+ cmac -> aes .keylen = keyLen ;
3679+ }
3680+
36593681#ifdef WOLFHSM_CFG_CANCEL_API
36603682 /* if the client marked they may want to cancel, handle the
36613683 * response in a separate call */
@@ -3671,16 +3693,17 @@ int wh_Client_Cmac(whClientContext* ctx, Cmac* cmac, CmacType type,
36713693 } while (ret == WH_ERROR_NOTREADY );
36723694 if (ret == WH_ERROR_OK ) {
36733695 /* Get response */
3674- ret =
3675- _getCryptoResponse ( dataPtr , WC_ALGO_TYPE_CMAC , (uint8_t * * )& res );
3696+ ret = _getCryptoResponse ( dataPtr , WC_ALGO_TYPE_CMAC ,
3697+ (uint8_t * * )& res );
36763698 /* wolfCrypt allows positive error codes on success in some
36773699 * scenarios */
36783700 if (ret >= 0 ) {
3679- /* read keyId and res_out */
3680- if (key != NULL ) {
3681- WH_DEBUG_CLIENT_VERBOSE ("got keyid %x\n" , res -> keyId );
3682- cmac -> devCtx = WH_KEYID_TO_DEVCTX (res -> keyId );
3683- }
3701+ /* Restore non-sensitive state from server response */
3702+ memcpy (cmac -> buffer , res -> resumeState .buffer , AES_BLOCK_SIZE );
3703+ memcpy (cmac -> digest , res -> resumeState .digest , AES_BLOCK_SIZE );
3704+ cmac -> bufferSz = res -> resumeState .bufferSz ;
3705+ cmac -> totalSz = res -> resumeState .totalSz ;
3706+
36843707 if (outMac != NULL ) {
36853708 uint8_t * res_mac = (uint8_t * )(res + 1 );
36863709 memcpy (outMac , res_mac , res -> outSz );
@@ -3711,7 +3734,6 @@ int wh_Client_CmacCancelableResponse(whClientContext* c, Cmac* cmac,
37113734 return WH_ERROR_BADARGS ;
37123735 }
37133736
3714-
37153737 /* Get data pointer */
37163738 dataPtr = (uint8_t * )wh_CommClient_GetDataPtr (c -> comm );
37173739 if (dataPtr == NULL ) {
@@ -3733,7 +3755,12 @@ int wh_Client_CmacCancelableResponse(whClientContext* c, Cmac* cmac,
37333755 ret = _getCryptoResponse (dataPtr , WC_ALGO_TYPE_CMAC , (uint8_t * * )& res );
37343756 /* wolfCrypt allows positive error codes on success in some scenarios */
37353757 if (ret >= 0 ) {
3736- cmac -> devCtx = (void * )((intptr_t )res -> keyId );
3758+ /* Restore non-sensitive state from server response */
3759+ memcpy (cmac -> buffer , res -> resumeState .buffer , AES_BLOCK_SIZE );
3760+ memcpy (cmac -> digest , res -> resumeState .digest , AES_BLOCK_SIZE );
3761+ cmac -> bufferSz = res -> resumeState .bufferSz ;
3762+ cmac -> totalSz = res -> resumeState .totalSz ;
3763+
37373764 if (out != NULL && outSz != NULL ) {
37383765 if (res -> outSz > * outSz ) {
37393766 ret = WH_ERROR_BUFFER_SIZE ;
0 commit comments