Skip to content

Commit 2dedb29

Browse files
committed
- refactor non-dma oneshot cmac generate to support cached keys
- refactor DMA CMAC to use client-supplied state vs state by reference - refactor to use stack allocated CMAC context - expand CMAC tests to mimic wolfCrypt tests but with cached keys - housekeeping, error checking
1 parent 43fe6c7 commit 2dedb29

6 files changed

Lines changed: 676 additions & 659 deletions

File tree

src/wh_client_crypto.c

Lines changed: 122 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -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,97 @@ 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 */
3842+
if (outMac != NULL && outMacLen != NULL) {
3843+
if (res->outSz < *outMacLen) {
3844+
*outMacLen = res->outSz;
3845+
}
3846+
uint8_t* res_mac = (uint8_t*)(res + 1);
3847+
memcpy(outMac, res_mac, *outMacLen);
3848+
}
3849+
}
38313850
}
38323851
}
38333852

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) {
3853+
/* Post DMA cleanup for input address */
3854+
if (in != NULL && inAddr != 0) {
38463855
(void)wh_Client_DmaProcessClientAddress(
3847-
ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz,
3856+
ctx, (uintptr_t)in, (void**)&inAddr, inLen,
38483857
WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0});
38493858
}
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});
3859+
38583860
return ret;
38593861
}
38603862
#endif /* WOLFHSM_CFG_DMA */

0 commit comments

Comments
 (0)