Skip to content

Commit e312cbb

Browse files
committed
WOLFCRYPT_TZ_WOLFHSM: Skoll review fixes + flash-adapter unit test
- callable: runtime flash config init (drop non-portable static cast), panic on init failures, volatile *rspSz read, clear borrowed NS pointers post-dispatch. - flash_hal: propagate hal_flash_* errors, hoist unlock/lock outside loop, per-iteration cached_sector wipe, validate config before copying into ctx, rename sector_base to sector_offset. - test-app: aes_inited guard, KeyEvict after KeyCommit, ForceZero consistency, drop redundant keyId reassignment. - test-app/Makefile: WOLFBOOT_LIB_WOLFHSM default for standalone test-app builds. - tools/unit-tests/unit-wolfhsm_flash_hal.c: 10-test host unit test for the flash adapter, modeled on unit-psa_store. CMSE pointer-range checks intentionally not applied: m33mu lacks TT/TTAT, and PKCS11/PSA/fwTPM siblings all skip CMSE
1 parent d6a38f6 commit e312cbb

6 files changed

Lines changed: 387 additions & 37 deletions

File tree

src/wolfhsm_callable.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <stdint.h>
1111
#include <string.h>
1212

13+
#include "loader.h"
1314
#include "store_sbrk.h"
1415
#include "wolfboot/wcs_wolfhsm.h"
1516
#include "wolfboot/wolfhsm_flash_hal.h"
@@ -49,11 +50,9 @@ extern uint32_t _flash_keyvault;
4950
extern uint32_t _flash_keyvault_size;
5051

5152
static whFlashH5Ctx g_flash_ctx;
52-
static const whFlashH5Ctx g_flash_cfg = {
53-
.base = (uint32_t)&_flash_keyvault,
54-
.size = (uint32_t)&_flash_keyvault_size,
55-
.partition_size = WCS_WOLFHSM_PARTITION_SIZE,
56-
};
53+
/* Fields filled at runtime in wcs_wolfhsm_init: pointer-to-integer casts of
54+
* linker symbols are not strictly conforming static initializers. */
55+
static whFlashH5Ctx g_flash_cfg;
5756

5857
static whNvmFlashContext g_nvm_flash_ctx;
5958
static whNvmFlashConfig g_nvm_flash_cfg = {
@@ -94,26 +93,29 @@ void wcs_wolfhsm_init(void)
9493
{
9594
int rc;
9695

96+
g_flash_cfg.base = (uint32_t)&_flash_keyvault;
97+
g_flash_cfg.size = (uint32_t)&_flash_keyvault_size;
98+
g_flash_cfg.partition_size = WCS_WOLFHSM_PARTITION_SIZE;
99+
97100
rc = wc_InitRng(g_crypto_ctx.rng);
98101
if (rc != 0) {
99-
return;
102+
wolfBoot_panic();
100103
}
101104
rc = wh_Nvm_Init(&g_nvm_ctx, &g_nvm_cfg);
102105
if (rc != WH_ERROR_OK) {
103-
return;
106+
wolfBoot_panic();
104107
}
105108
rc = wh_Server_Init(&g_server, &g_server_cfg);
106109
if (rc != WH_ERROR_OK) {
107-
return;
110+
wolfBoot_panic();
111+
}
112+
rc = wh_Server_SetConnected(&g_server, WH_COMM_CONNECTED);
113+
if (rc != WH_ERROR_OK) {
114+
wolfBoot_panic();
108115
}
109-
(void)wh_Server_SetConnected(&g_server, WH_COMM_CONNECTED);
110116
g_wolfhsm_ready = 1;
111117
}
112118

113-
/* Single NSC veneer. Per call: validate the NS pointers/sizes (single-fetch
114-
* defeats TOCTOU on *rspSz), park the buffers in the secure-side transport
115-
* context, run wh_Server_HandleRequestMessage exactly once, write back the
116-
* captured response size. */
117119
int CSME_NSE_API wcs_wolfhsm_transmit(const uint8_t *cmd, uint32_t cmdSz,
118120
uint8_t *rsp, uint32_t *rspSz)
119121
{
@@ -123,9 +125,8 @@ int CSME_NSE_API wcs_wolfhsm_transmit(const uint8_t *cmd, uint32_t cmdSz,
123125
if (cmd == NULL || rsp == NULL || rspSz == NULL) {
124126
return WH_ERROR_BADARGS;
125127
}
126-
/* Single fetch of the caller-supplied capacity; subsequent code uses
127-
* only this local copy. The NS caller cannot mutate it under us. */
128-
rsp_capacity = *rspSz;
128+
/* volatile read forbids the compiler from re-fetching *rspSz later. */
129+
rsp_capacity = *(volatile const uint32_t *)rspSz;
129130

130131
if (cmdSz == 0U || cmdSz > WH_COMM_MTU) {
131132
return WH_ERROR_BADARGS;
@@ -151,6 +152,13 @@ int CSME_NSE_API wcs_wolfhsm_transmit(const uint8_t *cmd, uint32_t cmdSz,
151152
} else {
152153
*rspSz = 0;
153154
}
155+
156+
g_srv_tx_ctx.req_buf = NULL;
157+
g_srv_tx_ctx.req_size = 0;
158+
g_srv_tx_ctx.rsp_buf = NULL;
159+
g_srv_tx_ctx.rsp_capacity = 0;
160+
g_srv_tx_ctx.request_pending = 0;
161+
154162
return rc;
155163
}
156164

src/wolfhsm_flash_hal.c

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#include "hal.h"
1414
#include "wolfboot/wolfhsm_flash_hal.h"
1515

16+
#include "wolfssl/wolfcrypt/settings.h"
17+
#include "wolfssl/wolfcrypt/misc.h"
18+
1619
#include "wolfhsm/wh_error.h"
1720
#include "wolfhsm/wh_flash.h"
1821

@@ -28,20 +31,22 @@ static uint8_t cached_sector[WHFH5_SECTOR_SIZE];
2831

2932
static int _Init(void *context, const void *config)
3033
{
31-
whFlashH5Ctx *ctx = (whFlashH5Ctx *)context;
34+
const whFlashH5Ctx *cfg = (const whFlashH5Ctx *)config;
35+
whFlashH5Ctx *ctx = (whFlashH5Ctx *)context;
3236

33-
if (ctx == NULL || config == NULL) {
37+
if (ctx == NULL || cfg == NULL) {
3438
return WH_ERROR_BADARGS;
3539
}
36-
*ctx = *((const whFlashH5Ctx *)config);
3740

38-
if (ctx->base == 0U || ctx->size == 0U || ctx->partition_size == 0U ||
39-
(ctx->base % WHFH5_SECTOR_SIZE) != 0U ||
40-
(ctx->size % WHFH5_SECTOR_SIZE) != 0U ||
41-
(ctx->partition_size % WHFH5_SECTOR_SIZE) != 0U ||
42-
ctx->size < (uint32_t)2 * ctx->partition_size) {
41+
if (cfg->base == 0U || cfg->size == 0U || cfg->partition_size == 0U ||
42+
(cfg->base % WHFH5_SECTOR_SIZE) != 0U ||
43+
(cfg->size % WHFH5_SECTOR_SIZE) != 0U ||
44+
(cfg->partition_size % WHFH5_SECTOR_SIZE) != 0U ||
45+
cfg->partition_size > cfg->size / 2U) {
4346
return WH_ERROR_BADARGS;
4447
}
48+
49+
*ctx = *cfg;
4550
return WH_ERROR_OK;
4651
}
4752

@@ -96,6 +101,7 @@ static int _Program(void *context, uint32_t offset, uint32_t size,
96101
{
97102
whFlashH5Ctx *ctx = (whFlashH5Ctx *)context;
98103
uint32_t written = 0U;
104+
int hrc = 0;
99105

100106
if (ctx == NULL || (size != 0U && data == NULL)) {
101107
return WH_ERROR_BADARGS;
@@ -107,28 +113,38 @@ static int _Program(void *context, uint32_t offset, uint32_t size,
107113
return WH_ERROR_OK;
108114
}
109115

116+
hal_flash_unlock();
110117
while (written < size) {
111118
uint32_t in_sector_off = (offset + written) % WHFH5_SECTOR_SIZE;
112-
uint32_t sector_base = (offset + written) - in_sector_off;
119+
uint32_t sector_offset = (offset + written) - in_sector_off;
113120
uint32_t chunk = WHFH5_SECTOR_SIZE - in_sector_off;
114121
if (chunk > size - written) {
115122
chunk = size - written;
116123
}
117124

118125
memcpy(cached_sector,
119-
(const uint8_t *)(ctx->base + sector_base),
126+
(const uint8_t *)(ctx->base + sector_offset),
120127
WHFH5_SECTOR_SIZE);
121128
memcpy(cached_sector + in_sector_off, data + written, chunk);
122129

123-
hal_flash_unlock();
124-
hal_flash_erase(ctx->base + sector_base, WHFH5_SECTOR_SIZE);
125-
hal_flash_write(ctx->base + sector_base, cached_sector,
126-
WHFH5_SECTOR_SIZE);
127-
hal_flash_lock();
130+
hrc = hal_flash_erase(ctx->base + sector_offset, WHFH5_SECTOR_SIZE);
131+
if (hrc == 0) {
132+
hrc = hal_flash_write(ctx->base + sector_offset, cached_sector,
133+
WHFH5_SECTOR_SIZE);
134+
}
135+
136+
/* Per-iteration wipe so a fault between sectors doesn't strand
137+
* plaintext keystore bytes in the static cache. */
138+
wc_ForceZero(cached_sector, sizeof(cached_sector));
128139

140+
if (hrc != 0) {
141+
break;
142+
}
129143
written += chunk;
130144
}
131-
return WH_ERROR_OK;
145+
hal_flash_lock();
146+
147+
return (hrc == 0) ? WH_ERROR_OK : WH_ERROR_ABORTED;
132148
}
133149

134150
static int _Erase(void *context, uint32_t offset, uint32_t size)

test-app/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
WOLFBOOT_LIB_WOLFSSL?=../lib/wolfssl
77
WOLFBOOT_LIB_WOLFTPM?=../lib/wolfTPM
8+
WOLFBOOT_LIB_WOLFHSM?=../lib/wolfHSM
89
WOLFSSL_LOCAL_OBJDIR?=wolfssl_obj
910
WOLFTPM_LOCAL_OBJDIR?=wolftpm_obj
1011
WOLFHSM_LOCAL_OBJDIR?=wolfhsm_obj

test-app/wcs/wolfhsm_test.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "wolfhsm/wh_keyid.h"
2222

2323
#include "wolfssl/wolfcrypt/aes.h"
24+
#include "wolfssl/wolfcrypt/misc.h"
2425
#include "wolfssl/wolfcrypt/random.h"
2526
#include "wolfssl/wolfcrypt/sha256.h"
2627

@@ -124,7 +125,8 @@ static int wolfhsm_test_aes_cached(whClientContext *client)
124125
static const uint8_t iv[16] = { 0 };
125126
Aes aes;
126127
uint8_t ct[16];
127-
uint16_t keyId = WH_KEYID_ERASED;
128+
uint16_t keyId = WH_KEYID_ERASED;
129+
int aes_inited = 0;
128130
int rc;
129131

130132
memset(&aes, 0, sizeof(aes));
@@ -142,6 +144,7 @@ static int wolfhsm_test_aes_cached(whClientContext *client)
142144
printf("wolfHSM AesInit failed: %d\r\n", rc);
143145
goto out;
144146
}
147+
aes_inited = 1;
145148

146149
rc = wh_Client_AesSetKeyId(&aes, keyId);
147150
if (rc != WH_ERROR_OK) {
@@ -166,7 +169,9 @@ static int wolfhsm_test_aes_cached(whClientContext *client)
166169
printf("wolfHSM AES ok\r\n");
167170

168171
out:
169-
wc_AesFree(&aes);
172+
if (aes_inited) {
173+
wc_AesFree(&aes);
174+
}
170175
(void)wh_Client_KeyEvict(client, keyId);
171176
return rc;
172177
}
@@ -188,11 +193,12 @@ static int wolfhsm_test_persist(whClientContext *client, int *boot_state)
188193
memcmp(out, persist_key, sizeof(persist_key)) == 0) {
189194
printf("wolfHSM second boot path, restored persisted key\r\n");
190195
*boot_state = WOLFHSM_TEST_SECOND_BOOT_OK;
196+
wc_ForceZero(out, sizeof(out));
191197
return 0;
192198
}
199+
wc_ForceZero(out, sizeof(out));
193200

194201
printf("wolfHSM first boot path, committing key to NVM\r\n");
195-
keyId = WH_MAKE_KEYID(0, WCS_WOLFHSM_CLIENT_ID, 1);
196202
rc = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ENCRYPT, NULL, 0,
197203
persist_key, (uint16_t)sizeof(persist_key),
198204
&keyId);
@@ -205,13 +211,14 @@ static int wolfhsm_test_persist(whClientContext *client, int *boot_state)
205211
printf("wolfHSM persist KeyCommit failed: %d\r\n", rc);
206212
return rc;
207213
}
214+
(void)wh_Client_KeyEvict(client, keyId);
208215
*boot_state = WOLFHSM_TEST_FIRST_BOOT_OK;
209216
return 0;
210217
}
211218

212219
int cmd_wolfhsm_test(const char *args)
213220
{
214-
static const whTransportNscClientConfig nsc_cfg = { 0 };
221+
static const whTransportNscClientConfig nsc_cfg = { { 0 } };
215222
whCommClientConfig comm_cfg;
216223
whClientConfig cfg;
217224
whClientContext client;

tools/unit-tests/Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ TESTS:=unit-parser unit-fdt unit-extflash unit-string unit-spi-flash unit-aes128
5151
unit-enc-nvm-flagshome unit-delta unit-update-flash unit-update-flash-delta \
5252
unit-update-flash-hook \
5353
unit-update-flash-self-update \
54-
unit-update-flash-enc unit-update-ram unit-update-ram-nofixed unit-pkcs11_store unit-psa_store unit-disk \
54+
unit-update-flash-enc unit-update-ram unit-update-ram-nofixed unit-pkcs11_store unit-psa_store unit-wolfhsm_flash_hal unit-disk \
5555
unit-update-disk unit-multiboot unit-boot-x86-fsp unit-loader-tpm-init unit-qspi-flash unit-fwtpm-stub unit-tpm-rsa-exp \
5656
unit-image-nopart unit-image-sha384 unit-image-sha3-384 unit-store-sbrk \
5757
unit-tpm-blob unit-policy-create unit-policy-sign unit-rot-auth unit-sdhci-response-bits \
@@ -357,6 +357,12 @@ unit-pkcs11_store: ../../include/target.h unit-pkcs11_store.c
357357
unit-psa_store: ../../include/target.h unit-psa_store.c
358358
gcc -o $@ $(WOLFCRYPT_SRC) unit-psa_store.c $(CFLAGS) $(WOLFCRYPT_CFLAGS) $(LDFLAGS)
359359

360+
unit-wolfhsm_flash_hal:CFLAGS+=-I$(WOLFBOOT_LIB_WOLFHSM) -DWOLFCRYPT_TZ_WOLFHSM -DWOLFHSM_CFG_NO_SYS_TIME -DMOCK_PARTITIONS
361+
unit-wolfhsm_flash_hal:WOLFCRYPT_SRC:=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/memory.c \
362+
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/misc.c
363+
unit-wolfhsm_flash_hal: ../../include/target.h unit-wolfhsm_flash_hal.c
364+
gcc -o $@ $(WOLFCRYPT_SRC) unit-wolfhsm_flash_hal.c $(CFLAGS) $(WOLFCRYPT_CFLAGS) $(LDFLAGS)
365+
360366
gpt-sfdisk-test.h:
361367
truncate -s 131072 .gpt-tmp.img
362368
printf 'label: gpt\nfirst-lba: 34\nstart=34, size=67, name="boot"\nstart=101, size=100, name="rootfs"\n' \

0 commit comments

Comments
 (0)