Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions port/posix/posix_transport_shm.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,9 @@ int posixTransportShm_ClientStaticMemDmaCallback(
else if (oper == WH_DMA_OPER_CLIENT_READ_POST) {
if (isInDma == 0) {
uint8_t* ptr = (uint8_t*)dmaPtr + (uintptr_t)*xformedCliAddr;
/* Scrub key material before freeing. len is bounded by the temp
* buffer's XMALLOC, well within uint32_t for this transport. */
wh_Utils_ForceZero(ptr, (uint32_t)len);
XFREE(ptr, heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
Expand All @@ -611,6 +614,9 @@ int posixTransportShm_ClientStaticMemDmaCallback(
uint8_t* ptr = (uint8_t*)dmaPtr + (uintptr_t)*xformedCliAddr;
memcpy((void*)clientAddr, ptr,
len); /* copy results of what server wrote */
/* Scrub key material before freeing. len is bounded by the temp
* buffer's XMALLOC, well within uint32_t for this transport. */
wh_Utils_ForceZero(ptr, (uint32_t)len);
XFREE(ptr, heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
Expand Down
35 changes: 13 additions & 22 deletions src/wh_server_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1471,40 +1471,35 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,

if (req_size != sizeof(req)) {
/* Request is malformed */
rc = WH_ERROR_ABORTED;
resp.rc = WH_ERROR_ABORTED;
}
if (rc == WH_ERROR_OK) {
if (resp.rc == WH_ERROR_OK) {
/* Convert request struct */
wh_MessageCert_TranslateVerifyDmaRequest(
magic, (whMessageCert_VerifyDmaRequest*)req_packet, &req);

/* Process client address */
rc = wh_Server_DmaProcessClientAddress(
resp.rc = wh_Server_DmaProcessClientAddress(
server, req.cert_addr, &cert_data, req.cert_len,
WH_DMA_OPER_CLIENT_READ_PRE, (whServerDmaFlags){0});
if (rc == WH_ERROR_OK) {
if (resp.rc == WH_ERROR_OK) {
cert_dma_pre_ok = 1;
}
}
if (rc == WH_ERROR_OK) {
if (resp.rc == WH_ERROR_OK) {
/* Process the verify action */
rc = WH_SERVER_NVM_LOCK(server);
if (rc == WH_ERROR_OK) {
rc = wh_Server_CertVerifyAcert(
resp.rc = WH_SERVER_NVM_LOCK(server);
if (resp.rc == WH_ERROR_OK) {
resp.rc = wh_Server_CertVerifyAcert(
server, cert_data, req.cert_len, req.trustedRootNvmId);

(void)WH_SERVER_NVM_UNLOCK(server);
} /* WH_SERVER_NVM_LOCK() */

/* Signature verification error is not an error for the server,
* so propagate this error to the client in the response,
* otherwise return the error code from the verify action */
if (rc == ASN_SIG_CONFIRM_E || rc == ASN_SIG_OID_E) {
/* A signature verification failure is reported to the client,
* not treated as a server error */
if (resp.rc == ASN_SIG_CONFIRM_E || resp.rc == ASN_SIG_OID_E) {
resp.rc = WH_ERROR_CERT_VERIFY;
rc = WH_ERROR_OK;
}
else {
resp.rc = rc;
}
}
/* Always call POST for successful PRE, regardless of operation
Expand All @@ -1515,15 +1510,11 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
WH_DMA_OPER_CLIENT_READ_POST, (whServerDmaFlags){0});
}

/* Convert the response struct */
/* Convert the response struct. resp.rc now holds the final status
* on every path, so translate last with no post fixup */
wh_MessageCert_TranslateSimpleResponse(
magic, &resp, (whMessageCert_SimpleResponse*)resp_packet);
*out_resp_size = sizeof(resp);

/* If there was an error, return it in the response */
if (rc != WH_ERROR_OK) {
resp.rc = rc;
}
} break;
#endif /* WOLFHSM_CFG_DMA */
#endif /* WOLFHSM_CFG_CERTIFICATE_MANAGER_ACERT */
Expand Down
3 changes: 2 additions & 1 deletion src/wh_server_counter.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ int wh_Server_HandleCounter(whServerContext* server, uint16_t magic,
} break;

default:
ret = WH_ERROR_BADARGS;
*out_resp_size = 0;
ret = WH_ERROR_BADARGS;
break;
}

Expand Down
8 changes: 8 additions & 0 deletions src/wh_server_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -4134,6 +4134,10 @@ static int _HandleCmac(whServerContext* ctx, uint16_t magic, int devId,
}
}
WH_DEBUG_SERVER_VERBOSE("cmac end ret:%d\n", ret);
/* Scrub tmpKey and the Cmac context (AES schedule + k1/k2). Full struct
* zero avoids a wc_CmacFree double free. */
wh_Utils_ForceZero(tmpKey, sizeof(tmpKey));
wh_Utils_ForceZero(cmac, sizeof(cmac));
return ret;
}
#endif /* WOLFSSL_CMAC && !NO_AES && WOLFSSL_AES_DIRECT */
Expand Down Expand Up @@ -8275,6 +8279,10 @@ static int _HandleCmacDma(whServerContext* ctx, uint16_t magic, int devId,
}

WH_DEBUG_SERVER_VERBOSE("dma cmac end ret:%d\n", ret);
/* Scrub tmpKey and the Cmac context (AES schedule + k1/k2). Full struct
* zero avoids a wc_CmacFree double free. */
wh_Utils_ForceZero(tmpKey, sizeof(tmpKey));
wh_Utils_ForceZero(cmac, sizeof(cmac));
return ret;
}
#endif /* WOLFSSL_CMAC && !NO_AES && WOLFSSL_AES_DIRECT */
Expand Down
28 changes: 28 additions & 0 deletions test/wh_test_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#if defined(WOLFHSM_CFG_CERTIFICATE_MANAGER) && !defined(WOLFHSM_CFG_NO_CRYPTO)

#include "wolfhsm/wh_error.h"
#include "wolfhsm/wh_message.h"
#include "wolfhsm/wh_message_cert.h"

#ifdef WOLFHSM_CFG_ENABLE_SERVER
#include "wolfhsm/wh_server.h"
Expand Down Expand Up @@ -1657,6 +1659,32 @@ int whTest_CertClientAcertDma_ClientServerTestInternal(whClientContext* client)
client, attrCert_der, attrCert_der_len, rootCertB_id, &out_rc));
WH_TEST_ASSERT_RETURN(out_rc == WH_ERROR_CERT_VERIFY);

/* Regression test for finding 4235. A malformed (undersized) ACERT_DMA
* request must report an error on the wire, not a false success. Send a
* raw 1 byte request with the low level API and confirm resp.rc is not OK.
*/
WH_TEST_PRINT("Sending malformed ACERT_DMA request...\n");
{
uint8_t badReq = 0;
uint16_t rgroup, raction, rsize;
whMessageCert_SimpleResponse badResp = {0};

do {
rc = wh_Client_SendRequest(
client, WH_MESSAGE_GROUP_CERT,
WH_MESSAGE_CERT_ACTION_VERIFY_ACERT_DMA, sizeof(badReq),
&badReq);
} while (rc == WH_ERROR_NOTREADY);
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_OK);

do {
rc = wh_Client_RecvResponse(client, &rgroup, &raction, &rsize,
&badResp);
} while (rc == WH_ERROR_NOTREADY);
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_OK);
WH_TEST_ASSERT_RETURN(badResp.rc != WH_ERROR_OK);
}

/* Clean up - delete the trusted certificates */
WH_TEST_PRINT("Deleting trusted certificates...\n");
WH_TEST_RETURN_ON_FAIL(
Expand Down
19 changes: 19 additions & 0 deletions test/wh_test_clientserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,25 @@ static int _testClientCounter(whClientContext* client)
wh_Client_CounterRead(client, (whNvmId)i, &counter));
}

/* Invalid counter action: the default case reports a zero length
* response, not the stale request sized buffer. */
{
uint8_t reqbuf[8] = {0};
uint8_t respbuf[64] = {0};
uint16_t respGroup = 0;
uint16_t respAction = 0;
uint16_t respSz = 0xFFFF;

WH_TEST_RETURN_ON_FAIL(wh_Client_SendRequest(
client, WH_MESSAGE_GROUP_COUNTER, 0x7F, sizeof(reqbuf), reqbuf));
do {
rc = wh_Client_RecvResponse(client, &respGroup, &respAction,
&respSz, respbuf);
} while (rc == WH_ERROR_NOTREADY);
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_OK);
WH_TEST_ASSERT_RETURN(respSz == 0);
}

/* Ensure NVM is empty */
WH_TEST_RETURN_ON_FAIL(rc = wh_Client_NvmGetAvailable(
client, &server_rc, &avail_size, &avail_objects,
Expand Down
Loading
Loading