From e34442e78c5912d36aca968143afcadf607f3b2b Mon Sep 17 00:00:00 2001 From: Yosuke Shimizu Date: Tue, 21 Jul 2026 13:13:03 +0900 Subject: [PATCH 1/2] Validate Ed25519 keygen response against received length --- src/wh_client_crypto.c | 13 +- .../posix/wh_test_malformed_response.c | 323 ++++++++++++++++++ test-refactor/posix/wh_test_posix_main.c | 11 + 3 files changed, 342 insertions(+), 5 deletions(-) create mode 100644 test-refactor/posix/wh_test_malformed_response.c diff --git a/src/wh_client_crypto.c b/src/wh_client_crypto.c index d0189b33a..b47a4eb4b 100644 --- a/src/wh_client_crypto.c +++ b/src/wh_client_crypto.c @@ -3470,6 +3470,14 @@ static int _Ed25519MakeKey(whClientContext* ctx, whKeyId* inout_key_id, ret = _getCryptoResponse(dataPtr, WC_PK_TYPE_ED25519_KEYGEN, (uint8_t**)&res); if (ret >= 0) { + const size_t hdr_sz = + sizeof(whMessageCrypto_GenericResponseHeader) + sizeof(*res); + + /* Defensive bound: res->outSz must fit within the received frame */ + if (res_len < hdr_sz || res->outSz > (res_len - hdr_sz)) { + return WH_ERROR_ABORTED; + } + key_id = (whKeyId)res->keyId; if (inout_key_id != NULL) { *inout_key_id = key_id; @@ -3479,11 +3487,6 @@ static int _Ed25519MakeKey(whClientContext* ctx, whKeyId* inout_key_id, if (flags & WH_NVM_FLAGS_EPHEMERAL) { uint8_t* out = (uint8_t*)(res + 1); uint16_t outSz = (uint16_t)res->outSz; - if (outSz + sizeof(whMessageCrypto_GenericResponseHeader) + - sizeof(*res) > - WOLFHSM_CFG_COMM_DATA_LEN) { - return WH_ERROR_ABORTED; - } ret = wh_Crypto_Ed25519DeserializeKeyDer(out, outSz, key); } } diff --git a/test-refactor/posix/wh_test_malformed_response.c b/test-refactor/posix/wh_test_malformed_response.c new file mode 100644 index 000000000..9ce3cebb9 --- /dev/null +++ b/test-refactor/posix/wh_test_malformed_response.c @@ -0,0 +1,323 @@ +/* + * 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/posix/wh_test_malformed_response.c + * + * Negative-path coverage for the client-side response frame bounds + * checks, driven by a fake server that declares a payload length its + * frame does not carry. POSIX/pthread only, and port-owned rather than + * in the common list, which runs against a real server process. + */ + +#include +#include +#include + +#include "wolfhsm/wh_settings.h" + +#include "wh_test_common.h" +#include "wh_test_list.h" + +#if defined(WOLFHSM_CFG_TEST_POSIX) && defined(WOLFHSM_CFG_ENABLE_CLIENT) && \ + !defined(WOLFHSM_CFG_NO_CRYPTO) + +#include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/wolfcrypt/ecc.h" +#include "wolfssl/wolfcrypt/ed25519.h" +#include "wolfssl/wolfcrypt/rsa.h" + +#include "wolfhsm/wh_client.h" +#include "wolfhsm/wh_client_crypto.h" +#include "wolfhsm/wh_comm.h" +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_message.h" +#include "wolfhsm/wh_message_crypto.h" +#include "wolfhsm/wh_transport_mem.h" + +#define WH_TEST_MALFORMED_BUFFER_SIZE 4096 + +/* Kept well inside WOLFHSM_CFG_COMM_DATA_LEN so only a frame-length + * check rejects it, not a buffer-capacity one. */ +#define WH_TEST_MALFORMED_CLAIMED_SZ 64 + +/* Malformed frame shapes, ordered as the client drives them. */ +typedef enum { + WH_TEST_MALFORMED_TRUNCATED = 0, + WH_TEST_MALFORMED_OVERSIZED, + WH_TEST_MALFORMED_SHAPE_COUNT +} whTestMalformedShape; + +typedef int (*whTestMalformedFn)(whClientContext* client); + +typedef struct { + const char* name; + whTestMalformedFn call; + uint16_t resSize; /* size of the algorithm's response struct */ +} whTestMalformedCase; + +/* Every keygen response in wh_message_crypto.h opens with this pair, so + * the fake server fills them all the same way. */ +typedef struct { + uint32_t keyId; + uint32_t len; +} whTestMalformedKeyGenBody; + + +/* Client calls. The key contexts never receive material, so a local + * wolfCrypt devId suffices. */ + +static int _callEd25519MakeKey(whClientContext* client) +{ + ed25519_key key[1]; + int ret; + + ret = wc_ed25519_init_ex(key, NULL, INVALID_DEVID); + if (ret != 0) { + return ret; + } + ret = wh_Client_Ed25519MakeExportKey(client, key); + wc_ed25519_free(key); + return ret; +} + +static int _callEccMakeKey(whClientContext* client) +{ + ecc_key key[1]; + int ret; + + ret = wc_ecc_init_ex(key, NULL, INVALID_DEVID); + if (ret != 0) { + return ret; + } + ret = wh_Client_EccMakeExportKey(client, 32, ECC_SECP256R1, key); + wc_ecc_free(key); + return ret; +} + +static int _callRsaMakeKey(whClientContext* client) +{ + RsaKey key[1]; + int ret; + + ret = wc_InitRsaKey_ex(key, NULL, INVALID_DEVID); + if (ret != 0) { + return ret; + } + ret = wh_Client_RsaMakeExportKey(client, 2048, 65537, key); + wc_FreeRsaKey(key); + return ret; +} + +/* Curve25519 keygen is absent on purpose: it has no frame check yet, + * so a row for it would fail until that path is fixed. */ +static const whTestMalformedCase _malformedCases[] = { + {"Ed25519 keygen", _callEd25519MakeKey, + (uint16_t)sizeof(whMessageCrypto_Ed25519KeyGenResponse)}, + {"ECC keygen", _callEccMakeKey, + (uint16_t)sizeof(whMessageCrypto_EccKeyGenResponse)}, + {"RSA keygen", _callRsaMakeKey, + (uint16_t)sizeof(whMessageCrypto_RsaKeyGenResponse)}, +}; + +#define WH_TEST_MALFORMED_CASE_COUNT \ + (sizeof(_malformedCases) / sizeof(_malformedCases[0])) + +static const struct timespec WH_TEST_MALFORMED_ONE_MS = {0, 1000000}; + +/* Set by the client thread so a failure reaches the caller. */ +static int _malformedClientRc = WH_TEST_SUCCESS; + + +/* Fake server. Echoes the request kind and sequence so the client + * accepts the reply, then declares a payload the frame lacks. */ +static void* _malformedServerThread(void* cf) +{ + whCommServerConfig* config = (whCommServerConfig*)cf; + whCommServer server[1]; + uint8_t rx_req[WH_TEST_MALFORMED_BUFFER_SIZE]; + uint8_t tx_resp[WH_TEST_MALFORMED_BUFFER_SIZE]; + uint16_t rx_req_len = 0; + uint16_t rx_req_flags = 0; + uint16_t rx_req_type = 0; + uint16_t rx_req_seq = 0; + uint16_t tx_resp_len = 0; + size_t shape; + size_t idx; + int ret; + + whMessageCrypto_GenericResponseHeader* hdr = + (whMessageCrypto_GenericResponseHeader*)tx_resp; + whTestMalformedKeyGenBody* body = + (whTestMalformedKeyGenBody*)(tx_resp + sizeof(*hdr)); + + ret = wh_CommServer_Init(server, config, NULL, NULL); + WH_TEST_ASSERT_MSG(0 == ret, "Fake server Init: ret=%d", ret); + + for (shape = 0; shape < (size_t)WH_TEST_MALFORMED_SHAPE_COUNT; shape++) { + for (idx = 0; idx < WH_TEST_MALFORMED_CASE_COUNT; idx++) { + do { + ret = wh_CommServer_RecvRequest(server, &rx_req_flags, + &rx_req_type, &rx_req_seq, + &rx_req_len, sizeof(rx_req), + rx_req); + } while ((ret == WH_ERROR_NOTREADY) && + (nanosleep(&WH_TEST_MALFORMED_ONE_MS, NULL) == 0)); + WH_TEST_ASSERT_MSG(0 == ret, "Fake server RecvRequest: ret=%d", + ret); + + memset(tx_resp, 0, sizeof(tx_resp)); + /* algoType must come from the crypto request header, not the + * comm kind, or the client rejects the reply as a mismatch + * before it ever reaches the bounds check. */ + hdr->rc = WH_ERROR_OK; + hdr->algoType = + ((whMessageCrypto_GenericRequestHeader*)rx_req)->algoType; + + if (shape == (size_t)WH_TEST_MALFORMED_TRUNCATED) { + /* Stop short of the response struct the client reads */ + tx_resp_len = (uint16_t)sizeof(*hdr); + } + else { + body->keyId = 0; + body->len = WH_TEST_MALFORMED_CLAIMED_SZ; + tx_resp_len = + (uint16_t)(sizeof(*hdr) + _malformedCases[idx].resSize); + } + + do { + ret = wh_CommServer_SendResponse(server, rx_req_flags, + rx_req_type, rx_req_seq, + tx_resp_len, tx_resp); + } while ((ret == WH_ERROR_NOTREADY) && + (nanosleep(&WH_TEST_MALFORMED_ONE_MS, NULL) == 0)); + WH_TEST_ASSERT_MSG(0 == ret, "Fake server SendResponse: ret=%d", + ret); + } + } + + ret = wh_CommServer_Cleanup(server); + WH_TEST_ASSERT_MSG(0 == ret, "Fake server Cleanup: ret=%d", ret); + return NULL; +} + + +static void* _malformedClientThread(void* cf) +{ + whClientConfig* config = (whClientConfig*)cf; + whClientContext client[1]; + size_t shape; + size_t idx; + int ret; + + ret = wh_Client_Init(client, config); + WH_TEST_ASSERT_MSG(0 == ret, "Fake client Init: ret=%d", ret); + if (ret != 0) { + _malformedClientRc = ret; + return NULL; + } + + for (shape = 0; shape < (size_t)WH_TEST_MALFORMED_SHAPE_COUNT; shape++) { + for (idx = 0; idx < WH_TEST_MALFORMED_CASE_COUNT; idx++) { + ret = _malformedCases[idx].call(client); + if (ret != WH_ERROR_ABORTED) { + WH_ERROR_PRINT("%s shape %u: expected WH_ERROR_ABORTED, " + "got %d\n", + _malformedCases[idx].name, (unsigned)shape, ret); + _malformedClientRc = WH_TEST_FAIL; + } + } + } + + (void)wh_Client_Cleanup(client); + return NULL; +} + + +int whTest_MalformedCryptoResponse(void* ctx) +{ + /* Transport memory shared by the client and fake server */ + uint8_t req[WH_TEST_MALFORMED_BUFFER_SIZE] = {0}; + uint8_t resp[WH_TEST_MALFORMED_BUFFER_SIZE] = {0}; + + whTransportMemConfig tmcf[1] = {{ + .req = (whTransportMemCsr*)req, + .req_size = sizeof(req), + .resp = (whTransportMemCsr*)resp, + .resp_size = sizeof(resp), + }}; + + whTransportClientCb tccb[1] = {WH_TRANSPORT_MEM_CLIENT_CB}; + whTransportMemClientContext tmcc[1] = {0}; + whCommClientConfig cc_conf[1] = {{ + .transport_cb = tccb, + .transport_context = (void*)tmcc, + .transport_config = (void*)tmcf, + .client_id = WH_TEST_DEFAULT_CLIENT_ID, + }}; + whClientConfig c_conf[1] = {{ + .comm = cc_conf, + }}; + + whTransportServerCb tscb[1] = {WH_TRANSPORT_MEM_SERVER_CB}; + whTransportMemServerContext tmsc[1] = {0}; + whCommServerConfig cs_conf[1] = {{ + .transport_cb = tscb, + .transport_context = (void*)tmsc, + .transport_config = (void*)tmcf, + .server_id = 1, + }}; + + pthread_t sthread; + pthread_t cthread; + int rc; + + (void)ctx; + + _malformedClientRc = WH_TEST_SUCCESS; + + rc = pthread_create(&sthread, NULL, _malformedServerThread, cs_conf); + if (rc != 0) { + WH_ERROR_PRINT("Fake server thread create: rc=%d\n", rc); + return WH_TEST_FAIL; + } + + rc = pthread_create(&cthread, NULL, _malformedClientThread, c_conf); + if (rc != 0) { + WH_ERROR_PRINT("Fake client thread create: rc=%d\n", rc); + (void)pthread_cancel(sthread); + (void)pthread_join(sthread, NULL); + return WH_TEST_FAIL; + } + + (void)pthread_join(cthread, NULL); + (void)pthread_join(sthread, NULL); + + return _malformedClientRc; +} + +#else /* !WOLFHSM_CFG_TEST_POSIX || !WOLFHSM_CFG_ENABLE_CLIENT || + * WOLFHSM_CFG_NO_CRYPTO */ + +int whTest_MalformedCryptoResponse(void* ctx) +{ + (void)ctx; + return WH_TEST_SKIPPED; +} + +#endif diff --git a/test-refactor/posix/wh_test_posix_main.c b/test-refactor/posix/wh_test_posix_main.c index 756ed6041..34a9029c5 100644 --- a/test-refactor/posix/wh_test_posix_main.c +++ b/test-refactor/posix/wh_test_posix_main.c @@ -76,6 +76,10 @@ int whTest_NvmAddOverwriteDestroy(void* ctx); int whTest_NvmFlashLog(void* ctx); int whTest_NvmRecovery(void* ctx); +/* Malformed-response test. Owns its own client and fake server over a + * private transport pair, so it can't use the runner's live contexts. */ +int whTest_MalformedCryptoResponse(void* ctx); + /* * Port-owned contexts. The thread functions fill these in and * hand them to the group functions, paralleling the firmware @@ -284,6 +288,13 @@ int main(void) if (rc != 0 && rc != WH_TEST_SKIPPED && miscRc == 0) { miscRc = rc; } + /* Runs here rather than in the client slot so its private + * client and fake server never overlap the real server. */ + rc = whTestGroup_RunOne("whTest_MalformedCryptoResponse", + whTest_MalformedCryptoResponse, NULL); + if (rc != 0 && rc != WH_TEST_SKIPPED && miscRc == 0) { + miscRc = rc; + } } rc = pthread_create(&sthread, NULL, _serverThread, NULL); From 9668c2ddbed71ed9601da889354f5264d7c38ff3 Mon Sep 17 00:00:00 2001 From: Yosuke Shimizu Date: Tue, 21 Jul 2026 15:00:29 +0900 Subject: [PATCH 2/2] Validate Curve25519 keygen response against received length --- src/wh_client_crypto.c | 8 + .../posix/wh_test_malformed_response.c | 144 +++++++++++------- 2 files changed, 100 insertions(+), 52 deletions(-) diff --git a/src/wh_client_crypto.c b/src/wh_client_crypto.c index b47a4eb4b..640733f8c 100644 --- a/src/wh_client_crypto.c +++ b/src/wh_client_crypto.c @@ -3008,6 +3008,14 @@ static int _Curve25519MakeKey(whClientContext* ctx, uint16_t size, (uint8_t**)&res); /* wolfCrypt allows positive error codes on success in some scenarios */ if (ret >= 0) { + const size_t hdr_sz = + sizeof(whMessageCrypto_GenericResponseHeader) + sizeof(*res); + + /* Defensive bound: res->len must fit within the received frame */ + if (data_len < hdr_sz || res->len > (data_len - hdr_sz)) { + return WH_ERROR_ABORTED; + } + WH_DEBUG_CLIENT_VERBOSE("Curve25519 KeyGen Res recv:keyid:%u, len:%u, " "ret:%d\n", (unsigned int)res->keyId, (unsigned int)res->len, ret); diff --git a/test-refactor/posix/wh_test_malformed_response.c b/test-refactor/posix/wh_test_malformed_response.c index 9ce3cebb9..e2e532b66 100644 --- a/test-refactor/posix/wh_test_malformed_response.c +++ b/test-refactor/posix/wh_test_malformed_response.c @@ -38,6 +38,7 @@ !defined(WOLFHSM_CFG_NO_CRYPTO) #include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/wolfcrypt/curve25519.h" #include "wolfssl/wolfcrypt/ecc.h" #include "wolfssl/wolfcrypt/ed25519.h" #include "wolfssl/wolfcrypt/rsa.h" @@ -52,11 +53,9 @@ #define WH_TEST_MALFORMED_BUFFER_SIZE 4096 -/* Kept well inside WOLFHSM_CFG_COMM_DATA_LEN so only a frame-length - * check rejects it, not a buffer-capacity one. */ +/* Inside WOLFHSM_CFG_COMM_DATA_LEN, so only a frame-length check rejects it */ #define WH_TEST_MALFORMED_CLAIMED_SZ 64 -/* Malformed frame shapes, ordered as the client drives them. */ typedef enum { WH_TEST_MALFORMED_TRUNCATED = 0, WH_TEST_MALFORMED_OVERSIZED, @@ -71,17 +70,13 @@ typedef struct { uint16_t resSize; /* size of the algorithm's response struct */ } whTestMalformedCase; -/* Every keygen response in wh_message_crypto.h opens with this pair, so - * the fake server fills them all the same way. */ +/* Every keygen response opens with this pair */ typedef struct { uint32_t keyId; uint32_t len; } whTestMalformedKeyGenBody; -/* Client calls. The key contexts never receive material, so a local - * wolfCrypt devId suffices. */ - static int _callEd25519MakeKey(whClientContext* client) { ed25519_key key[1]; @@ -124,8 +119,20 @@ static int _callRsaMakeKey(whClientContext* client) return ret; } -/* Curve25519 keygen is absent on purpose: it has no frame check yet, - * so a row for it would fail until that path is fixed. */ +static int _callCurve25519MakeKey(whClientContext* client) +{ + curve25519_key key[1]; + int ret; + + ret = wc_curve25519_init_ex(key, NULL, INVALID_DEVID); + if (ret != 0) { + return ret; + } + ret = wh_Client_Curve25519MakeExportKey(client, CURVE25519_KEYSIZE, key); + wc_curve25519_free(key); + return ret; +} + static const whTestMalformedCase _malformedCases[] = { {"Ed25519 keygen", _callEd25519MakeKey, (uint16_t)sizeof(whMessageCrypto_Ed25519KeyGenResponse)}, @@ -133,6 +140,8 @@ static const whTestMalformedCase _malformedCases[] = { (uint16_t)sizeof(whMessageCrypto_EccKeyGenResponse)}, {"RSA keygen", _callRsaMakeKey, (uint16_t)sizeof(whMessageCrypto_RsaKeyGenResponse)}, + {"Curve25519 keygen", _callCurve25519MakeKey, + (uint16_t)sizeof(whMessageCrypto_Curve25519KeyGenResponse)}, }; #define WH_TEST_MALFORMED_CASE_COUNT \ @@ -140,12 +149,14 @@ static const whTestMalformedCase _malformedCases[] = { static const struct timespec WH_TEST_MALFORMED_ONE_MS = {0, 1000000}; -/* Set by the client thread so a failure reaches the caller. */ +/* Bounds the 1 ms retry loops so a stalled peer fails the suite, not hangs it */ +#define WH_TEST_MALFORMED_MAX_TRIES 5000 + static int _malformedClientRc = WH_TEST_SUCCESS; +static int _malformedServerRc = WH_TEST_SUCCESS; -/* Fake server. Echoes the request kind and sequence so the client - * accepts the reply, then declares a payload the frame lacks. */ +/* Echoes the request kind and seq so the client accepts the reply */ static void* _malformedServerThread(void* cf) { whCommServerConfig* config = (whCommServerConfig*)cf; @@ -157,8 +168,10 @@ static void* _malformedServerThread(void* cf) uint16_t rx_req_type = 0; uint16_t rx_req_seq = 0; uint16_t tx_resp_len = 0; + size_t step; size_t shape; size_t idx; + int tries; int ret; whMessageCrypto_GenericResponseHeader* hdr = @@ -169,45 +182,69 @@ static void* _malformedServerThread(void* cf) ret = wh_CommServer_Init(server, config, NULL, NULL); WH_TEST_ASSERT_MSG(0 == ret, "Fake server Init: ret=%d", ret); - for (shape = 0; shape < (size_t)WH_TEST_MALFORMED_SHAPE_COUNT; shape++) { - for (idx = 0; idx < WH_TEST_MALFORMED_CASE_COUNT; idx++) { - do { - ret = wh_CommServer_RecvRequest(server, &rx_req_flags, - &rx_req_type, &rx_req_seq, - &rx_req_len, sizeof(rx_req), - rx_req); - } while ((ret == WH_ERROR_NOTREADY) && - (nanosleep(&WH_TEST_MALFORMED_ONE_MS, NULL) == 0)); - WH_TEST_ASSERT_MSG(0 == ret, "Fake server RecvRequest: ret=%d", - ret); - - memset(tx_resp, 0, sizeof(tx_resp)); - /* algoType must come from the crypto request header, not the - * comm kind, or the client rejects the reply as a mismatch - * before it ever reaches the bounds check. */ - hdr->rc = WH_ERROR_OK; - hdr->algoType = - ((whMessageCrypto_GenericRequestHeader*)rx_req)->algoType; - - if (shape == (size_t)WH_TEST_MALFORMED_TRUNCATED) { - /* Stop short of the response struct the client reads */ - tx_resp_len = (uint16_t)sizeof(*hdr); - } - else { - body->keyId = 0; - body->len = WH_TEST_MALFORMED_CLAIMED_SZ; - tx_resp_len = - (uint16_t)(sizeof(*hdr) + _malformedCases[idx].resSize); + /* Flattened so a timeout exits the exchange in one break */ + for (step = 0; step < (size_t)WH_TEST_MALFORMED_SHAPE_COUNT * + WH_TEST_MALFORMED_CASE_COUNT; + step++) { + shape = step / WH_TEST_MALFORMED_CASE_COUNT; + idx = step % WH_TEST_MALFORMED_CASE_COUNT; + + tries = 0; + do { + ret = wh_CommServer_RecvRequest(server, &rx_req_flags, + &rx_req_type, &rx_req_seq, + &rx_req_len, sizeof(rx_req), + rx_req); + if (ret != WH_ERROR_NOTREADY) { + break; } + /* Ignored: ending the loop on an interrupted sleep would + * strand the client waiting for a response. */ + (void)nanosleep(&WH_TEST_MALFORMED_ONE_MS, NULL); + tries++; + } while (tries < WH_TEST_MALFORMED_MAX_TRIES); + + if (ret != WH_ERROR_OK) { + WH_ERROR_PRINT("Fake server RecvRequest for %s: ret=%d\n", + _malformedCases[idx].name, ret); + _malformedServerRc = WH_TEST_FAIL; + break; + } + + memset(tx_resp, 0, sizeof(tx_resp)); + /* From the request header, not the comm kind, or the client + * rejects the reply before reaching the bounds check. */ + hdr->rc = WH_ERROR_OK; + hdr->algoType = + ((whMessageCrypto_GenericRequestHeader*)rx_req)->algoType; - do { - ret = wh_CommServer_SendResponse(server, rx_req_flags, - rx_req_type, rx_req_seq, - tx_resp_len, tx_resp); - } while ((ret == WH_ERROR_NOTREADY) && - (nanosleep(&WH_TEST_MALFORMED_ONE_MS, NULL) == 0)); - WH_TEST_ASSERT_MSG(0 == ret, "Fake server SendResponse: ret=%d", - ret); + if (shape == (size_t)WH_TEST_MALFORMED_TRUNCATED) { + /* Stop short of the response struct the client reads */ + tx_resp_len = (uint16_t)sizeof(*hdr); + } + else { + body->keyId = 0; + body->len = WH_TEST_MALFORMED_CLAIMED_SZ; + tx_resp_len = + (uint16_t)(sizeof(*hdr) + _malformedCases[idx].resSize); + } + + tries = 0; + do { + ret = wh_CommServer_SendResponse(server, rx_req_flags, rx_req_type, + rx_req_seq, tx_resp_len, tx_resp); + if (ret != WH_ERROR_NOTREADY) { + break; + } + (void)nanosleep(&WH_TEST_MALFORMED_ONE_MS, NULL); + tries++; + } while (tries < WH_TEST_MALFORMED_MAX_TRIES); + + if (ret != WH_ERROR_OK) { + WH_ERROR_PRINT("Fake server SendResponse for %s: ret=%d\n", + _malformedCases[idx].name, ret); + _malformedServerRc = WH_TEST_FAIL; + break; } } @@ -251,7 +288,6 @@ static void* _malformedClientThread(void* cf) int whTest_MalformedCryptoResponse(void* ctx) { - /* Transport memory shared by the client and fake server */ uint8_t req[WH_TEST_MALFORMED_BUFFER_SIZE] = {0}; uint8_t resp[WH_TEST_MALFORMED_BUFFER_SIZE] = {0}; @@ -290,6 +326,7 @@ int whTest_MalformedCryptoResponse(void* ctx) (void)ctx; _malformedClientRc = WH_TEST_SUCCESS; + _malformedServerRc = WH_TEST_SUCCESS; rc = pthread_create(&sthread, NULL, _malformedServerThread, cs_conf); if (rc != 0) { @@ -308,7 +345,10 @@ int whTest_MalformedCryptoResponse(void* ctx) (void)pthread_join(cthread, NULL); (void)pthread_join(sthread, NULL); - return _malformedClientRc; + if (_malformedClientRc != WH_TEST_SUCCESS) { + return _malformedClientRc; + } + return _malformedServerRc; } #else /* !WOLFHSM_CFG_TEST_POSIX || !WOLFHSM_CFG_ENABLE_CLIENT ||