diff --git a/benchmark/bench_modules/wh_bench_mod_cmac.c b/benchmark/bench_modules/wh_bench_mod_cmac.c index 86fe9e69f..c0301854c 100644 --- a/benchmark/bench_modules/wh_bench_mod_cmac.c +++ b/benchmark/bench_modules/wh_bench_mod_cmac.c @@ -24,6 +24,10 @@ #if !defined(WOLFHSM_CFG_NO_CRYPTO) && defined(WOLFHSM_CFG_BENCH_ENABLE) #include "wolfssl/wolfcrypt/cmac.h" +#if defined(WOLFHSM_CFG_DMA) && defined(WOLFHSM_CFG_TEST_POSIX) +#include "port/posix/posix_transport_shm.h" +#endif /* WOLFHSM_CFG_DMA && WOLFHSM_CFG_TEST_POSIX */ + #if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) static const uint8_t key128[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, @@ -44,10 +48,11 @@ int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id, whKeyId keyId = WH_KEYID_ERASED; Cmac cmac[1]; char keyLabel[] = "baby's first key"; - byte tag[16]; + byte tag[WC_CMAC_TAG_MAX_SZ]; int i; uint8_t* in = NULL; size_t inLen; + uint8_t* out = NULL; /* cache the key on the HSM */ ret = wh_Client_KeyCache(client, 0, (uint8_t*)keyLabel, sizeof(keyLabel), @@ -57,10 +62,32 @@ int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id, return ret; } + out = tag; /* default to using tag buffer on the stack */ #if defined(WOLFHSM_CFG_DMA) if (devId == WH_DEV_ID_DMA) { - in = WH_BENCH_DMA_BUFFER; inLen = WOLFHSM_CFG_BENCH_DMA_BUFFER_SIZE; +#if defined(WOLFHSM_CFG_TEST_POSIX) + if (ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { + /* if static memory was used with DMA then use XMALLOC */ + void* heap = + posixTransportShm_GetDmaHeap(client->comm->transport_context); + in = (uint8_t*)XMALLOC(inLen, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (in == NULL) { + WH_BENCH_PRINTF("Failed to allocate memory for DMA\n"); + return WH_ERROR_NOSPACE; + } + out = (uint8_t*)XMALLOC(WC_CMAC_TAG_MAX_SZ, heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (out == NULL) { + WH_BENCH_PRINTF("Failed to allocate memory for DMA\n"); + XFREE(in, heap, DYNAMIC_TYPE_TMP_BUFFER); + return WH_ERROR_NOSPACE; + } + } + else { + in = WH_BENCH_DMA_BUFFER; + } +#endif /* WOLFHSM_CFG_TEST_POSIX */ } else #endif @@ -101,7 +128,7 @@ int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id, benchStartRet = wh_Bench_StartOp(ctx, id); /* Oneshot CMAC through wolfCrypt API will always be most performant * implementation */ - ret = wc_AesCmacGenerate_ex(cmac, tag, &outLen, in, inLen, key, keyLen, + ret = wc_AesCmacGenerate_ex(cmac, out, &outLen, in, inLen, key, keyLen, NULL, devId); benchStopRet = wh_Bench_StopOp(ctx, id); @@ -131,6 +158,18 @@ int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id, ret = evictRet; } } +#if defined(WOLFHSM_CFG_DMA) +#if defined(WOLFHSM_CFG_TEST_POSIX) + if (devId == WH_DEV_ID_DMA && + ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { + /* if static memory was used with DMA then use XFREE */ + void* heap = + posixTransportShm_GetDmaHeap(client->comm->transport_context); + XFREE(in, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, heap, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif /* WOLFHSM_CFG_TEST_POSIX */ +#endif (void)wc_CmacFree(cmac); return ret; } diff --git a/benchmark/bench_modules/wh_bench_mod_sha2.c b/benchmark/bench_modules/wh_bench_mod_sha2.c index 46bc9d8ab..65270d311 100644 --- a/benchmark/bench_modules/wh_bench_mod_sha2.c +++ b/benchmark/bench_modules/wh_bench_mod_sha2.c @@ -52,7 +52,6 @@ int _benchSha256(whClientContext* client, whBenchOpContext* ctx, int id, #if defined(WOLFHSM_CFG_DMA) if (devId == WH_DEV_ID_DMA) { inLen = WOLFHSM_CFG_BENCH_DMA_BUFFER_SIZE; - #if defined(WOLFHSM_CFG_TEST_POSIX) if (ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { /* if static memory was used with DMA then use XMALLOC */ @@ -66,6 +65,7 @@ int _benchSha256(whClientContext* client, whBenchOpContext* ctx, int id, out = XMALLOC(WC_SHA256_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER); if (out == NULL) { WH_BENCH_PRINTF("Failed to allocate memory for DMA\n"); + XFREE((uint8_t*)in, heap, DYNAMIC_TYPE_TMP_BUFFER); return WH_ERROR_NOSPACE; } } diff --git a/src/wh_client.c b/src/wh_client.c index 26dcacc76..929350a6c 100644 --- a/src/wh_client.c +++ b/src/wh_client.c @@ -1340,7 +1340,9 @@ int wh_Client_KeyCacheDmaRequest(whClientContext* c, uint32_t flags, const void* keyAddr, uint16_t keySz, uint16_t keyId) { + int ret; whMessageKeystore_CacheDmaRequest* req = NULL; + uintptr_t keyAddrPtr = 0; if (c == NULL || (labelSz > 0 && label == NULL)) { return WH_ERROR_BADARGS; @@ -1356,8 +1358,11 @@ int wh_Client_KeyCacheDmaRequest(whClientContext* c, uint32_t flags, req->labelSz = labelSz; /* Set up DMA buffer info */ - req->key.addr = (uint64_t)((uintptr_t)keyAddr); req->key.sz = keySz; + ret = wh_Client_DmaProcessClientAddress( + c, (uintptr_t)keyAddr, (void**)&keyAddrPtr, keySz, + WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); + req->key.addr = keyAddrPtr; /* Copy label if provided, truncate if necessary */ if (labelSz > 0) { @@ -1367,8 +1372,15 @@ int wh_Client_KeyCacheDmaRequest(whClientContext* c, uint32_t flags, memcpy(req->label, label, labelSz); } - return wh_Client_SendRequest(c, WH_MESSAGE_GROUP_KEY, WH_KEY_CACHE_DMA, - sizeof(*req), (uint8_t*)req); + if (ret == WH_ERROR_OK) { + ret = wh_Client_SendRequest(c, WH_MESSAGE_GROUP_KEY, WH_KEY_CACHE_DMA, + sizeof(*req), (uint8_t*)req); + } + + (void)wh_Client_DmaProcessClientAddress( + c, (uintptr_t)keyAddr, (void**)&keyAddrPtr, keySz, + WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0}); + return ret; } int wh_Client_KeyCacheDmaResponse(whClientContext* c, uint16_t* keyId) diff --git a/src/wh_client_crypto.c b/src/wh_client_crypto.c index 815b8ad15..5d7f30879 100644 --- a/src/wh_client_crypto.c +++ b/src/wh_client_crypto.c @@ -290,7 +290,9 @@ int wh_Client_RngGenerateDma(whClientContext* ctx, uint8_t* out, uint32_t size) ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); - req->output.addr = outAddr; + if (ret == WH_ERROR_OK) { + req->output.addr = outAddr; + } if (ret == WH_ERROR_OK) { /* Send the request to the server */ @@ -912,7 +914,9 @@ int wh_Client_AesGcmDma(whClientContext* ctx, Aes* aes, int enc, ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)key, (void**)&keyAddr, req->key.sz, WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); - req->key.addr = keyAddr; + if (ret == WH_ERROR_OK) { + req->key.addr = keyAddr; + } } if (ret == WH_ERROR_OK && in != NULL) { @@ -920,7 +924,9 @@ int wh_Client_AesGcmDma(whClientContext* ctx, Aes* aes, int enc, ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); - req->input.addr = inAddr; + if (ret == WH_ERROR_OK) { + req->input.addr = inAddr; + } } if (ret == WH_ERROR_OK && out != NULL) { @@ -928,7 +934,9 @@ int wh_Client_AesGcmDma(whClientContext* ctx, Aes* aes, int enc, ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); - req->output.addr = outAddr; + if (ret == WH_ERROR_OK) { + req->output.addr = outAddr; + } } if (ret == WH_ERROR_OK && iv != NULL) { @@ -936,7 +944,9 @@ int wh_Client_AesGcmDma(whClientContext* ctx, Aes* aes, int enc, ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)iv, (void**)&ivAddr, req->iv.sz, WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); - req->iv.addr = ivAddr; + if (ret == WH_ERROR_OK) { + req->iv.addr = ivAddr; + } } if (ret == WH_ERROR_OK && authin != NULL) { @@ -944,7 +954,9 @@ int wh_Client_AesGcmDma(whClientContext* ctx, Aes* aes, int enc, ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)authin, (void**)&aadAddr, req->aad.sz, WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); - req->aad.addr = aadAddr; + if (ret == WH_ERROR_OK) { + req->aad.addr = aadAddr; + } } /* set auth tag by direction */ @@ -954,7 +966,9 @@ int wh_Client_AesGcmDma(whClientContext* ctx, Aes* aes, int enc, ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)dec_tag, (void**)&authTagAddr, req->authTag.sz, WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); - req->authTag.addr = authTagAddr; + if (ret == WH_ERROR_OK) { + req->authTag.addr = authTagAddr; + } #ifdef DEBUG_CRYPTOCB_VERBOSE wh_Utils_Hexdump("[client] dec tag: \n", dec_tag, tag_len); #endif @@ -965,7 +979,9 @@ int wh_Client_AesGcmDma(whClientContext* ctx, Aes* aes, int enc, ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)enc_tag, (void**)&authTagAddr, req->authTag.sz, WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); - req->authTag.addr = authTagAddr; + if (ret == WH_ERROR_OK) { + req->authTag.addr = authTagAddr; + } #ifdef DEBUG_CRYPTOCB_VERBOSE wh_Utils_Hexdump("[client] enc tag buffer: \n", enc_tag, tag_len); #endif @@ -976,7 +992,9 @@ int wh_Client_AesGcmDma(whClientContext* ctx, Aes* aes, int enc, #ifdef DEBUG_CRYPTOCB_VERBOSE wh_Utils_Hexdump("[client] AESGCM DMA req packet: \n", dataPtr, reqLen); #endif - ret = wh_Client_SendRequest(ctx, group, action, reqLen, dataPtr); + if (ret == WH_ERROR_OK) { + ret = wh_Client_SendRequest(ctx, group, action, reqLen, dataPtr); + } if (ret == 0) { uint16_t resLen = 0; do { @@ -2959,6 +2977,13 @@ int wh_Client_CmacDma(whClientContext* ctx, Cmac* cmac, CmacType type, whMessageCrypto_CmacDmaResponse* res = NULL; uint8_t* dataPtr = NULL; int finalize = 0; + uintptr_t inAddr = 0; /* The req->input.addr is reused elsewhere, this + local variable is to keep track of the resulting + DMA translation to pass back to the callback on + POST operations. */ + uintptr_t outAddr = 0; + uintptr_t keyAddr = 0; + uintptr_t stateAddr = 0; if (ctx == NULL || cmac == NULL) { return WH_ERROR_BADARGS; @@ -2981,30 +3006,50 @@ int wh_Client_CmacDma(whClientContext* ctx, Cmac* cmac, CmacType type, void* devCtx = cmac->devCtx; /* Set up DMA state buffer in client address space */ - req->state.addr = (uintptr_t)cmac; req->state.sz = sizeof(*cmac); + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)cmac, (void**)&stateAddr, req->state.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->state.addr = stateAddr; + } /* Handle different CMAC operations based on input parameters */ - if (key != NULL) { + if (ret == WH_ERROR_OK && key != NULL) { /* Initialize with provided key */ - req->key.addr = (uintptr_t)key; - req->key.sz = keyLen; + req->key.sz = keyLen; + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)key, (void**)&keyAddr, req->key.sz, + WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->key.addr = keyAddr; + } } - if (in != NULL) { + if (ret == WH_ERROR_OK && in != NULL) { /* Update operation */ - req->input.addr = (uintptr_t)in; req->input.sz = inLen; + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, + WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->input.addr = inAddr; + } } - if (outMac != NULL) { + if (ret == WH_ERROR_OK && outMac != NULL) { /* Finalize operation */ - req->output.addr = (uintptr_t)outMac; req->output.sz = (size_t)*outMacLen; - req->finalize = 1; - /* Also set local flag, as request will be trashed after a response - * is received */ - finalize = 1; + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)outMac, (void**)&outAddr, req->output.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->output.addr = outAddr; + req->finalize = 1; + /* Also set local flag, as request will be trashed after a response + * is received */ + finalize = 1; + } } /* If this is just a deferred initialization (NULL key, but keyId set), @@ -3014,11 +3059,13 @@ int wh_Client_CmacDma(whClientContext* ctx, Cmac* cmac, CmacType type, return 0; } - /* Send the request */ - ret = wh_Client_SendRequest( - ctx, WH_MESSAGE_GROUP_CRYPTO_DMA, WC_ALGO_TYPE_CMAC, - sizeof(whMessageCrypto_GenericRequestHeader) + sizeof(*req), - (uint8_t*)dataPtr); + if (ret == WH_ERROR_OK) { + /* Send the request */ + ret = wh_Client_SendRequest( + ctx, WH_MESSAGE_GROUP_CRYPTO_DMA, WC_ALGO_TYPE_CMAC, + sizeof(whMessageCrypto_GenericRequestHeader) + sizeof(*req), + (uint8_t*)dataPtr); + } if (ret == WH_ERROR_OK) { uint16_t respSz = 0; @@ -3043,6 +3090,25 @@ int wh_Client_CmacDma(whClientContext* ctx, Cmac* cmac, CmacType type, cmac->devCtx = devCtx; cmac->type = type; + /* post address translation callbacks (for cleanup) */ + if (key != NULL) { + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)key, (void**)&keyAddr, req->key.sz, + WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0}); + } + if (in != NULL) { + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, + WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0}); + } + if (outMac != NULL) { + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)outMac, (void**)&outAddr, req->output.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); + } + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)cmac, (void**)&stateAddr, req->state.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); return ret; } #endif /* WOLFHSM_CFG_DMA */ @@ -3240,20 +3306,26 @@ int wh_Client_Sha256Dma(whClientContext* ctx, wc_Sha256* sha, const uint8_t* in, ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)sha256, (void**)&stateAddr, req->state.sz, WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); - req->state.addr = stateAddr; + if (ret == WH_ERROR_OK) { + req->state.addr = stateAddr; + } if (ret == WH_ERROR_OK) { ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); - req->input.addr = inAddr; + if (ret == WH_ERROR_OK) { + req->input.addr = inAddr; + } } if (ret == WH_ERROR_OK) { ret = wh_Client_DmaProcessClientAddress( ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); - req->output.addr = outAddr; + if (ret == WH_ERROR_OK) { + req->output.addr = outAddr; + } } } @@ -3495,7 +3567,7 @@ int wh_Client_Sha224(whClientContext* ctx, wc_Sha224* sha224, const uint8_t* in, return ret; } - +#ifdef WOLFHSM_CFG_DMA int wh_Client_Sha224Dma(whClientContext* ctx, wc_Sha224* sha, const uint8_t* in, uint32_t inLen, uint8_t* out) { @@ -3506,6 +3578,9 @@ int wh_Client_Sha224Dma(whClientContext* ctx, wc_Sha224* sha, const uint8_t* in, uint8_t* dataPtr = NULL; whMessageCrypto_Sha2DmaRequest* req = NULL; whMessageCrypto_Sha2DmaResponse* resp = NULL; + uintptr_t inAddr = 0; + uintptr_t outAddr = 0; + uintptr_t stateAddr = 0; /* Get data pointer from the context to use as request/response storage */ dataPtr = (uint8_t*)wh_CommClient_GetDataPtr(ctx->comm); @@ -3517,17 +3592,43 @@ int wh_Client_Sha224Dma(whClientContext* ctx, wc_Sha224* sha, const uint8_t* in, req = (whMessageCrypto_Sha2DmaRequest*)_createCryptoRequest( dataPtr, WC_HASH_TYPE_SHA224); + if (in != NULL || out != NULL) { + req->state.sz = sizeof(*sha224); + req->input.sz = inLen; + req->output.sz = WC_SHA224_DIGEST_SIZE; /* not needed, but YOLO */ + + /* Perform address translations */ + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)sha224, (void**)&stateAddr, req->state.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->state.addr = stateAddr; + } + + if (ret == WH_ERROR_OK) { + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, + WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->input.addr = inAddr; + } + } + + if (ret == WH_ERROR_OK) { + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->output.addr = outAddr; + } + } + } /* Caller invoked SHA Update: * wc_CryptoCb_Sha224Hash(sha224, data, len, NULL) */ - if (in != NULL) { + if (in != NULL && ret == WH_ERROR_OK) { req->finalize = 0; - req->state.addr = (uint64_t)(uintptr_t)sha224; - req->state.sz = sizeof(*sha224); - req->input.addr = (uint64_t)(uintptr_t)in; - req->input.sz = inLen; - req->output.addr = (uint64_t)(uintptr_t)out; - req->output.sz = WC_SHA224_DIGEST_SIZE; /* not needed, but YOLO */ + #ifdef DEBUG_CRYPTOCB_VERBOSE printf("[client] SHA224 DMA UPDATE: inAddr=%p, inSz=%u\n", in, (unsigned int)inLen); @@ -3558,13 +3659,7 @@ int wh_Client_Sha224Dma(whClientContext* ctx, wc_Sha224* sha, const uint8_t* in, * wc_CryptoCb_Sha224Hash(sha224, NULL, 0, * hash) */ if ((ret == WH_ERROR_OK) && (out != NULL)) { /* Packet will have been trashed, so re-populate all fields */ - req->finalize = 1; - req->state.addr = (uint64_t)(uintptr_t)sha224; - req->state.sz = sizeof(*sha224); - req->input.addr = (uint64_t)(uintptr_t)in; - req->input.sz = inLen; - req->output.addr = (uint64_t)(uintptr_t)out; - req->output.sz = WC_SHA224_DIGEST_SIZE; /* not needed, but YOLO */ + req->finalize = 1; #ifdef DEBUG_CRYPTOCB_VERBOSE printf("[client] SHA224 DMA FINAL: outAddr=%p\n", out); @@ -3593,8 +3688,20 @@ int wh_Client_Sha224Dma(whClientContext* ctx, wc_Sha224* sha, const uint8_t* in, } } + if (in != NULL || out != NULL) { + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)sha224, (void**)&stateAddr, req->state.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, + WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0}); + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); + } return ret; } +#endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFSSL_SHA224 */ #ifdef WOLFSSL_SHA384 @@ -3751,6 +3858,8 @@ int wh_Client_Sha384(whClientContext* ctx, wc_Sha384* sha384, const uint8_t* in, return ret; } + +#ifdef WOLFHSM_CFG_DMA int wh_Client_Sha384Dma(whClientContext* ctx, wc_Sha384* sha, const uint8_t* in, uint32_t inLen, uint8_t* out) { @@ -3761,6 +3870,9 @@ int wh_Client_Sha384Dma(whClientContext* ctx, wc_Sha384* sha, const uint8_t* in, uint8_t* dataPtr = NULL; whMessageCrypto_Sha2DmaRequest* req = NULL; whMessageCrypto_Sha2DmaResponse* resp = NULL; + uintptr_t inAddr = 0; + uintptr_t outAddr = 0; + uintptr_t stateAddr = 0; /* Get data pointer from the context to use as request/response storage */ dataPtr = (uint8_t*)wh_CommClient_GetDataPtr(ctx->comm); @@ -3772,17 +3884,42 @@ int wh_Client_Sha384Dma(whClientContext* ctx, wc_Sha384* sha, const uint8_t* in, req = (whMessageCrypto_Sha2DmaRequest*)_createCryptoRequest( dataPtr, WC_HASH_TYPE_SHA384); + if (in != NULL || out != NULL) { + req->state.sz = sizeof(*sha384); + req->input.sz = inLen; + req->output.sz = WC_SHA384_DIGEST_SIZE; /* not needed, but YOLO */ + + /* Perform address translations */ + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)sha384, (void**)&stateAddr, req->state.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->state.addr = stateAddr; + } + + if (ret == WH_ERROR_OK) { + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, + WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->input.addr = inAddr; + } + } + + if (ret == WH_ERROR_OK) { + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->output.addr = outAddr; + } + } + } /* Caller invoked SHA Update: * wc_CryptoCb_Sha384Hash(sha384, data, len, NULL) */ - if (in != NULL) { - req->finalize = 0; - req->state.addr = (uint64_t)(uintptr_t)sha384; - req->state.sz = sizeof(*sha384); - req->input.addr = (uint64_t)(uintptr_t)in; - req->input.sz = inLen; - req->output.addr = (uint64_t)(uintptr_t)out; - req->output.sz = WC_SHA384_DIGEST_SIZE; /* not needed, but YOLO */ + if (in != NULL && ret == WH_ERROR_OK) { + req->finalize = 0; #ifdef DEBUG_CRYPTOCB_VERBOSE printf("[client] SHA384 DMA UPDATE: inAddr=%p, inSz=%u\n", in, (unsigned int)inLen); @@ -3813,13 +3950,7 @@ int wh_Client_Sha384Dma(whClientContext* ctx, wc_Sha384* sha, const uint8_t* in, * wc_CryptoCb_Sha384Hash(sha384, NULL, 0, * hash) */ if ((ret == WH_ERROR_OK) && (out != NULL)) { /* Packet will have been trashed, so re-populate all fields */ - req->finalize = 1; - req->state.addr = (uint64_t)(uintptr_t)sha384; - req->state.sz = sizeof(*sha384); - req->input.addr = (uint64_t)(uintptr_t)in; - req->input.sz = inLen; - req->output.addr = (uint64_t)(uintptr_t)out; - req->output.sz = WC_SHA384_DIGEST_SIZE; /* not needed, but YOLO */ + req->finalize = 1; #ifdef DEBUG_CRYPTOCB_VERBOSE printf("[client] SHA384 DMA FINAL: outAddr=%p\n", out); @@ -3848,8 +3979,20 @@ int wh_Client_Sha384Dma(whClientContext* ctx, wc_Sha384* sha, const uint8_t* in, } } + if (in != NULL || out != NULL) { + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)sha384, (void**)&stateAddr, req->state.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, + WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0}); + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); + } return ret; } +#endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFSSL_SHA384 */ @@ -4018,6 +4161,8 @@ int wh_Client_Sha512(whClientContext* ctx, wc_Sha512* sha512, const uint8_t* in, return ret; } + +#ifdef WOLFHSM_CFG_DMA int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in, uint32_t inLen, uint8_t* out) { @@ -4028,6 +4173,9 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in, uint8_t* dataPtr = NULL; whMessageCrypto_Sha2DmaRequest* req = NULL; whMessageCrypto_Sha2DmaResponse* resp = NULL; + uintptr_t inAddr = 0; + uintptr_t outAddr = 0; + uintptr_t stateAddr = 0; /* Get data pointer from the context to use as request/response storage */ dataPtr = (uint8_t*)wh_CommClient_GetDataPtr(ctx->comm); @@ -4039,17 +4187,43 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in, req = (whMessageCrypto_Sha2DmaRequest*)_createCryptoRequest( dataPtr, WC_HASH_TYPE_SHA512); + if (in != NULL || out != NULL) { + req->state.sz = sizeof(*sha512); + req->input.sz = inLen; + req->output.sz = WC_SHA512_DIGEST_SIZE; /* not needed, but YOLO */ + + /* Perform address translations */ + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)sha512, (void**)&stateAddr, req->state.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->state.addr = stateAddr; + } + + if (ret == WH_ERROR_OK) { + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, + WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->input.addr = inAddr; + } + } + + if (ret == WH_ERROR_OK) { + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->output.addr = outAddr; + } + } + } /* Caller invoked SHA Update: * wc_CryptoCb_Sha512Hash(sha512, data, len, NULL) */ - if (in != NULL) { + if (in != NULL && ret == WH_ERROR_OK) { req->finalize = 0; - req->state.addr = (uint64_t)(uintptr_t)sha512; - req->state.sz = sizeof(*sha512); - req->input.addr = (uint64_t)(uintptr_t)in; - req->input.sz = inLen; - req->output.addr = (uint64_t)(uintptr_t)out; - req->output.sz = WC_SHA512_DIGEST_SIZE; /* not needed, but YOLO */ + #ifdef DEBUG_CRYPTOCB_VERBOSE printf("[client] SHA512 DMA UPDATE: inAddr=%p, inSz=%u\n", in, (unsigned int)inLen); @@ -4080,13 +4254,7 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in, * wc_CryptoCb_Sha512Hash(sha512, NULL, 0, * hash) */ if ((ret == WH_ERROR_OK) && (out != NULL)) { /* Packet will have been trashed, so re-populate all fields */ - req->finalize = 1; - req->state.addr = (uint64_t)(uintptr_t)sha512; - req->state.sz = sizeof(*sha512); - req->input.addr = (uint64_t)(uintptr_t)in; - req->input.sz = inLen; - req->output.addr = (uint64_t)(uintptr_t)out; - req->output.sz = WC_SHA512_DIGEST_SIZE; /* not needed, but YOLO */ + req->finalize = 1; #ifdef DEBUG_CRYPTOCB_VERBOSE printf("[client] SHA512 DMA FINAL: outAddr=%p\n", out); @@ -4115,8 +4283,20 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in, } } + if (in != NULL || out != NULL) { + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)sha512, (void**)&stateAddr, req->state.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, + WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0}); + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); + } return ret; } +#endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFSSL_SHA512 */ #ifdef HAVE_DILITHIUM @@ -4691,6 +4871,8 @@ static int _MlDsaMakeKeyDma(whClientContext* ctx, int level, uint8_t* dataPtr = NULL; whMessageCrypto_MlDsaKeyGenDmaRequest* req = NULL; whMessageCrypto_MlDsaKeyGenDmaResponse* res = NULL; + uintptr_t keyAddr = 0; + uint64_t keyAddrSz = 0; if (ctx == NULL) { return WH_ERROR_BADARGS; @@ -4724,8 +4906,14 @@ static int _MlDsaMakeKeyDma(whClientContext* ctx, int level, req->level = level; req->flags = flags; req->keyId = key_id; - req->key.addr = (uint64_t)(uintptr_t)buffer; - req->key.sz = sizeof(buffer); + req->key.sz = keyAddrSz = sizeof(buffer); + + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)buffer, (void**)&keyAddr, keyAddrSz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->key.addr = (uint64_t)(uintptr_t)keyAddr; + } if ((label != NULL) && (label_len > 0)) { if (label_len > WH_NVM_LABEL_LEN) { @@ -4735,41 +4923,47 @@ static int _MlDsaMakeKeyDma(whClientContext* ctx, int level, req->labelSize = label_len; } - ret = wh_Client_SendRequest(ctx, group, action, req_len, - (uint8_t*)dataPtr); + if (ret == WH_ERROR_OK) { + ret = wh_Client_SendRequest(ctx, group, action, req_len, + (uint8_t*)dataPtr); + } if (ret == WH_ERROR_OK) { uint16_t res_len; do { ret = wh_Client_RecvResponse(ctx, &group, &action, &res_len, (uint8_t*)dataPtr); } while (ret == WH_ERROR_NOTREADY); + } - if (ret == WH_ERROR_OK) { - /* Get response structure pointer, validates generic header - * rc */ - ret = _getCryptoResponse(dataPtr, WC_PK_TYPE_PQC_SIG_KEYGEN, - (uint8_t**)&res); - /* wolfCrypt allows positive error codes on success in some - * scenarios */ - if (ret >= 0) { - /* Key is cached on server or is ephemeral */ - key_id = (whKeyId)(res->keyId); - - /* Update output variable if requested */ - if (inout_key_id != NULL) { - *inout_key_id = key_id; - } + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)buffer, (void**)&keyAddr, keyAddrSz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); - /* Update the context if provided */ - if (key != NULL) { - /* Set the key_id. Should be ERASED if EPHEMERAL */ - wh_Client_MlDsaSetKeyId(key, key_id); + if (ret == WH_ERROR_OK) { + /* Get response structure pointer, validates generic header + * rc */ + ret = _getCryptoResponse(dataPtr, WC_PK_TYPE_PQC_SIG_KEYGEN, + (uint8_t**)&res); + /* wolfCrypt allows positive error codes on success in some + * scenarios */ + if (ret >= 0) { + /* Key is cached on server or is ephemeral */ + key_id = (whKeyId)(res->keyId); - if (flags & WH_NVM_FLAGS_EPHEMERAL) { - /* Response has the exported key */ - ret = wh_Crypto_MlDsaDeserializeKeyDer( - buffer, res->keySize, key); - } + /* Update output variable if requested */ + if (inout_key_id != NULL) { + *inout_key_id = key_id; + } + + /* Update the context if provided */ + if (key != NULL) { + /* Set the key_id. Should be ERASED if EPHEMERAL */ + wh_Client_MlDsaSetKeyId(key, key_id); + + if (flags & WH_NVM_FLAGS_EPHEMERAL) { + /* Response has the exported key */ + ret = wh_Crypto_MlDsaDeserializeKeyDer( + buffer, res->keySize, key); } } } @@ -4801,6 +4995,8 @@ int wh_Client_MlDsaSignDma(whClientContext* ctx, const byte* in, word32 in_len, whMessageCrypto_MlDsaSignDmaRequest* req = NULL; whMessageCrypto_MlDsaSignDmaResponse* res = NULL; uint8_t* dataPtr = NULL; + uintptr_t inAddr = 0; + uintptr_t outAddr = 0; /* Transaction state */ whKeyId key_id; @@ -4863,14 +5059,29 @@ int wh_Client_MlDsaSignDma(whClientContext* ctx, const byte* in, word32 in_len, req->keyId = key_id; /* Set up DMA buffers */ - req->msg.addr = (uint64_t)(uintptr_t)in; req->msg.sz = in_len; - req->sig.addr = (uint64_t)(uintptr_t)out; - req->sig.sz = *out_len; + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->msg.sz, + WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->msg.addr = inAddr; + } + + if (ret == WH_ERROR_OK) { + req->sig.sz = *out_len; + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)out, (void**)&outAddr, req->sig.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->sig.addr = outAddr; + } + } /* Send Request */ - ret = wh_Client_SendRequest(ctx, group, action, req_len, - (uint8_t*)dataPtr); + if (ret == WH_ERROR_OK) { + ret = wh_Client_SendRequest(ctx, group, action, req_len, + (uint8_t*)dataPtr); + } if (ret == WH_ERROR_OK) { /* Server will evict at this point if requested */ evict = 0; @@ -4897,6 +5108,13 @@ int wh_Client_MlDsaSignDma(whClientContext* ctx, const byte* in, word32 in_len, } } } + + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)out, (void**)&outAddr, req->sig.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->msg.sz, + WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0}); } else { ret = WH_ERROR_BADARGS; @@ -4948,6 +5166,8 @@ int wh_Client_MlDsaVerifyDma(whClientContext* ctx, const byte* sig, uint16_t group = WH_MESSAGE_GROUP_CRYPTO_DMA; uint16_t action = WC_ALGO_TYPE_PK; uint32_t options = 0; + uintptr_t sigAddr = 0; + uintptr_t msgAddr = 0; uint16_t req_len = sizeof(whMessageCrypto_GenericRequestHeader) + sizeof(*req); @@ -4975,14 +5195,28 @@ int wh_Client_MlDsaVerifyDma(whClientContext* ctx, const byte* sig, req->keyId = key_id; /* Set up DMA buffers */ - req->sig.addr = (uint64_t)(uintptr_t)sig; req->sig.sz = sig_len; - req->msg.addr = (uint64_t)(uintptr_t)msg; - req->msg.sz = msg_len; + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)sig, (void**)&sigAddr, sig_len, + WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->sig.addr = sigAddr; + } + if (ret == WH_ERROR_OK) { + req->msg.sz = msg_len; + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)msg, (void**)&msgAddr, msg_len, + WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); + if (ret == WH_ERROR_OK) { + req->msg.addr = msgAddr; + } + } /* Send Request */ - ret = wh_Client_SendRequest(ctx, group, action, req_len, - (uint8_t*)dataPtr); + if (ret == WH_ERROR_OK) { + ret = wh_Client_SendRequest(ctx, group, action, req_len, + (uint8_t*)dataPtr); + } if (ret == WH_ERROR_OK) { /* Server will evict at this point if requested */ evict = 0; @@ -5009,6 +5243,13 @@ int wh_Client_MlDsaVerifyDma(whClientContext* ctx, const byte* sig, } } } + + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)msg, (void**)&msgAddr, msg_len, + WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0}); + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)sig, (void**)&sigAddr, sig_len, + WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0}); } else { ret = WH_ERROR_BADARGS; diff --git a/src/wh_server_crypto.c b/src/wh_server_crypto.c index 80b386d6a..1d247f35d 100644 --- a/src/wh_server_crypto.c +++ b/src/wh_server_crypto.c @@ -4318,6 +4318,7 @@ static int _HandleCmacDma(whServerContext* ctx, uint16_t magic, uint16_t seq, res.dmaAddrStatus.badAddr = req.input; } } + if (ret == WH_ERROR_OK && req.output.sz != 0) { ret = wh_Server_DmaProcessClientAddress( ctx, req.output.addr, &outAddr, req.output.sz, @@ -4326,6 +4327,7 @@ static int _HandleCmacDma(whServerContext* ctx, uint16_t magic, uint16_t seq, res.dmaAddrStatus.badAddr = req.output; } } + if (ret == WH_ERROR_OK && req.key.sz != 0) { ret = wh_Server_DmaProcessClientAddress( ctx, req.key.addr, &keyAddr, req.key.sz, diff --git a/src/wh_server_dma.c b/src/wh_server_dma.c index 46b71f6d3..5843f33d2 100644 --- a/src/wh_server_dma.c +++ b/src/wh_server_dma.c @@ -115,6 +115,7 @@ int wh_Server_DmaProcessClientAddress(whServerContext* server, rc = wh_Dma_CheckMemOperAgainstAllowList(server->dma.dmaAddrAllowList, oper, *xformedCliAddr, len); } + return rc; }