diff --git a/test-refactor/README.md b/test-refactor/README.md
index bdf1397e6..774c3ddfe 100644
--- a/test-refactor/README.md
+++ b/test-refactor/README.md
@@ -78,6 +78,8 @@ Translated tests:
| Legacy (`wolfHSM/test/`) | New location | Group | Notes |
|---|---|---|---|
| `wh_test_dma.c::whTest_Dma` | `misc/wh_test_dma.c::whTest_Dma` | Misc | |
+| `wh_test_comm.c::whTest_Comm` | `misc/wh_test_comm.c::whTest_Comm` | Misc | Sequential mem variant only; pthread mem/tcp/shmem variants remain in the legacy harness |
+| `wh_test_keystore_reqsize.c::whTest_KeystoreReqSize` | `misc/wh_test_keystore_reqsize.c::whTest_KeystoreReqSize` | Misc | |
| `wh_test_cert.c::whTest_CertRamSim` | `server/wh_test_cert.c::whTest_CertVerify` | Server | remove ramsim coupling and migrate to server group |
| `wh_test_crypto.c::whTest_Crypto` | `client-server/wh_test_crypto.c::{whTest_CryptoSha256, whTest_CryptoAes, whTest_CryptoEcc256}` | Client | Subset only; remaining cases listed below |
| `wh_test_clientserver.c` (echo and server-info paths) | `client-server/wh_test_echo.c::whTest_Echo`, `client-server/wh_test_server_info.c::whTest_ServerInfo` | Client | pthread test ported, sequential test dropped |
@@ -90,7 +92,7 @@ Not yet migrated (still live in `wolfHSM/test/`):
| Legacy (`wolfHSM/test/`) | Notes |
|---|---|
-| `wh_test_comm.c::whTest_Comm` | |
+| `wh_test_comm.c::whTest_Comm` | Pthread mem/tcp/shmem variants only; sequential mem variant has been ported |
| `wh_test_clientserver.c::whTest_ClientServer` | Pthread variant: remaining client-side coverage (NVM ops, etc.) still needs to be split out as new tests. The sequential test is dropped |
| `wh_test_crypto.c::whTest_Crypto` | RNG, key cache, key-cache enforcement, RSA, CMAC, Curve25519, ML-DSA, key usage policies, key revocation |
| `wh_test_crypto_affinity.c::whTest_CryptoAffinity` | |
diff --git a/test-refactor/config/wolfhsm_cfg.h b/test-refactor/config/wolfhsm_cfg.h
new file mode 100644
index 000000000..320257637
--- /dev/null
+++ b/test-refactor/config/wolfhsm_cfg.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 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 .
+ */
+/*
+ * wolfhsm_cfg.h
+ *
+ * wolfHSM compile-time options for the test-refactor suite. Sibling of
+ * test/config/wolfhsm_cfg.h; the two are intentionally allowed to diverge
+ * as the refactor matures.
+ */
+
+#ifndef WOLFHSM_CFG_H_
+#define WOLFHSM_CFG_H_
+
+#include "port/posix/posix_time.h"
+#define WOLFHSM_CFG_PORT_GETTIME posixGetTime
+
+#define WOLFHSM_CFG_COMM_DATA_LEN (1024 * 8)
+
+#define WOLFHSM_CFG_GLOBAL_KEYS
+
+#define WOLFHSM_CFG_LOGGING
+
+#define WOLFHSM_CFG_NVM_OBJECT_COUNT 30
+#define WOLFHSM_CFG_SERVER_KEYCACHE_COUNT 9
+#define WOLFHSM_CFG_SERVER_KEYCACHE_BUFSIZE 300
+#define WOLFHSM_CFG_SERVER_KEYCACHE_BIG_COUNT 3
+#define WOLFHSM_CFG_SERVER_KEYCACHE_BIG_BUFSIZE WOLFHSM_CFG_COMM_DATA_LEN
+#define WOLFHSM_CFG_DMAADDR_COUNT 8
+#define WOLFHSM_CFG_SERVER_CUSTOMCB_COUNT 6
+
+#define WOLFHSM_CFG_CERTIFICATE_MANAGER
+#define WOLFHSM_CFG_CERTIFICATE_MANAGER_ACERT
+
+#define WOLFHSM_CFG_SERVER_IMG_MGR
+
+#ifndef WOLFHSM_CFG_NO_CRYPTO
+#define WOLFHSM_CFG_KEYWRAP
+#endif
+
+#define WOLFHSM_CFG_SERVER_NVM_FLASH_LOG
+
+/* WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS is intentionally NOT
+ * defined here. Not implemented yet. */
+
+#define WOLFHSM_CFG_ENABLE_TIMEOUT
+
+#endif /* WOLFHSM_CFG_H_ */
diff --git a/test-refactor/misc/wh_test_comm.c b/test-refactor/misc/wh_test_comm.c
new file mode 100644
index 000000000..0010c1939
--- /dev/null
+++ b/test-refactor/misc/wh_test_comm.c
@@ -0,0 +1,279 @@
+/*
+ * 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_comm.c
+ *
+ * Sequential mem-transport coverage from legacy
+ * test/wh_test_comm.c::whTest_CommMem. The pthread mem/tcp/shmem
+ * variants live in the POSIX port (legacy harness retains them).
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if defined(WOLFHSM_CFG_ENABLE_CLIENT) && defined(WOLFHSM_CFG_ENABLE_SERVER)
+
+#include
+#include
+#include
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_comm.h"
+#include "wolfhsm/wh_transport_mem.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#define BUFFER_SIZE 4096
+#define REQ_SIZE 32
+#define RESP_SIZE 64
+#define REPEAT_COUNT 10
+
+
+static int _whTest_CommMem(void)
+{
+ int ret = 0;
+
+ /* Transport memory configuration */
+ uint8_t req[BUFFER_SIZE] = {0};
+ uint8_t resp[BUFFER_SIZE] = {0};
+ whTransportMemConfig tmcf[1] = {{
+ .req = (whTransportMemCsr*)req,
+ .req_size = sizeof(req),
+ .resp = (whTransportMemCsr*)resp,
+ .resp_size = sizeof(resp),
+ }};
+
+
+ /* Client configuration/contexts */
+ whTransportClientCb tccb[1] = {WH_TRANSPORT_MEM_CLIENT_CB};
+ whTransportMemClientContext tmcc[1] = {0};
+ whCommClientConfig c_conf[1] = {{
+ .transport_cb = tccb,
+ .transport_context = (void*)tmcc,
+ .transport_config = (void*)tmcf,
+ .client_id = WH_TEST_DEFAULT_CLIENT_ID,
+ }};
+ whCommClient client[1] = {0};
+
+ /* Server configuration/contexts */
+ whTransportServerCb tscb[1] = {WH_TRANSPORT_MEM_SERVER_CB};
+ whTransportMemServerContext tmsc[1] = {0};
+ whCommServerConfig s_conf[1] = {{
+ .transport_cb = tscb,
+ .transport_context = (void*)tmsc,
+ .transport_config = (void*)tmcf,
+ .server_id = 124,
+ }};
+ whCommServer server[1] = {0};
+
+ int counter = 1;
+
+ uint8_t tx_req[REQ_SIZE] = {0};
+ uint16_t tx_req_len = 0;
+ uint16_t tx_req_flags = WH_COMM_MAGIC_NATIVE;
+ uint16_t tx_req_type = 0;
+ uint16_t tx_req_seq = 0;
+
+ uint8_t rx_req[REQ_SIZE] = {0};
+ uint16_t rx_req_len = 0;
+ uint16_t rx_req_flags = 0;
+ uint16_t rx_req_type = 0;
+ uint16_t rx_req_seq = 0;
+
+ uint8_t tx_resp[RESP_SIZE] = {0};
+ uint16_t tx_resp_len = 0;
+
+ uint8_t rx_resp[RESP_SIZE] = {0};
+ uint16_t rx_resp_len = 0;
+ uint16_t rx_resp_flags = 0;
+ uint16_t rx_resp_type = 0;
+ uint16_t rx_resp_seq = 0;
+
+ uint16_t seq_snapshot = 0;
+ int rc = 0;
+
+ /* BADARGS on uninitialized or NULL context */
+ WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS ==
+ wh_CommClient_IsRequestPending(NULL));
+ WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS ==
+ wh_CommClient_IsRequestPending(client));
+ WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS == wh_CommClient_AbortPending(NULL));
+ WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS ==
+ wh_CommClient_AbortPending(client));
+
+ /* Init client and server */
+ WH_TEST_RETURN_ON_FAIL(wh_CommClient_Init(client, c_conf));
+ WH_TEST_RETURN_ON_FAIL(wh_CommServer_Init(server, s_conf, NULL, NULL));
+
+ /* Fresh context: idle */
+ WH_TEST_ASSERT_RETURN(0 == wh_CommClient_IsRequestPending(client));
+
+ /* Check that neither side is ready to recv */
+ WH_TEST_ASSERT_RETURN(WH_ERROR_NOTREADY ==
+ wh_CommServer_RecvRequest(server, &rx_req_flags,
+ &rx_req_type, &rx_req_seq,
+ &rx_req_len, rx_req));
+
+ /* RecvResponse with no outstanding request short-circuits to NOTREADY
+ * without touching the transport. */
+ WH_TEST_ASSERT_RETURN(
+ WH_ERROR_NOTREADY ==
+ wh_CommClient_RecvResponse(client, &rx_resp_flags, &rx_resp_type,
+ &rx_resp_seq, &rx_resp_len, rx_resp));
+
+ for (counter = 0; counter < REPEAT_COUNT; counter++) {
+ (void)snprintf((char*)tx_req, sizeof(tx_req), "Request:%u", counter);
+ tx_req_len = strlen((char*)tx_req);
+ tx_req_type = counter * 2;
+ WH_TEST_RETURN_ON_FAIL(
+ wh_CommClient_SendRequest(client, tx_req_flags, tx_req_type,
+ &tx_req_seq, tx_req_len, tx_req));
+ WH_TEST_DEBUG_PRINT("Client SendRequest:%d, flags %x, type:%x, seq:%d, len:%d, %s\n",
+ ret, tx_req_flags, tx_req_type, tx_req_seq, tx_req_len, tx_req);
+
+ if (counter == 0) {
+ WH_TEST_ASSERT_RETURN(WH_ERROR_NOTREADY ==
+ wh_CommClient_RecvResponse(
+ client, &rx_resp_flags, &rx_resp_type,
+ &rx_resp_seq, &rx_resp_len, rx_resp));
+
+ WH_TEST_ASSERT_RETURN(
+ WH_ERROR_REQUEST_PENDING ==
+ wh_CommClient_SendRequest(client, tx_req_flags, tx_req_type,
+ &tx_req_seq, tx_req_len, tx_req));
+ }
+
+ WH_TEST_RETURN_ON_FAIL(
+ wh_CommServer_RecvRequest(server, &rx_req_flags, &rx_req_type,
+ &rx_req_seq, &rx_req_len, rx_req));
+
+ WH_TEST_DEBUG_PRINT("Server RecvRequest:%d, flags %x, type:%x, seq:%d, len:%d, %s\n",
+ ret, rx_req_flags, rx_req_type, rx_req_seq, rx_req_len, rx_req);
+
+ (void)snprintf((char*)tx_resp, sizeof(tx_resp), "Response:%s", rx_req);
+ tx_resp_len = strlen((char*)tx_resp);
+ ret = wh_CommServer_SendResponse(server, rx_req_flags, rx_req_type,
+ rx_req_seq, tx_resp_len, tx_resp);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Server SendResponse:%d\n", ret);
+ return ret;
+ }
+
+ WH_TEST_DEBUG_PRINT(
+ "Server SendResponse:%d, flags %x, type:%x, seq:%d, len:%d, %s\n",
+ ret, rx_req_flags, rx_req_type, rx_req_seq, tx_resp_len, tx_resp);
+
+ WH_TEST_RETURN_ON_FAIL(
+ wh_CommClient_RecvResponse(client, &rx_resp_flags, &rx_resp_type,
+ &rx_resp_seq, &rx_resp_len, rx_resp));
+
+ WH_TEST_DEBUG_PRINT(
+ "Client RecvResponse:%d, flags %x, type:%x, seq:%d, len:%d, %s\n",
+ ret, rx_resp_flags, rx_resp_type, rx_resp_seq, rx_resp_len,
+ rx_resp);
+ }
+
+ /* Pending tracking: context is idle after the loop */
+ WH_TEST_ASSERT_RETURN(0 == wh_CommClient_IsRequestPending(client));
+
+ /* Send a request: transitions to pending */
+ (void)snprintf((char*)tx_req, sizeof(tx_req), "PendingTest");
+ tx_req_len = (uint16_t)strlen((char*)tx_req);
+ tx_req_type = 0xABCD;
+ WH_TEST_RETURN_ON_FAIL(wh_CommClient_SendRequest(
+ client, tx_req_flags, tx_req_type, &tx_req_seq, tx_req_len, tx_req));
+ WH_TEST_ASSERT_RETURN(1 == wh_CommClient_IsRequestPending(client));
+
+ /* Stacking guard: second send rejected without touching seq or transport */
+ seq_snapshot = client->seq;
+ rc = wh_CommClient_SendRequest(client, tx_req_flags, tx_req_type,
+ &tx_req_seq, tx_req_len, tx_req);
+ WH_TEST_ASSERT_RETURN(WH_ERROR_REQUEST_PENDING == rc);
+ WH_TEST_ASSERT_RETURN(seq_snapshot == client->seq);
+ WH_TEST_ASSERT_RETURN(1 == wh_CommClient_IsRequestPending(client));
+
+ /* Server completes the exchange */
+ WH_TEST_RETURN_ON_FAIL(wh_CommServer_RecvRequest(
+ server, &rx_req_flags, &rx_req_type, &rx_req_seq, &rx_req_len, rx_req));
+ (void)snprintf((char*)tx_resp, sizeof(tx_resp), "Resp");
+ tx_resp_len = (uint16_t)strlen((char*)tx_resp);
+ WH_TEST_RETURN_ON_FAIL(wh_CommServer_SendResponse(
+ server, rx_req_flags, rx_req_type, rx_req_seq, tx_resp_len, tx_resp));
+
+ /* Successful recv clears pending */
+ WH_TEST_RETURN_ON_FAIL(
+ wh_CommClient_RecvResponse(client, &rx_resp_flags, &rx_resp_type,
+ &rx_resp_seq, &rx_resp_len, rx_resp));
+ WH_TEST_ASSERT_RETURN(0 == wh_CommClient_IsRequestPending(client));
+
+ /* Second Recv with no outstanding request again yields NOTREADY */
+ WH_TEST_ASSERT_RETURN(
+ WH_ERROR_NOTREADY ==
+ wh_CommClient_RecvResponse(client, &rx_resp_flags, &rx_resp_type,
+ &rx_resp_seq, &rx_resp_len, rx_resp));
+
+ /* Send, then manually abort. Seq must not advance. */
+ WH_TEST_RETURN_ON_FAIL(wh_CommClient_SendRequest(
+ client, tx_req_flags, tx_req_type, &tx_req_seq, tx_req_len, tx_req));
+ WH_TEST_ASSERT_RETURN(1 == wh_CommClient_IsRequestPending(client));
+ seq_snapshot = client->seq;
+ WH_TEST_RETURN_ON_FAIL(wh_CommClient_AbortPending(client));
+ WH_TEST_ASSERT_RETURN(0 == wh_CommClient_IsRequestPending(client));
+ WH_TEST_ASSERT_RETURN(seq_snapshot == client->seq);
+
+ /* Drain the abandoned exchange on the server side so the transport state
+ * doesn't linger across tests. */
+ WH_TEST_RETURN_ON_FAIL(wh_CommServer_RecvRequest(
+ server, &rx_req_flags, &rx_req_type, &rx_req_seq, &rx_req_len, rx_req));
+ WH_TEST_RETURN_ON_FAIL(wh_CommServer_SendResponse(
+ server, rx_req_flags, rx_req_type, rx_req_seq, tx_resp_len, tx_resp));
+
+ /* After abort the late response is ignored - pending is 0 so
+ * RecvResponse short-circuits before consulting the transport. */
+ WH_TEST_ASSERT_RETURN(
+ WH_ERROR_NOTREADY ==
+ wh_CommClient_RecvResponse(client, &rx_resp_flags, &rx_resp_type,
+ &rx_resp_seq, &rx_resp_len, rx_resp));
+ WH_TEST_ASSERT_RETURN(0 == wh_CommClient_IsRequestPending(client));
+
+ WH_TEST_RETURN_ON_FAIL(wh_CommServer_Cleanup(server));
+ WH_TEST_RETURN_ON_FAIL(wh_CommClient_Cleanup(client));
+
+ /* After Cleanup the context is no longer initialized; API reports BADARGS
+ */
+ WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS ==
+ wh_CommClient_IsRequestPending(client));
+ WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS ==
+ wh_CommClient_AbortPending(client));
+
+ return ret;
+}
+
+
+int whTest_Comm(void* ctx)
+{
+ (void)ctx;
+
+ WH_TEST_PRINT("Testing comms: mem...\n");
+ WH_TEST_RETURN_ON_FAIL(_whTest_CommMem());
+
+ return WH_ERROR_OK;
+}
+
+#endif /* WOLFHSM_CFG_ENABLE_CLIENT && WOLFHSM_CFG_ENABLE_SERVER */
diff --git a/test-refactor/misc/wh_test_keystore_reqsize.c b/test-refactor/misc/wh_test_keystore_reqsize.c
new file mode 100644
index 000000000..a1af60a28
--- /dev/null
+++ b/test-refactor/misc/wh_test_keystore_reqsize.c
@@ -0,0 +1,339 @@
+/*
+ * 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_keystore_reqsize.c
+ *
+ * Unit tests to verify wh_Server_HandleKeyRequest validates req_size,
+ * preventing unbounded reads from the request packet.
+ *
+ * Each test crafts a request packet with a valid fixed-size header but passes
+ * a req_size that is too small to contain the variable-length data claimed by
+ * the header. A correct implementation must reject these with an error (e.g.
+ * WH_ERROR_BUFFER_SIZE) rather than blindly reading past the end of the
+ * packet.
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if defined(WOLFHSM_CFG_ENABLE_SERVER) && !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_comm.h"
+#include "wolfhsm/wh_message.h"
+#include "wolfhsm/wh_message_keystore.h"
+#include "wolfhsm/wh_server.h"
+#include "wolfhsm/wh_server_keystore.h"
+#include "wolfhsm/wh_transport_mem.h"
+#include "wolfhsm/wh_nvm.h"
+#include "wolfhsm/wh_nvm_flash.h"
+#include "wolfhsm/wh_flash_ramsim.h"
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#define BUFFER_SIZE 4096
+#define FLASH_RAM_SIZE (1024 * 1024)
+#define FLASH_SECTOR_SIZE (128 * 1024)
+#define FLASH_PAGE_SIZE 8
+
+/*
+ * Helper: set up a minimal server context suitable for calling
+ * wh_Server_HandleKeyRequest directly. Mirrors the pattern used in
+ * wh_test_she.c:wh_She_TestReqSizeChecking().
+ */
+typedef struct {
+ whServerContext server[1];
+ whNvmContext nvm[1];
+ whServerCryptoContext crypto[1];
+ /* Transport (not exercised, but required for server init) */
+ uint8_t reqBuf[BUFFER_SIZE];
+ uint8_t respBuf[BUFFER_SIZE];
+ whTransportMemConfig tmcf[1];
+ whTransportServerCb tscb[1];
+ whTransportMemServerContext tmsc[1];
+ whCommServerConfig cs_conf[1];
+ /* Flash / NVM */
+ whFlashRamsimCtx fc[1];
+ whFlashRamsimCfg fc_conf[1];
+ whFlashCb fcb[1];
+ whNvmFlashConfig nf_conf[1];
+ whNvmFlashContext nfc[1];
+ whNvmCb nfcb[1];
+ whNvmConfig n_conf[1];
+ whServerConfig s_conf[1];
+} TestCtx;
+
+/* Flash memory is static to avoid 1MB on the stack */
+static uint8_t _flashMemory[FLASH_RAM_SIZE];
+
+static int _SetupServer(TestCtx* ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ memset(_flashMemory, 0, sizeof(_flashMemory));
+
+ /* Transport */
+ ctx->tmcf[0] = (whTransportMemConfig){
+ .req = (whTransportMemCsr*)ctx->reqBuf,
+ .req_size = sizeof(ctx->reqBuf),
+ .resp = (whTransportMemCsr*)ctx->respBuf,
+ .resp_size = sizeof(ctx->respBuf),
+ };
+ ctx->tscb[0] = (whTransportServerCb)WH_TRANSPORT_MEM_SERVER_CB;
+ ctx->cs_conf[0] = (whCommServerConfig){
+ .transport_cb = ctx->tscb,
+ .transport_context = (void*)ctx->tmsc,
+ .transport_config = (void*)ctx->tmcf,
+ .server_id = 124,
+ };
+
+ /* Flash */
+ ctx->fc_conf[0] = (whFlashRamsimCfg){
+ .size = FLASH_RAM_SIZE,
+ .sectorSize = FLASH_SECTOR_SIZE,
+ .pageSize = FLASH_PAGE_SIZE,
+ .erasedByte = ~(uint8_t)0,
+ .memory = _flashMemory,
+ };
+ ctx->fcb[0] = (whFlashCb)WH_FLASH_RAMSIM_CB;
+ ctx->nf_conf[0] = (whNvmFlashConfig){
+ .cb = ctx->fcb,
+ .context = ctx->fc,
+ .config = ctx->fc_conf,
+ };
+ ctx->nfcb[0] = (whNvmCb)WH_NVM_FLASH_CB;
+ ctx->n_conf[0] = (whNvmConfig){
+ .cb = ctx->nfcb,
+ .context = ctx->nfc,
+ .config = ctx->nf_conf,
+ };
+
+ /* Server config */
+ ctx->s_conf[0] = (whServerConfig){
+ .comm_config = ctx->cs_conf,
+ .nvm = ctx->nvm,
+ .crypto = ctx->crypto,
+ };
+
+ WH_TEST_RETURN_ON_FAIL(wh_Nvm_Init(ctx->nvm, ctx->n_conf));
+ WH_TEST_RETURN_ON_FAIL(wolfCrypt_Init());
+ WH_TEST_RETURN_ON_FAIL(
+ wc_InitRng_ex(ctx->crypto->rng, NULL, INVALID_DEVID));
+ WH_TEST_RETURN_ON_FAIL(wh_Server_Init(ctx->server, ctx->s_conf));
+ WH_TEST_RETURN_ON_FAIL(
+ wh_Server_SetConnected(ctx->server, WH_COMM_CONNECTED));
+ return 0;
+}
+
+static void _CleanupServer(TestCtx* ctx)
+{
+ (void)wh_Server_Cleanup(ctx->server);
+ (void)wh_Nvm_Cleanup(ctx->nvm);
+ (void)wc_FreeRng(ctx->crypto->rng);
+ (void)wolfCrypt_Cleanup();
+}
+
+static int _whTest_KeystoreReqSize(void)
+{
+ TestCtx ctx[1];
+ uint8_t req_packet[WOLFHSM_CFG_COMM_DATA_LEN] = {0};
+ uint8_t resp_packet[WOLFHSM_CFG_COMM_DATA_LEN] = {0};
+ uint16_t req_size;
+ uint16_t resp_size;
+ int ret;
+
+ WH_TEST_RETURN_ON_FAIL(_SetupServer(ctx));
+
+ /*
+ * Test 1: WH_KEY_CACHE with req_size too small for the variable-length
+ * key data.
+ *
+ * The request declares 32 bytes of key data following the fixed header,
+ * but req_size only covers the header.
+ */
+ {
+ whMessageKeystore_CacheRequest* req =
+ (whMessageKeystore_CacheRequest*)req_packet;
+ whMessageKeystore_CacheResponse* cacheResp =
+ (whMessageKeystore_CacheResponse*)resp_packet;
+ memset(req_packet, 0, sizeof(req_packet));
+ memset(cacheResp, 0, sizeof(*cacheResp));
+ resp_size = 0;
+ req->sz = 32;
+ req->labelSz = 0;
+ req->id = 0;
+ req->flags = 0;
+ req_size = sizeof(*req);
+ ret = wh_Server_HandleKeyRequest(ctx->server, WH_COMM_MAGIC_NATIVE,
+ WH_KEY_CACHE, req_size, req_packet,
+ &resp_size, resp_packet);
+ if (ret == WH_ERROR_OK) {
+ WH_TEST_ASSERT_RETURN(resp_size == sizeof(*cacheResp));
+ WH_TEST_ASSERT_RETURN(cacheResp->rc != WH_ERROR_OK);
+ }
+ }
+
+ /*
+ * Test 2: WH_KEY_CACHE with req_size smaller than the fixed header.
+ */
+ {
+ whMessageKeystore_CacheResponse* cacheResp =
+ (whMessageKeystore_CacheResponse*)resp_packet;
+ memset(req_packet, 0, sizeof(req_packet));
+ memset(cacheResp, 0, sizeof(*cacheResp));
+ resp_size = 0;
+ req_size = sizeof(whMessageKeystore_CacheRequest) - 1;
+ ret = wh_Server_HandleKeyRequest(ctx->server, WH_COMM_MAGIC_NATIVE,
+ WH_KEY_CACHE, req_size, req_packet,
+ &resp_size, resp_packet);
+ if (ret == WH_ERROR_OK) {
+ WH_TEST_ASSERT_RETURN(resp_size == sizeof(*cacheResp));
+ WH_TEST_ASSERT_RETURN(cacheResp->rc != WH_ERROR_OK);
+ }
+ }
+
+ /*
+ * Test 3: WH_KEY_CACHE with req.sz claiming more data than the entire
+ * comm buffer.
+ */
+ {
+ whMessageKeystore_CacheRequest* req =
+ (whMessageKeystore_CacheRequest*)req_packet;
+ whMessageKeystore_CacheResponse* cacheResp =
+ (whMessageKeystore_CacheResponse*)resp_packet;
+ memset(req_packet, 0, sizeof(req_packet));
+ memset(cacheResp, 0, sizeof(*cacheResp));
+ resp_size = 0;
+ req->sz = WOLFHSM_CFG_COMM_DATA_LEN;
+ req->labelSz = 0;
+ req->id = 0;
+ req->flags = 0;
+ req_size = sizeof(*req);
+ ret = wh_Server_HandleKeyRequest(ctx->server, WH_COMM_MAGIC_NATIVE,
+ WH_KEY_CACHE, req_size, req_packet,
+ &resp_size, resp_packet);
+ if (ret == WH_ERROR_OK) {
+ WH_TEST_ASSERT_RETURN(resp_size == sizeof(*cacheResp));
+ WH_TEST_ASSERT_RETURN(cacheResp->rc != WH_ERROR_OK);
+ }
+ }
+
+ /*
+ * Test 4: WH_KEY_EVICT with req_size smaller than the fixed request
+ * header.
+ */
+ {
+ whMessageKeystore_EvictResponse* evictResp =
+ (whMessageKeystore_EvictResponse*)resp_packet;
+ memset(req_packet, 0, sizeof(req_packet));
+ memset(evictResp, 0, sizeof(*evictResp));
+ resp_size = 0;
+ req_size = sizeof(whMessageKeystore_EvictRequest) - 1;
+ ret = wh_Server_HandleKeyRequest(ctx->server, WH_COMM_MAGIC_NATIVE,
+ WH_KEY_EVICT, req_size, req_packet,
+ &resp_size, resp_packet);
+ if (ret == WH_ERROR_OK) {
+ WH_TEST_ASSERT_RETURN(resp_size == sizeof(*evictResp));
+ WH_TEST_ASSERT_RETURN(evictResp->rc != WH_ERROR_OK);
+ }
+ }
+
+ /*
+ * Test 5: WH_KEY_EXPORT with req_size smaller than the fixed request
+ * header.
+ */
+ {
+ whMessageKeystore_ExportResponse* exportResp =
+ (whMessageKeystore_ExportResponse*)resp_packet;
+ memset(req_packet, 0, sizeof(req_packet));
+ memset(exportResp, 0, sizeof(*exportResp));
+ resp_size = 0;
+ req_size = sizeof(whMessageKeystore_ExportRequest) - 1;
+ ret = wh_Server_HandleKeyRequest(ctx->server, WH_COMM_MAGIC_NATIVE,
+ WH_KEY_EXPORT, req_size, req_packet,
+ &resp_size, resp_packet);
+ if (ret == WH_ERROR_OK) {
+ WH_TEST_ASSERT_RETURN(resp_size == sizeof(*exportResp));
+ WH_TEST_ASSERT_RETURN(exportResp->rc != WH_ERROR_OK);
+ }
+ }
+
+ /*
+ * Test 6: WH_KEY_COMMIT with req_size smaller than the fixed request
+ * header.
+ */
+ {
+ whMessageKeystore_CommitResponse* commitResp =
+ (whMessageKeystore_CommitResponse*)resp_packet;
+ memset(req_packet, 0, sizeof(req_packet));
+ memset(commitResp, 0, sizeof(*commitResp));
+ resp_size = 0;
+ req_size = sizeof(whMessageKeystore_CommitRequest) - 1;
+ ret = wh_Server_HandleKeyRequest(ctx->server, WH_COMM_MAGIC_NATIVE,
+ WH_KEY_COMMIT, req_size, req_packet,
+ &resp_size, resp_packet);
+ if (ret == WH_ERROR_OK) {
+ WH_TEST_ASSERT_RETURN(resp_size == sizeof(*commitResp));
+ WH_TEST_ASSERT_RETURN(commitResp->rc != WH_ERROR_OK);
+ }
+ }
+
+ /*
+ * Test 7: WH_KEY_ERASE with req_size smaller than the fixed request
+ * header.
+ */
+ {
+ whMessageKeystore_EraseResponse* eraseResp =
+ (whMessageKeystore_EraseResponse*)resp_packet;
+ memset(req_packet, 0, sizeof(req_packet));
+ memset(eraseResp, 0, sizeof(*eraseResp));
+ resp_size = 0;
+ req_size = sizeof(whMessageKeystore_EraseRequest) - 1;
+ ret = wh_Server_HandleKeyRequest(ctx->server, WH_COMM_MAGIC_NATIVE,
+ WH_KEY_ERASE, req_size, req_packet,
+ &resp_size, resp_packet);
+ if (ret == WH_ERROR_OK) {
+ WH_TEST_ASSERT_RETURN(resp_size == sizeof(*eraseResp));
+ WH_TEST_ASSERT_RETURN(eraseResp->rc != WH_ERROR_OK);
+ }
+ }
+
+ WH_TEST_PRINT("Keystore req_size validation tests: ALL PASSED\n");
+
+ _CleanupServer(ctx);
+ return 0;
+}
+
+
+int whTest_KeystoreReqSize(void* ctx)
+{
+ (void)ctx;
+
+ WH_TEST_PRINT("Testing keystore HandleKeyRequest req_size validation...\n");
+ WH_TEST_RETURN_ON_FAIL(_whTest_KeystoreReqSize());
+
+ return WH_ERROR_OK;
+}
+
+#endif /* WOLFHSM_CFG_ENABLE_SERVER && !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/posix/Makefile b/test-refactor/posix/Makefile
index c19267fd2..760adb3e3 100644
--- a/test-refactor/posix/Makefile
+++ b/test-refactor/posix/Makefile
@@ -12,6 +12,7 @@ BIN = wh_test_refactor
PROJECT_DIR ?= .
REFACTOR_DIR ?= $(PROJECT_DIR)/..
CONFIG_DIR ?= $(REFACTOR_DIR)/../test/config
+REFACTOR_CFG_DIR ?= $(REFACTOR_DIR)/config
WOLFSSL_DIR ?= ../../../wolfssl
WOLFHSM_DIR ?= $(REFACTOR_DIR)/..
WOLFHSM_PORT_DIR ?= $(WOLFHSM_DIR)/port/posix
@@ -25,6 +26,7 @@ INC = -I$(PROJECT_DIR) \
-I$(REFACTOR_DIR)/server \
-I$(REFACTOR_DIR)/client-server \
-I$(REFACTOR_DIR)/misc \
+ -I$(REFACTOR_CFG_DIR) \
-I$(CONFIG_DIR) \
-I$(TEST_DIR) \
-I$(WOLFSSL_DIR) \
diff --git a/test-refactor/wh_test_list.c b/test-refactor/wh_test_list.c
index 0ba5674ae..ac29019a9 100644
--- a/test-refactor/wh_test_list.c
+++ b/test-refactor/wh_test_list.c
@@ -32,7 +32,9 @@
#include "wh_test_list.h"
/* Test declarations and weak skip implementations. */
+WH_TEST_DECL(whTest_Comm);
WH_TEST_DECL(whTest_Dma);
+WH_TEST_DECL(whTest_KeystoreReqSize);
WH_TEST_DECL(whTest_CertVerify);
WH_TEST_DECL(whTest_ClientCerts);
WH_TEST_DECL(whTest_CryptoAes);
@@ -46,7 +48,9 @@ WH_TEST_DECL(whTest_ServerInfo);
WH_TEST_DECL(whTest_WolfCryptTest);
const whTestCase whTestsMisc[] = {
- { "whTest_Dma", whTest_Dma },
+ { "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/wh_test_common.h b/test/wh_test_common.h
index aab655162..53cd38958 100644
--- a/test/wh_test_common.h
+++ b/test/wh_test_common.h
@@ -83,6 +83,21 @@
} 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)
+
/*
* Helper macro for test error propagation
* Mimics "assert" semantics by evaluating the "statement" argument, and if not