diff --git a/benchmark/bench_modules/wh_bench_mod_aes.c b/benchmark/bench_modules/wh_bench_mod_aes.c index 5186c3093..50380fa56 100644 --- a/benchmark/bench_modules/wh_bench_mod_aes.c +++ b/benchmark/bench_modules/wh_bench_mod_aes.c @@ -58,6 +58,8 @@ static int _benchAesCtrDma(whClientContext* client, whBenchOpContext* ctx, const uint8_t* in = NULL; uint8_t* out = NULL; + (void)wh_Client_SetDmaMode(client, 1); + #if defined(WOLFHSM_CFG_TEST_POSIX) /* Allocate buffers using XMALLOC with heap hints for DMA */ if (ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { @@ -90,7 +92,7 @@ static int _benchAesCtrDma(whClientContext* client, whBenchOpContext* ctx, #endif /* Initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; @@ -186,6 +188,8 @@ static int _benchAesCtr(whClientContext* client, whBenchOpContext* ctx, int id, WC_AES_BLOCK_SIZE; int i; + (void)wh_Client_SetDmaMode(client, 0); + #if defined(WOLFHSM_CFG_BENCH_INIT_DATA_BUFFERS) /* Initialize the input buffer with something non-zero */ memset(WH_BENCH_DATA_IN_BUFFER, 0xAA, inLen); @@ -193,7 +197,7 @@ static int _benchAesCtr(whClientContext* client, whBenchOpContext* ctx, int id, #endif /* Initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; @@ -382,6 +386,8 @@ static int _benchAesEcbDma(whClientContext* client, whBenchOpContext* ctx, const uint8_t* in = NULL; uint8_t* out = NULL; + (void)wh_Client_SetDmaMode(client, 1); + #if defined(WOLFHSM_CFG_TEST_POSIX) /* Allocate buffers using XMALLOC with heap hints for DMA */ if (ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { @@ -414,7 +420,7 @@ static int _benchAesEcbDma(whClientContext* client, whBenchOpContext* ctx, #endif /* Initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; @@ -513,6 +519,8 @@ static int _benchAesEcb(whClientContext* client, whBenchOpContext* ctx, int id, WC_AES_BLOCK_SIZE; int i; + (void)wh_Client_SetDmaMode(client, 0); + #if defined(WOLFHSM_CFG_BENCH_INIT_DATA_BUFFERS) /* Initialize the input buffer with something non-zero */ memset(WH_BENCH_DATA_IN_BUFFER, 0xAA, inLen); @@ -520,7 +528,7 @@ static int _benchAesEcb(whClientContext* client, whBenchOpContext* ctx, int id, #endif /* Initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; @@ -717,6 +725,8 @@ static int _benchAesCbcDma(whClientContext* client, whBenchOpContext* ctx, const uint8_t* in = NULL; uint8_t* out = NULL; + (void)wh_Client_SetDmaMode(client, 1); + #if defined(WOLFHSM_CFG_TEST_POSIX) /* Allocate buffers using XMALLOC with heap hints for DMA */ if (ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { @@ -749,7 +759,7 @@ static int _benchAesCbcDma(whClientContext* client, whBenchOpContext* ctx, #endif /* Initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; @@ -857,6 +867,8 @@ static int _benchAesCbc(whClientContext* client, whBenchOpContext* ctx, int id, WC_AES_BLOCK_SIZE; int i; + (void)wh_Client_SetDmaMode(client, 0); + #if defined(WOLFHSM_CFG_BENCH_INIT_DATA_BUFFERS) /* Initialize the input buffer with something non-zero */ memset(WH_BENCH_DATA_IN_BUFFER, 0xAA, inLen); @@ -864,7 +876,7 @@ static int _benchAesCbc(whClientContext* client, whBenchOpContext* ctx, int id, #endif /* Initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; @@ -1073,6 +1085,8 @@ static int _benchAesGcmDma(whClientContext* client, whBenchOpContext* ctx, const uint8_t* in = NULL; uint8_t* out = NULL; + (void)wh_Client_SetDmaMode(client, 1); + #if defined(WOLFHSM_CFG_TEST_POSIX) /* Allocate buffers using XMALLOC with heap hints for DMA */ if (ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { @@ -1105,7 +1119,7 @@ static int _benchAesGcmDma(whClientContext* client, whBenchOpContext* ctx, #endif /* initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; @@ -1230,6 +1244,8 @@ static int _benchAesGcm(whClientContext* client, whBenchOpContext* ctx, int id, WC_AES_BLOCK_SIZE; int i; + (void)wh_Client_SetDmaMode(client, 0); + #if defined(WOLFHSM_CFG_BENCH_INIT_DATA_BUFFERS) /* Initialize the input buffer with something non-zero */ memset(WH_BENCH_DATA_IN_BUFFER, 0xAA, inLen); @@ -1237,7 +1253,7 @@ static int _benchAesGcm(whClientContext* client, whBenchOpContext* ctx, int id, #endif /* initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; diff --git a/benchmark/bench_modules/wh_bench_mod_cmac.c b/benchmark/bench_modules/wh_bench_mod_cmac.c index 0bbfa50e3..c5fe990df 100644 --- a/benchmark/bench_modules/wh_bench_mod_cmac.c +++ b/benchmark/bench_modules/wh_bench_mod_cmac.c @@ -41,7 +41,7 @@ static const uint8_t key256[] = { int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id, - const uint8_t* key, size_t keyLen, int devId) + const uint8_t* key, size_t keyLen, int useDma) { int ret = 0; word32 outLen; @@ -54,6 +54,8 @@ int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id, size_t inLen; uint8_t* out = NULL; + (void)wh_Client_SetDmaMode(client, useDma); + /* cache the key on the HSM */ ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ANY, (uint8_t*)keyLabel, sizeof(keyLabel), (uint8_t*)key, keyLen, &keyId); @@ -64,7 +66,7 @@ int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id, out = tag; /* default to using tag buffer on the stack */ #if defined(WOLFHSM_CFG_DMA) - if (devId == WH_DEV_ID_DMA) { + if (useDma) { inLen = WOLFHSM_CFG_BENCH_DMA_BUFFER_SIZE; #if defined(WOLFHSM_CFG_TEST_POSIX) if (ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { @@ -111,7 +113,8 @@ int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id, int benchStopRet; /* initialize the cmac struct */ - ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, devId); + ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, + WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitCmac_ex %d\n", ret); goto exit; @@ -129,7 +132,7 @@ int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id, /* Oneshot CMAC through wolfCrypt API will always be most performant * implementation */ ret = wc_AesCmacGenerate_ex(cmac, out, &outLen, in, inLen, key, keyLen, - NULL, devId); + NULL, WH_CLIENT_DEVID(client)); benchStopRet = wh_Bench_StopOp(ctx, id); if (benchStartRet != 0) { @@ -160,8 +163,7 @@ int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id, } #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 (useDma && 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); @@ -178,7 +180,7 @@ int wh_Bench_Mod_CmacAes128(whClientContext* client, whBenchOpContext* ctx, int id, void* params) { (void)params; - return _benchCmacAes(client, ctx, id, key128, sizeof(key128), WH_DEV_ID); + return _benchCmacAes(client, ctx, id, key128, sizeof(key128), 0); } int wh_Bench_Mod_CmacAes128Dma(whClientContext* client, whBenchOpContext* ctx, @@ -186,8 +188,7 @@ int wh_Bench_Mod_CmacAes128Dma(whClientContext* client, whBenchOpContext* ctx, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchCmacAes(client, ctx, id, key128, sizeof(key128), - WH_DEV_ID_DMA); + return _benchCmacAes(client, ctx, id, key128, sizeof(key128), 1); #else (void)client; (void)ctx; @@ -201,7 +202,7 @@ int wh_Bench_Mod_CmacAes256(whClientContext* client, whBenchOpContext* ctx, int id, void* params) { (void)params; - return _benchCmacAes(client, ctx, id, key256, sizeof(key256), WH_DEV_ID); + return _benchCmacAes(client, ctx, id, key256, sizeof(key256), 0); } int wh_Bench_Mod_CmacAes256Dma(whClientContext* client, whBenchOpContext* ctx, @@ -209,8 +210,7 @@ int wh_Bench_Mod_CmacAes256Dma(whClientContext* client, whBenchOpContext* ctx, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchCmacAes(client, ctx, id, key256, sizeof(key256), - WH_DEV_ID_DMA); + return _benchCmacAes(client, ctx, id, key256, sizeof(key256), 1); #else (void)client; (void)ctx; diff --git a/benchmark/bench_modules/wh_bench_mod_cmac_kdf.c b/benchmark/bench_modules/wh_bench_mod_cmac_kdf.c index 6b30eb880..ee88979cb 100644 --- a/benchmark/bench_modules/wh_bench_mod_cmac_kdf.c +++ b/benchmark/bench_modules/wh_bench_mod_cmac_kdf.c @@ -32,7 +32,7 @@ #define WH_BENCH_CMAC_KDF_OUT_SIZE 40 static int _benchCmacKdf(whClientContext* client, whBenchOpContext* ctx, int id, - int devId) + int useDma) { /* Derivation inputs mirror the unit test vectors to provide realistic * message sizes while keeping the benchmark deterministic. */ @@ -55,7 +55,7 @@ static int _benchCmacKdf(whClientContext* client, whBenchOpContext* ctx, int id, whKeyId keyId; int i; - (void)devId; + (void)wh_Client_SetDmaMode(client, useDma); for (i = 0; i < WOLFHSM_CFG_BENCH_KG_ITERS && ret == 0; i++) { int benchStartRet; @@ -103,7 +103,7 @@ int wh_Bench_Mod_CmacKdf(whClientContext* client, whBenchOpContext* ctx, int id, void* params) { (void)params; - return _benchCmacKdf(client, ctx, id, WH_DEV_ID); + return _benchCmacKdf(client, ctx, id, 0); } #endif /* HAVE_CMAC_KDF && WOLFSSL_CMAC */ diff --git a/benchmark/bench_modules/wh_bench_mod_curve25519.c b/benchmark/bench_modules/wh_bench_mod_curve25519.c index 954ac2a4b..193921507 100644 --- a/benchmark/bench_modules/wh_bench_mod_curve25519.c +++ b/benchmark/bench_modules/wh_bench_mod_curve25519.c @@ -52,7 +52,6 @@ uint8_t key2_der[] = { int wh_Bench_Mod_Curve25519KeyGen(whClientContext* client, whBenchOpContext* ctx, int id, void* params) { - (void)client; (void)params; int ret = 0; @@ -62,8 +61,10 @@ int wh_Bench_Mod_Curve25519KeyGen(whClientContext* client, int initialized_rng = 0; int initialized_key = 0; + (void)wh_Client_SetDmaMode(client, 0); + /* Initialize the RNG for key generation */ - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -76,7 +77,7 @@ int wh_Bench_Mod_Curve25519KeyGen(whClientContext* client, int benchStopRet; /* Initialize the Curve25519 key before each iteration */ - ret = wc_curve25519_init_ex(key, NULL, WH_DEV_ID); + ret = wc_curve25519_init_ex(key, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_curve25519_init_ex %d\n", ret); break; @@ -140,6 +141,8 @@ int wh_Bench_Mod_Curve25519SharedSecret(whClientContext* client, whKeyId keyIdBob = WH_KEYID_ERASED; char keyLabel[] = "bench-key"; + (void)wh_Client_SetDmaMode(client, 0); + /* Cache Alice's key in the HSM */ ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ANY, (uint8_t*)keyLabel, strlen(keyLabel), key1_der, sizeof(key1_der), @@ -160,7 +163,7 @@ int wh_Bench_Mod_Curve25519SharedSecret(whClientContext* client, } /* Initialize Alice's key structure */ - ret = wc_curve25519_init_ex(keyAlice, NULL, WH_DEV_ID); + ret = wc_curve25519_init_ex(keyAlice, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to initialize Alice's key %d\n", ret); wh_Client_KeyEvict(client, keyIdAlice); @@ -177,7 +180,7 @@ int wh_Bench_Mod_Curve25519SharedSecret(whClientContext* client, } /* Initialize Bob's key structure */ - ret = wc_curve25519_init_ex(keyBob, NULL, WH_DEV_ID); + ret = wc_curve25519_init_ex(keyBob, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to initialize Bob's key %d\n", ret); goto exit; diff --git a/benchmark/bench_modules/wh_bench_mod_ecc.c b/benchmark/bench_modules/wh_bench_mod_ecc.c index a944e2182..60cfb2034 100644 --- a/benchmark/bench_modules/wh_bench_mod_ecc.c +++ b/benchmark/bench_modules/wh_bench_mod_ecc.c @@ -58,7 +58,7 @@ static const uint8_t bobKeyDer[] = { /* Helper function for ECC sign benchmark */ int _benchEccSign(whClientContext* client, whBenchOpContext* ctx, int id, - const uint8_t* key, size_t keyLen, int curveSize, int devId) + const uint8_t* key, size_t keyLen, int curveSize, int useDma) { int ret = 0; word32 sigLen; @@ -72,13 +72,15 @@ int _benchEccSign(whClientContext* client, whBenchOpContext* ctx, int id, whKeyId keyId = WH_KEYID_ERASED; char keyLabel[] = "bench-key"; + (void)wh_Client_SetDmaMode(client, useDma); + /* Initialize dummy hash data */ for (i = 0; i < (int)sizeof(hash); i++) { hash[i] = (byte)i; } /* Initialize the RNG */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; @@ -94,7 +96,7 @@ int _benchEccSign(whClientContext* client, whBenchOpContext* ctx, int id, } /* Initialize the ECC key */ - ret = wc_ecc_init_ex(eccKey, NULL, devId); + ret = wc_ecc_init_ex(eccKey, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_ecc_init_ex %d\n", ret); goto exit; @@ -168,7 +170,8 @@ int _benchEccSign(whClientContext* client, whBenchOpContext* ctx, int id, /* Helper function for ECC verify benchmark */ int _benchEccVerify(whClientContext* client, whBenchOpContext* ctx, int id, - const uint8_t* key, size_t keyLen, int curveSize, int devId) + const uint8_t* key, size_t keyLen, int curveSize, + int useDma) { int ret = 0; word32 sigLen; @@ -183,13 +186,15 @@ int _benchEccVerify(whClientContext* client, whBenchOpContext* ctx, int id, whKeyId keyId = WH_KEYID_ERASED; char keyLabel[] = "bench-key"; + (void)wh_Client_SetDmaMode(client, useDma); + /* Initialize dummy hash data */ for (i = 0; i < (int)sizeof(hash); i++) { hash[i] = (byte)i; } /* Initialize the RNG */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -205,7 +210,7 @@ int _benchEccVerify(whClientContext* client, whBenchOpContext* ctx, int id, } /* Initialize the ECC key */ - ret = wc_ecc_init_ex(eccKey, NULL, devId); + ret = wc_ecc_init_ex(eccKey, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_ecc_init_ex %d\n", ret); goto exit; @@ -291,10 +296,8 @@ int _benchEccVerify(whClientContext* client, whBenchOpContext* ctx, int id, /* Helper function for ECC key generation benchmark */ int _benchEccKeyGen(whClientContext* client, whBenchOpContext* ctx, int id, - int curveSize, int devId) + int curveSize, int useDma) { - (void)client; - int ret = 0; ecc_key key[1] = {0}; WC_RNG rng[1] = {0}; @@ -302,8 +305,10 @@ int _benchEccKeyGen(whClientContext* client, whBenchOpContext* ctx, int id, int initialized_rng = 0; int initialized_key = 0; + (void)wh_Client_SetDmaMode(client, useDma); + /* Initialize the RNG for key generation */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; @@ -316,7 +321,7 @@ int _benchEccKeyGen(whClientContext* client, whBenchOpContext* ctx, int id, int benchStopRet; /* Initialize the ECC key before each iteration */ - ret = wc_ecc_init_ex(key, NULL, devId); + ret = wc_ecc_init_ex(key, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_ecc_init_ex %d\n", ret); break; @@ -367,7 +372,7 @@ int _benchEccKeyGen(whClientContext* client, whBenchOpContext* ctx, int id, int _benchEccEcdh(whClientContext* client, whBenchOpContext* ctx, int id, const uint8_t* aliceKeyData, size_t aliceKeyLen, const uint8_t* bobKeyData, size_t bobKeyLen, int curveSize, - int devId) + int useDma) { int ret = 0; word32 outLen; @@ -383,8 +388,10 @@ int _benchEccEcdh(whClientContext* client, whBenchOpContext* ctx, int id, whKeyId keyIdBob = WH_KEYID_ERASED; char keyLabel[] = "bench-key"; + (void)wh_Client_SetDmaMode(client, useDma); + /* Initialize RNG for potential operations that require it */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; @@ -410,7 +417,7 @@ int _benchEccEcdh(whClientContext* client, whBenchOpContext* ctx, int id, } /* Initialize Alice's key structure */ - ret = wc_ecc_init_ex(aliceKey, NULL, devId); + ret = wc_ecc_init_ex(aliceKey, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to initialize Alice's key %d\n", ret); goto exit; @@ -431,7 +438,7 @@ int _benchEccEcdh(whClientContext* client, whBenchOpContext* ctx, int id, } /* Initialize Bob's key structure */ - ret = wc_ecc_init_ex(bobKey, NULL, devId); + ret = wc_ecc_init_ex(bobKey, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to initialize Bob's key %d\n", ret); goto exit; @@ -521,7 +528,7 @@ int wh_Bench_Mod_EccP256Sign(whClientContext* client, whBenchOpContext* ctx, { (void)params; return _benchEccSign(client, ctx, id, aliceKeyDer, sizeof(aliceKeyDer), 32, - WH_DEV_ID); + 0); } int wh_Bench_Mod_EccP256SignDma(whClientContext* client, whBenchOpContext* ctx, @@ -539,7 +546,7 @@ int wh_Bench_Mod_EccP256Verify(whClientContext* client, whBenchOpContext* ctx, { (void)params; return _benchEccVerify(client, ctx, id, aliceKeyDer, sizeof(aliceKeyDer), - 32, WH_DEV_ID); + 32, 0); } int wh_Bench_Mod_EccP256VerifyDma(whClientContext* client, @@ -556,7 +563,7 @@ int wh_Bench_Mod_EccP256KeyGen(whClientContext* client, whBenchOpContext* ctx, int id, void* params) { (void)params; - return _benchEccKeyGen(client, ctx, id, 32, WH_DEV_ID); + return _benchEccKeyGen(client, ctx, id, 32, 0); } int wh_Bench_Mod_EccP256Ecdh(whClientContext* client, whBenchOpContext* ctx, @@ -564,7 +571,7 @@ int wh_Bench_Mod_EccP256Ecdh(whClientContext* client, whBenchOpContext* ctx, { (void)params; return _benchEccEcdh(client, ctx, id, aliceKeyDer, sizeof(aliceKeyDer), - bobKeyDer, sizeof(bobKeyDer), 32, WH_DEV_ID); + bobKeyDer, sizeof(bobKeyDer), 32, 0); } #endif /* HAVE_ECC */ diff --git a/benchmark/bench_modules/wh_bench_mod_hkdf.c b/benchmark/bench_modules/wh_bench_mod_hkdf.c index 1bd5d0b19..26a8317d8 100644 --- a/benchmark/bench_modules/wh_bench_mod_hkdf.c +++ b/benchmark/bench_modules/wh_bench_mod_hkdf.c @@ -34,7 +34,7 @@ #define WH_BENCH_HKDF_OKM_SIZE 42 static int _benchHkdf(whClientContext* client, whBenchOpContext* ctx, int id, - int devId) + int useDma) { /* Simple fixed inputs for HKDF to measure performance. The data mirrors * sizes from RFC 5869 test case 1 but we only care about timing here. */ @@ -52,7 +52,7 @@ static int _benchHkdf(whClientContext* client, whBenchOpContext* ctx, int id, whKeyId keyId; int i; - (void)devId; + (void)wh_Client_SetDmaMode(client, useDma); for (i = 0; i < WOLFHSM_CFG_BENCH_KG_ITERS && ret == 0; i++) { int benchStartRet; @@ -98,7 +98,7 @@ int wh_Bench_Mod_HkdfSha256(whClientContext* client, whBenchOpContext* ctx, int id, void* params) { (void)params; - return _benchHkdf(client, ctx, id, WH_DEV_ID); + return _benchHkdf(client, ctx, id, 0); } #endif /* defined(HAVE_HKDF) */ diff --git a/benchmark/bench_modules/wh_bench_mod_hmac.c b/benchmark/bench_modules/wh_bench_mod_hmac.c index 1b8a248e4..9ae8bdec8 100644 --- a/benchmark/bench_modules/wh_bench_mod_hmac.c +++ b/benchmark/bench_modules/wh_bench_mod_hmac.c @@ -32,10 +32,8 @@ static const uint8_t key[] = static const size_t keyLen = sizeof(key) - 1; /* -1 for null terminator */ int _benchHmacSha256(whClientContext* client, whBenchOpContext* ctx, int id, - int devId) + int useDma) { - (void)client; - int ret = 0; Hmac hmac[1]; uint8_t out[WC_SHA256_DIGEST_SIZE]; @@ -44,8 +42,10 @@ int _benchHmacSha256(whClientContext* client, whBenchOpContext* ctx, int id, const uint8_t* in; size_t inLen; + (void)wh_Client_SetDmaMode(client, useDma); + #if defined(WOLFHSM_CFG_DMA) - if (devId == WH_DEV_ID_DMA) { + if (useDma) { in = WH_BENCH_DMA_BUFFER; inLen = WOLFHSM_CFG_BENCH_DMA_BUFFER_SIZE; } @@ -75,7 +75,7 @@ int _benchHmacSha256(whClientContext* client, whBenchOpContext* ctx, int id, /* Defer error checking until after all operations are complete */ benchStartRet = wh_Bench_StartOp(ctx, id); - initRet = wc_HmacInit(hmac, NULL, devId); + initRet = wc_HmacInit(hmac, NULL, WH_CLIENT_DEVID(client)); setKeyRet = wc_HmacSetKey(hmac, WC_SHA256, key, (word32)keyLen); updateRet = wc_HmacUpdate(hmac, in, inLen); finalRet = wc_HmacFinal(hmac, out); @@ -129,7 +129,7 @@ int wh_Bench_Mod_HmacSha256(whClientContext* client, whBenchOpContext* ctx, int id, void* params) { (void)params; - return _benchHmacSha256(client, ctx, id, WH_DEV_ID); + return _benchHmacSha256(client, ctx, id, 0); } int wh_Bench_Mod_HmacSha256Dma(whClientContext* client, whBenchOpContext* ctx, @@ -137,7 +137,7 @@ int wh_Bench_Mod_HmacSha256Dma(whClientContext* client, whBenchOpContext* ctx, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchHmacSha256(client, ctx, id, WH_DEV_ID_DMA); + return _benchHmacSha256(client, ctx, id, 1); #else (void)client; (void)ctx; diff --git a/benchmark/bench_modules/wh_bench_mod_mldsa.c b/benchmark/bench_modules/wh_bench_mod_mldsa.c index e260119c1..20a23c3a5 100644 --- a/benchmark/bench_modules/wh_bench_mod_mldsa.c +++ b/benchmark/bench_modules/wh_bench_mod_mldsa.c @@ -615,7 +615,7 @@ static byte test_msg[512] = { #if !defined(WOLFSSL_MLDSA_NO_SIGN) /* Helper function for ML-DSA sign benchmark */ static int _benchMlDsaSign(whClientContext* client, whBenchOpContext* ctx, - int id, int paramSet, int devId) + int id, int paramSet, int useDma) { int ret = 0; wc_MlDsaKey key; @@ -629,8 +629,10 @@ static int _benchMlDsaSign(whClientContext* client, whBenchOpContext* ctx, whKeyId keyId = WH_KEYID_ERASED; char keyLabel[] = "bench-mldsa-key"; + (void)wh_Client_SetDmaMode(client, useDma); + /* Initialize the RNG */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; @@ -638,7 +640,7 @@ static int _benchMlDsaSign(whClientContext* client, whBenchOpContext* ctx, initialized_rng = 1; /* Initialize the ML-DSA key */ - ret = wc_MlDsaKey_Init(&key, NULL, devId); + ret = wc_MlDsaKey_Init(&key, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_MlDsaKey_Init %d\n", ret); goto exit; @@ -663,7 +665,7 @@ static int _benchMlDsaSign(whClientContext* client, whBenchOpContext* ctx, /* Import key to the HSM */ #if defined(WOLFHSM_CFG_DMA) - if (devId == WH_DEV_ID_DMA) { + if (useDma) { ret = wh_Client_MlDsaImportKeyDma(client, &key, &keyId, WH_NVM_FLAGS_USAGE_ANY, strlen(keyLabel), (uint8_t*)keyLabel); @@ -766,7 +768,7 @@ static int _benchMlDsaSign(whClientContext* client, whBenchOpContext* ctx, #if !defined(WOLFSSL_MLDSA_NO_VERIFY) /* Helper function for ML-DSA verify benchmark */ static int _benchMlDsaVerify(whClientContext* client, whBenchOpContext* ctx, - int id, int paramSet, int devId) + int id, int paramSet, int useDma) { int ret = 0; wc_MlDsaKey key; @@ -779,8 +781,10 @@ static int _benchMlDsaVerify(whClientContext* client, whBenchOpContext* ctx, whKeyId keyId = WH_KEYID_ERASED; char keyLabel[] = "bench-mldsa-key"; + (void)wh_Client_SetDmaMode(client, useDma); + /* Initialize the RNG */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; @@ -788,7 +792,7 @@ static int _benchMlDsaVerify(whClientContext* client, whBenchOpContext* ctx, initialized_rng = 1; /* Initialize the ML-DSA key */ - ret = wc_MlDsaKey_Init(&key, NULL, devId); + ret = wc_MlDsaKey_Init(&key, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_MlDsaKey_Init %d\n", ret); goto exit; @@ -813,7 +817,7 @@ static int _benchMlDsaVerify(whClientContext* client, whBenchOpContext* ctx, /* Import key to the HSM */ #if defined(WOLFHSM_CFG_DMA) - if (devId == WH_DEV_ID_DMA) { + if (useDma) { ret = wh_Client_MlDsaImportKeyDma(client, &key, &keyId, WH_NVM_FLAGS_USAGE_ANY, strlen(keyLabel), (uint8_t*)keyLabel); @@ -897,10 +901,8 @@ static int _benchMlDsaVerify(whClientContext* client, whBenchOpContext* ctx, #if !defined(WOLFSSL_MLDSA_NO_MAKE_KEY) /* Helper function for ML-DSA key generation benchmark */ static int _benchMlDsaKeyGen(whClientContext* client, whBenchOpContext* ctx, - int id, int paramSet, int devId) + int id, int paramSet, int useDma) { - (void)client; - int ret = 0; wc_MlDsaKey key; WC_RNG rng[1] = {0}; @@ -908,8 +910,10 @@ static int _benchMlDsaKeyGen(whClientContext* client, whBenchOpContext* ctx, int initialized_rng = 0; int initialized_key = 0; + (void)wh_Client_SetDmaMode(client, useDma); + /* Initialize the RNG */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -922,7 +926,7 @@ static int _benchMlDsaKeyGen(whClientContext* client, whBenchOpContext* ctx, int benchStopRet; /* Initialize the ML-DSA key before each iteration */ - ret = wc_MlDsaKey_Init(&key, NULL, devId); + ret = wc_MlDsaKey_Init(&key, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_MlDsaKey_Init %d\n", ret); break; @@ -982,7 +986,7 @@ int wh_Bench_Mod_MlDsa44Sign(whClientContext* client, whBenchOpContext* ctx, #if !defined(WOLFSSL_MLDSA_NO_SIGN) && \ !defined(WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY) (void)params; - return _benchMlDsaSign(client, ctx, id, WC_ML_DSA_44, WH_DEV_ID); + return _benchMlDsaSign(client, ctx, id, WC_ML_DSA_44, 0); #else (void)client; (void)ctx; @@ -997,7 +1001,7 @@ int wh_Bench_Mod_MlDsa44SignDma(whClientContext* client, whBenchOpContext* ctx, { #if defined(WOLFHSM_CFG_DMA) && !defined(WOLFSSL_MLDSA_NO_SIGN) (void)params; - return _benchMlDsaSign(client, ctx, id, WC_ML_DSA_44, WH_DEV_ID_DMA); + return _benchMlDsaSign(client, ctx, id, WC_ML_DSA_44, 1); #else (void)client; (void)ctx; @@ -1013,7 +1017,7 @@ int wh_Bench_Mod_MlDsa44Verify(whClientContext* client, whBenchOpContext* ctx, #if !defined(WOLFSSL_MLDSA_NO_VERIFY) && \ !defined(WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY) (void)params; - return _benchMlDsaVerify(client, ctx, id, WC_ML_DSA_44, WH_DEV_ID); + return _benchMlDsaVerify(client, ctx, id, WC_ML_DSA_44, 0); #else (void)client; (void)ctx; @@ -1028,7 +1032,7 @@ int wh_Bench_Mod_MlDsa44VerifyDma(whClientContext* client, { #if defined(WOLFHSM_CFG_DMA) && !defined(WOLFSSL_MLDSA_NO_VERIFY) (void)params; - return _benchMlDsaVerify(client, ctx, id, WC_ML_DSA_44, WH_DEV_ID_DMA); + return _benchMlDsaVerify(client, ctx, id, WC_ML_DSA_44, 1); #else (void)client; (void)ctx; @@ -1044,7 +1048,7 @@ int wh_Bench_Mod_MlDsa44KeyGen(whClientContext* client, whBenchOpContext* ctx, #if !defined(WOLFSSL_MLDSA_NO_MAKE_KEY) && \ !defined(WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY) (void)params; - return _benchMlDsaKeyGen(client, ctx, id, WC_ML_DSA_44, WH_DEV_ID); + return _benchMlDsaKeyGen(client, ctx, id, WC_ML_DSA_44, 0); #else (void)client; (void)ctx; @@ -1059,7 +1063,7 @@ int wh_Bench_Mod_MlDsa44KeyGenDma(whClientContext* client, { #if defined(WOLFHSM_CFG_DMA) && !defined(WOLFSSL_MLDSA_NO_MAKE_KEY) (void)params; - return _benchMlDsaKeyGen(client, ctx, id, WC_ML_DSA_44, WH_DEV_ID_DMA); + return _benchMlDsaKeyGen(client, ctx, id, WC_ML_DSA_44, 1); #else (void)client; (void)ctx; diff --git a/benchmark/bench_modules/wh_bench_mod_mlkem.c b/benchmark/bench_modules/wh_bench_mod_mlkem.c index 5d75b6a8c..a3a885c25 100644 --- a/benchmark/bench_modules/wh_bench_mod_mlkem.c +++ b/benchmark/bench_modules/wh_bench_mod_mlkem.c @@ -29,17 +29,20 @@ #if defined(WOLFSSL_HAVE_MLKEM) static int _benchMlKemKeyGen(whClientContext* client, whBenchOpContext* ctx, - int id, int securityLevel, int devId) + int id, int securityLevel, int useDma) { int ret = WH_ERROR_OK; int i; + (void)wh_Client_SetDmaMode(client, useDma); + for (i = 0; i < WOLFHSM_CFG_BENCH_KG_ITERS && ret == WH_ERROR_OK; i++) { MlKemKey key[1]; int benchStartRet; int benchStopRet; - ret = wc_MlKemKey_Init(key, securityLevel, NULL, devId); + ret = + wc_MlKemKey_Init(key, securityLevel, NULL, WH_CLIENT_DEVID(client)); if (ret != WH_ERROR_OK) { WH_BENCH_PRINTF("Failed to wc_MlKemKey_Init %d\n", ret); break; @@ -47,7 +50,7 @@ static int _benchMlKemKeyGen(whClientContext* client, whBenchOpContext* ctx, benchStartRet = wh_Bench_StartOp(ctx, id); #ifdef WOLFHSM_CFG_DMA - if (devId == WH_DEV_ID_DMA) { + if (useDma) { ret = wh_Client_MlKemMakeExportKeyDma(client, securityLevel, key); } else @@ -76,7 +79,7 @@ static int _benchMlKemKeyGen(whClientContext* client, whBenchOpContext* ctx, } static int _benchMlKemEncaps(whClientContext* client, whBenchOpContext* ctx, - int id, int securityLevel, int devId) + int id, int securityLevel, int useDma) { int ret = WH_ERROR_OK; int i; @@ -84,14 +87,16 @@ static int _benchMlKemEncaps(whClientContext* client, whBenchOpContext* ctx, byte ct[WC_ML_KEM_MAX_CIPHER_TEXT_SIZE]; byte ss[WC_ML_KEM_SS_SZ]; - ret = wc_MlKemKey_Init(key, securityLevel, NULL, devId); + (void)wh_Client_SetDmaMode(client, useDma); + + ret = wc_MlKemKey_Init(key, securityLevel, NULL, WH_CLIENT_DEVID(client)); if (ret != WH_ERROR_OK) { WH_BENCH_PRINTF("Failed to wc_MlKemKey_Init %d\n", ret); return ret; } #ifdef WOLFHSM_CFG_DMA - if (devId == WH_DEV_ID_DMA) { + if (useDma) { ret = wh_Client_MlKemMakeExportKeyDma(client, securityLevel, key); } else @@ -116,7 +121,7 @@ static int _benchMlKemEncaps(whClientContext* client, whBenchOpContext* ctx, benchStartRet = wh_Bench_StartOp(ctx, id); #ifdef WOLFHSM_CFG_DMA - if (devId == WH_DEV_ID_DMA) { + if (useDma) { ret = wh_Client_MlKemEncapsulateDma(client, key, ct, &ctLen, ss, &ssLen); } @@ -145,7 +150,7 @@ static int _benchMlKemEncaps(whClientContext* client, whBenchOpContext* ctx, } static int _benchMlKemDecaps(whClientContext* client, whBenchOpContext* ctx, - int id, int securityLevel, int devId) + int id, int securityLevel, int useDma) { int ret = WH_ERROR_OK; int i; @@ -156,14 +161,16 @@ static int _benchMlKemDecaps(whClientContext* client, whBenchOpContext* ctx, word32 ctLen = sizeof(ct); word32 ssEncLen = sizeof(ssEnc); - ret = wc_MlKemKey_Init(key, securityLevel, NULL, devId); + (void)wh_Client_SetDmaMode(client, useDma); + + ret = wc_MlKemKey_Init(key, securityLevel, NULL, WH_CLIENT_DEVID(client)); if (ret != WH_ERROR_OK) { WH_BENCH_PRINTF("Failed to wc_MlKemKey_Init %d\n", ret); return ret; } #ifdef WOLFHSM_CFG_DMA - if (devId == WH_DEV_ID_DMA) { + if (useDma) { ret = wh_Client_MlKemMakeExportKeyDma(client, securityLevel, key); } else @@ -178,7 +185,7 @@ static int _benchMlKemDecaps(whClientContext* client, whBenchOpContext* ctx, } #ifdef WOLFHSM_CFG_DMA - if (devId == WH_DEV_ID_DMA) { + if (useDma) { ret = wh_Client_MlKemEncapsulateDma(client, key, ct, &ctLen, ssEnc, &ssEncLen); } @@ -203,7 +210,7 @@ static int _benchMlKemDecaps(whClientContext* client, whBenchOpContext* ctx, benchStartRet = wh_Bench_StartOp(ctx, id); #ifdef WOLFHSM_CFG_DMA - if (devId == WH_DEV_ID_DMA) { + if (useDma) { ret = wh_Client_MlKemDecapsulateDma(client, key, ct, ctLen, ssDec, &ssDecLen); } @@ -237,56 +244,50 @@ static int _benchMlKemDecaps(whClientContext* client, whBenchOpContext* ctx, return ret; } -#define WH_DEFINE_MLKEM_BENCH_NON_DMA_FNS(_Suffix, _Level) \ -int wh_Bench_Mod_MlKem##_Suffix##KeyGen(whClientContext* client, \ - whBenchOpContext* ctx, int id, \ - void* params) \ -{ \ - (void)params; \ - return _benchMlKemKeyGen(client, ctx, id, _Level, WH_DEV_ID); \ -} \ - \ -int wh_Bench_Mod_MlKem##_Suffix##Encaps(whClientContext* client, \ - whBenchOpContext* ctx, int id, \ - void* params) \ -{ \ - (void)params; \ - return _benchMlKemEncaps(client, ctx, id, _Level, WH_DEV_ID); \ -} \ - \ -int wh_Bench_Mod_MlKem##_Suffix##Decaps(whClientContext* client, \ - whBenchOpContext* ctx, int id, \ - void* params) \ -{ \ - (void)params; \ - return _benchMlKemDecaps(client, ctx, id, _Level, WH_DEV_ID); \ -} +#define WH_DEFINE_MLKEM_BENCH_NON_DMA_FNS(_Suffix, _Level) \ + int wh_Bench_Mod_MlKem##_Suffix##KeyGen( \ + whClientContext* client, whBenchOpContext* ctx, int id, void* params) \ + { \ + (void)params; \ + return _benchMlKemKeyGen(client, ctx, id, _Level, 0); \ + } \ + \ + int wh_Bench_Mod_MlKem##_Suffix##Encaps( \ + whClientContext* client, whBenchOpContext* ctx, int id, void* params) \ + { \ + (void)params; \ + return _benchMlKemEncaps(client, ctx, id, _Level, 0); \ + } \ + \ + int wh_Bench_Mod_MlKem##_Suffix##Decaps( \ + whClientContext* client, whBenchOpContext* ctx, int id, void* params) \ + { \ + (void)params; \ + return _benchMlKemDecaps(client, ctx, id, _Level, 0); \ + } #ifdef WOLFHSM_CFG_DMA -#define WH_DEFINE_MLKEM_BENCH_DMA_FNS(_Suffix, _Level) \ -int wh_Bench_Mod_MlKem##_Suffix##KeyGenDma(whClientContext* client, \ - whBenchOpContext* ctx, int id, \ - void* params) \ -{ \ - (void)params; \ - return _benchMlKemKeyGen(client, ctx, id, _Level, WH_DEV_ID_DMA); \ -} \ - \ -int wh_Bench_Mod_MlKem##_Suffix##EncapsDma(whClientContext* client, \ - whBenchOpContext* ctx, int id, \ - void* params) \ -{ \ - (void)params; \ - return _benchMlKemEncaps(client, ctx, id, _Level, WH_DEV_ID_DMA); \ -} \ - \ -int wh_Bench_Mod_MlKem##_Suffix##DecapsDma(whClientContext* client, \ - whBenchOpContext* ctx, int id, \ - void* params) \ -{ \ - (void)params; \ - return _benchMlKemDecaps(client, ctx, id, _Level, WH_DEV_ID_DMA); \ -} +#define WH_DEFINE_MLKEM_BENCH_DMA_FNS(_Suffix, _Level) \ + int wh_Bench_Mod_MlKem##_Suffix##KeyGenDma( \ + whClientContext* client, whBenchOpContext* ctx, int id, void* params) \ + { \ + (void)params; \ + return _benchMlKemKeyGen(client, ctx, id, _Level, 1); \ + } \ + \ + int wh_Bench_Mod_MlKem##_Suffix##EncapsDma( \ + whClientContext* client, whBenchOpContext* ctx, int id, void* params) \ + { \ + (void)params; \ + return _benchMlKemEncaps(client, ctx, id, _Level, 1); \ + } \ + \ + int wh_Bench_Mod_MlKem##_Suffix##DecapsDma( \ + whClientContext* client, whBenchOpContext* ctx, int id, void* params) \ + { \ + (void)params; \ + return _benchMlKemDecaps(client, ctx, id, _Level, 1); \ + } #else #define WH_DEFINE_MLKEM_BENCH_DMA_FNS(_Suffix, _Level) \ int wh_Bench_Mod_MlKem##_Suffix##KeyGenDma(whClientContext* client, \ diff --git a/benchmark/bench_modules/wh_bench_mod_rng.c b/benchmark/bench_modules/wh_bench_mod_rng.c index 9a7651b2f..d28726c0a 100644 --- a/benchmark/bench_modules/wh_bench_mod_rng.c +++ b/benchmark/bench_modules/wh_bench_mod_rng.c @@ -25,10 +25,9 @@ #if !defined(WC_NO_RNG) -int _benchRng(whClientContext* client, whBenchOpContext* ctx, int id, int devId) +int _benchRng(whClientContext* client, whBenchOpContext* ctx, int id, + int useDma) { - (void)client; - int ret = 0; WC_RNG rng; int i = 0; @@ -36,7 +35,9 @@ int _benchRng(whClientContext* client, whBenchOpContext* ctx, int id, int devId) uint8_t* out = WH_BENCH_DATA_OUT_BUFFER; word32 outLen = WOLFHSM_CFG_BENCH_DATA_BUFFER_SIZE; - ret = wc_InitRng_ex(&rng, NULL, devId); + (void)wh_Client_SetDmaMode(client, useDma); + + ret = wc_InitRng_ex(&rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -89,7 +90,7 @@ int wh_Bench_Mod_Rng(whClientContext* client, whBenchOpContext* ctx, int id, { (void)params; - return _benchRng(client, ctx, id, WH_DEV_ID); + return _benchRng(client, ctx, id, 0); } #endif /* !defined(WC_NO_RNG) */ diff --git a/benchmark/bench_modules/wh_bench_mod_rsa.c b/benchmark/bench_modules/wh_bench_mod_rsa.c index bd4410def..e63084105 100644 --- a/benchmark/bench_modules/wh_bench_mod_rsa.c +++ b/benchmark/bench_modules/wh_bench_mod_rsa.c @@ -331,7 +331,7 @@ unsigned char rsa4096KeyDer[] = { int _benchRsaCrypt(whClientContext* client, whBenchOpContext* ctx, int id, - const uint8_t* key, size_t keyLen, int operation, int devId) + const uint8_t* key, size_t keyLen, int operation, int useDma) { int ret = 0; whKeyId keyId = WH_KEYID_ERASED; @@ -348,13 +348,15 @@ int _benchRsaCrypt(whClientContext* client, whBenchOpContext* ctx, int id, int initialized_rsa = 0; int needEvict = 0; + (void)wh_Client_SetDmaMode(client, useDma); + if (operation != RSA_PUBLIC_ENCRYPT && operation != RSA_PRIVATE_DECRYPT) { WH_BENCH_PRINTF("Unsupported RSA crypto operation %d\n", operation); return -1; } /* Initialize RNG for RSA operations */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; @@ -371,7 +373,7 @@ int _benchRsaCrypt(whClientContext* client, whBenchOpContext* ctx, int id, needEvict = 1; /* Initialize the RSA key structure */ - ret = wc_InitRsaKey_ex(rsa, NULL, devId); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRsaKey_ex %d\n", ret); goto exit; @@ -465,7 +467,7 @@ int _benchRsaCrypt(whClientContext* client, whBenchOpContext* ctx, int id, } int _benchRsaVerify(whClientContext* client, whBenchOpContext* ctx, int id, - const uint8_t* key, size_t keyLen, int devId) + const uint8_t* key, size_t keyLen, int useDma) { int ret = 0; whKeyId keyId = WH_KEYID_ERASED; @@ -481,13 +483,15 @@ int _benchRsaVerify(whClientContext* client, whBenchOpContext* ctx, int id, int initialized_rsa = 0; int needEvict = 0; + (void)wh_Client_SetDmaMode(client, useDma); + /* Fill message buffer with some pattern */ for (i = 0; i < (int)sizeof(message); i++) { message[i] = (byte)i; } /* Initialize RNG for RSA operations */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; @@ -504,7 +508,7 @@ int _benchRsaVerify(whClientContext* client, whBenchOpContext* ctx, int id, needEvict = 1; /* Initialize the RSA key structure */ - ret = wc_InitRsaKey_ex(rsa, NULL, devId); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRsaKey_ex %d\n", ret); goto exit; @@ -588,7 +592,7 @@ int _benchRsaVerify(whClientContext* client, whBenchOpContext* ctx, int id, } int _benchRsaSign(whClientContext* client, whBenchOpContext* ctx, int id, - const uint8_t* key, size_t keyLen, int devId) + const uint8_t* key, size_t keyLen, int useDma) { int ret = 0; whKeyId keyId = WH_KEYID_ERASED; @@ -603,13 +607,15 @@ int _benchRsaSign(whClientContext* client, whBenchOpContext* ctx, int id, int initialized_rsa = 0; int needEvict = 0; + (void)wh_Client_SetDmaMode(client, useDma); + /* Fill message buffer with some pattern */ for (i = 0; i < (int)sizeof(message); i++) { message[i] = (byte)i; } /* Initialize RNG for RSA operations */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; @@ -626,7 +632,7 @@ int _benchRsaSign(whClientContext* client, whBenchOpContext* ctx, int id, needEvict = 1; /* Initialize the RSA key structure */ - ret = wc_InitRsaKey_ex(rsa, NULL, devId); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRsaKey_ex %d\n", ret); goto exit; @@ -696,10 +702,8 @@ int _benchRsaSign(whClientContext* client, whBenchOpContext* ctx, int id, } int _benchRsaKeyGen(whClientContext* client, whBenchOpContext* ctx, int id, - int keySize, int devId) + int keySize, int useDma) { - (void)client; - int ret = 0; RsaKey rsa[1]; WC_RNG rng[1]; @@ -708,8 +712,10 @@ int _benchRsaKeyGen(whClientContext* client, whBenchOpContext* ctx, int id, int initialized_rsa = 0; long exponent = WC_RSA_EXPONENT; /* Standard RSA exponent (65537) */ + (void)wh_Client_SetDmaMode(client, useDma); + /* Initialize RNG for RSA operations */ - ret = wc_InitRng_ex(rng, NULL, devId); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -721,7 +727,7 @@ int _benchRsaKeyGen(whClientContext* client, whBenchOpContext* ctx, int id, int benchStopRet; int opRet; - ret = wc_InitRsaKey_ex(rsa, NULL, devId); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_BENCH_PRINTF("Failed to wc_InitRsaKey_ex in iteration %d: %d\n", i, ret); @@ -772,7 +778,7 @@ int wh_Bench_Mod_Rsa2048PubEncrypt(whClientContext* client, #if (RSA_MAX_SIZE >= 2048) (void)params; return _benchRsaCrypt(client, ctx, id, rsa2048KeyDer, sizeof(rsa2048KeyDer), - RSA_PUBLIC_ENCRYPT, WH_DEV_ID); + RSA_PUBLIC_ENCRYPT, 0); #else (void)client; (void)ctx; @@ -807,7 +813,7 @@ int wh_Bench_Mod_Rsa2048PrvDecrypt(whClientContext* client, #if (RSA_MAX_SIZE >= 2048) (void)params; return _benchRsaCrypt(client, ctx, id, rsa2048KeyDer, sizeof(rsa2048KeyDer), - RSA_PRIVATE_DECRYPT, WH_DEV_ID); + RSA_PRIVATE_DECRYPT, 0); #else (void)client; (void)ctx; @@ -843,7 +849,7 @@ int wh_Bench_Mod_Rsa2048Sign(whClientContext* client, whBenchOpContext* ctx, #if (RSA_MAX_SIZE >= 2048) (void)params; return _benchRsaSign(client, ctx, id, rsa2048KeyDer, sizeof(rsa2048KeyDer), - WH_DEV_ID); + 0); #else (void)client; (void)ctx; @@ -878,7 +884,7 @@ int wh_Bench_Mod_Rsa2048Verify(whClientContext* client, whBenchOpContext* ctx, #if (RSA_MAX_SIZE >= 2048) (void)params; return _benchRsaVerify(client, ctx, id, rsa2048KeyDer, - sizeof(rsa2048KeyDer), WH_DEV_ID); + sizeof(rsa2048KeyDer), 0); #else (void)client; (void)ctx; @@ -911,7 +917,7 @@ int wh_Bench_Mod_Rsa2048KeyGen(whClientContext* client, whBenchOpContext* ctx, { #if (RSA_MAX_SIZE >= 2048) (void)params; - return _benchRsaKeyGen(client, ctx, id, 2048, WH_DEV_ID); + return _benchRsaKeyGen(client, ctx, id, 2048, 0); #else (void)client; (void)ctx; @@ -946,7 +952,7 @@ int wh_Bench_Mod_Rsa4096PubEncrypt(whClientContext* client, !defined(WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY) (void)params; return _benchRsaCrypt(client, ctx, id, rsa4096KeyDer, sizeof(rsa4096KeyDer), - RSA_PUBLIC_ENCRYPT, WH_DEV_ID); + RSA_PUBLIC_ENCRYPT, 0); #else (void)client; (void)ctx; @@ -982,7 +988,7 @@ int wh_Bench_Mod_Rsa4096PrvDecrypt(whClientContext* client, !defined(WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY) (void)params; return _benchRsaCrypt(client, ctx, id, rsa4096KeyDer, sizeof(rsa4096KeyDer), - RSA_PRIVATE_DECRYPT, WH_DEV_ID); + RSA_PRIVATE_DECRYPT, 0); #else (void)client; (void)ctx; @@ -1018,7 +1024,7 @@ int wh_Bench_Mod_Rsa4096Sign(whClientContext* client, whBenchOpContext* ctx, !defined(WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY) (void)params; return _benchRsaSign(client, ctx, id, rsa4096KeyDer, sizeof(rsa4096KeyDer), - WH_DEV_ID); + 0); #else (void)client; (void)ctx; @@ -1053,7 +1059,7 @@ int wh_Bench_Mod_Rsa4096Verify(whClientContext* client, whBenchOpContext* ctx, !defined(WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY) (void)params; return _benchRsaVerify(client, ctx, id, rsa4096KeyDer, - sizeof(rsa4096KeyDer), WH_DEV_ID); + sizeof(rsa4096KeyDer), 0); #else (void)client; (void)ctx; @@ -1087,7 +1093,7 @@ int wh_Bench_Mod_Rsa4096KeyGen(whClientContext* client, whBenchOpContext* ctx, #if (RSA_MAX_SIZE >= 4096) && \ !defined(WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY) (void)params; - return _benchRsaKeyGen(client, ctx, id, 4096, WH_DEV_ID); + return _benchRsaKeyGen(client, ctx, id, 4096, 0); #else (void)client; (void)ctx; diff --git a/benchmark/bench_modules/wh_bench_mod_sha2.c b/benchmark/bench_modules/wh_bench_mod_sha2.c index 65270d311..0b66c83c4 100644 --- a/benchmark/bench_modules/wh_bench_mod_sha2.c +++ b/benchmark/bench_modules/wh_bench_mod_sha2.c @@ -32,10 +32,8 @@ #if !defined(NO_SHA256) int _benchSha256(whClientContext* client, whBenchOpContext* ctx, int id, - int devId) + int useDma) { - (void)client; - int ret = 0; wc_Sha256* sha256 = NULL; wc_Sha256 sha256Stack; @@ -49,8 +47,10 @@ int _benchSha256(whClientContext* client, whBenchOpContext* ctx, int id, sha256 = &sha256Stack; out = outStack; + (void)wh_Client_SetDmaMode(client, useDma); + #if defined(WOLFHSM_CFG_DMA) - if (devId == WH_DEV_ID_DMA) { + if (useDma) { inLen = WOLFHSM_CFG_BENCH_DMA_BUFFER_SIZE; #if defined(WOLFHSM_CFG_TEST_POSIX) if (ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { @@ -100,7 +100,7 @@ int _benchSha256(whClientContext* client, whBenchOpContext* ctx, int id, /* Defer error checking until after all operations are complete */ benchStartRet = wh_Bench_StartOp(ctx, id); - initRet = wc_InitSha256_ex(sha256, NULL, devId); + initRet = wc_InitSha256_ex(sha256, NULL, WH_CLIENT_DEVID(client)); updateRet = wc_Sha256Update(sha256, in, inLen); finalRet = wc_Sha256Final(sha256, out); benchStopRet = wh_Bench_StopOp(ctx, id); @@ -142,8 +142,7 @@ int _benchSha256(whClientContext* client, whBenchOpContext* ctx, int id, } #if defined(WOLFHSM_CFG_DMA) && defined(WOLFHSM_CFG_TEST_POSIX) - if (devId == WH_DEV_ID_DMA && - ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { + if (useDma && 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); @@ -159,7 +158,7 @@ int wh_Bench_Mod_Sha256(whClientContext* client, whBenchOpContext* ctx, int id, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchSha256(client, ctx, id, WH_DEV_ID); + return _benchSha256(client, ctx, id, 0); #else (void)client; (void)ctx; @@ -174,7 +173,7 @@ int wh_Bench_Mod_Sha256Dma(whClientContext* client, whBenchOpContext* ctx, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchSha256(client, ctx, id, WH_DEV_ID_DMA); + return _benchSha256(client, ctx, id, 1); #else (void)client; (void)ctx; @@ -190,10 +189,8 @@ int wh_Bench_Mod_Sha256Dma(whClientContext* client, whBenchOpContext* ctx, #if defined(WOLFSSL_SHA224) int _benchSha224(whClientContext* client, whBenchOpContext* ctx, int id, - int devId) + int useDma) { - (void)client; - int ret = 0; wc_Sha224 sha224[1]; uint8_t out[WC_SHA224_DIGEST_SIZE]; @@ -202,8 +199,10 @@ int _benchSha224(whClientContext* client, whBenchOpContext* ctx, int id, const uint8_t* in; size_t inLen; + (void)wh_Client_SetDmaMode(client, useDma); + #if defined(WOLFHSM_CFG_DMA) - if (devId == WH_DEV_ID_DMA) { + if (useDma) { in = WH_BENCH_DMA_BUFFER; inLen = WOLFHSM_CFG_BENCH_DMA_BUFFER_SIZE; } @@ -232,7 +231,7 @@ int _benchSha224(whClientContext* client, whBenchOpContext* ctx, int id, /* Defer error checking until after all operations are complete */ benchStartRet = wh_Bench_StartOp(ctx, id); - initRet = wc_InitSha224_ex(sha224, NULL, devId); + initRet = wc_InitSha224_ex(sha224, NULL, WH_CLIENT_DEVID(client)); updateRet = wc_Sha224Update(sha224, in, inLen); finalRet = wc_Sha224Final(sha224, out); benchStopRet = wh_Bench_StopOp(ctx, id); @@ -281,7 +280,7 @@ int wh_Bench_Mod_Sha224(whClientContext* client, whBenchOpContext* ctx, int id, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchSha224(client, ctx, id, WH_DEV_ID); + return _benchSha224(client, ctx, id, 0); #else (void)client; (void)ctx; @@ -296,7 +295,7 @@ int wh_Bench_Mod_Sha224Dma(whClientContext* client, whBenchOpContext* ctx, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchSha224(client, ctx, id, WH_DEV_ID_DMA); + return _benchSha224(client, ctx, id, 1); #else (void)client; (void)ctx; @@ -311,10 +310,8 @@ int wh_Bench_Mod_Sha224Dma(whClientContext* client, whBenchOpContext* ctx, #if defined(WOLFSSL_SHA384) int _benchSha384(whClientContext* client, whBenchOpContext* ctx, int id, - int devId) + int useDma) { - (void)client; - int ret = 0; wc_Sha384 sha384[1]; uint8_t out[WC_SHA384_DIGEST_SIZE]; @@ -323,8 +320,10 @@ int _benchSha384(whClientContext* client, whBenchOpContext* ctx, int id, const uint8_t* in; size_t inLen; + (void)wh_Client_SetDmaMode(client, useDma); + #if defined(WOLFHSM_CFG_DMA) - if (devId == WH_DEV_ID_DMA) { + if (useDma) { in = WH_BENCH_DMA_BUFFER; inLen = WOLFHSM_CFG_BENCH_DMA_BUFFER_SIZE; } @@ -353,7 +352,7 @@ int _benchSha384(whClientContext* client, whBenchOpContext* ctx, int id, /* Defer error checking until after all operations are complete */ benchStartRet = wh_Bench_StartOp(ctx, id); - initRet = wc_InitSha384_ex(sha384, NULL, devId); + initRet = wc_InitSha384_ex(sha384, NULL, WH_CLIENT_DEVID(client)); updateRet = wc_Sha384Update(sha384, in, inLen); finalRet = wc_Sha384Final(sha384, out); benchStopRet = wh_Bench_StopOp(ctx, id); @@ -402,7 +401,7 @@ int wh_Bench_Mod_Sha384(whClientContext* client, whBenchOpContext* ctx, int id, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchSha384(client, ctx, id, WH_DEV_ID); + return _benchSha384(client, ctx, id, 0); #else (void)client; (void)ctx; @@ -417,7 +416,7 @@ int wh_Bench_Mod_Sha384Dma(whClientContext* client, whBenchOpContext* ctx, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchSha384(client, ctx, id, WH_DEV_ID_DMA); + return _benchSha384(client, ctx, id, 1); #else (void)client; (void)ctx; @@ -431,10 +430,8 @@ int wh_Bench_Mod_Sha384Dma(whClientContext* client, whBenchOpContext* ctx, #if defined(WOLFSSL_SHA512) int _benchSha512(whClientContext* client, whBenchOpContext* ctx, int id, - int devId) + int useDma) { - (void)client; - int ret = 0; wc_Sha512 sha512[1]; uint8_t out[WC_SHA512_DIGEST_SIZE]; @@ -443,8 +440,10 @@ int _benchSha512(whClientContext* client, whBenchOpContext* ctx, int id, const uint8_t* in; size_t inLen; + (void)wh_Client_SetDmaMode(client, useDma); + #if defined(WOLFHSM_CFG_DMA) - if (devId == WH_DEV_ID_DMA) { + if (useDma) { in = WH_BENCH_DMA_BUFFER; inLen = WOLFHSM_CFG_BENCH_DMA_BUFFER_SIZE; } @@ -473,7 +472,7 @@ int _benchSha512(whClientContext* client, whBenchOpContext* ctx, int id, /* Defer error checking until after all operations are complete */ benchStartRet = wh_Bench_StartOp(ctx, id); - initRet = wc_InitSha512_ex(sha512, NULL, devId); + initRet = wc_InitSha512_ex(sha512, NULL, WH_CLIENT_DEVID(client)); updateRet = wc_Sha512Update(sha512, in, inLen); finalRet = wc_Sha512Final(sha512, out); benchStopRet = wh_Bench_StopOp(ctx, id); @@ -522,7 +521,7 @@ int wh_Bench_Mod_Sha512(whClientContext* client, whBenchOpContext* ctx, int id, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchSha512(client, ctx, id, WH_DEV_ID); + return _benchSha512(client, ctx, id, 0); #else (void)client; (void)ctx; @@ -537,7 +536,7 @@ int wh_Bench_Mod_Sha512Dma(whClientContext* client, whBenchOpContext* ctx, { #if defined(WOLFHSM_CFG_DMA) (void)params; - return _benchSha512(client, ctx, id, WH_DEV_ID_DMA); + return _benchSha512(client, ctx, id, 1); #else (void)client; (void)ctx; diff --git a/docs/src/3-Quickstart.md b/docs/src/3-Quickstart.md index 6521517f8..018b4fd94 100644 --- a/docs/src/3-Quickstart.md +++ b/docs/src/3-Quickstart.md @@ -238,7 +238,7 @@ This is the same callback-driven layering used throughout wolfHSM, so the NVM fl The server performs cryptographic operations with wolfCrypt, so `wolfCrypt_Init()` must be called before `wh_Server_Init()`. The server's `whServerCryptoContext` owns a wolfCrypt random number generator that must be seeded with `wc_InitRng_ex()`. -Passing `INVALID_DEVID` makes the server perform crypto in software. To offload to a hardware accelerator instead, register a wolfCrypt crypto callback and pass its device ID both to `wc_InitRng_ex()` and to the `.devId` field of the server configuration. Note that the client does *not* initialize wolfCrypt for offloaded operations: it transparently routes wolfCrypt API calls to the server by using the `WH_DEV_ID` device ID. See [Cryptography and wolfCrypt Integration](5-Features.md#cryptography-and-wolfcrypt-integration). +Passing `INVALID_DEVID` makes the server perform crypto in software. To offload to a hardware accelerator instead, register a wolfCrypt crypto callback and pass its device ID both to `wc_InitRng_ex()` and to the `.devId` field of the server configuration. Note that the client does *not* initialize wolfCrypt for offloaded operations: it transparently routes wolfCrypt API calls to the server by using its device ID — set in the client config's `.devId` field, or the default `WH_DEV_ID` when left `0` — read with `WH_CLIENT_DEVID(client)` after `wh_Client_Init()`. See [Cryptography and wolfCrypt Integration](5-Features.md#cryptography-and-wolfcrypt-integration). ### Initializing the Server Context diff --git a/docs/src/5-Features.md b/docs/src/5-Features.md index 550c05164..dcdf90298 100644 --- a/docs/src/5-Features.md +++ b/docs/src/5-Features.md @@ -33,7 +33,7 @@ This chapter provides a detailed overview of the high level features that wolfHS - [Communication Layer](#communication-layer) - [Transport Backends](#transport-backends) - [DMA Support](#dma-support) - - [The DMA Crypto Device (`WH_DEV_ID_DMA`)](#the-dma-crypto-device-wh_dev_id_dma) + - [DMA Dispatch Mode (`wh_Client_SetDmaMode`)](#dma-dispatch-mode-wh_client_setdmamode) - [Pre-Access and Post-Access Callbacks](#pre-access-and-post-access-callbacks) - [Address Allowlisting](#address-allowlisting) - [32-bit vs. 64-bit Address Handling](#32-bit-vs-64-bit-address-handling) @@ -81,7 +81,16 @@ wolfHSM uses wolfCrypt as its cryptographic provider on both sides of the client Clients can use the wolfCrypt API directly because of wolfCrypt's [crypto callback (cryptoCb)](https://www.wolfssl.com/documentation/manuals/wolfssl/chapter06.html#crypto-callbacks-cryptocb) framework. Crypto callbacks let you override selected algorithms at runtime by registering a callback against a device identifier (`devId`). Most wolfCrypt functions take a `devId`, and when it matches a registered device the call is dispatched through that callback instead of running locally. -The wolfHSM client library registers a crypto callback that turns each supported wolfCrypt call into a request/response exchange with the server. The same wolfCrypt source can be retargeted to the HSM by changing only the `devId` — nothing else in the application changes. wolfHSM defines `WH_DEV_ID` for the server crypto device, and `WH_DEV_ID_DMA` when DMA support is compiled in; passing either to a wolfCrypt function routes the operation to the server. +The wolfHSM client library registers a crypto callback that turns each supported wolfCrypt call into a request/response exchange with the server. The same wolfCrypt source can be retargeted to the HSM by changing only the `devId` — nothing else in the application changes. Each client context registers a device ID chosen by the application in the `.devId` field of `whClientConfig`; leaving the field `0` selects the default `WH_DEV_ID`. `wh_Client_Init()` registers the ID and binds it to that context, and `wh_Client_Cleanup()` unregisters it. At a wolfCrypt call site the application can either read the ID back from the context with the `WH_CLIENT_DEVID(client)` macro, or simply pass the same constant it placed in the config — convenient where the client context is not in scope. Because each client can own a distinct `devId`, a single process can run multiple client connections (to one server or several) and each wolfCrypt call is serviced by exactly the client whose `devId` it was initialized with; a multi-client process must configure a distinct, nonzero `devId` for every client. + +In addition to the configured per-client ID, every `wh_Client_Init()` registers the two process-global device IDs: + +- `WH_DEV_ID` is registered with the same unified callback as a configured `devId`, so it behaves identically — including honoring the [DMA dispatch mode](#dma-dispatch-mode-wh_client_setdmamode). It is also the ID a client is bound to when its config leaves `.devId` 0. +- `WH_DEV_ID_DMA` (present only with `WOLFHSM_CFG_DMA`) is registered with the DMA-only callback: operations always use the DMA request forms, and algorithms without a DMA variant fail rather than falling back to the standard path. It is reserved for this purpose and is not valid as a configured `.devId`. + +The global IDs preserve the behavior of earlier wolfHSM releases: an application with a **single client per process** needs no devId configuration at all and can keep passing `WH_DEV_ID` (or `WH_DEV_ID_DMA`) straight to wolfCrypt functions, exactly as before — they are always registered and available after `wh_Client_Init()`. Because these registrations are process-global and keyed on the integer value, each `wh_Client_Init()` rebinds them to the most recently initialized client, and **any** client's `wh_Client_Cleanup()` unregisters them. In a multi-client process they are therefore unreliable and should not be passed to wolfCrypt; use the per-client configured IDs instead. Both values are overridable at compile time (see [Configuration](9-Configuration.md#cryptography-features)). + +Registered device IDs occupy slots in wolfCrypt's fixed-size crypto-callback table (`MAX_CRYPTO_DEVID_CALLBACKS`, default 8): the global IDs occupy one slot each, shared by all clients in the process (every init rebinds the same table entries), and each distinct configured `devId` adds one more. `wh_Client_Cleanup()` releases the client's slots. Applications that run many simultaneous clients in one process may need to raise the wolfCrypt limit. In effect the callback layer is a transparent RPC framework for wolfCrypt: clients write ordinary wolfCrypt code, and wolfHSM handles request marshaling, transport, dispatch, and response delivery underneath. It also makes prototyping easy — develop against a local wolfCrypt instance, then switch to the HSM by toggling one parameter once the server is available. @@ -96,20 +105,21 @@ The wolfHSM server exposes the full set of wolfCrypt software algorithms, and th - **Random number generation**: DRBG/RNG backed by the server's entropy source - **Post-quantum cryptography**: ML-DSA (FIPS 204) and ML-KEM (FIPS 203) -For the authoritative list of algorithms, parameter ranges, and options, see the [wolfCrypt API reference](https://www.wolfssl.com/documentation/manuals/wolfssl/index.html). An algorithm not yet wired through the crypto callback can still be used locally against the client's own wolfCrypt instance — only operations dispatched to `WH_DEV_ID` are offloaded. +For the authoritative list of algorithms, parameter ranges, and options, see the [wolfCrypt API reference](https://www.wolfssl.com/documentation/manuals/wolfssl/index.html). An algorithm not yet wired through the crypto callback can still be used locally against the client's own wolfCrypt instance — only operations dispatched to the client's `devId` are offloaded. ### Referencing Keys by ID When a client offloads an operation, it usually does *not* send the key with the request. The key lives in the server [keystore](#keystore) under a numeric **key ID**, and the client refers to it by that ID alone. The bytes never cross the client/server boundary — the client holds only the ID, and the server looks up the material when it runs the operation. This is what lets an HSM guard a private key while still letting a client sign or decrypt with it. -A wolfCrypt key object is tied to a server-side key ID with a per-algorithm `SetKeyId` call. Every offloaded algorithm has one — `wh_Client_RsaSetKeyId`, `wh_Client_EccSetKeyId`, `wh_Client_AesSetKeyId`, `wh_Client_Ed25519SetKeyId`, `wh_Client_Curve25519SetKeyId`, `wh_Client_CmacSetKeyId`, `wh_Client_MlDsaSetKeyId`, and so on (each with a matching `GetKeyId`). You initialize an ordinary wolfCrypt key struct with `WH_DEV_ID`, associate it with a key ID instead of loading key bytes, and call wolfCrypt as usual: +A wolfCrypt key object is tied to a server-side key ID with a per-algorithm `SetKeyId` call. Every offloaded algorithm has one — `wh_Client_RsaSetKeyId`, `wh_Client_EccSetKeyId`, `wh_Client_AesSetKeyId`, `wh_Client_Ed25519SetKeyId`, `wh_Client_Curve25519SetKeyId`, `wh_Client_CmacSetKeyId`, `wh_Client_MlDsaSetKeyId`, and so on (each with a matching `GetKeyId`). You initialize an ordinary wolfCrypt key struct with the client's devId, associate it with a key ID instead of loading key bytes, and call wolfCrypt as usual: ```c RsaKey rsa; whKeyId keyId = 4; /* keyId 4 must be resident on the server */ -/* Initialize the RSA key context to use wolfHSM offload via WH_DEV_ID */ -wc_InitRsaKey_ex(&rsa, NULL, WH_DEV_ID); +/* Initialize the RSA key context to use wolfHSM offload via the + * devId of an initialized client context */ +wc_InitRsaKey_ex(&rsa, NULL, WH_CLIENT_DEVID(client)); /* Bind the key object to the server-side key */ wh_Client_RsaSetKeyId(&rsa, keyId); @@ -518,9 +528,11 @@ The motivating use cases all involve payloads that are either too large or too i - **Certificate chain verification** (see [DMA Variants](#dma-variants)) where the chain itself may be several kilobytes and the application already holds it in its own memory. - **In-place image verification** by the [image manager](#image-manager), which is the canonical case: the image being authenticated is already mapped in flash or RAM, and copying it through the comm buffer would defeat the purpose. -### The DMA Crypto Device (`WH_DEV_ID_DMA`) +### DMA Dispatch Mode (`wh_Client_SetDmaMode`) + +For wolfCrypt-mediated operations, opt-in to DMA is a per-client dispatch mode rather than a separate device ID: the application calls `wh_Client_SetDmaMode(client, 1)` (or sets `.preferDma` in the client's `whClientDmaConfig` at init), and subsequent wolfCrypt calls made with `WH_CLIENT_DEVID(client)` construct DMA-flavored requests whose payloads carry pointers and lengths into the client's address space rather than inline data. The server-side dispatcher recognizes the DMA request kind and, for each referenced buffer, hands the pointer to the server's DMA address-processing path (described below) before invoking the underlying wolfCrypt primitive. The set of algorithms that have a DMA path mirrors the most performance-sensitive subset of the supported algorithms; with DMA mode preferred, an algorithm without a DMA path automatically falls back to the standard (non-DMA) request, so no call-site changes are needed. The mode can be toggled at any time — `wh_Client_SetDmaMode(client, 0)` returns the client to standard dispatch, and `wh_Client_GetDmaMode()` reads the current setting. -For wolfCrypt-mediated operations, opt-in to DMA is a single change at the call site: instead of passing `WH_DEV_ID` as the device identifier, the client passes `WH_DEV_ID_DMA`. Both device IDs route to the wolfHSM client crypto callback, but the DMA device tells the callback to construct a DMA-flavored request whose payload carries pointers and lengths into the client's address space rather than inline data. The server-side dispatcher recognizes the DMA request kind and, for each referenced buffer, hands the pointer to the server's DMA address-processing path (described below) before invoking the underlying wolfCrypt primitive. The set of algorithms that have a DMA path mirrors the most performance-sensitive subset of the supported algorithms; algorithms without a DMA path return an unsupported error if invoked with `WH_DEV_ID_DMA`, and the application can fall back to the standard `WH_DEV_ID` for those. +The global `WH_DEV_ID_DMA` device ID is also always registered when `WOLFHSM_CFG_DMA` is enabled and always produces DMA-flavored requests for the most recently initialized client; unlike the DMA dispatch mode, it does not fall back to the standard path for algorithms without a DMA variant. See [Transparent Offload via Crypto Callbacks](#transparent-offload-via-crypto-callbacks) for the global device IDs' single-client-per-process scope. For the non-crypto subsystems (NVM, certificate manager, image manager, key cache/export, and the data-wrap API) the DMA-aware request kinds are exposed as `*Dma` variants of the corresponding client API functions — `wh_Client_NvmAddObjectDma`, `wh_Client_KeyCacheDma`, `wh_Client_KeyExportDma`, `wh_Client_CertVerifyDma`, and so on. See the [client API reference](10-API-docs-client.md) for the full set. diff --git a/docs/src/9-Configuration.md b/docs/src/9-Configuration.md index 88d36bb95..136017494 100644 --- a/docs/src/9-Configuration.md +++ b/docs/src/9-Configuration.md @@ -76,6 +76,8 @@ These macros enable or tune optional cryptographic subsystems built on top of wo | `WOLFHSM_CFG_KEYWRAP_MAX_KEY_SIZE` | `2000` | Maximum size, in bytes, of a key that can be wrapped or unwrapped in a single operation. Only consulted when `WOLFHSM_CFG_KEYWRAP` is defined. | | `WOLFHSM_CFG_KEYWRAP_MAX_DATA_SIZE` | `2000` | Maximum size, in bytes, of the plaintext or wrapped payload carried by a single key-wrap request. Only consulted when `WOLFHSM_CFG_KEYWRAP` is defined. | | `WOLFHSM_CFG_GLOBAL_KEYS` | Undefined | If defined, enable the global-keys feature, allowing keys to be cached so that they are visible to every client rather than scoped to the caching client. See [Global Keys](5-Features.md#global-keys) for a full discussion of the API and security implications. | +| `WH_DEV_ID` | `0x5748534D` (`"WHSM"`) | Value of the process-global crypto device ID registered by every `wh_Client_Init()` with the unified client crypto callback. Also the device ID bound to a client whose `whClientConfig.devId` is left `0`. Override it if the default collides with another crypto-callback device ID in the application. See [Transparent Offload via Crypto Callbacks](5-Features.md#transparent-offload-via-crypto-callbacks) for registration lifetime, multi-client rules, and wolfCrypt callback-table sizing (`MAX_CRYPTO_DEVID_CALLBACKS`, default 8). | +| `WH_DEV_ID_DMA` | `0x57444D41` (`"WDMA"`) | Value of the process-global DMA-only crypto device ID, registered by every `wh_Client_Init()` when `WOLFHSM_CFG_DMA` is defined. Reserved: not valid as a `whClientConfig.devId`. Override it if the default collides with another crypto-callback device ID in the application. | ## Keystore and Key Cache @@ -124,7 +126,7 @@ These macros gate and tune DMA-mode crypto and large-buffer operations. | Macro | Default | Description | |---|---|---| -| `WOLFHSM_CFG_DMA` | Undefined | If defined, compile the DMA-capable code paths: the `WH_DEV_ID_DMA` crypto device, DMA message types, pre/post access callbacks, and the address allowlist machinery. Without this macro, DMA APIs are stubbed out. | +| `WOLFHSM_CFG_DMA` | Undefined | If defined, compile the DMA-capable code paths: the per-client DMA dispatch mode (`wh_Client_SetDmaMode()`), DMA message types, pre/post access callbacks, the address allowlist machinery, and the `WH_DEV_ID_DMA` crypto device. Without this macro, DMA APIs are stubbed out. | | `WOLFHSM_CFG_DMAADDR_COUNT` | `10` | Number of entries in the DMA address allowlist used by the server to validate client-supplied DMA buffers. | | `WOLFHSM_CFG_DMA_PTR_SIZE` | Compiler-detected (`__SIZEOF_POINTER__`) | Override the assumed DMA pointer size, in bytes (must be `4` or `8`). Auto-detection works for GCC/Clang and IAR; define this explicitly for any toolchain that does not provide `__SIZEOF_POINTER__`. | | `WOLFHSM_CFG_DMA_ALT_PTR_SIZE` | Undefined | If defined, allows the DMA pointer size to differ from the native CPU pointer size (e.g. a 32-bit-pointer server reachable from a 64-bit-pointer client). When undefined, wh_settings.h refuses to build with a mismatched `WOLFHSM_CFG_DMA_PTR_SIZE`. | diff --git a/examples/demo/client/wh_demo_client_crypto.c b/examples/demo/client/wh_demo_client_crypto.c index 19108a8d2..a7c3dc91d 100644 --- a/examples/demo/client/wh_demo_client_crypto.c +++ b/examples/demo/client/wh_demo_client_crypto.c @@ -71,14 +71,14 @@ int wh_DemoClient_CryptoRsa(whClientContext* clientContext) plainText[sizeof(plainText)-1] = '\0'; /* initialize rng to make the rsa key */ - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; } /* initialize the rsa key */ - ret = wc_InitRsaKey_ex(rsa, NULL, WH_DEV_ID); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitRsaKey_ex %d\n", ret); goto exit; @@ -149,7 +149,7 @@ int wh_DemoClient_CryptoRsaImport(whClientContext* clientContext) plainText[sizeof(plainText)-1] = '\0'; /* initialize rng to encrypt with the rsa key */ - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; @@ -182,7 +182,7 @@ int wh_DemoClient_CryptoRsaImport(whClientContext* clientContext) needEvict = 1; /* initialize the rsa key */ - ret = wc_InitRsaKey_ex(rsa, NULL, WH_DEV_ID); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitRsaKey_ex %d\n", ret); goto exit; @@ -257,20 +257,22 @@ int wh_DemoClient_CryptoCurve25519(whClientContext* clientContext) WC_RNG rng[1]; /* initialize rng to make the curve25519 keys */ - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; } /* initialize the keys */ - ret = wc_curve25519_init_ex(curve25519PrivateKey, NULL, WH_DEV_ID); + ret = wc_curve25519_init_ex(curve25519PrivateKey, NULL, + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_curve25519_init_ex %d\n", ret); goto exit; } - ret = wc_curve25519_init_ex(curve25519PublicKey, NULL, WH_DEV_ID); + ret = wc_curve25519_init_ex(curve25519PublicKey, NULL, + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_curve25519_init_ex %d\n", ret); goto exit; @@ -371,7 +373,7 @@ int wh_DemoClient_CryptoCurve25519Import(whClientContext* clientContext) } /* initialize the wolfCrypt struct to use the cached key */ - ret = wc_curve25519_init_ex(bobKey, NULL, WH_DEV_ID); + ret = wc_curve25519_init_ex(bobKey, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_curve25519_init_ex %d\n", ret); goto exit; @@ -407,7 +409,7 @@ int wh_DemoClient_CryptoCurve25519Import(whClientContext* clientContext) } /* Initialize the wolfCrypt struct to use the cached key */ - ret = wc_curve25519_init_ex(aliceKey, NULL, WH_DEV_ID); + ret = wc_curve25519_init_ex(aliceKey, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_curve25519_init_ex %d\n", ret); goto exit; @@ -505,19 +507,19 @@ int wh_DemoClient_CryptoEcc(whClientContext* clientContext) byte signature[128]; /* Initialize the rng to make the ecc keys */ - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; } /* Initialize the local wolfCrypt structs */ - ret = wc_ecc_init_ex(aliceKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(aliceKey, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_ecc_init_ex %d\n", ret); goto exit; } - ret = wc_ecc_init_ex(bobKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(bobKey, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_ecc_init_ex %d\n", ret); goto exit; @@ -638,7 +640,7 @@ int wh_DemoClient_CryptoEccImport(whClientContext* clientContext) uint8_t keyBuf[256]; /* Initialize the rng for signature signing */ - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto exit; @@ -674,7 +676,7 @@ int wh_DemoClient_CryptoEccImport(whClientContext* clientContext) /* Initialize the local wolfCrypt struct, and configure it to use the cached * key */ - ret = wc_ecc_init_ex(aliceKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(aliceKey, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_ecc_init_ex %d\n", ret); goto exit; @@ -720,7 +722,7 @@ int wh_DemoClient_CryptoEccImport(whClientContext* clientContext) /* Initialize the local wolfCrypt struct, and configure it to use the cached * key */ - ret = wc_ecc_init_ex(bobKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(bobKey, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_ecc_init_ex %d\n", ret); goto exit; @@ -841,7 +843,7 @@ int wh_DemoClient_CryptoAesCbc(whClientContext* clientContext) byte finalText[16]; /* Initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_AesInit %d\n", ret); } @@ -912,7 +914,7 @@ int wh_DemoClient_CryptoAesCbcImport(whClientContext* clientContext) byte finalText[16]; /* Initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; @@ -998,7 +1000,7 @@ int wh_DemoClient_CryptoAesGcm(whClientContext* clientContext) byte finalText[16]; /* initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; @@ -1061,7 +1063,7 @@ int wh_DemoClient_CryptoAesGcmImport(whClientContext* clientContext) byte finalText[16]; /* initialize the aes struct */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_AesInit %d\n", ret); goto exit; @@ -1152,7 +1154,7 @@ int wh_DemoClient_CryptoCmac(whClientContext* clientContext) /* initialize the cmac struct and set the key */ ret = wc_InitCmac_ex(cmac, key, sizeof(key), WC_CMAC_AES, NULL, NULL, - WH_DEV_ID); + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitCmac_ex %d\n", ret); goto exit; @@ -1174,9 +1176,9 @@ int wh_DemoClient_CryptoCmac(whClientContext* clientContext) } /* verify the tag */ - ret = - wc_AesCmacVerify_ex(cmac, tag, sizeof(tag), (byte*)message, - strlen(message), key, sizeof(key), NULL, WH_DEV_ID); + ret = wc_AesCmacVerify_ex(cmac, tag, sizeof(tag), (byte*)message, + strlen(message), key, sizeof(key), NULL, + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("CMAC hash and verify failed %d\n", ret); goto exit; @@ -1205,7 +1207,8 @@ int wh_DemoClient_CryptoCmacImport(whClientContext* clientContext) byte tag[16]; /* initialize the cmac struct */ - ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, WH_DEV_ID); + ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitCmac_ex %d\n", ret); goto exit; @@ -1247,7 +1250,8 @@ int wh_DemoClient_CryptoCmacImport(whClientContext* clientContext) */ /* initialize the cmac struct */ - ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, WH_DEV_ID); + ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitCmac_ex %d\n", ret); goto exit; @@ -1274,7 +1278,8 @@ int wh_DemoClient_CryptoCmacImport(whClientContext* clientContext) * the best one-shot performance. No need to pass a key since the key is * cached on the HSM and the keyId is associated with the CMAC struct */ ret = wc_AesCmacVerify_ex(cmac, tag, sizeof(tag), (byte*)message, - sizeof(message), NULL, 0, NULL, WH_DEV_ID); + sizeof(message), NULL, 0, NULL, + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("CMAC hash and verify failed with imported key %d\n", ret); goto exit; @@ -1303,7 +1308,8 @@ int wh_DemoClient_CryptoCmacOneshotImport(whClientContext* clientContext) byte tag[16]; /* initialize the cmac struct */ - ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, WH_DEV_ID); + ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitCmac_ex %d\n", ret); goto exit; @@ -1330,7 +1336,8 @@ int wh_DemoClient_CryptoCmacOneshotImport(whClientContext* clientContext) * cached on the HSM and the keyId is associated with the CMAC struct */ outLen = sizeof(tag); ret = wc_AesCmacGenerate_ex(cmac, tag, &outLen, (byte*)message, - sizeof(message), NULL, 0, NULL, WH_DEV_ID); + sizeof(message), NULL, 0, NULL, + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wh_Client_AesCmacGenerate %d\n", ret); goto exit; @@ -1341,7 +1348,8 @@ int wh_DemoClient_CryptoCmacOneshotImport(whClientContext* clientContext) * operation is finalized */ /* initialize the cmac struct */ - ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, WH_DEV_ID); + ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitCmac_ex %d\n", ret); goto exit; @@ -1368,7 +1376,8 @@ int wh_DemoClient_CryptoCmacOneshotImport(whClientContext* clientContext) * the best one-shot performance. No need to pass a key since the key is * cached on the HSM and the keyId is associated with the CMAC struct */ ret = wc_AesCmacVerify_ex(cmac, tag, sizeof(tag), (byte*)message, - sizeof(message), NULL, 0, NULL, WH_DEV_ID); + sizeof(message), NULL, 0, NULL, + WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("CMAC hash and verify oneshot failed with imported key %d\n", ret); @@ -1395,7 +1404,7 @@ int wh_DemoClient_CryptoCmacOneshotImport(whClientContext* clientContext) int wh_DemoClient_CryptoHkdfExport(whClientContext* clientContext) { int ret = 0; - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(clientContext); /* Example inputs for HKDF. Data is from RFC 5869 test case 1 */ const byte ikm[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, @@ -1569,7 +1578,7 @@ int wh_DemoClient_CryptoCmacKdfExport(whClientContext* clientContext) demoCmacKdfSalt, (word32)sizeof(demoCmacKdfSalt), demoCmacKdfZ, (word32)sizeof(demoCmacKdfZ), demoCmacKdfFixedInfo, (word32)sizeof(demoCmacKdfFixedInfo), derived, (word32)sizeof(derived), - NULL, WH_DEV_ID); + NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_KDA_KDF_twostep_cmac %d\n", ret); } diff --git a/examples/demo/client/wh_demo_client_keystore.c b/examples/demo/client/wh_demo_client_keystore.c index e8936b484..57deb9793 100644 --- a/examples/demo/client/wh_demo_client_keystore.c +++ b/examples/demo/client/wh_demo_client_keystore.c @@ -166,7 +166,7 @@ int wh_DemoClient_KeystoreAes(whClientContext* clientContext) * used at any time, including across server restarts */ /* Initialize AES context to use wolfHSM offload */ - ret = wc_AesInit(&aes, NULL, WH_DEV_ID); + ret = wc_AesInit(&aes, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to initialize AES: %d\n", ret); return ret; @@ -229,7 +229,7 @@ int wh_DemoClient_KeystoreAes(whClientContext* clientContext) /* Though the key is evicted, we can still use it for crypto operations, * usage will just require the server to load the key from NVM. The key will * be restored in the cache after using it */ - ret = wc_AesInit(&aes, NULL, WH_DEV_ID); + ret = wc_AesInit(&aes, NULL, WH_CLIENT_DEVID(clientContext)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to initialize AES: %d\n", ret); return ret; diff --git a/examples/demo/client/wh_demo_client_keywrap.c b/examples/demo/client/wh_demo_client_keywrap.c index dcef0a1f9..0f50076d0 100644 --- a/examples/demo/client/wh_demo_client_keywrap.c +++ b/examples/demo/client/wh_demo_client_keywrap.c @@ -118,7 +118,7 @@ int wh_DemoClient_AesGcmKeyWrap(whClientContext* client) /* Generating and wrapping a key */ /* Initialize the RNG so we can generate an AES GCM key to wrap */ - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_InitRng_ex %d\n", ret); goto cleanup_kek; @@ -159,7 +159,7 @@ int wh_DemoClient_AesGcmKeyWrap(whClientContext* client) } /* Initialize AES context */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WOLFHSM_CFG_PRINTF("Failed to wc_AesInit %d\n", ret); goto cleanup_cached_key; diff --git a/examples/demo/client/wh_demo_client_secboot.c b/examples/demo/client/wh_demo_client_secboot.c index 692768743..d051fbeff 100644 --- a/examples/demo/client/wh_demo_client_secboot.c +++ b/examples/demo/client/wh_demo_client_secboot.c @@ -52,11 +52,13 @@ const char file_to_measure[] = "/bin/sh"; static int _showNvm(whClientContext* clientContext); static int _provisionMakeCommitKey(whClientContext* clientContext); -static int _sha256File(const char* file_to_measure, uint8_t* hash); -static int _signHash(const uint8_t* hash, size_t hash_len, uint8_t* sig, - uint16_t* sig_len); -static int _verifyHash(const uint8_t* hash, size_t hash_len, const uint8_t* sig, - uint16_t sig_len, int32_t* rc); +static int _sha256File(whClientContext* clientContext, + const char* file_to_measure, uint8_t* hash); +static int _signHash(whClientContext* clientContext, const uint8_t* hash, + size_t hash_len, uint8_t* sig, uint16_t* sig_len); +static int _verifyHash(whClientContext* clientContext, const uint8_t* hash, + size_t hash_len, const uint8_t* sig, uint16_t sig_len, + int32_t* rc); static int _showNvm(whClientContext* clientContext) { @@ -116,7 +118,8 @@ static int _provisionMakeCommitKey(whClientContext* clientContext) return ret; } -static int _sha256File(const char* file_to_measure, uint8_t* hash) +static int _sha256File(whClientContext* clientContext, + const char* file_to_measure, uint8_t* hash) { int ret = 0; int fd = open(file_to_measure, O_RDONLY); @@ -131,7 +134,8 @@ static int _sha256File(const char* file_to_measure, uint8_t* hash) WOLFHSM_CFG_PRINTF("Generating SHA256 of %s over %u bytes at %p\n", file_to_measure, (unsigned int)size, ptr); wc_Sha256 sha256[1]; - ret = wc_InitSha256_ex(sha256, NULL, WH_DEV_ID); + ret = + wc_InitSha256_ex(sha256, NULL, WH_CLIENT_DEVID(clientContext)); if (ret == 0) { ret = wc_Sha256Update(sha256, ptr, (word32)size); if (ret == 0) { @@ -153,11 +157,11 @@ static int _sha256File(const char* file_to_measure, uint8_t* hash) return ret; } -static int _signHash(const uint8_t* hash, size_t hash_len, uint8_t* sig, - uint16_t* sig_len) +static int _signHash(whClientContext* clientContext, const uint8_t* hash, + size_t hash_len, uint8_t* sig, uint16_t* sig_len) { ecc_key key[1]; - int ret = wc_ecc_init_ex(key, NULL, WH_DEV_ID); + int ret = wc_ecc_init_ex(key, NULL, WH_CLIENT_DEVID(clientContext)); if (ret == 0) { ret = wh_Client_EccSetKeyId(key, prov_keyId); if (ret == 0) { @@ -173,11 +177,12 @@ static int _signHash(const uint8_t* hash, size_t hash_len, uint8_t* sig, return ret; } -static int _verifyHash(const uint8_t* hash, size_t hash_len, const uint8_t* sig, - uint16_t sig_len, int32_t* rc) +static int _verifyHash(whClientContext* clientContext, const uint8_t* hash, + size_t hash_len, const uint8_t* sig, uint16_t sig_len, + int32_t* rc) { ecc_key key[1]; - int ret = wc_ecc_init_ex(key, NULL, WH_DEV_ID); + int ret = wc_ecc_init_ex(key, NULL, WH_CLIENT_DEVID(clientContext)); if (ret == 0) { ret = wh_Client_EccSetKeyId(key, prov_keyId); if (ret == 0) { @@ -215,13 +220,14 @@ int wh_DemoClient_SecBoot_Provision(whClientContext* clientContext) uint8_t hash[WC_SHA256_DIGEST_SIZE] = {0}; WOLFHSM_CFG_PRINTF("Measuring image %s...\n", file_to_measure); - ret = _sha256File(file_to_measure, hash); + ret = _sha256File(clientContext, file_to_measure, hash); if (ret == WH_ERROR_OK) { uint8_t sig[ECC_MAX_SIG_SIZE] = {0}; uint16_t siglen = sizeof(sig); WOLFHSM_CFG_PRINTF("Signing hash...\n"); - ret = _signHash(hash, sizeof(hash), sig, &siglen); + ret = + _signHash(clientContext, hash, sizeof(hash), sig, &siglen); if (ret == WH_ERROR_OK) { int32_t rc = 0; uint8_t sigLabel[WH_NVM_LABEL_LEN] = {0}; @@ -286,11 +292,12 @@ int wh_DemoClient_SecBoot_Boot(whClientContext* clientContext) uint8_t hash[WC_SHA256_DIGEST_SIZE] = {0}; WOLFHSM_CFG_PRINTF("Measuring image %s...\n", file_to_measure); - ret = _sha256File(file_to_measure, hash); + ret = _sha256File(clientContext, file_to_measure, hash); if (ret == WH_ERROR_OK) { WOLFHSM_CFG_PRINTF("SecBoot Client Verifying signature using keyId %u\n", prov_keyId); - ret = _verifyHash(hash, sizeof(hash), sig, siglen, &rc); + ret = _verifyHash(clientContext, hash, sizeof(hash), sig, siglen, + &rc); WOLFHSM_CFG_PRINTF("ecc_verify:%d rc:%d\n", ret, rc); if ((ret == 0) && (rc == 1)) { diff --git a/examples/posix/wh_posix_client/wh_posix_client.c b/examples/posix/wh_posix_client/wh_posix_client.c index 36c5a61bd..1d90ec650 100644 --- a/examples/posix/wh_posix_client/wh_posix_client.c +++ b/examples/posix/wh_posix_client/wh_posix_client.c @@ -144,7 +144,7 @@ static int wh_ClientTask(void* cf, const char* type, int test) /* Context 2: Client Remote Crypto */ memset(buffer, 0, sizeof(buffer)); - wc_InitRng_ex(rng, NULL, WH_DEV_ID); + wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); wc_RNG_GenerateBlock(rng, buffer, sizeof(buffer)); wc_FreeRng(rng); wh_Utils_Hexdump("Context 2: Client Remote RNG:\n", buffer, sizeof(buffer)); diff --git a/src/wh_client.c b/src/wh_client.c index 5c22f58ae..917ddd3ac 100644 --- a/src/wh_client.c +++ b/src/wh_client.c @@ -59,24 +59,53 @@ #include "wolfhsm/wh_message_counter.h" #include "wolfhsm/wh_client.h" +int wh_Client_Init(whClientContext* c, const whClientConfig* config) +{ + int rc = 0; #ifndef WOLFHSM_CFG_NO_CRYPTO -const int WH_DEV_IDS_ARRAY[WH_NUM_DEVIDS] = { - WH_DEV_ID, + /* Track which cryptoCb registrations this Init performed so the failure + * path can unwind exactly those and never disturb table entries it did + * not create. */ + int clientCbRegistered = 0; + int globalCbRegistered = 0; #ifdef WOLFHSM_CFG_DMA - WH_DEV_ID_DMA, + int dmaCbRegistered = 0; #endif /* WOLFHSM_CFG_DMA */ -}; -#endif /* WOLFHSM_CFG_NO_CRYPTO */ +#endif /* !WOLFHSM_CFG_NO_CRYPTO */ -int wh_Client_Init(whClientContext* c, const whClientConfig* config) -{ - int rc = 0; - if((c == NULL) || (config == NULL)) { + /* Client ids are 1..WH_CLIENT_ID_MAX: the id is the keystore user field + * (4 bits, enforced by the server at COMM INIT) */ + if ((c == NULL) || (config == NULL) || (config->comm == NULL) || + (config->comm->client_id == 0) || + (config->comm->client_id > WH_CLIENT_ID_MAX)) { return WH_ERROR_BADARGS; } +#ifndef WOLFHSM_CFG_NO_CRYPTO + /* devId 0 (e.g. uninitialized config field) falls back to the global + * default WH_DEV_ID. Any other value must be positive and must not collide + * with WH_DEV_ID_DMA, which is reserved for the DMA-only callback. */ + if (config->devId < 0) { + return WH_ERROR_BADARGS; + } +#ifdef WOLFHSM_CFG_DMA + /* WH_DEV_ID is valid since it would be used in the default (0) case anyway) + */ + if (config->devId == WH_DEV_ID_DMA) { + return WH_ERROR_BADARGS; + } +#endif /* WOLFHSM_CFG_DMA */ +#endif /* !WOLFHSM_CFG_NO_CRYPTO */ + memset(c, 0, sizeof(*c)); +#ifndef WOLFHSM_CFG_NO_CRYPTO + /* Bind the devId for the life of the context. A nonzero devId also marks + * the context as successfully initialized: the failure path below zeroes + * it again so wh_Client_Cleanup() can tell the two apart. */ + c->devId = (config->devId == 0) ? WH_DEV_ID : config->devId; +#endif /* !WOLFHSM_CFG_NO_CRYPTO */ + rc = wh_CommClient_Init(c->comm, config->comm); #ifndef WOLFHSM_CFG_NO_CRYPTO @@ -86,34 +115,91 @@ int wh_Client_Init(whClientContext* c, const whClientConfig* config) rc = WH_ERROR_ABORTED; } + /* Register the client's configured devId with the unified cryptoCb. + * This runs before the global rebinds below so the most common + * failure (cryptoCb table full) aborts before any global binding is + * touched. When the config selects the default (devId 0 -> + * WH_DEV_ID), the global registration below covers it. */ + if ((rc == 0) && (c->devId != WH_DEV_ID)) { + rc = wc_CryptoCb_RegisterDevice(c->devId, wh_Client_CryptoCb, c); + if (rc != 0) { + rc = WH_ERROR_ABORTED; + } + else { + clientCbRegistered = 1; + } + } + + /* Rebind the global WH_DEV_ID to this context with the unified + * cryptoCb. The registration is process-global and keyed on the + * devId value, so it always routes to the most recently initialized + * client: single-client processes can pass WH_DEV_ID to wolfCrypt + * directly (with DMA dispatch still available via + * wh_Client_SetDmaMode), while multi-client processes must use their + * configured per-client devIds. The explicit unregister keeps the + * rebind working even with a wolfCrypt that rejects duplicate + * registrations. */ if (rc == 0) { - rc = wc_CryptoCb_RegisterDevice(WH_DEV_ID, - wh_Client_CryptoCb, c); + wc_CryptoCb_UnRegisterDevice(WH_DEV_ID); + rc = wc_CryptoCb_RegisterDevice(WH_DEV_ID, wh_Client_CryptoCb, c); if (rc != 0) { rc = WH_ERROR_ABORTED; } + else { + globalCbRegistered = 1; + } + } #ifdef WOLFHSM_CFG_DMA - if (rc == 0) { - /* Initialize DMA configuration and callbacks, if provided */ - if (NULL != config->dmaConfig) { - c->dma.dmaAddrAllowList = - config->dmaConfig->dmaAddrAllowList; - c->dma.cb = config->dmaConfig->cb; - } + /* Initialize DMA configuration and callbacks, if provided. */ + if (rc == 0) { + if (NULL != config->dmaConfig) { + c->dma.dmaAddrAllowList = config->dmaConfig->dmaAddrAllowList; + c->dma.cb = config->dmaConfig->cb; + c->dma.preferDma = config->dmaConfig->preferDma; + } + } - rc = wc_CryptoCb_RegisterDevice(WH_DEV_ID_DMA, - wh_Client_CryptoCbDma, c); - if (rc != 0) { - rc = WH_ERROR_ABORTED; - } + /* Rebind the global WH_DEV_ID_DMA to this context with the DMA-only + * cryptoCb (no standard-path fallback): a single-client convenience, + * exactly as WH_DEV_ID above. */ + if (rc == 0) { + wc_CryptoCb_UnRegisterDevice(WH_DEV_ID_DMA); + rc = wc_CryptoCb_RegisterDevice(WH_DEV_ID_DMA, + wh_Client_CryptoCbDma, c); + if (rc != 0) { + rc = WH_ERROR_ABORTED; + } + else { + dmaCbRegistered = 1; } -#endif /* WOLFHSM_CFG_DMA */ } +#endif /* WOLFHSM_CFG_DMA */ } #endif /* !WOLFHSM_CFG_NO_CRYPTO */ if (rc != 0) { +#ifndef WOLFHSM_CFG_NO_CRYPTO + /* Unwind only the registrations this Init performed, then zero the + * devId to mark the context never-initialized so the Cleanup below + * skips cryptoCb unregistration and leaves table entries owned by + * other contexts alone. In a multi-client process a failed Init can + * still leave the global devIds unregistered (a prior binding cannot + * be queried or restored); the globals are a single-client + * convenience. */ + if (clientCbRegistered != 0) { + wc_CryptoCb_UnRegisterDevice(c->devId); + } + if (globalCbRegistered != 0) { + wc_CryptoCb_UnRegisterDevice(WH_DEV_ID); + } +#ifdef WOLFHSM_CFG_DMA + if (dmaCbRegistered != 0) { + wc_CryptoCb_UnRegisterDevice(WH_DEV_ID_DMA); + } +#endif /* WOLFHSM_CFG_DMA */ + c->devId = 0; +#endif /* !WOLFHSM_CFG_NO_CRYPTO */ wh_Client_Cleanup(c); } return rc; @@ -126,6 +212,21 @@ int wh_Client_Cleanup(whClientContext* c) } #ifndef WOLFHSM_CFG_NO_CRYPTO + /* Unregister this context's cryptoCb entries before dropping the wolfCrypt + * reference. wolfCrypt only clears its fixed-size callback table when the + * process-wide last wolfCrypt_Cleanup runs, so while any other client (or + * wolfCrypt user) remains active a stale entry would otherwise keep its + * table slot and dispatch into this zeroed context. The devId is nonzero + * only on a successfully initialized context (Init zeroes it when + * unwinding a failed init). The global WH_DEV_ID / WH_DEV_ID_DMA entries + * are unregistered unconditionally */ + if (c->devId != 0) { + (void)wc_CryptoCb_UnRegisterDevice(c->devId); + (void)wc_CryptoCb_UnRegisterDevice(WH_DEV_ID); +#ifdef WOLFHSM_CFG_DMA + (void)wc_CryptoCb_UnRegisterDevice(WH_DEV_ID_DMA); +#endif /* WOLFHSM_CFG_DMA */ + } (void)wolfCrypt_Cleanup(); #endif /* !WOLFHSM_CFG_NO_CRYPTO */ @@ -436,6 +537,32 @@ int wh_Client_GetCryptoAffinity(whClientContext* c, uint32_t* out_affinity) return WH_ERROR_OK; } +int wh_Client_SetDmaMode(whClientContext* c, int useDma) +{ + if (c == NULL) { + return WH_ERROR_BADARGS; + } +#ifdef WOLFHSM_CFG_DMA + c->dma.preferDma = (uint32_t)(useDma ? 1 : 0); +#else + (void)useDma; +#endif /* WOLFHSM_CFG_DMA */ + return WH_ERROR_OK; +} + +int wh_Client_GetDmaMode(whClientContext* c, int* out_useDma) +{ + if (c == NULL || out_useDma == NULL) { + return WH_ERROR_BADARGS; + } +#ifdef WOLFHSM_CFG_DMA + *out_useDma = (c->dma.preferDma != 0) ? 1 : 0; +#else + *out_useDma = 0; +#endif /* WOLFHSM_CFG_DMA */ + return WH_ERROR_OK; +} + int wh_Client_CommCloseRequest(whClientContext* c) { diff --git a/src/wh_client_cryptocb.c b/src/wh_client_cryptocb.c index 70e00daa5..11d1d0269 100644 --- a/src/wh_client_cryptocb.c +++ b/src/wh_client_cryptocb.c @@ -76,6 +76,40 @@ static int _handlePqcSigCheckPrivKey(whClientContext* ctx, wc_CryptoInfo* info, #endif /* WOLFSSL_HAVE_MLDSA || HAVE_FALCON */ int wh_Client_CryptoCb(int devId, wc_CryptoInfo* info, void* inCtx) +{ + int ret; + + if ((devId == INVALID_DEVID) || (info == NULL) || (inCtx == NULL)) { + return BAD_FUNC_ARG; + } + +#ifdef WOLFHSM_CFG_DMA + /* If the client prefers DMA operations, dispatch to the DMA callback first + * and fall back to the standard (non-DMA) callback if the algorithm is not + * supported by the DMA callback. */ + if (((whClientContext*)inCtx)->dma.preferDma) { + ret = wh_Client_CryptoCbDma(devId, info, inCtx); + if (ret == CRYPTOCB_UNAVAILABLE) { + ret = wh_Client_CryptoCbStd(devId, info, inCtx); + } + } + else +#endif /* WOLFHSM_CFG_DMA */ + { + /* DMA not preferred (or not compiled in); use the standard callback */ + ret = wh_Client_CryptoCbStd(devId, info, inCtx); + } + + /* Propagate the error unchanged so if the algo is unsupported + * (CRYPTOCB_UNAVAILABLE), wolfCrypt can fall back to its default + * (software) implementation for operations wolfHSM does not offload. + * Eventually we want this to be a hard error, but there are edge cases + * around compound operations that need to be carefully handled and may + * require changes to wolfCrypt to successfully facilitate. */ + return ret; +} + +int wh_Client_CryptoCbStd(int devId, wc_CryptoInfo* info, void* inCtx) { /* III When possible, return wolfCrypt-enumerated errors */ int ret = CRYPTOCB_UNAVAILABLE; diff --git a/test-refactor/client-server/wh_test_crypto_aes.c b/test-refactor/client-server/wh_test_crypto_aes.c index 12a1e4d06..066358ed5 100644 --- a/test-refactor/client-server/wh_test_crypto_aes.c +++ b/test-refactor/client-server/wh_test_crypto_aes.c @@ -19,7 +19,8 @@ /* * test-refactor/client-server/wh_test_crypto_aes.c * - * AES round-trips routed through the server via WH_DEV_ID. Covers CBC, CTR, + * AES round-trips routed through the server via the per-client devId + * (WH_CLIENT_DEVID). Covers CBC, CTR, * ECB, and GCM in both client-side-key and HSM-cached-key forms, plus the * AES-CBC streaming request/response API. Under a WOLFHSM_CFG_DMA build the * wc_Aes* calls dispatch to the *Dma wrappers via the cryptocb. @@ -1018,9 +1019,18 @@ int whTest_CryptoAesKeyUsagePolicies(whClientContext* ctx) int whTest_Crypto_Aes(whClientContext* ctx) { - /* AES round-trips dispatch through the cryptocb, so run on every devId to - * cover both the normal and DMA server transports. */ - WH_TEST_FOREACH_DEVID(whTest_CryptoAesImpl(ctx, devId)); + int i; + + /* AES round-trips dispatch through the cryptocb, so run once per dispatch + * mode on the per-client devId to cover both the normal and DMA server + * paths. */ + for (i = 0; i < WH_TEST_DMA_MODE_CNT; i++) { + (void)wh_Client_SetDmaMode(ctx, i); + WH_TEST_RETURN_ON_FAIL( + whTest_CryptoAesImpl(ctx, WH_CLIENT_DEVID(ctx))); + } + (void)wh_Client_SetDmaMode(ctx, 0); + #ifdef HAVE_AES_CBC /* CBC streaming drives the request/response API directly (INVALID_DEVID), * so it is not devId-routed -- run it once. */ diff --git a/test-refactor/client-server/wh_test_crypto_cmac.c b/test-refactor/client-server/wh_test_crypto_cmac.c index bd2990acb..d31ac2622 100644 --- a/test-refactor/client-server/wh_test_crypto_cmac.c +++ b/test-refactor/client-server/wh_test_crypto_cmac.c @@ -364,9 +364,16 @@ static int whTest_CryptoCmacImpl(whClientContext* ctx, int devId) int whTest_Crypto_Cmac(whClientContext* ctx) { - /* CMAC dispatches through the cryptocb, so run on every devId to cover both - * the normal and DMA server transports. */ - WH_TEST_FOREACH_DEVID(whTest_CryptoCmacImpl(ctx, devId)); + int i; + + /* CMAC dispatches through the cryptocb, so run once per dispatch mode on + * the per-client devId to cover both the normal and DMA server paths. */ + for (i = 0; i < WH_TEST_DMA_MODE_CNT; i++) { + (void)wh_Client_SetDmaMode(ctx, i); + WH_TEST_RETURN_ON_FAIL( + whTest_CryptoCmacImpl(ctx, WH_CLIENT_DEVID(ctx))); + } + (void)wh_Client_SetDmaMode(ctx, 0); return 0; } #endif /* WOLFSSL_CMAC && !NO_AES && WOLFSSL_AES_DIRECT */ diff --git a/test-refactor/client-server/wh_test_crypto_curve25519.c b/test-refactor/client-server/wh_test_crypto_curve25519.c index ab3b7f141..a72a8a4c0 100644 --- a/test-refactor/client-server/wh_test_crypto_curve25519.c +++ b/test-refactor/client-server/wh_test_crypto_curve25519.c @@ -19,7 +19,8 @@ /* * test-refactor/client-server/wh_test_crypto_curve25519.c * - * Curve25519 ECDH round-trips routed through the server via WH_DEV_ID, + * Curve25519 ECDH round-trips routed through the server via the per-client + * devId (WH_CLIENT_DEVID), * across ephemeral / server-export / server-cache key paths. */ @@ -46,7 +47,7 @@ #ifdef HAVE_CURVE25519 static int _whTest_CryptoCurve25519(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; WC_RNG rng[1]; curve25519_key key_a[1] = {0}; @@ -67,7 +68,7 @@ static int _whTest_CryptoCurve25519(whClientContext* ctx) return ret; } - /* Test 1: ephemeral wolfCrypt keys via WH_DEV_ID */ + /* Test 1: ephemeral wolfCrypt keys via the per-client devId */ ret = wc_curve25519_init_ex(key_a, NULL, devId); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_curve25519_init_ex %d\n", ret); @@ -247,7 +248,7 @@ static int _whTest_CryptoCurve25519(whClientContext* ctx) * wh_Client_Curve25519ExportPublicKey). */ static int _whTest_CryptoCurve25519ExportPublicKey(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; WC_RNG rng[1]; curve25519_key hsmPub[1] = {0}; diff --git a/test-refactor/client-server/wh_test_crypto_ecc.c b/test-refactor/client-server/wh_test_crypto_ecc.c index 08903968f..28962a60b 100644 --- a/test-refactor/client-server/wh_test_crypto_ecc.c +++ b/test-refactor/client-server/wh_test_crypto_ecc.c @@ -19,7 +19,8 @@ /* * test-refactor/client-server/wh_test_crypto_ecc.c * - * ECC tests routed through the server via WH_DEV_ID: + * ECC tests routed through the server via the per-client devId + * (WH_CLIENT_DEVID): * _whTest_CryptoEcc - ECDH + ECDSA across ephemeral / export / * cache key paths * _whTest_CryptoEccCacheDuplicate - cache slot replacement semantics @@ -51,7 +52,7 @@ #if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) && defined(HAVE_ECC_VERIFY) /* Full coverage of ECDH + ECDSA across the three key-management paths: - * - ephemeral wolfCrypt keys with WH_DEV_ID + * - ephemeral wolfCrypt keys with the per-client devId * - server-generated keys exported back to the client * - server-cached keys referenced via keyId */ #define TEST_ECC_KEYSIZE 32 @@ -59,7 +60,7 @@ static int _whTest_CryptoEcc(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = WH_ERROR_OK; WC_RNG rng[1]; ecc_key bobKey[1]; @@ -166,12 +167,12 @@ static int _whTest_CryptoEcc(whClientContext* ctx) memset(shared_ba, 0, sizeof(shared_ba)); memset(sig, 0, sizeof(sig)); - ret = wc_ecc_init_ex(bobKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(bobKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_ecc_init_ex for export key %d\n", ret); } else { - ret = wc_ecc_init_ex(aliceKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(aliceKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_ecc_init_ex for export key %d\n", ret); @@ -269,7 +270,7 @@ static int _whTest_CryptoEcc(whClientContext* ctx) WH_ERROR_PRINT("Failed to wh_Client_EccMakeCacheKey %d\n", ret); } if (ret == 0) { - ret = wc_ecc_init_ex(bobKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(bobKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_ecc_init_ex for cache key %d\n", ret); @@ -301,7 +302,7 @@ static int _whTest_CryptoEcc(whClientContext* ctx) } } if (ret == 0) { - ret = wc_ecc_init_ex(aliceKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(aliceKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT( "Failed to wc_ecc_init_ex for peer key %d\n", ret); @@ -442,7 +443,7 @@ static int _whTest_CryptoEccCacheDuplicate(whClientContext* ctx) * verify the signature client-side. */ static int _whTest_CryptoEccExportPublicKey(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; WC_RNG rng[1]; ecc_key hsmKey[1]; @@ -588,7 +589,7 @@ static int whTest_CryptoEccCrossVerify_OneCurve(whClientContext* ctx, pubYLen = keySize; /* Test 1: HSM sign + Software verify */ - ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(hsmKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("%s: Failed to init HSM key: %d\n", name, ret); } @@ -697,7 +698,7 @@ static int whTest_CryptoEccCrossVerify_OneCurve(whClientContext* ctx, } } if (ret == 0) { - ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(hsmKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("%s: Failed to init HSM key: %d\n", name, ret); } @@ -742,7 +743,7 @@ static int whTest_CryptoEccCrossVerify_OneCurve(whClientContext* ctx, static int _whTest_CryptoEccCrossVerify(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = WH_ERROR_OK; WC_RNG rng[1]; @@ -818,7 +819,7 @@ static int whTest_CryptoEccSignVerifyAsync_OneCurve(whClientContext* ctx, pubXLen = keySize; pubYLen = keySize; - ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(hsmKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret == 0) { hsmKeyInit = 1; ret = wc_ecc_make_key(rng, keySize, hsmKey); @@ -1076,7 +1077,7 @@ static int whTest_CryptoEccSharedSecretAsync_OneCurve(whClientContext* ctx, pubAxLen = pubAyLen = pubBxLen = pubByLen = keySize; - ret = wc_ecc_init_ex(keyA, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(keyA, NULL, WH_CLIENT_DEVID(ctx)); if (ret == 0) { keyAInit = 1; ret = wc_ecc_make_key(rng, keySize, keyA); @@ -1089,7 +1090,7 @@ static int whTest_CryptoEccSharedSecretAsync_OneCurve(whClientContext* ctx, sizeof(privLabelA), privLabelA); } if (ret == 0) { - ret = wc_ecc_init_ex(keyB, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(keyB, NULL, WH_CLIENT_DEVID(ctx)); } if (ret == 0) { keyBInit = 1; @@ -1555,7 +1556,7 @@ static int whTest_CryptoEccMakeKeyAsync_OneCurve(whClientContext* ctx, static int _whTest_CryptoEccAsync(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = WH_ERROR_OK; WC_RNG rng[1]; @@ -1654,7 +1655,7 @@ static int _whTest_CryptoEccExportPublicKeyDma(whClientContext* ctx) uint8_t derBuf[256]; uint16_t derSz = sizeof(derBuf); - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -1675,7 +1676,7 @@ static int _whTest_CryptoEccExportPublicKeyDma(whClientContext* ctx) /* Sign on the server with the cached private key. */ if (ret == 0) { ecc_key hsmKey[1]; - ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(hsmKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret == 0) { ret = wh_Client_EccSetKeyId(hsmKey, keyId); } diff --git a/test-refactor/client-server/wh_test_crypto_ed25519.c b/test-refactor/client-server/wh_test_crypto_ed25519.c index 1491f846b..63ab0937a 100644 --- a/test-refactor/client-server/wh_test_crypto_ed25519.c +++ b/test-refactor/client-server/wh_test_crypto_ed25519.c @@ -19,7 +19,8 @@ /* * test-refactor/client-server/wh_test_crypto_ed25519.c * - * Ed25519 sign/verify routed through the server via WH_DEV_ID: + * Ed25519 sign/verify routed through the server via the per-client devId + * (WH_CLIENT_DEVID): * _whTest_CryptoEd25519Inline - pure wolfCrypt (sign+verify locally, * plus negative case for tampered sig) * _whTest_CryptoEd25519ServerKey - server-cached sign and verify keyIds @@ -131,7 +132,7 @@ static int whTest_Ed25519ImportToServer(whClientContext* ctx, int devId, static int _whTest_CryptoEd25519Inline(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; WC_RNG rng[1]; ed25519_key key[1] = {0}; @@ -238,7 +239,7 @@ static int _whTest_CryptoEd25519Inline(whClientContext* ctx) static int _whTest_CryptoEd25519ServerKey(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; WC_RNG rng[1]; ed25519_key key[1] = {0}; @@ -362,7 +363,7 @@ static int _whTest_CryptoEd25519ServerKey(whClientContext* ctx) #ifdef WOLFHSM_CFG_DMA static int _whTest_CryptoEd25519Dma(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; WC_RNG rng[1]; ed25519_key key[1] = {0}; @@ -467,7 +468,7 @@ static int _whTest_CryptoEd25519Dma(whClientContext* ctx) * verify the signature client-side. */ static int _whTest_CryptoEd25519ExportPublicKey(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; ed25519_key hsmKey[1] = {0}; ed25519_key pubKey[1] = {0}; @@ -565,7 +566,7 @@ static int _whTest_CryptoEd25519ExportPublicKey(whClientContext* ctx) * return WH_ERROR_BUFFER_SIZE and report the required signature length. */ static int _whTest_CryptoEd25519BufferTooSmall(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret; WC_RNG rng[1]; ed25519_key key[1]; diff --git a/test-refactor/client-server/wh_test_crypto_kdf.c b/test-refactor/client-server/wh_test_crypto_kdf.c index 0fbe5db9e..b23ede013 100644 --- a/test-refactor/client-server/wh_test_crypto_kdf.c +++ b/test-refactor/client-server/wh_test_crypto_kdf.c @@ -55,7 +55,7 @@ static int _whTest_CryptoHkdf(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = WH_ERROR_OK; whKeyId keyId = WH_KEYID_ERASED; @@ -219,7 +219,7 @@ static int _whTest_CryptoHkdf(whClientContext* ctx) static int _whTest_CryptoCmacKdf(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = WH_ERROR_OK; whKeyId keyId = WH_KEYID_ERASED; diff --git a/test-refactor/client-server/wh_test_crypto_keypolicy.c b/test-refactor/client-server/wh_test_crypto_keypolicy.c index 9602cd41d..07a1919a4 100644 --- a/test-refactor/client-server/wh_test_crypto_keypolicy.c +++ b/test-refactor/client-server/wh_test_crypto_keypolicy.c @@ -55,7 +55,7 @@ static int _whTest_CryptoKeyUsagePolicies(whClientContext* client) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(client); int ret = 0; WC_RNG rng[1]; uint8_t plaintext[16] = {0}; @@ -100,7 +100,7 @@ static int _whTest_CryptoKeyUsagePolicies(whClientContext* client) (uint8_t*)"aes-no-enc", strlen("aes-no-enc"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -143,7 +143,7 @@ static int _whTest_CryptoKeyUsagePolicies(whClientContext* client) (uint8_t*)"aes-enc-only", strlen("aes-enc-only"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -164,7 +164,7 @@ static int _whTest_CryptoKeyUsagePolicies(whClientContext* client) client, WH_NVM_FLAGS_USAGE_ENCRYPT, (uint8_t*)"aes-no-dec", strlen("aes-no-dec"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -212,7 +212,7 @@ static int _whTest_CryptoKeyUsagePolicies(whClientContext* client) client, 32, ECC_SECP256R1, &keyId, WH_NVM_FLAGS_NONE, strlen("ecc-no-sign"), (uint8_t*)"ecc-no-sign"); if (ret == 0) { - ret = wc_ecc_init_ex(eccKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(eccKey, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wc_ecc_set_curve(eccKey, 32, ECC_SECP256R1); if (ret == 0) { @@ -260,7 +260,7 @@ static int _whTest_CryptoKeyUsagePolicies(whClientContext* client) client, 32, ECC_SECP256R1, &keyId, WH_NVM_FLAGS_NONE, strlen("ecc-no-derive"), (uint8_t*)"ecc-no-derive"); if (ret == 0) { - ret = wc_ecc_init_ex(privKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(privKey, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wc_ecc_set_curve(privKey, 32, ECC_SECP256R1); if (ret == 0) { @@ -372,13 +372,13 @@ static int _whTest_CryptoKeyUsagePolicies(whClientContext* client) } if (ret == 0) { ret = wc_InitCmac_ex(&cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, - WH_DEV_ID); + WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_CmacSetKeyId(&cmac, cmacKeyId); if (ret == 0) { ret = wc_AesCmacGenerate_ex(&cmac, tag, &tagLen, message, sizeof(message), NULL, 0, NULL, - WH_DEV_ID); + WH_CLIENT_DEVID(client)); if (ret == WH_ERROR_USAGE) { WH_TEST_PRINT( " PASS: Correctly denied CMAC generate\n"); @@ -421,13 +421,13 @@ static int _whTest_CryptoKeyUsagePolicies(whClientContext* client) } if (ret == 0) { ret = wc_InitCmac_ex(&cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, - WH_DEV_ID); + WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_CmacSetKeyId(&cmac, cmacKeyId); if (ret == 0) { ret = wc_AesCmacVerify_ex(&cmac, tag, tagLen, message, sizeof(message), NULL, 0, NULL, - WH_DEV_ID); + WH_CLIENT_DEVID(client)); if (ret == WH_ERROR_USAGE) { WH_TEST_PRINT( " PASS: Correctly denied CMAC verify\n"); @@ -524,7 +524,7 @@ static int whTest_RevocationTryAESEncrypt(whKeyId keyId, WC_RNG* rng, ret); return ret; } - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_ERROR_PRINT("Failed to init AES for revoked key test: %d\n", ret); return ret; @@ -551,7 +551,7 @@ static int whTest_RevocationTryAESEncrypt(whKeyId keyId, WC_RNG* rng, static int _whTest_CryptoKeyRevocationAesCbc(whClientContext* client) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(client); int ret = 0; WC_RNG rng[1]; uint8_t key[32] = {0}; @@ -692,6 +692,9 @@ static int _whTest_CryptoKeyRevocationAesCbc(whClientContext* client) int whTest_Crypto_KeyPolicy(whClientContext* ctx) { + /* A preceding suite may leave the DMA-preferred dispatch mode set; reset + * to the std path so this suite runs the same way in every config. */ + (void)wh_Client_SetDmaMode(ctx, 0); WH_TEST_RETURN_ON_FAIL(_whTest_CryptoKeyUsagePolicies(ctx)); #if !defined(NO_AES) && defined(HAVE_AES_CBC) && \ defined(WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS) diff --git a/test-refactor/client-server/wh_test_crypto_mldsa.c b/test-refactor/client-server/wh_test_crypto_mldsa.c index d37454ff8..4b69738bd 100644 --- a/test-refactor/client-server/wh_test_crypto_mldsa.c +++ b/test-refactor/client-server/wh_test_crypto_mldsa.c @@ -57,7 +57,7 @@ static int _whTest_CryptoMlDsaClient(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; MlDsaKey key[1]; @@ -175,7 +175,7 @@ static int _whTest_CryptoMlDsaClient(whClientContext* ctx) * wh_Client_MlDsaExportPublicKey returns a public-only key struct. */ static int _whTest_CryptoMlDsaExportPublicKey(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; MlDsaKey pub[1] = {0}; whKeyId keyId = WH_KEYID_ERASED; @@ -240,7 +240,7 @@ static int _whTest_CryptoMlDsaExportPublicKey(whClientContext* ctx) #ifdef WOLFHSM_CFG_DMA static int _whTest_CryptoMlDsaDmaClient(whClientContext* ctx) { - int devId = WH_DEV_ID_DMA; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; MlDsaKey key[1]; MlDsaKey imported_key[1]; @@ -443,7 +443,7 @@ static int _whTest_CryptoMlDsaDmaClient(whClientContext* ctx) * public-only key. */ static int _whTest_CryptoMlDsaExportPublicKeyDma(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = 0; MlDsaKey pub[1] = {0}; whKeyId keyId = WH_KEYID_ERASED; @@ -516,7 +516,7 @@ static int _whTest_CryptoMlDsaExportPublicKeyDma(whClientContext* ctx) defined(WOLFHSM_CFG_DMA) static int _whTest_CryptoMlDsaVerifyOnlyDma(whClientContext* ctx) { - int devId = WH_DEV_ID_DMA; + int devId = WH_CLIENT_DEVID(ctx); /* Vectors from wolfCrypt test vectors, but decoupled for isolated usage */ const byte ml_dsa_44_pub_key[] = { @@ -883,10 +883,15 @@ static int _whTest_CryptoMlDsaVerifyOnlyDma(whClientContext* ctx) whNvmId keyId = WH_KEYID_ERASED; int evictKey = 0; + /* DMA-only test: prefer DMA dispatch so the wolfCrypt verify below routes + * through the DMA path. */ + (void)wh_Client_SetDmaMode(ctx, 1); + /* Initialize keys */ ret = wc_MlDsaKey_Init(key, NULL, devId); if (ret != 0) { WH_ERROR_PRINT("Failed to initialize ML-DSA key: %d\n", ret); + (void)wh_Client_SetDmaMode(ctx, 0); return ret; } else { @@ -910,14 +915,10 @@ static int _whTest_CryptoMlDsaVerifyOnlyDma(whClientContext* ctx) WH_ERROR_PRINT("Failed to import ML-DSA public key: %d\n", ret); } } - /* Import the key into wolfHSM via the wolfCrypt structure */ + /* Import the key into wolfHSM via the wolfCrypt structure. This is the + * DMA-only verify test, so always import via the DMA path. */ if (ret == 0) { - if (devId == WH_DEV_ID_DMA) { - ret = wh_Client_MlDsaImportKeyDma(ctx, key, &keyId, 0, 0, NULL); - } - else { - ret = wh_Client_MlDsaImportKey(ctx, key, &keyId, 0, 0, NULL); - } + ret = wh_Client_MlDsaImportKeyDma(ctx, key, &keyId, 0, 0, NULL); if (ret == WH_ERROR_OK) { evictKey = 1; } @@ -956,6 +957,8 @@ static int _whTest_CryptoMlDsaVerifyOnlyDma(whClientContext* ctx) WH_TEST_PRINT("ML-DSA VERIFY ONLY: SUCCESS\n"); } + /* Restore the standard (non-DMA) dispatch mode */ + (void)wh_Client_SetDmaMode(ctx, 0); return ret; } #endif /* !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && \ @@ -968,9 +971,9 @@ static int _whTest_CryptoMlDsaVerifyOnlyDma(whClientContext* ctx) /* * ML-DSA exercised through the plain wolfCrypt API (wc_MlDsaKey_MakeKey / * SignCtx / VerifyCtx), which dispatches through the cryptocb. PQC keygen/ - * sign/verify is handled by both the normal and DMA cryptocbs, so the entry - * point loops this over every devId. Complements the wh_Client_MlDsa* - * direct-API tests above. + * sign/verify is handled by both the standard and DMA dispatch paths, so the + * entry point loops this over every dispatch mode. Complements the + * wh_Client_MlDsa* direct-API tests above. */ static int whTest_CryptoMlDsaWolfCryptImpl(whClientContext* ctx, int devId) { @@ -983,9 +986,7 @@ static int whTest_CryptoMlDsaWolfCryptImpl(whClientContext* ctx, int devId) byte sig[DILITHIUM_MAX_SIG_SIZE]; word32 sigSz = sizeof(sig); - (void)ctx; - - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -1065,7 +1066,7 @@ static int whTest_CryptoMlDsaWolfCryptImpl(whClientContext* ctx, int devId) * WH_ERROR_BUFFER_SIZE and report a required length greater than the buffer. */ static int _whTest_CryptoMlDsaBufferTooSmall(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret; MlDsaKey key[1]; const byte msg[] = "ml-dsa buf size test"; @@ -1125,10 +1126,19 @@ int whTest_Crypto_MlDsa(whClientContext* ctx) #if !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && \ !defined(WOLFSSL_DILITHIUM_NO_SIGN) && \ !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) && !defined(WOLFSSL_NO_ML_DSA_44) + int i; + /* Plain wolfCrypt-API ML-DSA dispatches through the cryptocb; PQC is - * handled by both the normal and DMA cryptocbs, so loop over every devId. - * The wh_Client_MlDsa* direct-API tests below run on their own devIds. */ - WH_TEST_FOREACH_DEVID(whTest_CryptoMlDsaWolfCryptImpl(ctx, devId)); + * handled by both the standard and DMA dispatch paths, so loop over every + * dispatch mode. The wh_Client_MlDsa* direct-API tests below manage the + * dispatch mode themselves. */ + for (i = 0; i < WH_TEST_DMA_MODE_CNT; i++) { + (void)wh_Client_SetDmaMode(ctx, i); + WH_TEST_RETURN_ON_FAIL( + whTest_CryptoMlDsaWolfCryptImpl(ctx, WH_CLIENT_DEVID(ctx))); + } + (void)wh_Client_SetDmaMode(ctx, 0); + WH_TEST_RETURN_ON_FAIL(_whTest_CryptoMlDsaClient(ctx)); WH_TEST_RETURN_ON_FAIL(_whTest_CryptoMlDsaExportPublicKey(ctx)); WH_TEST_RETURN_ON_FAIL(_whTest_CryptoMlDsaBufferTooSmall(ctx)); diff --git a/test-refactor/client-server/wh_test_crypto_rng.c b/test-refactor/client-server/wh_test_crypto_rng.c index f2e05960e..779bd70af 100644 --- a/test-refactor/client-server/wh_test_crypto_rng.c +++ b/test-refactor/client-server/wh_test_crypto_rng.c @@ -362,9 +362,23 @@ static int _whTest_CryptoRngDmaAsync(whClientContext* ctx) int whTest_Crypto_Rng(whClientContext* ctx) { - /* Synchronous wolfCrypt RNG dispatches through the cryptocb, so run it on - * every devId to cover both the normal and DMA server transports. */ - WH_TEST_FOREACH_DEVID(whTest_CryptoRngImpl(ctx, devId)); + int i; + + /* Synchronous wolfCrypt RNG dispatches through the cryptocb, so run it + * once per dispatch mode on the per-client devId to cover both the normal + * and DMA server paths. */ + for (i = 0; i < WH_TEST_DMA_MODE_CNT; i++) { + int dmaMode = -1; + (void)wh_Client_SetDmaMode(ctx, i); + /* Round-trip the dispatch mode through the getter (reports 0 in + * non-DMA builds, where this loop only runs mode 0) */ + WH_TEST_RETURN_ON_FAIL(wh_Client_GetDmaMode(ctx, &dmaMode)); + WH_TEST_ASSERT_RETURN(dmaMode == i); + WH_TEST_RETURN_ON_FAIL( + whTest_CryptoRngImpl(ctx, WH_CLIENT_DEVID(ctx))); + } + (void)wh_Client_SetDmaMode(ctx, 0); + /* The explicit request/response primitives are transport-specific * (comm-buffer vs DMA), not devId-routed -- run each once. */ WH_TEST_RETURN_ON_FAIL(_whTest_CryptoRngAsync(ctx)); diff --git a/test-refactor/client-server/wh_test_crypto_rsa.c b/test-refactor/client-server/wh_test_crypto_rsa.c index dfcc896a0..e859e7f7c 100644 --- a/test-refactor/client-server/wh_test_crypto_rsa.c +++ b/test-refactor/client-server/wh_test_crypto_rsa.c @@ -19,7 +19,8 @@ /* * test-refactor/client-server/wh_test_crypto_rsa.c * - * RSA encrypt/decrypt round-trips routed through the server via WH_DEV_ID: + * RSA encrypt/decrypt round-trips routed through the server via the + * per-client devId (WH_CLIENT_DEVID): * ephemeral key, server-exported key, and server-cached key paths. */ @@ -52,7 +53,7 @@ static int _whTest_CryptoRsa(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = WH_ERROR_OK; WC_RNG rng[1]; RsaKey rsa[1]; @@ -109,7 +110,7 @@ static int _whTest_CryptoRsa(whClientContext* ctx) /* Using client export key */ memset(cipherText, 0, sizeof(cipherText)); memset(finalText, 0, sizeof(finalText)); - ret = wc_InitRsaKey_ex(rsa, NULL, WH_DEV_ID); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRsaKey_ex %d\n", ret); } @@ -158,7 +159,7 @@ static int _whTest_CryptoRsa(whClientContext* ctx) WH_ERROR_PRINT("Failed to make cached key %d\n", ret); } else { - ret = wc_InitRsaKey_ex(rsa, NULL, WH_DEV_ID); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRsaKey_ex %d\n", ret); } @@ -217,7 +218,7 @@ static int _whTest_CryptoRsa(whClientContext* ctx) * trip proves the exported public key matches the cached private. */ static int _whTest_CryptoRsaExportPublicKey(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret = WH_ERROR_OK; WC_RNG rng[1]; RsaKey rsaPub[1]; @@ -324,7 +325,7 @@ static int _whTest_CryptoRsaExportPublicKey(whClientContext* ctx) /* Exercises wh_Client_RsaFunction with an undersized output buffer. */ static int _whTest_CryptoRsaBufferTooSmall(whClientContext* ctx) { - const int devId = WH_DEV_ID; + const int devId = WH_CLIENT_DEVID(ctx); const int rsa_key_bits = 2048; const int rsa_key_bytes = rsa_key_bits / 8; int ret; diff --git a/test-refactor/client-server/wh_test_crypto_sha.c b/test-refactor/client-server/wh_test_crypto_sha.c index 38f9b4a42..f9377eab1 100644 --- a/test-refactor/client-server/wh_test_crypto_sha.c +++ b/test-refactor/client-server/wh_test_crypto_sha.c @@ -19,7 +19,8 @@ /* * test-refactor/client-server/wh_test_crypto_sha.c * - * SHA-224 / 256 / 384 / 512 routed through the server via WH_DEV_ID. + * SHA-224 / 256 / 384 / 512 routed through the server via the per-client + * devId (WH_CLIENT_DEVID). * Each hash size has four variants: * whTest_CryptoSha sync wolfCrypt API single+multi block * whTest_CryptoShaLargeInput sync test with input larger than the @@ -571,7 +572,7 @@ static int _whTest_CryptoSha256(whClientContext* ctx, int devId) int ret; WC_RNG rng[1]; - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -586,7 +587,7 @@ static int _whTest_CryptoSha256LargeInput(whClientContext* ctx, int devId) int ret; WC_RNG rng[1]; - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -598,7 +599,7 @@ static int _whTest_CryptoSha256LargeInput(whClientContext* ctx, int devId) static int _whTest_CryptoSha256Async(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret; WC_RNG rng[1]; @@ -615,17 +616,23 @@ static int _whTest_CryptoSha256Async(whClientContext* ctx) #ifdef WOLFHSM_CFG_DMA static int _whTest_CryptoSha256DmaAsync(whClientContext* ctx) { - int devId = WH_DEV_ID_DMA; + int devId = WH_CLIENT_DEVID(ctx); int ret; WC_RNG rng[1]; + /* Prefer DMA dispatch so wolfCrypt-routed ops take the DMA path alongside + * the wh_Client_*Dma request API driven by the Impl. */ + (void)wh_Client_SetDmaMode(ctx, 1); ret = wc_InitRng_ex(rng, NULL, devId); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); + (void)wh_Client_SetDmaMode(ctx, 0); return ret; } ret = whTest_CryptoSha256DmaAsyncImpl(ctx, devId, rng); (void)wc_FreeRng(rng); + /* Restore the standard (non-DMA) dispatch mode */ + (void)wh_Client_SetDmaMode(ctx, 0); return ret; } #endif /* WOLFHSM_CFG_DMA */ @@ -1152,7 +1159,7 @@ static int _whTest_CryptoSha224(whClientContext* ctx, int devId) int ret; WC_RNG rng[1]; - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -1167,7 +1174,7 @@ static int _whTest_CryptoSha224LargeInput(whClientContext* ctx, int devId) int ret; WC_RNG rng[1]; - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -1179,7 +1186,7 @@ static int _whTest_CryptoSha224LargeInput(whClientContext* ctx, int devId) static int _whTest_CryptoSha224Async(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret; WC_RNG rng[1]; @@ -1196,17 +1203,23 @@ static int _whTest_CryptoSha224Async(whClientContext* ctx) #ifdef WOLFHSM_CFG_DMA static int _whTest_CryptoSha224DmaAsync(whClientContext* ctx) { - int devId = WH_DEV_ID_DMA; + int devId = WH_CLIENT_DEVID(ctx); int ret; WC_RNG rng[1]; + /* Prefer DMA dispatch so wolfCrypt-routed ops take the DMA path alongside + * the wh_Client_*Dma request API driven by the Impl. */ + (void)wh_Client_SetDmaMode(ctx, 1); ret = wc_InitRng_ex(rng, NULL, devId); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); + (void)wh_Client_SetDmaMode(ctx, 0); return ret; } ret = whTest_CryptoSha224DmaAsyncImpl(ctx, devId, rng); (void)wc_FreeRng(rng); + /* Restore the standard (non-DMA) dispatch mode */ + (void)wh_Client_SetDmaMode(ctx, 0); return ret; } #endif /* WOLFHSM_CFG_DMA */ @@ -1738,7 +1751,7 @@ static int _whTest_CryptoSha384(whClientContext* ctx, int devId) int ret; WC_RNG rng[1]; - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -1753,7 +1766,7 @@ static int _whTest_CryptoSha384LargeInput(whClientContext* ctx, int devId) int ret; WC_RNG rng[1]; - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -1765,7 +1778,7 @@ static int _whTest_CryptoSha384LargeInput(whClientContext* ctx, int devId) static int _whTest_CryptoSha384Async(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret; WC_RNG rng[1]; @@ -1782,17 +1795,23 @@ static int _whTest_CryptoSha384Async(whClientContext* ctx) #ifdef WOLFHSM_CFG_DMA static int _whTest_CryptoSha384DmaAsync(whClientContext* ctx) { - int devId = WH_DEV_ID_DMA; + int devId = WH_CLIENT_DEVID(ctx); int ret; WC_RNG rng[1]; + /* Prefer DMA dispatch so wolfCrypt-routed ops take the DMA path alongside + * the wh_Client_*Dma request API driven by the Impl. */ + (void)wh_Client_SetDmaMode(ctx, 1); ret = wc_InitRng_ex(rng, NULL, devId); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); + (void)wh_Client_SetDmaMode(ctx, 0); return ret; } ret = whTest_CryptoSha384DmaAsyncImpl(ctx, devId, rng); (void)wc_FreeRng(rng); + /* Restore the standard (non-DMA) dispatch mode */ + (void)wh_Client_SetDmaMode(ctx, 0); return ret; } #endif /* WOLFHSM_CFG_DMA */ @@ -2328,7 +2347,7 @@ static int _whTest_CryptoSha512(whClientContext* ctx, int devId) int ret; WC_RNG rng[1]; - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -2343,7 +2362,7 @@ static int _whTest_CryptoSha512LargeInput(whClientContext* ctx, int devId) int ret; WC_RNG rng[1]; - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; @@ -2355,7 +2374,7 @@ static int _whTest_CryptoSha512LargeInput(whClientContext* ctx, int devId) static int _whTest_CryptoSha512Async(whClientContext* ctx) { - int devId = WH_DEV_ID; + int devId = WH_CLIENT_DEVID(ctx); int ret; WC_RNG rng[1]; @@ -2372,62 +2391,94 @@ static int _whTest_CryptoSha512Async(whClientContext* ctx) #ifdef WOLFHSM_CFG_DMA static int _whTest_CryptoSha512DmaAsync(whClientContext* ctx) { - int devId = WH_DEV_ID_DMA; + int devId = WH_CLIENT_DEVID(ctx); int ret; WC_RNG rng[1]; + /* Prefer DMA dispatch so wolfCrypt-routed ops take the DMA path alongside + * the wh_Client_*Dma request API driven by the Impl. */ + (void)wh_Client_SetDmaMode(ctx, 1); ret = wc_InitRng_ex(rng, NULL, devId); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); + (void)wh_Client_SetDmaMode(ctx, 0); return ret; } ret = whTest_CryptoSha512DmaAsyncImpl(ctx, devId, rng); (void)wc_FreeRng(rng); + /* Restore the standard (non-DMA) dispatch mode */ + (void)wh_Client_SetDmaMode(ctx, 0); return ret; } #endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFSSL_SHA512 */ +/* Run the synchronous (devId-routed) hash tests for every compiled SHA + * algorithm against the given devId. */ +static int _whTest_CryptoShaImpl(whClientContext* ctx, int devId) +{ +#ifdef WOLFSSL_SHA224 + WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha224(ctx, devId)); + WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha224LargeInput(ctx, devId)); +#endif +#ifndef NO_SHA256 + WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha256(ctx, devId)); + WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha256LargeInput(ctx, devId)); +#endif +#ifdef WOLFSSL_SHA384 + WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha384(ctx, devId)); + WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha384LargeInput(ctx, devId)); +#endif +#ifdef WOLFSSL_SHA512 + WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha512(ctx, devId)); + WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha512LargeInput(ctx, devId)); +#endif + (void)ctx; + (void)devId; + return 0; +} + int whTest_Crypto_Sha(whClientContext* ctx) { + int i; + /* Synchronous hashing (plain + large input) dispatches through the - * cryptocb, so run it on every devId to cover the normal and DMA server - * transports. The explicit request/response suites are transport-specific - * (comm-buffer Async vs DmaAsync), not devId-routed -- run each once. */ + * cryptocb, so run it once per dispatch mode on the per-client devId to + * cover the normal and DMA server paths. The explicit request/response + * suites are transport-specific (comm-buffer Async vs DmaAsync), not + * devId-routed -- run each once. */ + for (i = 0; i < WH_TEST_DMA_MODE_CNT; i++) { + (void)wh_Client_SetDmaMode(ctx, i); + WH_TEST_RETURN_ON_FAIL( + _whTest_CryptoShaImpl(ctx, WH_CLIENT_DEVID(ctx))); + } + (void)wh_Client_SetDmaMode(ctx, 0); + #ifdef WOLFSSL_SHA224 - WH_TEST_FOREACH_DEVID(_whTest_CryptoSha224(ctx, devId)); - WH_TEST_FOREACH_DEVID(_whTest_CryptoSha224LargeInput(ctx, devId)); WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha224Async(ctx)); #ifdef WOLFHSM_CFG_DMA WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha224DmaAsync(ctx)); #endif #endif #ifndef NO_SHA256 - WH_TEST_FOREACH_DEVID(_whTest_CryptoSha256(ctx, devId)); - WH_TEST_FOREACH_DEVID(_whTest_CryptoSha256LargeInput(ctx, devId)); WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha256Async(ctx)); #ifdef WOLFHSM_CFG_DMA WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha256DmaAsync(ctx)); #endif #endif #ifdef WOLFSSL_SHA384 - WH_TEST_FOREACH_DEVID(_whTest_CryptoSha384(ctx, devId)); - WH_TEST_FOREACH_DEVID(_whTest_CryptoSha384LargeInput(ctx, devId)); WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha384Async(ctx)); #ifdef WOLFHSM_CFG_DMA WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha384DmaAsync(ctx)); #endif #endif #ifdef WOLFSSL_SHA512 - WH_TEST_FOREACH_DEVID(_whTest_CryptoSha512(ctx, devId)); - WH_TEST_FOREACH_DEVID(_whTest_CryptoSha512LargeInput(ctx, devId)); WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha512Async(ctx)); #ifdef WOLFHSM_CFG_DMA WH_TEST_RETURN_ON_FAIL(_whTest_CryptoSha512DmaAsync(ctx)); #endif #endif - (void)ctx; return 0; } diff --git a/test-refactor/misc/wh_test_client_devid.c b/test-refactor/misc/wh_test_client_devid.c new file mode 100644 index 000000000..5c5568c2a --- /dev/null +++ b/test-refactor/misc/wh_test_client_devid.c @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2026 wolfSSL Inc. + * + * This file is part of wolfHSM. + * + * wolfHSM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfHSM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wolfHSM. If not, see . + */ + +/* + * test-refactor/misc/wh_test_client_devid.c + * + * Client devId registration lifecycle. Equivalent coverage to + * test/wh_test_multiclient.c::whTest_MultiClientDevIdLifecycle. + * + * wh_Client_Init registers the client's devIds in wolfCrypt's process-global, + * fixed-size cryptoCb table and wh_Client_Cleanup must unregister them: the + * table is only reset when the last wolfCrypt user in the process cleans up, + * so a leaked entry both consumes a table slot and keeps dispatching into the + * dead client context. Every Init rebinds the global WH_DEV_ID (and + * WH_DEV_ID_DMA with DMA) to its own context and additionally registers the + * configured devId when it differs from WH_DEV_ID; any client's Cleanup + * unregisters the globals. These tests observe table occupancy through the + * only public accessors (Register/UnRegister) by counting how many throwaway + * registrations fit before the table is full. + */ + +#include "wolfhsm/wh_settings.h" + +#if defined(WOLFHSM_CFG_ENABLE_CLIENT) && !defined(WOLFHSM_CFG_NO_CRYPTO) && \ + defined(WOLF_CRYPTO_CB) + +#include +#include +#include + +#include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/wolfcrypt/types.h" +#include "wolfssl/wolfcrypt/cryptocb.h" + +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_comm.h" +#include "wolfhsm/wh_transport_mem.h" +#include "wolfhsm/wh_client.h" + +#include "wh_test_common.h" +#include "wh_test_list.h" + +#define BUFFER_SIZE 4096 + +/* Throwaway devId base for probing free cryptoCb table slots ("WHT\0"+i). + * Outside the global devIds (WH_DEV_ID / WH_DEV_ID_DMA), the custom test + * devIds, and the fill range below. */ +#define PROBE_DEV_ID_BASE 0x57485400 +/* Upper bound on probed slots. Must be >= wolfCrypt's + * MAX_CRYPTO_DEVID_CALLBACKS (internal to cryptocb.c; default 8). */ +#define PROBE_MAX_SLOTS 128 + +/* Separate devId base ("WHU\0"+i) for table-fill entries that stay + * registered while _countFreeCryptoCbSlots() runs: wolfCrypt re-registration + * of an existing devId reuses its entry, so fill ids must never collide with + * the probe ids or the count comes back wrong (and the counter's + * unregistration pass would tear the fill entries down). */ +#define FILL_DEV_ID_BASE 0x57485500 + +/* Global devIds rebound by every wh_Client_Init: WH_DEV_ID, plus + * WH_DEV_ID_DMA when DMA support is compiled in. Their table slots are + * shared by all clients in the process (each Init rebinds the same + * entries). */ +#ifdef WOLFHSM_CFG_DMA +#define GLOBAL_DEVID_COUNT 2 +#else +#define GLOBAL_DEVID_COUNT 1 +#endif + +/* Slots consumed by one wh_Client_Init with a custom (non-default) devId on + * an otherwise unoccupied table: the globals plus the configured devId */ +#define DEVIDS_PER_INIT (GLOBAL_DEVID_COUNT + 1) + +/* Custom per-client devIds for the two-client cases ("WH"+n). Distinct from + * WH_DEV_ID, WH_DEV_ID_DMA, and the probe range. */ +#define TEST_DEVID_1 0x57480001 +#define TEST_DEVID_2 0x57480002 + +static int _probeCryptoCb(int devId, wc_CryptoInfo* info, void* ctx) +{ + (void)devId; + (void)info; + (void)ctx; + return CRYPTOCB_UNAVAILABLE; +} + +/* Count free slots in the cryptoCb table by registering throwaway devIds + * until registration fails, then unregistering them all. */ +static int _countFreeCryptoCbSlots(void) +{ + int count = 0; + int i; + + for (i = 0; i < PROBE_MAX_SLOTS; i++) { + if (wc_CryptoCb_RegisterDevice(PROBE_DEV_ID_BASE + i, _probeCryptoCb, + NULL) != 0) { + break; + } + count++; + } + for (i = 0; i < count; i++) { + wc_CryptoCb_UnRegisterDevice(PROBE_DEV_ID_BASE + i); + } + return count; +} + +static int _whTest_ClientDevIdLifecycle(void) +{ + int slotsBase = 0; + int slots = 0; + int rc = 0; + int i = 0; + + /* Client transports: no servers needed, registration lifecycle only */ + static uint8_t req1[BUFFER_SIZE]; + static uint8_t resp1[BUFFER_SIZE]; + whTransportMemConfig tmcf1[1] = {{ + .req = (whTransportMemCsr*)req1, + .req_size = sizeof(req1), + .resp = (whTransportMemCsr*)resp1, + .resp_size = sizeof(resp1), + }}; + + whTransportClientCb tccb1[1] = {WH_TRANSPORT_MEM_CLIENT_CB}; + whTransportMemClientContext tmcc1[1] = {0}; + whCommClientConfig cc_conf1[1] = {{ + .transport_cb = tccb1, + .transport_context = (void*)tmcc1, + .transport_config = (void*)tmcf1, + .client_id = WH_TEST_DEFAULT_CLIENT_ID, + }}; + whClientContext client1[1] = {0}; + whClientConfig c_conf1[1] = {{ + .comm = cc_conf1, + }}; + + static uint8_t req2[BUFFER_SIZE]; + static uint8_t resp2[BUFFER_SIZE]; + whTransportMemConfig tmcf2[1] = {{ + .req = (whTransportMemCsr*)req2, + .req_size = sizeof(req2), + .resp = (whTransportMemCsr*)resp2, + .resp_size = sizeof(resp2), + }}; + + whTransportClientCb tccb2[1] = {WH_TRANSPORT_MEM_CLIENT_CB}; + whTransportMemClientContext tmcc2[1] = {0}; + whCommClientConfig cc_conf2[1] = {{ + .transport_cb = tccb2, + .transport_context = (void*)tmcc2, + .transport_config = (void*)tmcf2, + .client_id = WH_TEST_DEFAULT_CLIENT_ID + 1, + }}; + whClientContext client2[1] = {0}; + whClientConfig c_conf2[1] = {{ + .comm = cc_conf2, + }}; + + /* Client ids outside 1..WH_CLIENT_ID_MAX are rejected before any + * initialization */ + cc_conf1[0].client_id = 0; + WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS == wh_Client_Init(client1, c_conf1)); + cc_conf1[0].client_id = WH_CLIENT_ID_MAX + 1; + WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS == wh_Client_Init(client1, c_conf1)); + cc_conf1[0].client_id = WH_TEST_DEFAULT_CLIENT_ID; + + /* Negative devIds and (with DMA) the reserved WH_DEV_ID_DMA are + * rejected before any initialization */ + c_conf1[0].devId = -1; + WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS == wh_Client_Init(client1, c_conf1)); +#ifdef WOLFHSM_CFG_DMA + c_conf1[0].devId = WH_DEV_ID_DMA; + WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS == wh_Client_Init(client1, c_conf1)); +#endif /* WOLFHSM_CFG_DMA */ + c_conf1[0].devId = 0; + + /* Hold an app-level wolfCrypt reference for the whole test so the + * cryptoCb table is never reset by a final wolfCrypt_Cleanup: any entry + * a client leaks stays visible, as it would in a process with other + * active wolfCrypt users. */ + WH_TEST_RETURN_ON_FAIL(wolfCrypt_Init()); + + slotsBase = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slotsBase >= GLOBAL_DEVID_COUNT + 2); + + /* A config that leaves devId 0 binds the default WH_DEV_ID; only the + * global devIds occupy table slots */ + WH_TEST_RETURN_ON_FAIL(wh_Client_Init(client1, c_conf1)); + WH_TEST_ASSERT_RETURN(WH_CLIENT_DEVID(client1) == WH_DEV_ID); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - GLOBAL_DEVID_COUNT); + + /* Cleanup must release every slot Init consumed even though wolfCrypt + * stays initialized (the app still holds a reference) */ + WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase); + + /* Re-init with the same config must succeed and register again */ + WH_TEST_RETURN_ON_FAIL(wh_Client_Init(client1, c_conf1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - GLOBAL_DEVID_COUNT); + WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase); + + /* A custom configured devId is registered alongside the globals */ + c_conf1[0].devId = TEST_DEVID_1; + WH_TEST_RETURN_ON_FAIL(wh_Client_Init(client1, c_conf1)); + WH_TEST_ASSERT_RETURN(WH_CLIENT_DEVID(client1) == TEST_DEVID_1); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - DEVIDS_PER_INIT); + + /* Two simultaneously active clients with distinct devIds: the second + * Init rebinds the shared global entries (net zero new slots) and adds + * only its own devId */ + c_conf2[0].devId = TEST_DEVID_2; + WH_TEST_RETURN_ON_FAIL(wh_Client_Init(client2, c_conf2)); + WH_TEST_ASSERT_RETURN(WH_CLIENT_DEVID(client2) == TEST_DEVID_2); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - DEVIDS_PER_INIT - 1); + + /* Cleaning up one client releases its own devId and the shared global + * devIds -- the globals are yanked from the still-active sibling, which + * is the documented single-client contract for WH_DEV_ID/WH_DEV_ID_DMA. + * The sibling's own configured devId stays registered. */ + WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - 1); + + /* Re-init the first client while the second stays active: the globals + * are rebound and both custom devIds are live again */ + WH_TEST_RETURN_ON_FAIL(wh_Client_Init(client1, c_conf1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - DEVIDS_PER_INIT - 1); + + WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client2)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - 1); + + WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase); + c_conf1[0].devId = 0; + c_conf2[0].devId = 0; + + /* Init with a full cryptoCb table must fail cleanly (WH_ERROR_ABORTED) + * and the failure-path cleanup must not disturb existing entries */ + for (i = 0; i < slotsBase; i++) { + WH_TEST_RETURN_ON_FAIL(wc_CryptoCb_RegisterDevice( + FILL_DEV_ID_BASE + i, _probeCryptoCb, NULL)); + } + rc = wh_Client_Init(client1, c_conf1); + WH_TEST_ASSERT_RETURN(rc == WH_ERROR_ABORTED); + WH_TEST_ASSERT_RETURN(WH_CLIENT_DEVID(client1) == 0); + for (i = 0; i < slotsBase; i++) { + wc_CryptoCb_UnRegisterDevice(FILL_DEV_ID_BASE + i); + } + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase); + + /* Init that fails partway through its registrations (the custom devId + * fits, but a later global rebind hits the full table) must unwind + * exactly the entries it registered and leave the fill entries intact */ + for (i = 0; i < slotsBase - (DEVIDS_PER_INIT - 1); i++) { + WH_TEST_RETURN_ON_FAIL(wc_CryptoCb_RegisterDevice( + FILL_DEV_ID_BASE + i, _probeCryptoCb, NULL)); + } + c_conf1[0].devId = TEST_DEVID_1; + rc = wh_Client_Init(client1, c_conf1); + WH_TEST_ASSERT_RETURN(rc == WH_ERROR_ABORTED); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == DEVIDS_PER_INIT - 1); + for (i = 0; i < slotsBase - (DEVIDS_PER_INIT - 1); i++) { + wc_CryptoCb_UnRegisterDevice(FILL_DEV_ID_BASE + i); + } + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase); + c_conf1[0].devId = 0; + + (void)wolfCrypt_Cleanup(); + + return 0; +} + +int whTest_ClientDevId(void* ctx) +{ + (void)ctx; + + WH_TEST_PRINT("Testing client devId registration lifecycle...\n"); + WH_TEST_RETURN_ON_FAIL(_whTest_ClientDevIdLifecycle()); + + return WH_ERROR_OK; +} + +#endif /* WOLFHSM_CFG_ENABLE_CLIENT && !WOLFHSM_CFG_NO_CRYPTO && \ + * WOLF_CRYPTO_CB */ diff --git a/test-refactor/posix/Makefile b/test-refactor/posix/Makefile index 4a1247462..63284b326 100644 --- a/test-refactor/posix/Makefile +++ b/test-refactor/posix/Makefile @@ -152,6 +152,9 @@ ifeq ($(TESTWOLFCRYPT),1) TESTWOLFCRYPT_DEVID ?= $(TESTWOLFCRYPT_DEFAULT_DEVID) + # The wolfCrypt test suite drives the HSM through the always-registered + # global devIds (TESTWOLFCRYPT_DEVID defaults to WH_DEV_ID; + # TESTWOLFCRYPT_DMA uses WH_DEV_ID_DMA). DEF += -DWC_USE_DEVID=$(TESTWOLFCRYPT_DEVID) # wolfCrypt test source files diff --git a/test-refactor/wh_test_list.c b/test-refactor/wh_test_list.c index 3d1d2b50c..98c7df2d9 100644 --- a/test-refactor/wh_test_list.c +++ b/test-refactor/wh_test_list.c @@ -36,6 +36,7 @@ #include "wh_test_list.h" /* Test declarations and weak skip implementations. */ +WH_TEST_DECL(whTest_ClientDevId); WH_TEST_DECL(whTest_Comm); WH_TEST_DECL(whTest_Dma); WH_TEST_DECL(whTest_KeystoreReqSize); @@ -59,9 +60,10 @@ WH_TEST_DECL(whTest_ServerInfo); WH_TEST_DECL(whTest_WolfCryptTest); const whTestCase whTestsMisc[] = { - { "whTest_Comm", whTest_Comm }, - { "whTest_Dma", whTest_Dma }, - { "whTest_KeystoreReqSize", whTest_KeystoreReqSize }, + {"whTest_ClientDevId", whTest_ClientDevId}, + {"whTest_Comm", whTest_Comm}, + {"whTest_Dma", whTest_Dma}, + {"whTest_KeystoreReqSize", whTest_KeystoreReqSize}, }; const size_t whTestsMiscCount = sizeof(whTestsMisc) / sizeof(whTestsMisc[0]); diff --git a/test/Makefile b/test/Makefile index c26cf030d..ed2bbed88 100644 --- a/test/Makefile +++ b/test/Makefile @@ -241,7 +241,9 @@ ifeq ($(TESTWOLFCRYPT),1) # Set default TESTWOLFCRYPT_DEVID if not defined by the user TESTWOLFCRYPT_DEVID ?= $(TESTWOLFCRYPT_DEFAULT_DEVID) - # Set the defines for WC_USE_DEVID + # Set the defines for WC_USE_DEVID. The wolfCrypt test suite drives the + # HSM through the always-registered global devIds (TESTWOLFCRYPT_DEVID + # defaults to WH_DEV_ID; TESTWOLFCRYPT_DMA uses WH_DEV_ID_DMA). DEF += -DWC_USE_DEVID=$(TESTWOLFCRYPT_DEVID) # wolfCrypt test source files diff --git a/test/wh_test_common.h b/test/wh_test_common.h index 53cd38958..e9d836616 100644 --- a/test/wh_test_common.h +++ b/test/wh_test_common.h @@ -82,21 +82,20 @@ } \ } while (0) - -/* - * Helper macro to run a test on each devId. - * Only applicable to tests which use the cryptocb and use the devID arg. - * "Call" should be of the form "whTest_Func(ctx, devId)". Second arg must - * be named "devId". - */ -#define WH_TEST_FOREACH_DEVID(call) \ - do { \ - int idx; \ - for (idx = 0; idx < WH_NUM_DEVIDS; idx++) { \ - int devId = WH_DEV_IDS_ARRAY[idx]; \ - WH_TEST_RETURN_ON_FAIL(call); \ - } \ - } while (0) +/* Number of cryptoCb dispatch modes the test suites exercise on the client + * devId. With DMA compiled in we run the relevant tests twice -- once with + * the standard (non-DMA) path (preferDma=0) and once with DMA preferred + * (preferDma=1) -- toggling the client context via wh_Client_SetDmaMode(). + * Without DMA there is only the std path. The test configs leave + * whClientConfig.devId 0, so WH_CLIENT_DEVID resolves to the default global + * WH_DEV_ID. The DMA-only WH_DEV_ID_DMA is exercised by running the + * wolfCrypt test suite against it (TESTWOLFCRYPT=1 defaults WC_USE_DEVID to + * WH_DEV_ID; TESTWOLFCRYPT_DMA=1 uses WH_DEV_ID_DMA). */ +#ifdef WOLFHSM_CFG_DMA +#define WH_TEST_DMA_MODE_CNT 2 +#else +#define WH_TEST_DMA_MODE_CNT 1 +#endif /* * Helper macro for test error propagation diff --git a/test/wh_test_crypto.c b/test/wh_test_crypto.c index d8ab4d1ae..7ee9e348f 100644 --- a/test/wh_test_crypto.c +++ b/test/wh_test_crypto.c @@ -492,7 +492,7 @@ static int whTest_CryptoRsa(whClientContext* ctx, int devId, WC_RNG* rng) /* Using client export key */ memset(cipherText, 0, sizeof(cipherText)); memset(finalText, 0, sizeof(finalText)); - ret = wc_InitRsaKey_ex(rsa, NULL, WH_DEV_ID); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(ctx)); if (ret!= 0) { WH_ERROR_PRINT("Failed to wc_InitRsaKey_ex %d\n", ret); } else { @@ -534,7 +534,7 @@ static int whTest_CryptoRsa(whClientContext* ctx, int devId, WC_RNG* rng) if (ret != 0) { WH_ERROR_PRINT("Failed to make cached key %d\n", ret); } else { - ret = wc_InitRsaKey_ex(rsa, NULL, WH_DEV_ID); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRsaKey_ex %d\n", ret); } else { @@ -643,7 +643,8 @@ static int whTest_CryptoRsa(whClientContext* ctx, int devId, WC_RNG* rng) ret = encLen; } else { - ret = wc_InitRsaKey_ex(rsaFull, NULL, WH_DEV_ID); + ret = wc_InitRsaKey_ex(rsaFull, NULL, + WH_CLIENT_DEVID(ctx)); if (ret == 0) { ret = wh_Client_RsaSetKeyId(rsaFull, pubOnlyId); } @@ -986,7 +987,7 @@ static int whTest_CryptoRsaAsync(whClientContext* ctx, WC_RNG* rng) /* 9) RsaMakeExportKey async: server generates ephemeral key, returns DER. */ if (ret == WH_ERROR_OK) { - ret = wc_InitRsaKey_ex(rsa, NULL, WH_DEV_ID); + ret = wc_InitRsaKey_ex(rsa, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("wc_InitRsaKey_ex failed: %d\n", ret); } @@ -1155,12 +1156,12 @@ static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng) memset(shared_ba, 0, sizeof(shared_ba)); memset(sig, 0, sizeof(sig)); - ret = wc_ecc_init_ex(bobKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(bobKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_ecc_init_ex for export key %d\n", ret); } else { - ret = wc_ecc_init_ex(aliceKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(aliceKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_ecc_init_ex for export key %d\n", ret); @@ -1262,7 +1263,7 @@ static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng) } if (ret == 0) { /* Init the cached key struct and associate with server key ID */ - ret = wc_ecc_init_ex(bobKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(bobKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_ecc_init_ex for cache key %d\n", ret); @@ -1297,7 +1298,7 @@ static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng) } /* Create ephemeral peer key for ECDH test */ if (ret == 0) { - ret = wc_ecc_init_ex(aliceKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(aliceKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT( "Failed to wc_ecc_init_ex for peer key %d\n", ret); @@ -1523,7 +1524,7 @@ static int whTest_CryptoEccExportPublicDma(whClientContext* ctx, int devId, /* Sign on HSM with the cached private key (non-DMA cryptoCb). */ if (ret == 0) { ecc_key hsmKey[1]; - ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(hsmKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret == 0) { ret = wh_Client_EccSetKeyId(hsmKey, keyId); } @@ -1674,7 +1675,7 @@ static int whTest_CryptoEccCrossVerify_OneCurve(whClientContext* ctx, pubYLen = keySize; /* Test 1: HSM sign + Software verify */ - ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(hsmKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("%s: Failed to init HSM key: %d\n", name, ret); } @@ -1791,7 +1792,7 @@ static int whTest_CryptoEccCrossVerify_OneCurve(whClientContext* ctx, } if (ret == 0) { /* Import public key into HSM key for verification */ - ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(hsmKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret != 0) { WH_ERROR_PRINT("%s: Failed to init HSM key: %d\n", name, ret); } @@ -1923,7 +1924,7 @@ static int whTest_CryptoEccSignVerifyAsync_OneCurve(whClientContext* ctx, pubXLen = keySize; pubYLen = keySize; - ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(hsmKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret == 0) { hsmKeyInit = 1; ret = wc_ecc_make_key(rng, keySize, hsmKey); @@ -2203,7 +2204,7 @@ static int whTest_CryptoEccSharedSecretAsync_OneCurve(whClientContext* ctx, /* Generate two local ECC keys, then import each to the server cache so * that both private keys have valid keyIds usable by the async API. */ - ret = wc_ecc_init_ex(keyA, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(keyA, NULL, WH_CLIENT_DEVID(ctx)); if (ret == 0) { keyAInit = 1; ret = wc_ecc_make_key(rng, keySize, keyA); @@ -2216,7 +2217,7 @@ static int whTest_CryptoEccSharedSecretAsync_OneCurve(whClientContext* ctx, sizeof(privLabelA), privLabelA); } if (ret == 0) { - ret = wc_ecc_init_ex(keyB, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(keyB, NULL, WH_CLIENT_DEVID(ctx)); } if (ret == 0) { keyBInit = 1; @@ -2507,7 +2508,7 @@ static int whTest_CryptoEccSharedSecretCacheKey_OneCurve(whClientContext* ctx, pubBxLen = pubByLen = keySize; /* Generate two keys A and B, then import both private and public halves */ - ret = wc_ecc_init_ex(keyA, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(keyA, NULL, WH_CLIENT_DEVID(ctx)); if (ret == 0) { keyAInit = 1; ret = wc_ecc_make_key(rng, keySize, keyA); @@ -2519,7 +2520,7 @@ static int whTest_CryptoEccSharedSecretCacheKey_OneCurve(whClientContext* ctx, ctx, keyA, &privAId, WH_NVM_FLAGS_USAGE_DERIVE, sizeof(lbl), lbl); } if (ret == 0) { - ret = wc_ecc_init_ex(keyB, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(keyB, NULL, WH_CLIENT_DEVID(ctx)); } if (ret == 0) { keyBInit = 1; @@ -3454,7 +3455,7 @@ static int whTest_CryptoEd25519ExportPublic(whClientContext* ctx, int devId, /* Sign on HSM */ if (ret == 0) { - ret = wc_ed25519_init_ex(hsmKey, NULL, WH_DEV_ID); + ret = wc_ed25519_init_ex(hsmKey, NULL, WH_CLIENT_DEVID(ctx)); if (ret == 0) { ret = wh_Client_Ed25519SetKeyId(hsmKey, keyId); } @@ -12128,14 +12129,10 @@ int whTestCrypto_MlDsaVerifyOnlyDma(whClientContext* ctx, int devId, WH_ERROR_PRINT("Failed to import ML-DSA public key: %d\n", ret); } } - /* Import the key into wolfHSM via the wolfCrypt structure */ + /* Import the key into wolfHSM via the wolfCrypt structure. This is the + * DMA-only verify test, so always import via the DMA path. */ if (ret == 0) { - if (devId == WH_DEV_ID_DMA) { - ret = wh_Client_MlDsaImportKeyDma(ctx, key, &keyId, 0, 0, NULL); - } - else { - ret = wh_Client_MlDsaImportKey(ctx, key, &keyId, 0, 0, NULL); - } + ret = wh_Client_MlDsaImportKeyDma(ctx, key, &keyId, 0, 0, NULL); if (ret == WH_ERROR_OK) { evictKey = 1; } @@ -13254,7 +13251,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) key, keyLen, &keyId); if (ret == 0) { /* Initialize AES with HSM device ID */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { /* Set the cached keyId (not raw key material) */ ret = wh_Client_AesSetKeyId(aes, keyId); @@ -13300,7 +13297,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"aes-enc-only", strlen("aes-enc-only"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13326,7 +13323,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) &keyId); if (ret == 0) { /* Initialize AES with HSM device ID */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { /* Set the cached keyId */ ret = wh_Client_AesSetKeyId(aes, keyId); @@ -13375,7 +13372,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"ctr-no-enc", strlen("ctr-no-enc"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13415,7 +13412,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"ctr-no-dec", strlen("ctr-no-dec"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13456,7 +13453,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"ecb-no-enc", strlen("ecb-no-enc"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13492,7 +13489,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"ecb-no-dec", strlen("ecb-no-dec"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13532,7 +13529,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"gcm-no-enc", strlen("gcm-no-enc"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13572,7 +13569,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"gcm-no-dec", strlen("gcm-no-dec"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13614,7 +13611,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"dctr-no-enc", strlen("dctr-no-enc"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13654,7 +13651,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"dctr-no-dec", strlen("dctr-no-dec"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13695,7 +13692,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"decb-no-enc", strlen("decb-no-enc"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13731,7 +13728,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"decb-no-dec", strlen("decb-no-dec"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13770,7 +13767,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"dcbc-no-enc", strlen("dcbc-no-enc"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13810,7 +13807,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"dcbc-no-dec", strlen("dcbc-no-dec"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13853,7 +13850,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"dgcm-no-enc", strlen("dgcm-no-enc"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13894,7 +13891,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) (uint8_t*)"dgcm-no-dec", strlen("dgcm-no-dec"), key, keyLen, &keyId); if (ret == 0) { - ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wh_Client_AesSetKeyId(aes, keyId); if (ret == 0) { @@ -13944,7 +13941,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) strlen("ecc-no-sign"), (uint8_t*)"ecc-no-sign"); if (ret == 0) { /* Initialize ecc_key with HSM device ID and set curve */ - ret = wc_ecc_init_ex(eccKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(eccKey, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wc_ecc_set_curve(eccKey, 32, ECC_SECP256R1); if (ret == 0) { @@ -13996,7 +13993,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) strlen("ecc-no-derive"), (uint8_t*)"ecc-no-derive"); if (ret == 0) { /* Initialize private key with HSM device ID and set curve */ - ret = wc_ecc_init_ex(privKey, NULL, WH_DEV_ID); + ret = wc_ecc_init_ex(privKey, NULL, WH_CLIENT_DEVID(client)); if (ret == 0) { ret = wc_ecc_set_curve(privKey, 32, ECC_SECP256R1); if (ret == 0) { @@ -14119,7 +14116,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) if (ret == 0) { /* Initialize CMAC with HSM device ID */ ret = wc_InitCmac_ex(&cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, - WH_DEV_ID); + WH_CLIENT_DEVID(client)); if (ret == 0) { /* Associate cached key */ ret = wh_Client_CmacSetKeyId(&cmac, keyId); @@ -14127,7 +14124,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) /* Try to generate CMAC - should fail */ ret = wc_AesCmacGenerate_ex(&cmac, tag, &tagLen, message, sizeof(message), NULL, 0, NULL, - WH_DEV_ID); + WH_CLIENT_DEVID(client)); if (ret == WH_ERROR_USAGE) { WH_TEST_PRINT(" PASS: Correctly denied CMAC generate\n"); ret = 0; /* Test passed */ @@ -14172,7 +14169,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) if (ret == 0) { /* Initialize CMAC with HSM device ID */ ret = wc_InitCmac_ex(&cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, - WH_DEV_ID); + WH_CLIENT_DEVID(client)); if (ret == 0) { /* Associate cached key */ ret = wh_Client_CmacSetKeyId(&cmac, keyId); @@ -14180,7 +14177,7 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) /* Try to verify CMAC - should fail */ ret = wc_AesCmacVerify_ex(&cmac, tag, tagLen, message, sizeof(message), NULL, 0, NULL, - WH_DEV_ID); + WH_CLIENT_DEVID(client)); if (ret == WH_ERROR_USAGE) { WH_TEST_PRINT(" PASS: Correctly denied CMAC verify\n"); ret = 0; /* Test passed */ @@ -14258,7 +14255,8 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) #if !defined(NO_AES) && defined(HAVE_AES_CBC) && \ defined(WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS) -int _testRevocationTryAESEncrypt(whKeyId keyId, WC_RNG* rng, int* encryptRes) +int _testRevocationTryAESEncrypt(whClientContext* client, whKeyId keyId, + WC_RNG* rng, int* encryptRes) { int ret; Aes aes[1]; @@ -14276,7 +14274,7 @@ int _testRevocationTryAESEncrypt(whKeyId keyId, WC_RNG* rng, int* encryptRes) return ret; } /* try to encrypt with the given keyId */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_ERROR_PRINT("Failed to init AES for revoked key test: %d\n", ret); return ret; @@ -14333,7 +14331,7 @@ int whTest_CryptoKeyRevocationAesCbc(whClientContext* client, WC_RNG* rng) } /* encrypt should work */ - ret = _testRevocationTryAESEncrypt(keyId, rng, &encryptRes); + ret = _testRevocationTryAESEncrypt(client, keyId, rng, &encryptRes); if (ret != 0) { WH_ERROR_PRINT("Failed to encrypt with unrevoked AES key: %d\n", ret); @@ -14355,7 +14353,7 @@ int whTest_CryptoKeyRevocationAesCbc(whClientContext* client, WC_RNG* rng) } /* now encrypt should fail */ - ret = _testRevocationTryAESEncrypt(keyId, rng, &encryptRes); + ret = _testRevocationTryAESEncrypt(client, keyId, rng, &encryptRes); if (ret != 0 || encryptRes != WH_ERROR_USAGE) { WH_ERROR_PRINT( "Encrypt with revoked AES key should fail (%d), got %d\n", @@ -14371,7 +14369,7 @@ int whTest_CryptoKeyRevocationAesCbc(whClientContext* client, WC_RNG* rng) } /* keep failing */ - ret = _testRevocationTryAESEncrypt(keyId, rng, &encryptRes); + ret = _testRevocationTryAESEncrypt(client, keyId, rng, &encryptRes); if (ret != 0 || encryptRes != WH_ERROR_USAGE) { WH_ERROR_PRINT( "Encrypt with revoked AES key should fail (%d), got %d\n", @@ -14402,7 +14400,7 @@ int whTest_CryptoKeyRevocationAesCbc(whClientContext* client, WC_RNG* rng) return ret; } /* try encrypt first */ - ret = _testRevocationTryAESEncrypt(keyId, rng, &encryptRes); + ret = _testRevocationTryAESEncrypt(client, keyId, rng, &encryptRes); if (ret != 0 || encryptRes != 0) { WH_ERROR_PRINT("Failed to encrypt with unrevoked AES key (2nd " "time): %d\n", @@ -14423,7 +14421,7 @@ int whTest_CryptoKeyRevocationAesCbc(whClientContext* client, WC_RNG* rng) return ret; } /* this should still fail */ - ret = _testRevocationTryAESEncrypt(keyId, rng, &encryptRes); + ret = _testRevocationTryAESEncrypt(client, keyId, rng, &encryptRes); if (ret != 0 || encryptRes != WH_ERROR_USAGE) { WH_ERROR_PRINT( "Encrypt with revoked AES key should fail (%d), got %d\n", @@ -14441,6 +14439,9 @@ int whTest_CryptoKeyRevocationAesCbc(whClientContext* client, WC_RNG* rng) #endif /* !NO_AES && HAVE_AES_CBC && \ WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS */ +/* WH_TEST_DMA_MODE_CNT (number of cryptoCb dispatch modes to exercise) is + * provided by wh_test_common.h */ + int whTest_CryptoClientConfig(whClientConfig* config) { int i; @@ -14478,11 +14479,26 @@ int whTest_CryptoClientConfig(whClientConfig* config) } #endif /* WOLFHSM_CFG_DEBUG_VERBOSE */ - /* First crypto test should be of RNG so we can iterate over and test all - * devIds before choosing one to run the rest of the tests on */ + /* Run RNG first, exercising each DMA dispatch mode (std and, when compiled, + * DMA-preferred) on the single per-client devId before the remaining tests + * settle on a default mode. */ i = 0; - while ((ret == WH_ERROR_OK) && (i < WH_NUM_DEVIDS)) { - ret = whTest_CryptoRng(client, WH_DEV_IDS_ARRAY[i], rng); + while ((ret == WH_ERROR_OK) && (i < WH_TEST_DMA_MODE_CNT)) { + int dmaMode = -1; + /* Exercise RNG through both dispatch modes (std and, if compiled, + * DMA-preferred) on the single per-client devId. */ + (void)wh_Client_SetDmaMode(client, i); + /* Round-trip the dispatch mode through the getter (reports 0 in + * non-DMA builds, where this loop only runs mode 0) */ + ret = wh_Client_GetDmaMode(client, &dmaMode); + if ((ret == WH_ERROR_OK) && (dmaMode != i)) { + WH_ERROR_PRINT("GetDmaMode returned %d after SetDmaMode(%d)\n", + dmaMode, i); + ret = WH_ERROR_ABORTED; + } + if (ret == WH_ERROR_OK) { + ret = whTest_CryptoRng(client, WH_CLIENT_DEVID(client), rng); + } if (ret == WH_ERROR_OK) { wc_FreeRng(rng); i++; @@ -14490,7 +14506,7 @@ int whTest_CryptoClientConfig(whClientConfig* config) } /* Direct exercise of the async RNG primitives (does not go through the - * wolfCrypt callback path, so devId is not relevant). */ + * wolfCrypt callback path, so DMA mode is not relevant). */ if (ret == WH_ERROR_OK) { ret = whTest_CryptoRngAsync(client); } @@ -14500,11 +14516,12 @@ int whTest_CryptoClientConfig(whClientConfig* config) } #endif /* WOLFHSM_CFG_DMA */ - /* Now that we have tested all RNG devIds, reinitialize the default RNG - * devId (non-DMA) that will be used by the remainder of the tests for - * random input generation */ + /* The remaining once-run tests below historically used the non-DMA devId; + * select the std (non-DMA) dispatch mode for them. Reinitialize the default + * RNG used by the rest of the tests for random input generation. */ if (ret == 0) { - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + (void)wh_Client_SetDmaMode(client, 0); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_ERROR_PRINT("Failed to reinitialize RNG %d\n", ret); } @@ -14515,12 +14532,13 @@ int whTest_CryptoClientConfig(whClientConfig* config) if (ret == 0) { /* Test Key Cache functions */ - ret = whTest_KeyCache(client, WH_DEV_ID, rng); + ret = whTest_KeyCache(client, WH_CLIENT_DEVID(client), rng); } if (ret == 0) { /* Test Non-Exportable Flag enforcement on keystore */ - ret = whTest_NonExportableKeystore(client, WH_DEV_ID, rng); + ret = + whTest_NonExportableKeystore(client, WH_CLIENT_DEVID(client), rng); } if (ret == 0) { @@ -14539,49 +14557,57 @@ int whTest_CryptoClientConfig(whClientConfig* config) #ifndef NO_AES i = 0; - while ((ret == WH_ERROR_OK) && (i < WH_NUM_DEVIDS)) { - ret = whTestCrypto_Aes(client, WH_DEV_IDS_ARRAY[i], rng); + while ((ret == WH_ERROR_OK) && (i < WH_TEST_DMA_MODE_CNT)) { + (void)wh_Client_SetDmaMode(client, i); + ret = whTestCrypto_Aes(client, WH_CLIENT_DEVID(client), rng); if (ret == WH_ERROR_OK) { - ret = whTest_CryptoAesAsync(client, WH_DEV_IDS_ARRAY[i], rng); + ret = whTest_CryptoAesAsync(client, WH_CLIENT_DEVID(client), rng); } if (ret == WH_ERROR_OK) { - ret = whTest_CryptoAesAsyncKat(client, WH_DEV_IDS_ARRAY[i]); + ret = whTest_CryptoAesAsyncKat(client, WH_CLIENT_DEVID(client)); } if (ret == WH_ERROR_OK) { i++; } } #ifdef WOLFHSM_CFG_DMA + /* Dedicated async DMA tests drive the wh_Client_*Dma APIs directly; prefer + * DMA so any wolfCrypt-routed operations also take the DMA path. */ + (void)wh_Client_SetDmaMode(client, 1); if (ret == WH_ERROR_OK) { - ret = whTest_CryptoAesDmaAsync(client, WH_DEV_ID_DMA, rng); + ret = whTest_CryptoAesDmaAsync(client, WH_CLIENT_DEVID(client), rng); } if (ret == WH_ERROR_OK) { - ret = whTest_CryptoAesDmaAsyncKat(client, WH_DEV_ID_DMA); + ret = whTest_CryptoAesDmaAsyncKat(client, WH_CLIENT_DEVID(client)); } #endif /* WOLFHSM_CFG_DMA */ #endif /* !NO_AES */ #if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) i = 0; - while ((ret == WH_ERROR_OK) && (i < WH_NUM_DEVIDS)) { - ret = whTestCrypto_Cmac(client, WH_DEV_IDS_ARRAY[i], rng); + while ((ret == WH_ERROR_OK) && (i < WH_TEST_DMA_MODE_CNT)) { + (void)wh_Client_SetDmaMode(client, i); + ret = whTestCrypto_Cmac(client, WH_CLIENT_DEVID(client), rng); if (ret == WH_ERROR_OK) { - ret = whTestCrypto_CmacAsync(client, WH_DEV_IDS_ARRAY[i], rng); + ret = whTestCrypto_CmacAsync(client, WH_CLIENT_DEVID(client), rng); } if (ret == WH_ERROR_OK) { i++; } } #ifdef WOLFHSM_CFG_DMA + (void)wh_Client_SetDmaMode(client, 1); if (ret == WH_ERROR_OK) { - ret = whTestCrypto_CmacDmaAsync(client, WH_DEV_ID_DMA, rng); + ret = whTestCrypto_CmacDmaAsync(client, WH_CLIENT_DEVID(client), rng); } #endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFSSL_CMAC && !NO_AES && WOLFSSL_AES_DIRECT */ #ifndef NO_RSA + /* Once-run public-key tests use the std (non-DMA) dispatch mode. */ + (void)wh_Client_SetDmaMode(client, 0); if (ret == 0) { - ret = whTest_CryptoRsa(client, WH_DEV_ID, rng); + ret = whTest_CryptoRsa(client, WH_CLIENT_DEVID(client), rng); } if (ret == 0) { ret = whTest_CryptoRsaAsync(client, rng); @@ -14589,8 +14615,9 @@ int whTest_CryptoClientConfig(whClientConfig* config) #endif /* NO_RSA */ #ifdef HAVE_ECC + (void)wh_Client_SetDmaMode(client, 0); if (ret == 0) { - ret = whTest_CryptoEcc(client, WH_DEV_ID, rng); + ret = whTest_CryptoEcc(client, WH_CLIENT_DEVID(client), rng); } if (ret == 0) { ret = whTest_CryptoEccCacheDuplicate(client); @@ -14605,8 +14632,10 @@ int whTest_CryptoClientConfig(whClientConfig* config) } #endif #ifdef WOLFHSM_CFG_DMA + (void)wh_Client_SetDmaMode(client, 1); if (ret == 0) { - ret = whTest_CryptoEccExportPublicDma(client, WH_DEV_ID_DMA, rng); + ret = whTest_CryptoEccExportPublicDma(client, WH_CLIENT_DEVID(client), + rng); if (ret != 0) { WH_ERROR_PRINT( "ECC export-public DMA test failed: %d\n", ret); @@ -14620,27 +14649,31 @@ int whTest_CryptoClientConfig(whClientConfig* config) WH_ERROR_PRINT("Pre-Ed25519 tests ret=%d\n", ret); return ret; } + (void)wh_Client_SetDmaMode(client, 0); if (ret == 0) { - ret = whTest_CryptoEd25519Inline(client, WH_DEV_ID, rng); + ret = whTest_CryptoEd25519Inline(client, WH_CLIENT_DEVID(client), rng); if (ret != 0) { WH_ERROR_PRINT("Ed25519 inline test failed: %d\n", ret); } } if (ret == 0) { - ret = whTest_CryptoEd25519ServerKey(client, WH_DEV_ID, rng); + ret = + whTest_CryptoEd25519ServerKey(client, WH_CLIENT_DEVID(client), rng); if (ret != 0) { WH_ERROR_PRINT("Ed25519 server key test failed: %d\n", ret); } } if (ret == 0) { - ret = whTest_CryptoEd25519ExportPublic(client, WH_DEV_ID, rng); + ret = whTest_CryptoEd25519ExportPublic(client, WH_CLIENT_DEVID(client), + rng); if (ret != 0) { WH_ERROR_PRINT("Ed25519 export-public test failed: %d\n", ret); } } #ifdef WOLFHSM_CFG_DMA + (void)wh_Client_SetDmaMode(client, 1); if (ret == 0) { - ret = whTest_CryptoEd25519Dma(client, WH_DEV_ID_DMA, rng); + ret = whTest_CryptoEd25519Dma(client, WH_CLIENT_DEVID(client), rng); if (ret != 0) { WH_ERROR_PRINT("Ed25519 DMA test failed: %d\n", ret); } @@ -14649,20 +14682,22 @@ int whTest_CryptoClientConfig(whClientConfig* config) #endif /* HAVE_ED25519 */ #ifdef HAVE_CURVE25519 - /* test curve25519 */ + /* test curve25519 (std/non-DMA dispatch mode) */ + (void)wh_Client_SetDmaMode(client, 0); if (ret == 0) { - ret = whTest_CryptoCurve25519(client, WH_DEV_ID, rng); + ret = whTest_CryptoCurve25519(client, WH_CLIENT_DEVID(client), rng); } if (ret == 0) { - ret = - whTest_CryptoCurve25519SharedSecretCacheKey(client, WH_DEV_ID, rng); + ret = whTest_CryptoCurve25519SharedSecretCacheKey( + client, WH_CLIENT_DEVID(client), rng); if (ret != 0) { WH_ERROR_PRINT( "Curve25519 shared-secret cache-key test failed: %d\n", ret); } } if (ret == 0) { - ret = whTest_CryptoCurve25519ExportPublic(client, WH_DEV_ID, rng); + ret = whTest_CryptoCurve25519ExportPublic(client, + WH_CLIENT_DEVID(client), rng); if (ret != 0) { WH_ERROR_PRINT("Curve25519 export-public test failed: %d\n", ret); } @@ -14671,101 +14706,115 @@ int whTest_CryptoClientConfig(whClientConfig* config) #ifndef NO_SHA256 i = 0; - while ((ret == WH_ERROR_OK) && (i < WH_NUM_DEVIDS)) { - ret = whTest_CryptoSha256(client, WH_DEV_IDS_ARRAY[i], rng); + while ((ret == WH_ERROR_OK) && (i < WH_TEST_DMA_MODE_CNT)) { + (void)wh_Client_SetDmaMode(client, i); + ret = whTest_CryptoSha256(client, WH_CLIENT_DEVID(client), rng); if (ret == WH_ERROR_OK) { - ret = - whTest_CryptoSha256LargeInput(client, WH_DEV_IDS_ARRAY[i], rng); + ret = whTest_CryptoSha256LargeInput(client, WH_CLIENT_DEVID(client), + rng); } if (ret == WH_ERROR_OK) { - ret = whTest_CryptoSha256Async(client, WH_DEV_IDS_ARRAY[i], rng); + ret = + whTest_CryptoSha256Async(client, WH_CLIENT_DEVID(client), rng); } if (ret == WH_ERROR_OK) { i++; } } #ifdef WOLFHSM_CFG_DMA + (void)wh_Client_SetDmaMode(client, 1); if (ret == WH_ERROR_OK) { - ret = whTest_CryptoSha256DmaAsync(client, WH_DEV_ID_DMA, rng); + ret = whTest_CryptoSha256DmaAsync(client, WH_CLIENT_DEVID(client), rng); } #endif /* WOLFHSM_CFG_DMA */ #endif /* !NO_SHA256 */ #ifdef WOLFSSL_SHA224 i = 0; - while ((ret == WH_ERROR_OK) && (i < WH_NUM_DEVIDS)) { - ret = whTest_CryptoSha224(client, WH_DEV_IDS_ARRAY[i], rng); + while ((ret == WH_ERROR_OK) && (i < WH_TEST_DMA_MODE_CNT)) { + (void)wh_Client_SetDmaMode(client, i); + ret = whTest_CryptoSha224(client, WH_CLIENT_DEVID(client), rng); if (ret == WH_ERROR_OK) { - ret = - whTest_CryptoSha224LargeInput(client, WH_DEV_IDS_ARRAY[i], rng); + ret = whTest_CryptoSha224LargeInput(client, WH_CLIENT_DEVID(client), + rng); } if (ret == WH_ERROR_OK) { - ret = whTest_CryptoSha224Async(client, WH_DEV_IDS_ARRAY[i], rng); + ret = + whTest_CryptoSha224Async(client, WH_CLIENT_DEVID(client), rng); } if (ret == WH_ERROR_OK) { i++; } } #ifdef WOLFHSM_CFG_DMA + (void)wh_Client_SetDmaMode(client, 1); if (ret == WH_ERROR_OK) { - ret = whTest_CryptoSha224DmaAsync(client, WH_DEV_ID_DMA, rng); + ret = whTest_CryptoSha224DmaAsync(client, WH_CLIENT_DEVID(client), rng); } #endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFSSL_SHA224 */ #ifdef WOLFSSL_SHA384 i = 0; - while ((ret == WH_ERROR_OK) && (i < WH_NUM_DEVIDS)) { - ret = whTest_CryptoSha384(client, WH_DEV_IDS_ARRAY[i], rng); + while ((ret == WH_ERROR_OK) && (i < WH_TEST_DMA_MODE_CNT)) { + (void)wh_Client_SetDmaMode(client, i); + ret = whTest_CryptoSha384(client, WH_CLIENT_DEVID(client), rng); if (ret == WH_ERROR_OK) { - ret = - whTest_CryptoSha384LargeInput(client, WH_DEV_IDS_ARRAY[i], rng); + ret = whTest_CryptoSha384LargeInput(client, WH_CLIENT_DEVID(client), + rng); } if (ret == WH_ERROR_OK) { - ret = whTest_CryptoSha384Async(client, WH_DEV_IDS_ARRAY[i], rng); + ret = + whTest_CryptoSha384Async(client, WH_CLIENT_DEVID(client), rng); } if (ret == WH_ERROR_OK) { i++; } } #ifdef WOLFHSM_CFG_DMA + (void)wh_Client_SetDmaMode(client, 1); if (ret == WH_ERROR_OK) { - ret = whTest_CryptoSha384DmaAsync(client, WH_DEV_ID_DMA, rng); + ret = whTest_CryptoSha384DmaAsync(client, WH_CLIENT_DEVID(client), rng); } #endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 i = 0; - while ((ret == WH_ERROR_OK) && (i < WH_NUM_DEVIDS)) { - ret = whTest_CryptoSha512(client, WH_DEV_IDS_ARRAY[i], rng); + while ((ret == WH_ERROR_OK) && (i < WH_TEST_DMA_MODE_CNT)) { + (void)wh_Client_SetDmaMode(client, i); + ret = whTest_CryptoSha512(client, WH_CLIENT_DEVID(client), rng); if (ret == WH_ERROR_OK) { - ret = - whTest_CryptoSha512LargeInput(client, WH_DEV_IDS_ARRAY[i], rng); + ret = whTest_CryptoSha512LargeInput(client, WH_CLIENT_DEVID(client), + rng); } if (ret == WH_ERROR_OK) { - ret = whTest_CryptoSha512Async(client, WH_DEV_IDS_ARRAY[i], rng); + ret = + whTest_CryptoSha512Async(client, WH_CLIENT_DEVID(client), rng); } if (ret == WH_ERROR_OK) { i++; } } #ifdef WOLFHSM_CFG_DMA + (void)wh_Client_SetDmaMode(client, 1); if (ret == WH_ERROR_OK) { - ret = whTest_CryptoSha512DmaAsync(client, WH_DEV_ID_DMA, rng); + ret = whTest_CryptoSha512DmaAsync(client, WH_CLIENT_DEVID(client), rng); } #endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFSSL_SHA512 */ #ifdef HAVE_HKDF + (void)wh_Client_SetDmaMode(client, 0); if (ret == WH_ERROR_OK) { - ret = whTest_CryptoHkdf(client, WH_DEV_ID, rng); + ret = whTest_CryptoHkdf(client, WH_CLIENT_DEVID(client), rng); } #endif /* HAVE_HKDF */ #ifdef HAVE_CMAC_KDF + (void)wh_Client_SetDmaMode(client, 0); if (ret == WH_ERROR_OK) { - ret = whTest_CryptoCmacKdf(client, WH_DEV_ID, rng); + ret = whTest_CryptoCmacKdf(client, WH_CLIENT_DEVID(client), rng); } #endif /* HAVE_CMAC_KDF */ @@ -14797,24 +14846,29 @@ int whTest_CryptoClientConfig(whClientConfig* config) for (li = 0; (ret == 0) && (li < mldsaLevelCnt); li++) { int level = mldsaLevels[li]; - for (i = 0; (ret == WH_ERROR_OK) && (i < WH_NUM_DEVIDS); i++) { + for (i = 0; (ret == WH_ERROR_OK) && (i < WH_TEST_DMA_MODE_CNT); + i++) { #ifdef WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY - if (WH_DEV_IDS_ARRAY[i] != WH_DEV_ID_DMA) { + /* Large-data DMA-only: exercise the DMA-preferred mode only */ + if (i != 1) { continue; } #endif /* WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY */ - ret = whTestCrypto_MlDsaWolfCrypt(client, WH_DEV_IDS_ARRAY[i], - rng, level); + (void)wh_Client_SetDmaMode(client, i); + ret = whTestCrypto_MlDsaWolfCrypt( + client, WH_CLIENT_DEVID(client), rng, level); } + (void)wh_Client_SetDmaMode(client, 0); if (ret == 0) { - ret = whTestCrypto_MlDsaClient(client, WH_DEV_ID, rng, level); + ret = whTestCrypto_MlDsaClient(client, WH_CLIENT_DEVID(client), + rng, level); } #ifdef WOLFSSL_MLDSA_PUBLIC_KEY if (ret == 0) { - ret = whTestCrypto_MlDsaExportPublic(client, WH_DEV_ID, rng, - level); + ret = whTestCrypto_MlDsaExportPublic( + client, WH_CLIENT_DEVID(client), rng, level); if (ret != 0) { WH_ERROR_PRINT( "ML-DSA export-public test failed (level %d): %d\n", @@ -14824,14 +14878,15 @@ int whTest_CryptoClientConfig(whClientConfig* config) #endif #ifdef WOLFHSM_CFG_DMA + (void)wh_Client_SetDmaMode(client, 1); if (ret == 0) { - ret = whTestCrypto_MlDsaDmaClient(client, WH_DEV_ID_DMA, rng, - level); + ret = whTestCrypto_MlDsaDmaClient( + client, WH_CLIENT_DEVID(client), rng, level); } #ifdef WOLFSSL_MLDSA_PUBLIC_KEY if (ret == 0) { - ret = whTestCrypto_MlDsaExportPublicDma(client, WH_DEV_ID_DMA, - rng, level); + ret = whTestCrypto_MlDsaExportPublicDma( + client, WH_CLIENT_DEVID(client), rng, level); if (ret != 0) { WH_ERROR_PRINT( "ML-DSA export-public DMA test failed (level %d): " @@ -14851,8 +14906,10 @@ int whTest_CryptoClientConfig(whClientConfig* config) #if !defined(WOLFSSL_MLDSA_NO_VERIFY) && \ !defined(WOLFSSL_NO_ML_DSA_44) && \ defined(WOLFHSM_CFG_DMA) + (void)wh_Client_SetDmaMode(client, 1); if (ret == 0) { - ret = whTestCrypto_MlDsaVerifyOnlyDma(client, WH_DEV_ID_DMA, rng); + ret = whTestCrypto_MlDsaVerifyOnlyDma(client, WH_CLIENT_DEVID(client), + rng); } #endif /* !defined(WOLFSSL_MLDSA_NO_VERIFY) && \ !defined(WOLFSSL_NO_ML_DSA_44) && \ @@ -14865,36 +14922,42 @@ int whTest_CryptoClientConfig(whClientConfig* config) !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \ !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) i = 0; - while (ret == WH_ERROR_OK && i < WH_NUM_DEVIDS) { + while (ret == WH_ERROR_OK && i < WH_TEST_DMA_MODE_CNT) { #ifdef WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY - if (WH_DEV_IDS_ARRAY[i] != WH_DEV_ID_DMA) { + /* Large-data DMA-only: exercise the DMA-preferred mode only */ + if (i != 1) { i++; continue; } #endif /* WOLFHSM_CFG_TEST_CLIENT_LARGE_DATA_DMA_ONLY */ - ret = whTestCrypto_MlKemWolfCrypt(client, WH_DEV_IDS_ARRAY[i], rng); + (void)wh_Client_SetDmaMode(client, i); + ret = whTestCrypto_MlKemWolfCrypt(client, WH_CLIENT_DEVID(client), rng); if (ret == WH_ERROR_OK) { i++; } } + (void)wh_Client_SetDmaMode(client, 0); if (ret == 0) { - ret = whTestCrypto_MlKemClient(client, WH_DEV_ID, rng); + ret = whTestCrypto_MlKemClient(client, WH_CLIENT_DEVID(client), rng); } if (ret == 0) { - ret = whTestCrypto_MlKemExportPublic(client, WH_DEV_ID, rng); + ret = whTestCrypto_MlKemExportPublic(client, WH_CLIENT_DEVID(client), + rng); if (ret != 0) { WH_ERROR_PRINT("ML-KEM export-public test failed: %d\n", ret); } } #ifdef WOLFHSM_CFG_DMA + (void)wh_Client_SetDmaMode(client, 1); if (ret == 0) { - ret = whTestCrypto_MlKemDmaClient(client, WH_DEV_ID_DMA, rng); + ret = whTestCrypto_MlKemDmaClient(client, WH_CLIENT_DEVID(client), rng); } if (ret == 0) { - ret = whTestCrypto_MlKemExportPublicDma(client, WH_DEV_ID_DMA, rng); + ret = whTestCrypto_MlKemExportPublicDma(client, WH_CLIENT_DEVID(client), + rng); if (ret != 0) { WH_ERROR_PRINT("ML-KEM export-public DMA test failed: %d\n", ret); } @@ -14915,6 +14978,9 @@ int whTest_CryptoClientConfig(whClientConfig* config) defined(WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS) /* keep last, leaves artifact in the NVM layer */ if (ret == 0) { + /* The DMA-only groups above don't restore the dispatch mode; reset to + * the std path so this test runs the same way in every config. */ + (void)wh_Client_SetDmaMode(client, 0); /* Test key revocation */ ret = whTest_CryptoKeyRevocationAesCbc(client, rng); } @@ -15072,7 +15138,10 @@ static int wh_ClientServer_MemThreadTest(whTestNvmBackendType nvmType) }}; #ifdef WOLFHSM_CFG_DMA - whClientDmaConfig clientDmaConfig = {0}; + /* In-process (shared address space) test: prefer DMA by default. The + * orchestrator toggles this per-group via wh_Client_SetDmaMode() to + * exercise both the standard and DMA dispatch paths. */ + whClientDmaConfig clientDmaConfig = {.preferDma = 1}; #endif whClientConfig c_conf[1] = {{ .comm = cc_conf, diff --git a/test/wh_test_keywrap.c b/test/wh_test_keywrap.c index cd0611e78..fdbbed684 100644 --- a/test/wh_test_keywrap.c +++ b/test/wh_test_keywrap.c @@ -138,7 +138,7 @@ static int _AesGcm_TestKeyWrap(whClientContext* client, WC_RNG* rng) } /* Initialize AES context */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); + ret = wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_AesInit %d\n", ret); return ret; @@ -355,7 +355,7 @@ int whTest_Client_KeyWrap(whClientContext* client) return ret; } - ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client)); if (ret != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); return ret; diff --git a/test/wh_test_multiclient.c b/test/wh_test_multiclient.c index 8e54e9e64..76d3815f4 100644 --- a/test/wh_test_multiclient.c +++ b/test/wh_test_multiclient.c @@ -47,6 +47,12 @@ #include "wolfhsm/wh_nvm_flash.h" #include "wolfhsm/wh_flash_ramsim.h" +#ifndef WOLFHSM_CFG_NO_CRYPTO +#include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/wolfcrypt/types.h" +#include "wolfssl/wolfcrypt/cryptocb.h" +#endif /* !WOLFHSM_CFG_NO_CRYPTO */ + #include "wh_test_common.h" /* Test configuration */ @@ -1638,6 +1644,269 @@ static int whTest_MultiClientSequential(void) return 0; } +#if !defined(WOLFHSM_CFG_NO_CRYPTO) && defined(WOLF_CRYPTO_CB) + +/* ============================================================================ + * CLIENT DEVID REGISTRATION LIFECYCLE + * + * wh_Client_Init registers the client's devIds in wolfCrypt's process-global, + * fixed-size cryptoCb table and wh_Client_Cleanup must unregister them: the + * table is only reset when the last wolfCrypt user in the process cleans up, + * so a leaked entry both consumes a table slot and keeps dispatching into the + * dead client context. Every Init rebinds the global WH_DEV_ID (and + * WH_DEV_ID_DMA with DMA) to its own context and additionally registers the + * configured devId when it differs from WH_DEV_ID; any client's Cleanup + * unregisters the globals. These tests observe table occupancy through the + * only public accessors (Register/UnRegister) by counting how many throwaway + * registrations fit before the table is full. + * ========================================================================== */ + +/* Throwaway devId base for probing free cryptoCb table slots ("WHT\0"+i). + * Outside the global devIds (WH_DEV_ID / WH_DEV_ID_DMA), the custom test + * devIds, and the fill range below. */ +#define PROBE_DEV_ID_BASE 0x57485400 +/* Upper bound on probed slots. Must be >= wolfCrypt's + * MAX_CRYPTO_DEVID_CALLBACKS (internal to cryptocb.c; default 8). */ +#define PROBE_MAX_SLOTS 128 + +/* Separate devId base ("WHU\0"+i) for table-fill entries that stay + * registered while _countFreeCryptoCbSlots() runs: wolfCrypt re-registration + * of an existing devId reuses its entry, so fill ids must never collide with + * the probe ids or the count comes back wrong (and the counter's + * unregistration pass would tear the fill entries down). */ +#define FILL_DEV_ID_BASE 0x57485500 + +/* Global devIds rebound by every wh_Client_Init: WH_DEV_ID, plus + * WH_DEV_ID_DMA when DMA support is compiled in. Their table slots are + * shared by all clients in the process (each Init rebinds the same + * entries). */ +#ifdef WOLFHSM_CFG_DMA +#define GLOBAL_DEVID_COUNT 2 +#else +#define GLOBAL_DEVID_COUNT 1 +#endif + +/* Slots consumed by one wh_Client_Init with a custom (non-default) devId on + * an otherwise unoccupied table: the globals plus the configured devId */ +#define DEVIDS_PER_INIT (GLOBAL_DEVID_COUNT + 1) + +/* Custom per-client devIds for the two-client cases ("WH"+n). Distinct from + * WH_DEV_ID, WH_DEV_ID_DMA, and the probe range. */ +#define TEST_DEVID_1 0x57480001 +#define TEST_DEVID_2 0x57480002 + +static int _probeCryptoCb(int devId, wc_CryptoInfo* info, void* ctx) +{ + (void)devId; + (void)info; + (void)ctx; + return CRYPTOCB_UNAVAILABLE; +} + +/* Count free slots in the cryptoCb table by registering throwaway devIds + * until registration fails, then unregistering them all. */ +static int _countFreeCryptoCbSlots(void) +{ + int count = 0; + int i; + + for (i = 0; i < PROBE_MAX_SLOTS; i++) { + if (wc_CryptoCb_RegisterDevice(PROBE_DEV_ID_BASE + i, _probeCryptoCb, + NULL) != 0) { + break; + } + count++; + } + for (i = 0; i < count; i++) { + wc_CryptoCb_UnRegisterDevice(PROBE_DEV_ID_BASE + i); + } + return count; +} + +static int whTest_MultiClientDevIdLifecycle(void) +{ + int slotsBase = 0; + int slots = 0; + int rc = 0; + int i = 0; + + /* Client transports: no servers needed, registration lifecycle only */ + static uint8_t req1[BUFFER_SIZE]; + static uint8_t resp1[BUFFER_SIZE]; + whTransportMemConfig tmcf1[1] = {{ + .req = (whTransportMemCsr*)req1, + .req_size = sizeof(req1), + .resp = (whTransportMemCsr*)resp1, + .resp_size = sizeof(resp1), + }}; + + whTransportClientCb tccb1[1] = {WH_TRANSPORT_MEM_CLIENT_CB}; + whTransportMemClientContext tmcc1[1] = {0}; + whCommClientConfig cc_conf1[1] = {{ + .transport_cb = tccb1, + .transport_context = (void*)tmcc1, + .transport_config = (void*)tmcf1, + .client_id = WH_TEST_DEFAULT_CLIENT_ID, + }}; + whClientContext client1[1] = {0}; + whClientConfig c_conf1[1] = {{ + .comm = cc_conf1, + }}; + + static uint8_t req2[BUFFER_SIZE]; + static uint8_t resp2[BUFFER_SIZE]; + whTransportMemConfig tmcf2[1] = {{ + .req = (whTransportMemCsr*)req2, + .req_size = sizeof(req2), + .resp = (whTransportMemCsr*)resp2, + .resp_size = sizeof(resp2), + }}; + + whTransportClientCb tccb2[1] = {WH_TRANSPORT_MEM_CLIENT_CB}; + whTransportMemClientContext tmcc2[1] = {0}; + whCommClientConfig cc_conf2[1] = {{ + .transport_cb = tccb2, + .transport_context = (void*)tmcc2, + .transport_config = (void*)tmcf2, + .client_id = WH_TEST_DEFAULT_CLIENT_ID + 1, + }}; + whClientContext client2[1] = {0}; + whClientConfig c_conf2[1] = {{ + .comm = cc_conf2, + }}; + + WH_TEST_PRINT("=== Multi-Client DevId Lifecycle Tests Begin ===\n"); + + /* Client ids outside 1..WH_CLIENT_ID_MAX are rejected before any + * initialization */ + cc_conf1[0].client_id = 0; + WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS == wh_Client_Init(client1, c_conf1)); + cc_conf1[0].client_id = WH_CLIENT_ID_MAX + 1; + WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS == wh_Client_Init(client1, c_conf1)); + cc_conf1[0].client_id = WH_TEST_DEFAULT_CLIENT_ID; + + /* Negative devIds and (with DMA) the reserved WH_DEV_ID_DMA are + * rejected before any initialization */ + c_conf1[0].devId = -1; + WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS == wh_Client_Init(client1, c_conf1)); +#ifdef WOLFHSM_CFG_DMA + c_conf1[0].devId = WH_DEV_ID_DMA; + WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS == wh_Client_Init(client1, c_conf1)); +#endif /* WOLFHSM_CFG_DMA */ + c_conf1[0].devId = 0; + + /* Hold an app-level wolfCrypt reference for the whole test so the + * cryptoCb table is never reset by a final wolfCrypt_Cleanup: any entry + * a client leaks stays visible, as it would in a process with other + * active wolfCrypt users. */ + WH_TEST_RETURN_ON_FAIL(wolfCrypt_Init()); + + slotsBase = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slotsBase >= GLOBAL_DEVID_COUNT + 2); + + /* A config that leaves devId 0 binds the default WH_DEV_ID; only the + * global devIds occupy table slots */ + WH_TEST_RETURN_ON_FAIL(wh_Client_Init(client1, c_conf1)); + WH_TEST_ASSERT_RETURN(WH_CLIENT_DEVID(client1) == WH_DEV_ID); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - GLOBAL_DEVID_COUNT); + + /* Cleanup must release every slot Init consumed even though wolfCrypt + * stays initialized (the app still holds a reference) */ + WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase); + + /* Re-init with the same config must succeed and register again */ + WH_TEST_RETURN_ON_FAIL(wh_Client_Init(client1, c_conf1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - GLOBAL_DEVID_COUNT); + WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase); + + /* A custom configured devId is registered alongside the globals */ + c_conf1[0].devId = TEST_DEVID_1; + WH_TEST_RETURN_ON_FAIL(wh_Client_Init(client1, c_conf1)); + WH_TEST_ASSERT_RETURN(WH_CLIENT_DEVID(client1) == TEST_DEVID_1); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - DEVIDS_PER_INIT); + + /* Two simultaneously active clients with distinct devIds: the second + * Init rebinds the shared global entries (net zero new slots) and adds + * only its own devId */ + c_conf2[0].devId = TEST_DEVID_2; + WH_TEST_RETURN_ON_FAIL(wh_Client_Init(client2, c_conf2)); + WH_TEST_ASSERT_RETURN(WH_CLIENT_DEVID(client2) == TEST_DEVID_2); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - DEVIDS_PER_INIT - 1); + + /* Cleaning up one client releases its own devId and the shared global + * devIds -- the globals are yanked from the still-active sibling, which + * is the documented single-client contract for WH_DEV_ID/WH_DEV_ID_DMA. + * The sibling's own configured devId stays registered. */ + WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - 1); + + /* Re-init the first client while the second stays active: the globals + * are rebound and both custom devIds are live again */ + WH_TEST_RETURN_ON_FAIL(wh_Client_Init(client1, c_conf1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - DEVIDS_PER_INIT - 1); + + WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client2)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase - 1); + + WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client1)); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase); + c_conf1[0].devId = 0; + c_conf2[0].devId = 0; + + /* Init with a full cryptoCb table must fail cleanly (WH_ERROR_ABORTED) + * and the failure-path cleanup must not disturb existing entries */ + for (i = 0; i < slotsBase; i++) { + WH_TEST_RETURN_ON_FAIL(wc_CryptoCb_RegisterDevice( + FILL_DEV_ID_BASE + i, _probeCryptoCb, NULL)); + } + rc = wh_Client_Init(client1, c_conf1); + WH_TEST_ASSERT_RETURN(rc == WH_ERROR_ABORTED); + WH_TEST_ASSERT_RETURN(WH_CLIENT_DEVID(client1) == 0); + for (i = 0; i < slotsBase; i++) { + wc_CryptoCb_UnRegisterDevice(FILL_DEV_ID_BASE + i); + } + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase); + + /* Init that fails partway through its registrations (the custom devId + * fits, but a later global rebind hits the full table) must unwind + * exactly the entries it registered and leave the fill entries intact */ + for (i = 0; i < slotsBase - (DEVIDS_PER_INIT - 1); i++) { + WH_TEST_RETURN_ON_FAIL(wc_CryptoCb_RegisterDevice( + FILL_DEV_ID_BASE + i, _probeCryptoCb, NULL)); + } + c_conf1[0].devId = TEST_DEVID_1; + rc = wh_Client_Init(client1, c_conf1); + WH_TEST_ASSERT_RETURN(rc == WH_ERROR_ABORTED); + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == DEVIDS_PER_INIT - 1); + for (i = 0; i < slotsBase - (DEVIDS_PER_INIT - 1); i++) { + wc_CryptoCb_UnRegisterDevice(FILL_DEV_ID_BASE + i); + } + slots = _countFreeCryptoCbSlots(); + WH_TEST_ASSERT_RETURN(slots == slotsBase); + c_conf1[0].devId = 0; + + (void)wolfCrypt_Cleanup(); + + WH_TEST_PRINT("=== Multi-Client DevId Lifecycle Tests Complete ===\n"); + return 0; +} + +#endif /* !WOLFHSM_CFG_NO_CRYPTO && WOLF_CRYPTO_CB */ + /* ============================================================================ * PUBLIC API * ========================================================================== */ @@ -1645,7 +1914,11 @@ static int whTest_MultiClientSequential(void) /* Main entry point for multi-client tests */ int whTest_MultiClient(void) { - return whTest_MultiClientSequential(); + WH_TEST_RETURN_ON_FAIL(whTest_MultiClientSequential()); +#if !defined(WOLFHSM_CFG_NO_CRYPTO) && defined(WOLF_CRYPTO_CB) + WH_TEST_RETURN_ON_FAIL(whTest_MultiClientDevIdLifecycle()); +#endif + return 0; } #endif /* WOLFHSM_CFG_ENABLE_CLIENT && WOLFHSM_CFG_ENABLE_SERVER */ diff --git a/test/wh_test_she.c b/test/wh_test_she.c index e4058a00c..b15deddd4 100644 --- a/test/wh_test_she.c +++ b/test/wh_test_she.c @@ -201,7 +201,7 @@ int whTest_SheClientConfig(whClientConfig* config) } /* generate a new cmac key */ - if ((ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID)) != 0) { + if ((ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client))) != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); goto exit; } @@ -581,7 +581,7 @@ static int whTest_SheClientConfigBoundarySecureBoot(whClientConfig* config) bootloaderSz = maxBoundaryUpdateChunk; - if ((ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID)) != 0) { + if ((ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client))) != 0) { WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); goto exit_boundary; } @@ -722,7 +722,7 @@ static int whTest_SheWriteProtect(whClientConfig* config) wh_Client_CommInit(client, &outClientId, &outServerId)); /* generate boot MAC key and fake bootloader */ - if ((ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID)) != 0) { + if ((ret = wc_InitRng_ex(rng, NULL, WH_CLIENT_DEVID(client))) != 0) { WH_ERROR_PRINT( "Failed to wc_InitRng_ex %d\n", ret); goto exit_wp; diff --git a/test/wh_test_timeout.c b/test/wh_test_timeout.c index e8596f915..5e08143f9 100644 --- a/test/wh_test_timeout.c +++ b/test/wh_test_timeout.c @@ -181,7 +181,7 @@ static int whTest_TimeoutAesCbc(void) uint8_t plain[AES_BLOCK_SIZE] = {0xAA}; uint8_t cipher[AES_BLOCK_SIZE] = {0}; - WH_TEST_RETURN_ON_FAIL(wc_AesInit(aes, NULL, WH_DEV_ID)); + WH_TEST_RETURN_ON_FAIL(wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client))); WH_TEST_RETURN_ON_FAIL( wc_AesSetKey(aes, key, sizeof(key), iv, AES_ENCRYPTION)); @@ -341,7 +341,7 @@ static int whTest_TimeoutAesCbcOverride(void) uint8_t plain[AES_BLOCK_SIZE] = {0xAA}; uint8_t cipher[AES_BLOCK_SIZE] = {0}; - WH_TEST_RETURN_ON_FAIL(wc_AesInit(aes, NULL, WH_DEV_ID)); + WH_TEST_RETURN_ON_FAIL(wc_AesInit(aes, NULL, WH_CLIENT_DEVID(client))); WH_TEST_RETURN_ON_FAIL( wc_AesSetKey(aes, key, sizeof(key), iv, AES_ENCRYPTION)); diff --git a/wolfhsm/wh_client.h b/wolfhsm/wh_client.h index 6be78cc9f..d55b58762 100644 --- a/wolfhsm/wh_client.h +++ b/wolfhsm/wh_client.h @@ -25,8 +25,14 @@ * WolfHSM Server. All communications and state are internally managed by * registering a crypto callback function to be invoked synchronously when * wolfCrypt functions are called. In order to specify to use the WolfHSM - * Server for cryptographic operations, the device id WH_DEV_ID should be - * passed into any of the wolfCrypt init functions. + * Server for cryptographic operations, the client's devId should be passed + * into any of the wolfCrypt init functions. The devId is chosen by the + * application in whClientConfig.devId (0 selects the default WH_DEV_ID) and + * can be read back from an initialized context with WH_CLIENT_DEVID(c). + * Single-client processes may simply pass the always-registered global + * WH_DEV_ID (or WH_DEV_ID_DMA for DMA-only dispatch) directly; processes + * running multiple clients must configure a distinct devId per client. See + * WH_CLIENT_DEVID and WH_DEV_ID below. * * In addition to the offload of cryptographic functions, the WolfHSM Client * also exposes WolfHSM Server key management, non-volatile memory, and protocol @@ -65,25 +71,51 @@ typedef struct whClientContext_t whClientContext; /* WolfCrypt types and defines */ #include "wolfssl/wolfcrypt/types.h" -/* Device Id to be registered and passed to wolfCrypt functions */ -enum WH_CLIENT_DEVID_ENUM { - WH_DEV_ID = 0x5748534D, /* "WHSM" */ -#ifdef WOLFHSM_CFG_DMA - WH_DEV_ID_DMA = 0x57444D41, /* "WDMA" */ - WH_NUM_DEVIDS = 2 -#else - WH_NUM_DEVIDS = 1 +/* Global devId for wolfHSM offload, overridable by the user. Registered by + * every wh_Client_Init() with the unified client crypto callback, so it + * behaves exactly like a configured per-client devId, including honoring the + * DMA dispatch mode (wh_Client_SetDmaMode). It is also the devId bound to a + * client whose config leaves devId 0. The registration is process-global and + * keyed on the devId value: it always routes to the most recently initialized + * client and is unregistered by any client's wh_Client_Cleanup(). Passing it + * directly to wolfCrypt is therefore only meaningful in processes with a + * single client context; multi-client processes must configure a distinct + * devId per client and use those instead. */ +#ifndef WH_DEV_ID +#define WH_DEV_ID 0x5748534D /* "WHSM" */ #endif -}; -extern const int WH_DEV_IDS_ARRAY[WH_NUM_DEVIDS]; -#else + +#ifdef WOLFHSM_CFG_DMA + +/* Global devId for DMA-only wolfHSM offload, overridable by the user. + * Registered by every wh_Client_Init() with the DMA-only client crypto + * callback: operations always use the DMA request forms and fail with + * CRYPTOCB_UNAVAILABLE (no standard-path fallback) for algorithms without a + * DMA variant. Reserved: not valid as whClientConfig.devId. Like WH_DEV_ID, + * it binds to the most recently initialized client and is unregistered by any + * client's wh_Client_Cleanup(), so it is a single-client convenience only. */ +#ifndef WH_DEV_ID_DMA +#define WH_DEV_ID_DMA 0x57444D41 /* "WDMA" */ +#endif /* WH_DEV_ID_DMA */ + +#endif /* WOLFHSM_CFG_DMA */ + +#else /* WOLFHSM_CFG_NO_CRYPTO */ + /* for compile purpose */ #define WH_DEV_ID -2 /* invalid ID */ /* cipher types */ enum wc_CipherType { WC_CIPHER_NONE = 0, }; -#endif + +#endif /* !WOLFHSM_CFG_NO_CRYPTO*/ + +/* Helper macro to get the registered devId for a client context (c is a + * whClientContext*). Reads the devId bound at wh_Client_Init(): the value + * from whClientConfig.devId, or WH_DEV_ID when the config left it 0. Only + * valid after a successful init. */ +#define WH_CLIENT_DEVID(c) ((c)->devId) /** Client DMA address translation and validation */ #ifdef WOLFHSM_CFG_DMA @@ -96,6 +128,8 @@ typedef int (*whClientDmaClientMemCb)(struct whClientContext_t* client, typedef struct { whClientDmaClientMemCb cb; const whDmaAddrAllowList* dmaAddrAllowList; /* allowed addresses */ + /* bool indicating whether DMA messages should be prioritized */ + uint32_t preferDma; } whClientDmaConfig; /* Per-operation async DMA context: stores translated input DMA address @@ -162,6 +196,8 @@ typedef struct { const whDmaAddrAllowList* dmaAddrAllowList; /* allowed addresses */ void* heap; /* heap hint for using static memory (or other allocator) */ whClientDmaAsyncCtx asyncCtx; + /* bool indicating whether DMA messages should be prioritized */ + uint32_t preferDma; } whClientDmaContext; #endif /* WOLFHSM_CFG_DMA */ @@ -170,6 +206,9 @@ struct whClientContext_t { uint16_t last_req_id; uint16_t last_req_kind; uint32_t cryptoAffinity; + /* wolfCrypt devId this client registered at init (see WH_CLIENT_DEVID). + * Nonzero only on a successfully initialized context. */ + int devId; #ifdef WOLFHSM_CFG_DMA whClientDmaContext dma; #endif /* WOLFHSM_CFG_DMA */ @@ -178,6 +217,11 @@ struct whClientContext_t { struct whClientConfig_t { whCommClientConfig* comm; + /* wolfCrypt devId to register for this client. 0 selects the global + * default WH_DEV_ID. Otherwise the value must be positive and, when + * WOLFHSM_CFG_DMA is enabled, must not equal WH_DEV_ID_DMA (reserved for + * the DMA-only callback). Ignored when WOLFHSM_CFG_NO_CRYPTO. */ + int devId; #ifdef WOLFHSM_CFG_DMA whClientDmaConfig* dmaConfig; #endif /* WOLFHSM_CFG_DMA */ @@ -433,6 +477,34 @@ int wh_Client_SetCryptoAffinity(whClientContext* c, uint32_t affinity); */ int wh_Client_GetCryptoAffinity(whClientContext* c, uint32_t* out_affinity); +/** + * @brief Sets the DMA mode (DMA preference) on the client context. + * + * When enabled, the unified client crypto callback dispatches DMA-capable + * algorithms to the DMA path, falling back to the standard (non-DMA) path for + * algorithms the DMA callback does not support. The mode is stored locally and + * may be toggled at any time. No round-trip to the server is required. + * + * This function is always available; in a build without WOLFHSM_CFG_DMA it is a + * no-op that returns success, so callers need not guard it with #ifdef. + * + * @param[in] c Pointer to the client context. + * @param[in] useDma Non-zero to prefer DMA for supported algorithms, zero to + * use the standard (non-DMA) path. + * @return int Returns 0 on success, or WH_ERROR_BADARGS on invalid input. + */ +int wh_Client_SetDmaMode(whClientContext* c, int useDma); + +/** + * @brief Gets the current DMA mode (DMA preference) from the client context. + * + * @param[in] c Pointer to the client context. + * @param[out] out_useDma Pointer to store the current DMA mode (0 or 1; always + * 0 in a build without WOLFHSM_CFG_DMA). + * @return int Returns 0 on success, or WH_ERROR_BADARGS on invalid input. + */ +int wh_Client_GetDmaMode(whClientContext* c, int* out_useDma); + /** * @brief Sends a communication close request to the server. * diff --git a/wolfhsm/wh_client_cryptocb.h b/wolfhsm/wh_client_cryptocb.h index d08d35985..11d8fb28c 100644 --- a/wolfhsm/wh_client_cryptocb.h +++ b/wolfhsm/wh_client_cryptocb.h @@ -36,9 +36,18 @@ #include "wolfhsm/wh_client.h" +/* Unified cryptoCb, registered for WH_DEV_ID and the client's configured + * devId. Dispatches to the DMA path when the client's DMA mode is set (see + * wh_Client_SetDmaMode), falling back to the standard path for algorithms + * without a DMA variant; otherwise uses the standard path directly. */ int wh_Client_CryptoCb(int devId, wc_CryptoInfo* info, void* ctx); +/* Standard (non-DMA) cryptoCb */ +int wh_Client_CryptoCbStd(int devId, wc_CryptoInfo* info, void* ctx); + #ifdef WOLFHSM_CFG_DMA +/* DMA-only cryptoCb, registered for WH_DEV_ID_DMA. No standard-path + * fallback: algorithms without a DMA variant return CRYPTOCB_UNAVAILABLE. */ int wh_Client_CryptoCbDma(int devId, wc_CryptoInfo* info, void* inCtx); #endif /* WOLFHSM_CFG_DMA */ diff --git a/wolfhsm/wh_comm.h b/wolfhsm/wh_comm.h index ab151b515..a36392d4e 100644 --- a/wolfhsm/wh_comm.h +++ b/wolfhsm/wh_comm.h @@ -160,6 +160,9 @@ typedef struct { void* transport_context; const void* transport_config; whCommSetConnectedCb connect_cb; + /* Unique client identifier, 1..WH_CLIENT_ID_MAX (wh_keyid.h). Identifies + * this client to the server; must remain constant for the life of the + * client context. */ uint8_t client_id; uint8_t WH_PAD[7]; #ifdef WOLFHSM_CFG_ENABLE_TIMEOUT diff --git a/wolfhsm/wh_keyid.h b/wolfhsm/wh_keyid.h index c206f82f3..be1c91ebf 100644 --- a/wolfhsm/wh_keyid.h +++ b/wolfhsm/wh_keyid.h @@ -47,12 +47,14 @@ typedef uint16_t whKeyId; #define WH_KEYTYPE_SHIFT 12 /* Maximum valid client_id. The USER field of whKeyId is 4 bits, so client_id - * must fit in [0, WH_CLIENT_ID_MAX]. Values outside this range would be - * silently truncated by WH_MAKE_KEYID, breaking per-client key isolation, so - * the server rejects them at WH_MESSAGE_COMM_ACTION_INIT. With - * WOLFHSM_CFG_GLOBAL_KEYS enabled, value 0 is reserved for the global-keys - * namespace and is also rejected. Derived from WH_KEYUSER_MASK so the bound - * stays in sync if the USER field is ever widened. */ + * must fit in [1, WH_CLIENT_ID_MAX]: value 0 is reserved for the global-keys + * namespace (WH_KEYUSER_GLOBAL), and larger values would be silently + * truncated by WH_MAKE_KEYID, breaking per-client key isolation. + * wh_Client_Init() rejects out-of-range ids (including 0) before any + * communication; the server rejects ids above the maximum at + * WH_MESSAGE_COMM_ACTION_INIT and, with WOLFHSM_CFG_GLOBAL_KEYS, also rejects + * 0. Derived from WH_KEYUSER_MASK so the bound stays in sync if the USER + * field is ever widened. */ #define WH_CLIENT_ID_MAX (WH_KEYUSER_MASK >> WH_KEYUSER_SHIFT) /* @@ -120,8 +122,9 @@ typedef uint16_t whKeyId; * WH_KEYTYPE_WRAPPED is used if the input clientId has the * WH_CLIENT_KEYID_WRAPPED flag set. * @param clientId Client identifier to use as USER field. Must be in - * [0, WH_CLIENT_ID_MAX]; the server enforces this at INIT so callers may - * assume the value fits in the 4-bit USER field. + * [1, WH_CLIENT_ID_MAX] (0 is reserved for WH_KEYUSER_GLOBAL); + * wh_Client_Init() and the server's INIT handling enforce this so callers + * may assume the value fits in the 4-bit USER field. * @param reqId Requested keyId from client (may include flags) * @return Server-internal keyId with TYPE, USER, and ID fields properly set. */