Skip to content

Commit cc1b033

Browse files
committed
Add zeroization for stack buffers, add test for write protect
1 parent 5ac5385 commit cc1b033

2 files changed

Lines changed: 245 additions & 0 deletions

File tree

src/wh_server_she.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,10 @@ static int _ExportRamKey(whServerContext* server, uint16_t magic,
895895
resp_packet);
896896
*out_resp_size = sizeof(resp);
897897

898+
ForceZero(kdfInput, sizeof(kdfInput));
899+
ForceZero(cmacOutput, sizeof(cmacOutput));
900+
ForceZero(tmpKey, sizeof(tmpKey));
901+
898902
return ret;
899903
}
900904

@@ -998,6 +1002,10 @@ static int _InitRnd(whServerContext* server, uint16_t magic, uint16_t req_size,
9981002
(void)wh_MessageShe_TranslateInitRngResponse(magic, &resp, resp_packet);
9991003
*out_resp_size = sizeof(resp);
10001004

1005+
ForceZero(kdfInput, sizeof(kdfInput));
1006+
ForceZero(cmacOutput, sizeof(cmacOutput));
1007+
ForceZero(tmpKey, sizeof(tmpKey));
1008+
10011009
return ret;
10021010
}
10031011

@@ -1189,6 +1197,9 @@ static int _EncEcb(whServerContext* server, uint16_t magic, uint16_t req_size,
11891197
}
11901198
resp.rc = _TranslateSheReturnCode(ret);
11911199
(void)wh_MessageShe_TranslateEncEcbResponse(magic, &resp, resp_packet);
1200+
1201+
ForceZero(tmpKey, sizeof(tmpKey));
1202+
11921203
return ret;
11931204
}
11941205

@@ -1270,6 +1281,8 @@ static int _EncCbc(whServerContext* server, uint16_t magic, uint16_t req_size,
12701281
resp.rc = _TranslateSheReturnCode(ret);
12711282
(void)wh_MessageShe_TranslateEncCbcResponse(magic, &resp, resp_packet);
12721283

1284+
ForceZero(tmpKey, sizeof(tmpKey));
1285+
12731286
return ret;
12741287
}
12751288

@@ -1351,6 +1364,8 @@ static int _DecEcb(whServerContext* server, uint16_t magic, uint16_t req_size,
13511364
resp.rc = _TranslateSheReturnCode(ret);
13521365
(void)wh_MessageShe_TranslateDecEcbResponse(magic, &resp, resp_packet);
13531366

1367+
ForceZero(tmpKey, sizeof(tmpKey));
1368+
13541369
return ret;
13551370
}
13561371

@@ -1432,6 +1447,8 @@ static int _DecCbc(whServerContext* server, uint16_t magic, uint16_t req_size,
14321447
resp.rc = _TranslateSheReturnCode(ret);
14331448
(void)wh_MessageShe_TranslateDecCbcResponse(magic, &resp, resp_packet);
14341449

1450+
ForceZero(tmpKey, sizeof(tmpKey));
1451+
14351452
return ret;
14361453
}
14371454

@@ -1487,6 +1504,8 @@ static int _GenerateMac(whServerContext* server, uint16_t magic,
14871504
(void)wh_MessageShe_TranslateGenMacResponse(magic, &resp, resp_packet);
14881505
*out_resp_size = sizeof(resp);
14891506

1507+
ForceZero(tmpKey, sizeof(tmpKey));
1508+
14901509
return ret;
14911510
}
14921511

@@ -1560,6 +1579,8 @@ static int _VerifyMac(whServerContext* server, uint16_t magic,
15601579
(void)wh_MessageShe_TranslateVerifyMacResponse(magic, &resp, resp_packet);
15611580
*out_resp_size = sizeof(resp);
15621581

1582+
ForceZero(tmpKey, sizeof(tmpKey));
1583+
15631584
return ret;
15641585
}
15651586

test/wh_test_she.c

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,227 @@ static int whTest_SheClientConfigBoundarySecureBoot(whClientConfig* config)
576576
}
577577
#endif /* WOLFHSM_CFG_TEST_POSIX && WOLFHSM_CFG_ENABLE_CLIENT && \
578578
WOLFHSM_CFG_ENABLE_SERVER */
579+
580+
#if defined(WOLFHSM_CFG_TEST_POSIX) && \
581+
defined(WOLFHSM_CFG_ENABLE_CLIENT) && \
582+
defined(WOLFHSM_CFG_ENABLE_SERVER)
583+
/* Test that a key with WH_SHE_FLAG_WRITE_PROTECT cannot be overwritten
584+
* via SHE LoadKey, and that ERC_WRITE_PROTECTED is returned */
585+
static int whTest_SheWriteProtect(whClientConfig* config)
586+
{
587+
int ret = 0;
588+
WC_RNG rng[1];
589+
Cmac cmac[1];
590+
whClientContext client[1] = {0};
591+
uint8_t sheUid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593+
0x01};
594+
uint8_t secretKey[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2,
595+
0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf,
596+
0x4f, 0x3c};
597+
uint8_t rawKey[] = {0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09,
598+
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
599+
0x01, 0x00};
600+
uint8_t zeros[WH_SHE_BOOT_MAC_PREFIX_LEN] = {0};
601+
uint8_t bootMacKey[WH_SHE_KEY_SZ] = {0};
602+
uint8_t bootloader[512];
603+
uint8_t bootMacDigest[WH_SHE_KEY_SZ] = {0};
604+
uint32_t digestSz = sizeof(bootMacDigest);
605+
uint32_t bootloaderSz = sizeof(bootloader);
606+
uint8_t messageOne[WH_SHE_M1_SZ];
607+
uint8_t messageTwo[WH_SHE_M2_SZ];
608+
uint8_t messageThree[WH_SHE_M3_SZ];
609+
uint8_t messageFour[WH_SHE_M4_SZ];
610+
uint8_t messageFive[WH_SHE_M5_SZ];
611+
uint32_t outClientId = 0;
612+
uint32_t outServerId = 0;
613+
const uint32_t WP_TEST_KEY_ID = 4;
614+
615+
if (config == NULL) {
616+
return WH_ERROR_BADARGS;
617+
}
618+
619+
WH_TEST_RETURN_ON_FAIL(
620+
wh_Client_Init(client, config));
621+
WH_TEST_RETURN_ON_FAIL(
622+
wh_Client_CommInit(client, &outClientId, &outServerId));
623+
624+
/* generate boot MAC key and fake bootloader */
625+
if ((ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID)) != 0) {
626+
WH_ERROR_PRINT(
627+
"Failed to wc_InitRng_ex %d\n", ret);
628+
goto exit_wp;
629+
}
630+
if ((ret = wc_RNG_GenerateBlock(
631+
rng, bootMacKey, sizeof(bootMacKey))) != 0) {
632+
WH_ERROR_PRINT(
633+
"Failed to wc_RNG_GenerateBlock %d\n", ret);
634+
wc_FreeRng(rng);
635+
goto exit_wp;
636+
}
637+
if ((ret = wc_RNG_GenerateBlock(
638+
rng, bootloader, sizeof(bootloader))) != 0) {
639+
WH_ERROR_PRINT(
640+
"Failed to wc_RNG_GenerateBlock %d\n", ret);
641+
wc_FreeRng(rng);
642+
goto exit_wp;
643+
}
644+
wc_FreeRng(rng);
645+
646+
/* compute boot MAC digest: CMAC(0..0 | size | bootloader) */
647+
if ((ret = wc_InitCmac(cmac, bootMacKey,
648+
sizeof(bootMacKey), WC_CMAC_AES, NULL)) != 0) {
649+
WH_ERROR_PRINT(
650+
"Failed to wc_InitCmac %d\n", ret);
651+
goto exit_wp;
652+
}
653+
if ((ret = wc_CmacUpdate(
654+
cmac, zeros, sizeof(zeros))) != 0) {
655+
WH_ERROR_PRINT(
656+
"Failed to wc_CmacUpdate %d\n", ret);
657+
goto exit_wp;
658+
}
659+
if ((ret = wc_CmacUpdate(cmac,
660+
(uint8_t*)&bootloaderSz,
661+
sizeof(bootloaderSz))) != 0) {
662+
WH_ERROR_PRINT(
663+
"Failed to wc_CmacUpdate %d\n", ret);
664+
goto exit_wp;
665+
}
666+
if ((ret = wc_CmacUpdate(
667+
cmac, bootloader, sizeof(bootloader))) != 0) {
668+
WH_ERROR_PRINT(
669+
"Failed to wc_CmacUpdate %d\n", ret);
670+
goto exit_wp;
671+
}
672+
digestSz = AES_BLOCK_SIZE;
673+
if ((ret = wc_CmacFinal(cmac, bootMacDigest,
674+
(word32*)&digestSz)) != 0) {
675+
WH_ERROR_PRINT(
676+
"Failed to wc_CmacFinal %d\n", ret);
677+
goto exit_wp;
678+
}
679+
680+
/* pre-program boot MAC key and digest for secure boot */
681+
if ((ret = wh_Client_ShePreProgramKey(
682+
client, WH_SHE_BOOT_MAC_KEY_ID, 0,
683+
bootMacKey, sizeof(bootMacKey))) != 0) {
684+
WH_ERROR_PRINT(
685+
"Failed to pre-program boot MAC key %d\n", ret);
686+
goto exit_wp;
687+
}
688+
if ((ret = wh_Client_ShePreProgramKey(
689+
client, WH_SHE_BOOT_MAC, 0,
690+
bootMacDigest, sizeof(bootMacDigest))) != 0) {
691+
WH_ERROR_PRINT(
692+
"Failed to pre-program boot MAC digest %d\n",
693+
ret);
694+
goto exit_wp;
695+
}
696+
697+
/* set the SHE UID */
698+
if ((ret = wh_Client_SheSetUid(
699+
client, sheUid, sizeof(sheUid))) != 0) {
700+
WH_ERROR_PRINT(
701+
"Failed to wh_Client_SheSetUid %d\n", ret);
702+
goto exit_wp;
703+
}
704+
705+
/* secure boot must succeed before SHE LoadKey is allowed */
706+
if ((ret = wh_Client_SheSecureBoot(
707+
client, bootloader, bootloaderSz)) != 0) {
708+
WH_ERROR_PRINT(
709+
"Failed to wh_Client_SheSecureBoot %d\n", ret);
710+
goto exit_wp;
711+
}
712+
713+
/* pre-program the secret key as auth key */
714+
if ((ret = wh_Client_ShePreProgramKey(
715+
client, WH_SHE_SECRET_KEY_ID, 0,
716+
secretKey, sizeof(secretKey))) != 0) {
717+
WH_ERROR_PRINT(
718+
"Failed to pre-program secret key %d\n", ret);
719+
goto exit_wp;
720+
}
721+
722+
/* pre-program the target key WITH write protect flag */
723+
if ((ret = wh_Client_ShePreProgramKey(
724+
client, WP_TEST_KEY_ID,
725+
WH_SHE_FLAG_WRITE_PROTECT,
726+
rawKey, sizeof(rawKey))) != 0) {
727+
WH_ERROR_PRINT(
728+
"Failed to pre-program write-protected key %d\n",
729+
ret);
730+
goto exit_wp;
731+
}
732+
733+
/* generate loadable key messages for the protected slot */
734+
if ((ret = wh_She_GenerateLoadableKey(
735+
WP_TEST_KEY_ID, WH_SHE_SECRET_KEY_ID,
736+
1, 0, sheUid, rawKey, secretKey,
737+
messageOne, messageTwo, messageThree,
738+
messageFour, messageFive)) != 0) {
739+
WH_ERROR_PRINT(
740+
"Failed to generate loadable key %d\n", ret);
741+
goto exit_wp;
742+
}
743+
744+
/* attempt to load key into the write-protected slot */
745+
ret = wh_Client_SheLoadKey(client, messageOne, messageTwo,
746+
messageThree, messageFour,
747+
messageFive);
748+
if (ret != WH_SHE_ERC_WRITE_PROTECTED) {
749+
WH_ERROR_PRINT(
750+
"Expected WH_SHE_ERC_WRITE_PROTECTED, got %d\n",
751+
ret);
752+
ret = WH_ERROR_ABORTED;
753+
goto exit_wp;
754+
}
755+
756+
/* load succeeded (returned the expected error) */
757+
ret = 0;
758+
WH_TEST_PRINT("SHE write protect test SUCCESS\n");
759+
760+
/* destroy test keys to prevent NVM leaks */
761+
if ((ret = _destroySheKey(
762+
client, WH_SHE_BOOT_MAC_KEY_ID)) != 0) {
763+
WH_ERROR_PRINT(
764+
"Failed to _destroySheKey, ret=%d\n", ret);
765+
goto exit_wp;
766+
}
767+
if ((ret = _destroySheKey(
768+
client, WH_SHE_BOOT_MAC)) != 0) {
769+
WH_ERROR_PRINT(
770+
"Failed to _destroySheKey, ret=%d\n", ret);
771+
goto exit_wp;
772+
}
773+
if ((ret = _destroySheKey(
774+
client, WH_SHE_SECRET_KEY_ID)) != 0) {
775+
WH_ERROR_PRINT(
776+
"Failed to _destroySheKey, ret=%d\n", ret);
777+
goto exit_wp;
778+
}
779+
if ((ret = _destroySheKey(client, WP_TEST_KEY_ID)) != 0) {
780+
WH_ERROR_PRINT(
781+
"Failed to _destroySheKey, ret=%d\n", ret);
782+
goto exit_wp;
783+
}
784+
785+
exit_wp:
786+
WH_TEST_RETURN_ON_FAIL(wh_Client_CommClose(client));
787+
788+
if (ret == 0) {
789+
WH_TEST_RETURN_ON_FAIL(wh_Client_Cleanup(client));
790+
}
791+
else {
792+
wh_Client_Cleanup(client);
793+
}
794+
795+
return ret;
796+
}
797+
#endif /* WOLFHSM_CFG_TEST_POSIX && WOLFHSM_CFG_ENABLE_CLIENT && \
798+
WOLFHSM_CFG_ENABLE_SERVER */
799+
579800
#endif /* WOLFHSM_CFG_ENABLE_CLIENT */
580801

581802
#ifdef WOLFHSM_CFG_ENABLE_SERVER
@@ -1341,6 +1562,9 @@ int whTest_She(void)
13411562
WH_TEST_PRINT("Testing SHE: (pthread) mem boundary secure boot...\n");
13421563
WH_TEST_RETURN_ON_FAIL(wh_ClientServer_MemThreadTest(
13431564
whTest_SheClientConfigBoundarySecureBoot));
1565+
WH_TEST_PRINT("Testing SHE: (pthread) mem write protect...\n");
1566+
WH_TEST_RETURN_ON_FAIL(
1567+
wh_ClientServer_MemThreadTest(whTest_SheWriteProtect));
13441568
return 0;
13451569
}
13461570
#endif

0 commit comments

Comments
 (0)