@@ -3594,19 +3594,24 @@ int wh_Client_Cmac(whClientContext* ctx, Cmac* cmac, CmacType type,
35943594 whMessageCrypto_CmacResponse * res = NULL ;
35953595 uint8_t * dataPtr = NULL ;
35963596
3597+ if (ctx == NULL || cmac == NULL ) {
3598+ return WH_ERROR_BADARGS ;
3599+ }
3600+
35973601 whKeyId key_id = WH_DEVCTX_TO_KEYID (cmac -> devCtx );
35983602 uint32_t mac_len =
35993603 ((outMac == NULL ) || (outMacLen == NULL )) ? 0 : * outMacLen ;
36003604
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 */
3605+ /* For non-HSM keys on incremental calls (update/final with no key argument
3606+ * provided), send the stored key bytes so the server can reconstruct the
3607+ * CMAC context */
36033608 if (key == NULL && keyLen == 0 && WH_KEYID_ISERASED (key_id ) &&
36043609 (inLen != 0 || mac_len != 0 )) {
36053610 key = (const uint8_t * )cmac -> aes .devKey ;
36063611 keyLen = cmac -> aes .keylen ;
36073612 }
36083613
3609- /* Return success for a call with NULL params, or 0 len's */
3614+ /* Update type and return success for 0 length data, nothing else to do */
36103615 if ((inLen == 0 ) && (keyLen == 0 ) && (mac_len == 0 )) {
36113616 /* Update the type */
36123617 cmac -> type = type ;
@@ -3630,19 +3635,14 @@ int wh_Client_Cmac(whClientContext* ctx, Cmac* cmac, CmacType type,
36303635
36313636 uint8_t * req_in = (uint8_t * )(req + 1 );
36323637 uint8_t * req_key = req_in + inLen ;
3633- uint16_t req_len = sizeof ( whMessageCrypto_GenericRequestHeader ) +
3634- sizeof (* req ) + inLen + keyLen ;
3638+ uint32_t hdr_sz =
3639+ sizeof ( whMessageCrypto_GenericRequestHeader ) + sizeof (* req );
36353640
3636- /* TODO get rid of this logic, we should always fail */
3637- if (req_len > WOLFHSM_CFG_COMM_DATA_LEN ) {
3638- /* if we're using an HSM req_key return BAD_FUNC_ARG */
3639- if (!WH_KEYID_ISERASED (key_id )) {
3640- return WH_ERROR_BADARGS ;
3641- }
3642- else {
3643- return CRYPTOCB_UNAVAILABLE ;
3644- }
3641+ if (inLen > WOLFHSM_CFG_COMM_DATA_LEN - hdr_sz ||
3642+ keyLen > WOLFHSM_CFG_COMM_DATA_LEN - hdr_sz - inLen ) {
3643+ return WH_ERROR_BADARGS ;
36453644 }
3645+ uint16_t req_len = hdr_sz + inLen + keyLen ;
36463646
36473647 /* Setup request packet */
36483648 req -> type = type ;
@@ -3652,13 +3652,14 @@ int wh_Client_Cmac(whClientContext* ctx, Cmac* cmac, CmacType type,
36523652 req -> outSz = mac_len ;
36533653
36543654 /* 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 );
3655+ memcpy (req -> resumeState .buffer , cmac -> buffer ,
3656+ sizeof (req -> resumeState .buffer ));
3657+ memcpy (req -> resumeState .digest , cmac -> digest ,
3658+ sizeof (req -> resumeState .digest ));
36573659 req -> resumeState .bufferSz = cmac -> bufferSz ;
36583660 req -> resumeState .totalSz = cmac -> totalSz ;
36593661
3660- /* multiple modes are possible so we need to set zero size if buffers
3661- * are NULL */
3662+ /* copy input data to request, if relevant */
36623663 if ((in != NULL ) && (inLen > 0 )) {
36633664 memcpy (req_in , in , inLen );
36643665 }
@@ -3672,7 +3673,7 @@ int wh_Client_Cmac(whClientContext* ctx, Cmac* cmac, CmacType type,
36723673 /* Update the local type since call succeeded */
36733674 cmac -> type = type ;
36743675
3675- /* Store key bytes locally for future calls (non-HSM keys) */
3676+ /* If using non-HSM keys, store key bytes locally for future calls */
36763677 if (key != NULL && keyLen > 0 && WH_KEYID_ISERASED (key_id )) {
36773678 memcpy ((void * )cmac -> aes .devKey , key , keyLen );
36783679 cmac -> aes .keylen = keyLen ;
@@ -3686,23 +3687,26 @@ int wh_Client_Cmac(whClientContext* ctx, Cmac* cmac, CmacType type,
36863687 } while (ret == WH_ERROR_NOTREADY );
36873688 if (ret == WH_ERROR_OK ) {
36883689 /* Get response */
3689- ret = _getCryptoResponse ( dataPtr , WC_ALGO_TYPE_CMAC ,
3690- (uint8_t * * )& res );
3690+ ret =
3691+ _getCryptoResponse ( dataPtr , WC_ALGO_TYPE_CMAC , (uint8_t * * )& res );
36913692 /* wolfCrypt allows positive error codes on success in some
36923693 * scenarios */
36933694 if (ret >= 0 ) {
36943695 /* Restore non-sensitive state from server response */
3695- memcpy (cmac -> buffer , res -> resumeState .buffer , AES_BLOCK_SIZE );
3696- memcpy (cmac -> digest , res -> resumeState .digest , AES_BLOCK_SIZE );
3696+ memcpy (cmac -> buffer , res -> resumeState .buffer ,
3697+ sizeof (cmac -> buffer ));
3698+ memcpy (cmac -> digest , res -> resumeState .digest ,
3699+ sizeof (cmac -> digest ));
36973700 cmac -> bufferSz = res -> resumeState .bufferSz ;
36983701 cmac -> totalSz = res -> resumeState .totalSz ;
36993702
3700- if (outMac != NULL ) {
3701- uint8_t * res_mac = (uint8_t * )(res + 1 );
3702- memcpy (outMac , res_mac , res -> outSz );
3703- if (outMacLen != NULL ) {
3704- * (outMacLen ) = res -> outSz ;
3703+ /* Copy out finalized CMAC if present */
3704+ if (outMac != NULL && outMacLen != NULL ) {
3705+ if (res -> outSz < * outMacLen ) {
3706+ * outMacLen = res -> outSz ;
37053707 }
3708+ uint8_t * res_mac = (uint8_t * )(res + 1 );
3709+ memcpy (outMac , res_mac , * outMacLen );
37063710 }
37073711 }
37083712 }
@@ -3718,23 +3722,40 @@ int wh_Client_CmacDma(whClientContext* ctx, Cmac* cmac, CmacType type,
37183722 const uint8_t * key , uint32_t keyLen , const uint8_t * in ,
37193723 uint32_t inLen , uint8_t * outMac , uint32_t * outMacLen )
37203724{
3721- int ret = WH_ERROR_OK ;
3722- whMessageCrypto_CmacDmaRequest * req = NULL ;
3723- whMessageCrypto_CmacDmaResponse * res = NULL ;
3724- uint8_t * dataPtr = NULL ;
3725- int finalize = 0 ;
3726- uintptr_t inAddr = 0 ; /* The req->input.addr is reused elsewhere, this
3727- local variable is to keep track of the resulting
3728- DMA translation to pass back to the callback on
3729- POST operations. */
3730- uintptr_t outAddr = 0 ;
3731- uintptr_t keyAddr = 0 ;
3732- uintptr_t stateAddr = 0 ;
3725+ int ret = WH_ERROR_OK ;
3726+ whMessageCrypto_CmacDmaRequest * req = NULL ;
3727+ whMessageCrypto_CmacDmaResponse * res = NULL ;
3728+ uint8_t * dataPtr = NULL ;
3729+ uintptr_t inAddr = 0 ;
37333730
37343731 if (ctx == NULL || cmac == NULL ) {
37353732 return WH_ERROR_BADARGS ;
37363733 }
37373734
3735+ whKeyId key_id = WH_DEVCTX_TO_KEYID (cmac -> devCtx );
3736+ uint32_t mac_len =
3737+ ((outMac == NULL ) || (outMacLen == NULL )) ? 0 : * outMacLen ;
3738+
3739+ /* For non-HSM keys on subsequent calls (no key provided), send the
3740+ * stored key bytes so the server can reconstruct the CMAC context */
3741+ if (key == NULL && keyLen == 0 && WH_KEYID_ISERASED (key_id ) &&
3742+ (inLen != 0 || mac_len != 0 )) {
3743+ key = (const uint8_t * )cmac -> aes .devKey ;
3744+ keyLen = cmac -> aes .keylen ;
3745+ }
3746+
3747+ /* Return success for a call with NULL params, or 0 len's */
3748+ if ((inLen == 0 ) && (keyLen == 0 ) && (mac_len == 0 )) {
3749+ /* Update the type */
3750+ cmac -> type = type ;
3751+ return WH_ERROR_OK ;
3752+ }
3753+
3754+ WH_DEBUG_CLIENT_VERBOSE (
3755+ "cmac dma key:%p key_len:%d in:%p in_len:%d out:%p out_len:%d "
3756+ "keyId:%x\n" ,
3757+ key , (int )keyLen , in , (int )inLen , outMac , (int )mac_len , key_id );
3758+
37383759 /* Get data pointer from the context to use as request/response storage */
37393760 dataPtr = (uint8_t * )wh_CommClient_GetDataPtr (ctx -> comm );
37403761 if (dataPtr == NULL ) {
@@ -3745,116 +3766,99 @@ int wh_Client_CmacDma(whClientContext* ctx, Cmac* cmac, CmacType type,
37453766 req = (whMessageCrypto_CmacDmaRequest * )_createCryptoRequest (
37463767 dataPtr , WC_ALGO_TYPE_CMAC );
37473768 memset (req , 0 , sizeof (* req ));
3748- req -> type = type ;
37493769
3750- /* Store devId and devCtx to restore after request */
3751- int devId = cmac -> devId ;
3752- void * devCtx = cmac -> devCtx ;
3770+ uint8_t * req_key = ( uint8_t * )( req + 1 );
3771+ uint32_t hdr_sz =
3772+ sizeof ( whMessageCrypto_GenericRequestHeader ) + sizeof ( * req ) ;
37533773
3754- /* Set up DMA state buffer in client address space */
3755- req -> state .sz = sizeof (* cmac );
3756- ret = wh_Client_DmaProcessClientAddress (
3757- ctx , (uintptr_t )cmac , (void * * )& stateAddr , req -> state .sz ,
3758- WH_DMA_OPER_CLIENT_WRITE_PRE , (whDmaFlags ){0 });
3759- if (ret == WH_ERROR_OK ) {
3760- req -> state .addr = stateAddr ;
3774+ if (keyLen > WOLFHSM_CFG_COMM_DATA_LEN - hdr_sz ) {
3775+ return WH_ERROR_BADARGS ;
37613776 }
3777+ uint16_t req_len = hdr_sz + keyLen ;
37623778
3763- /* Handle different CMAC operations based on input parameters */
3764- if (ret == WH_ERROR_OK && key != NULL ) {
3765- /* Initialize with provided key */
3766- req -> key .sz = keyLen ;
3767- ret = wh_Client_DmaProcessClientAddress (
3768- ctx , (uintptr_t )key , (void * * )& keyAddr , req -> key .sz ,
3769- WH_DMA_OPER_CLIENT_READ_PRE , (whDmaFlags ){0 });
3770- if (ret == WH_ERROR_OK ) {
3771- req -> key .addr = keyAddr ;
3772- }
3779+ /* Setup request fields */
3780+ req -> type = type ;
3781+ req -> outSz = mac_len ;
3782+ req -> keyId = key_id ;
3783+ req -> keySz = keyLen ;
3784+
3785+ /* Pack non-sensitive CMAC state into request */
3786+ memcpy (req -> resumeState .buffer , cmac -> buffer , AES_BLOCK_SIZE );
3787+ memcpy (req -> resumeState .digest , cmac -> digest , AES_BLOCK_SIZE );
3788+ req -> resumeState .bufferSz = cmac -> bufferSz ;
3789+ req -> resumeState .totalSz = cmac -> totalSz ;
3790+
3791+ /* Copy key bytes into trailing data */
3792+ if ((key != NULL ) && (keyLen > 0 )) {
3793+ memcpy (req_key , key , keyLen );
37733794 }
37743795
3775- if ( ret == WH_ERROR_OK && in != NULL ) {
3776- /* Update operation */
3777- req -> input .sz = inLen ;
3778- ret = wh_Client_DmaProcessClientAddress (
3796+ /* DMA for input data only */
3797+ if ( ret == WH_ERROR_OK && in != NULL && inLen != 0 ) {
3798+ req -> input .sz = inLen ;
3799+ ret = wh_Client_DmaProcessClientAddress (
37793800 ctx , (uintptr_t )in , (void * * )& inAddr , req -> input .sz ,
37803801 WH_DMA_OPER_CLIENT_READ_PRE , (whDmaFlags ){0 });
37813802 if (ret == WH_ERROR_OK ) {
37823803 req -> input .addr = inAddr ;
37833804 }
37843805 }
37853806
3786- if (ret == WH_ERROR_OK && outMac != NULL ) {
3787- /* Finalize operation */
3788- req -> output .sz = (size_t )* outMacLen ;
3789- ret = wh_Client_DmaProcessClientAddress (
3790- ctx , (uintptr_t )outMac , (void * * )& outAddr , req -> output .sz ,
3791- WH_DMA_OPER_CLIENT_WRITE_PRE , (whDmaFlags ){0 });
3792- if (ret == WH_ERROR_OK ) {
3793- req -> output .addr = outAddr ;
3794- req -> finalize = 1 ;
3795- /* Also set local flag, as request will be trashed after a response
3796- * is received */
3797- finalize = 1 ;
3798- }
3799- }
3800-
3801- /* If this is just a deferred initialization (NULL key, but keyId set),
3802- * don't send a request - server will initialize on first update */
3803- if ((key == NULL ) && (in == NULL ) && (outMac == NULL )) {
3804- /* Just a keyId set operation, nothing to do via DMA */
3805- return 0 ;
3806- }
3807-
38083807 if (ret == WH_ERROR_OK ) {
38093808 /* Send the request */
3810- ret = wh_Client_SendRequest (
3811- ctx , WH_MESSAGE_GROUP_CRYPTO_DMA , WC_ALGO_TYPE_CMAC ,
3812- sizeof (whMessageCrypto_GenericRequestHeader ) + sizeof (* req ),
3813- (uint8_t * )dataPtr );
3809+ ret = wh_Client_SendRequest (ctx , WH_MESSAGE_GROUP_CRYPTO_DMA ,
3810+ WC_ALGO_TYPE_CMAC , req_len ,
3811+ (uint8_t * )dataPtr );
38143812 }
38153813
38163814 if (ret == WH_ERROR_OK ) {
3815+ /* Update the local type since call succeeded */
3816+ cmac -> type = type ;
3817+
3818+ /* Store key bytes locally for future calls (non-HSM keys) */
3819+ if (key != NULL && keyLen > 0 && WH_KEYID_ISERASED (key_id )) {
3820+ memcpy ((void * )cmac -> aes .devKey , key , keyLen );
3821+ cmac -> aes .keylen = keyLen ;
3822+ }
3823+
38173824 uint16_t respSz = 0 ;
38183825 do {
38193826 ret = wh_Client_RecvResponse (ctx , NULL , NULL , & respSz ,
38203827 (uint8_t * )dataPtr );
38213828 } while (ret == WH_ERROR_NOTREADY );
3822- }
38233829
3824- if (ret == WH_ERROR_OK ) {
3825- /* Get response structure pointer, validates generic header
3826- * rc */
3827- ret = _getCryptoResponse (dataPtr , WC_ALGO_TYPE_CMAC , (uint8_t * * )& res );
3828- if (ret == WH_ERROR_OK && finalize ) {
3829- /* Update outSz with actual size of CMAC output */
3830- * outMacLen = res -> outSz ;
3830+ if (ret == WH_ERROR_OK ) {
3831+ ret =
3832+ _getCryptoResponse (dataPtr , WC_ALGO_TYPE_CMAC , (uint8_t * * )& res );
3833+ /* wolfCrypt allows positive error codes on success */
3834+ if (ret >= 0 ) {
3835+ /* Restore non-sensitive state from server response */
3836+ memcpy (cmac -> buffer , res -> resumeState .buffer , AES_BLOCK_SIZE );
3837+ memcpy (cmac -> digest , res -> resumeState .digest , AES_BLOCK_SIZE );
3838+ cmac -> bufferSz = res -> resumeState .bufferSz ;
3839+ cmac -> totalSz = res -> resumeState .totalSz ;
3840+
3841+ /* Copy out finalized CMAC if present, truncating to
3842+ * the caller's buffer size */
3843+ /* Copy out finalized CMAC if present */
3844+ if (outMac != NULL && outMacLen != NULL ) {
3845+ if (res -> outSz < * outMacLen ) {
3846+ * outMacLen = res -> outSz ;
3847+ }
3848+ uint8_t * res_mac = (uint8_t * )(res + 1 );
3849+ memcpy (outMac , res_mac , * outMacLen );
3850+ }
3851+ }
38313852 }
38323853 }
38333854
3834- /* Restore devId, devCtx, and type after DMA operation */
3835- cmac -> devId = devId ;
3836- cmac -> devCtx = devCtx ;
3837- cmac -> type = type ;
3838-
3839- /* post address translation callbacks (for cleanup) */
3840- if (key != NULL ) {
3841- (void )wh_Client_DmaProcessClientAddress (
3842- ctx , (uintptr_t )key , (void * * )& keyAddr , req -> key .sz ,
3843- WH_DMA_OPER_CLIENT_READ_POST , (whDmaFlags ){0 });
3844- }
3845- if (in != NULL ) {
3855+ /* Post DMA cleanup for input address */
3856+ if (in != NULL && inAddr != 0 ) {
38463857 (void )wh_Client_DmaProcessClientAddress (
3847- ctx , (uintptr_t )in , (void * * )& inAddr , req -> input . sz ,
3858+ ctx , (uintptr_t )in , (void * * )& inAddr , inLen ,
38483859 WH_DMA_OPER_CLIENT_READ_POST , (whDmaFlags ){0 });
38493860 }
3850- if (outMac != NULL ) {
3851- (void )wh_Client_DmaProcessClientAddress (
3852- ctx , (uintptr_t )outMac , (void * * )& outAddr , req -> output .sz ,
3853- WH_DMA_OPER_CLIENT_WRITE_POST , (whDmaFlags ){0 });
3854- }
3855- (void )wh_Client_DmaProcessClientAddress (
3856- ctx , (uintptr_t )cmac , (void * * )& stateAddr , req -> state .sz ,
3857- WH_DMA_OPER_CLIENT_WRITE_POST , (whDmaFlags ){0 });
3861+
38583862 return ret ;
38593863}
38603864#endif /* WOLFHSM_CFG_DMA */
0 commit comments