Skip to content

Commit a00676d

Browse files
committed
Fix SHE master ECU key fallback writing metadata to wrong variable
In wh_Server_KeystoreReadKey, the SHE master ECU key fallback path (when the key is not found in cache or NVM) correctly zeroed outMeta but then wrote len and id to the local stack variable `meta` instead of the caller's output parameter `outMeta`. This left the caller with a zeroed metadata struct (len=0, id=0), contradicting the intended behavior of returning WH_SHE_KEY_SZ and the correct keyId. Also fix two related issues in the same function: - Use sizeof(*outMeta) instead of sizeof(meta) in memset/memcpy calls targeting outMeta, for clarity and consistency with the target variable. - Add a NULL check on `out` before memset in the SHE fallback, matching the guards already present in the cache and NVM paths. Add a direct server-side test that exercises the fallback by reading the master ECU key without provisioning it, verifying the returned metadata contains the correct len and id. Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
1 parent 95cb29c commit a00676d

2 files changed

Lines changed: 116 additions & 5 deletions

File tree

src/wh_server_keystore.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ int wh_Server_KeystoreReadKey(whServerContext* server, whKeyId keyId,
675675
*outSz = meta->len;
676676
/* read meta */
677677
if (outMeta != NULL)
678-
memcpy((uint8_t*)outMeta, (uint8_t*)meta, sizeof(meta));
678+
memcpy((uint8_t*)outMeta, (uint8_t*)meta, sizeof(*outMeta));
679679
/* read the object */
680680
if (out != NULL)
681681
ret = wh_Nvm_Read(server->nvm, keyId, 0, *outSz, out);
@@ -689,13 +689,14 @@ int wh_Server_KeystoreReadKey(whServerContext* server, whKeyId keyId,
689689
if ((ret == WH_ERROR_NOTFOUND) &&
690690
(WH_KEYID_TYPE(keyId) == WH_KEYTYPE_SHE) &&
691691
(WH_KEYID_ID(keyId) == WH_SHE_MASTER_ECU_KEY_ID)) {
692-
memset(out, 0, WH_SHE_KEY_SZ);
692+
if (out != NULL)
693+
memset(out, 0, WH_SHE_KEY_SZ);
693694
*outSz = WH_SHE_KEY_SZ;
694695
if (outMeta != NULL) {
695696
/* need empty flags and correct length and id */
696-
memset(outMeta, 0, sizeof(meta));
697-
meta->len = WH_SHE_KEY_SZ;
698-
meta->id = keyId;
697+
memset(outMeta, 0, sizeof(*outMeta));
698+
outMeta->len = WH_SHE_KEY_SZ;
699+
outMeta->id = keyId;
699700
}
700701
ret = 0;
701702
}

test/wh_test_she.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "wolfhsm/wh_nvm.h"
3434
#include "wolfhsm/wh_nvm_flash.h"
3535
#include "wolfhsm/wh_flash_ramsim.h"
36+
#include "wolfhsm/wh_server_keystore.h"
3637
#endif
3738

3839
#include "wolfhsm/wh_comm.h"
@@ -594,10 +595,119 @@ static int wh_ClientServer_MemThreadTest(void)
594595
#endif /* WOLFHSM_CFG_TEST_POSIX && WOLFHSM_CFG_ENABLE_CLIENT && \
595596
WOLFHSM_CFG_ENABLE_SERVER */
596597

598+
#if defined(WOLFHSM_CFG_ENABLE_SERVER)
599+
static int wh_She_TestMasterEcuKeyFallback(void)
600+
{
601+
int ret = 0;
602+
whServerContext server[1] = {0};
603+
whNvmMetadata outMeta[1] = {0};
604+
uint8_t keyBuf[WH_SHE_KEY_SZ] = {0};
605+
uint32_t keySz = sizeof(keyBuf);
606+
uint8_t zeros[WH_SHE_KEY_SZ] = {0};
607+
whKeyId masterEcuKeyId;
608+
609+
/* Transport (not used, but required for server init) */
610+
uint8_t reqBuf[BUFFER_SIZE] = {0};
611+
uint8_t respBuf[BUFFER_SIZE] = {0};
612+
whTransportMemConfig tmcf[1] = {{
613+
.req = (whTransportMemCsr*)reqBuf,
614+
.req_size = sizeof(reqBuf),
615+
.resp = (whTransportMemCsr*)respBuf,
616+
.resp_size = sizeof(respBuf),
617+
}};
618+
whTransportServerCb tscb[1] = {WH_TRANSPORT_MEM_SERVER_CB};
619+
whTransportMemServerContext tmsc[1] = {0};
620+
whCommServerConfig cs_conf[1] = {{
621+
.transport_cb = tscb,
622+
.transport_context = (void*)tmsc,
623+
.transport_config = (void*)tmcf,
624+
.server_id = 124,
625+
}};
626+
627+
/* RamSim Flash state and configuration */
628+
uint8_t memory[FLASH_RAM_SIZE] = {0};
629+
whFlashRamsimCtx fc[1] = {0};
630+
whFlashRamsimCfg fc_conf[1] = {{
631+
.size = FLASH_RAM_SIZE,
632+
.sectorSize = FLASH_SECTOR_SIZE,
633+
.pageSize = FLASH_PAGE_SIZE,
634+
.erasedByte = ~(uint8_t)0,
635+
.memory = memory,
636+
}};
637+
const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB};
638+
639+
/* NVM */
640+
whNvmFlashConfig nf_conf[1] = {{
641+
.cb = fcb,
642+
.context = fc,
643+
.config = fc_conf,
644+
}};
645+
whNvmFlashContext nfc[1] = {0};
646+
whNvmCb nfcb[1] = {WH_NVM_FLASH_CB};
647+
whNvmConfig n_conf[1] = {{
648+
.cb = nfcb,
649+
.context = nfc,
650+
.config = nf_conf,
651+
}};
652+
whNvmContext nvm[1] = {{0}};
653+
654+
/* Crypto context */
655+
whServerCryptoContext crypto[1] = {{
656+
.devId = INVALID_DEVID,
657+
}};
658+
659+
whServerSheContext she[1];
660+
memset(she, 0, sizeof(she));
661+
662+
whServerConfig s_conf[1] = {{
663+
.comm_config = cs_conf,
664+
.nvm = nvm,
665+
.crypto = crypto,
666+
.she = she,
667+
.devId = INVALID_DEVID,
668+
}};
669+
670+
WH_TEST_RETURN_ON_FAIL(wh_Nvm_Init(nvm, n_conf));
671+
WH_TEST_RETURN_ON_FAIL(wolfCrypt_Init());
672+
WH_TEST_RETURN_ON_FAIL(wc_InitRng_ex(crypto->rng, NULL, crypto->devId));
673+
WH_TEST_RETURN_ON_FAIL(wh_Server_Init(server, s_conf));
674+
WH_TEST_RETURN_ON_FAIL(
675+
wh_Server_SetConnected(server, WH_COMM_CONNECTED));
676+
677+
masterEcuKeyId = WH_MAKE_KEYID(WH_KEYTYPE_SHE,
678+
server->comm->client_id,
679+
WH_SHE_MASTER_ECU_KEY_ID);
680+
681+
/* Fill keyBuf with non-zero to ensure it gets overwritten */
682+
memset(keyBuf, 0xFF, sizeof(keyBuf));
683+
684+
/* Read master ECU key when it has never been provisioned */
685+
ret = wh_Server_KeystoreReadKey(server, masterEcuKeyId, outMeta,
686+
keyBuf, &keySz);
687+
688+
WH_TEST_ASSERT_RETURN(ret == 0);
689+
WH_TEST_ASSERT_RETURN(keySz == WH_SHE_KEY_SZ);
690+
WH_TEST_ASSERT_RETURN(memcmp(keyBuf, zeros, WH_SHE_KEY_SZ) == 0);
691+
WH_TEST_ASSERT_RETURN(outMeta->len == WH_SHE_KEY_SZ);
692+
WH_TEST_ASSERT_RETURN(outMeta->id == masterEcuKeyId);
693+
694+
WH_TEST_PRINT("SHE master ECU key fallback metadata test SUCCESS\n");
695+
696+
wh_Server_Cleanup(server);
697+
wh_Nvm_Cleanup(nvm);
698+
wc_FreeRng(crypto->rng);
699+
wolfCrypt_Cleanup();
700+
701+
return 0;
702+
}
703+
#endif /* WOLFHSM_CFG_ENABLE_SERVER */
704+
597705
#if defined(WOLFHSM_CFG_TEST_POSIX) && defined(WOLFHSM_CFG_ENABLE_CLIENT) && \
598706
defined(WOLFHSM_CFG_ENABLE_SERVER)
599707
int whTest_She(void)
600708
{
709+
WH_TEST_PRINT("Testing SHE: master ECU key fallback...\n");
710+
WH_TEST_RETURN_ON_FAIL(wh_She_TestMasterEcuKeyFallback());
601711
WH_TEST_PRINT("Testing SHE: (pthread) mem...\n");
602712
WH_TEST_RETURN_ON_FAIL(wh_ClientServer_MemThreadTest());
603713
return 0;

0 commit comments

Comments
 (0)