Skip to content

Commit bb0cb94

Browse files
committed
Add support for "nonexportable" flag to NVM objects, keys, and certs.
1 parent 848af18 commit bb0cb94

File tree

13 files changed

+546
-76
lines changed

13 files changed

+546
-76
lines changed

examples/demo/client/wh_demo_client_nvm.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ int wh_DemoClient_Nvm(whClientContext* clientContext)
5252
* against what we wrote */
5353
for (int i = 0; i < NUM_OBJECTS; i++) {
5454
/* Add an object */
55-
rc = wh_Client_NvmAddObject(clientContext, objectIds[i],
56-
WH_NVM_ACCESS_ANY,
57-
WH_NVM_FLAGS_ANY, sizeof(labels[i]),
58-
labels[i], dataLen, data[i], &serverRc);
55+
rc = wh_Client_NvmAddObject(
56+
clientContext, objectIds[i], WH_NVM_ACCESS_ANY, WH_NVM_FLAGS_NONE,
57+
sizeof(labels[i]), labels[i], dataLen, data[i], &serverRc);
5958
if (rc != 0 || serverRc != 0) {
6059
printf("Add Object %d failed with error code: %d, server error "
6160
"code: %d\n",

examples/demo/client/wh_demo_client_secboot.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static int _showNvm(whClientContext* clientContext)
6262
{
6363
int ret = 0;
6464
whNvmAccess access = WH_NVM_ACCESS_ANY;
65-
whNvmFlags flags = WH_NVM_FLAGS_ANY;
65+
whNvmFlags flags = WH_NVM_FLAGS_NONE;
6666
whNvmId id = 0;
6767
whNvmId count = 0;
6868

src/wh_client_cert.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ int wh_Client_CertInit(whClientContext* c, int32_t* out_rc)
115115

116116
/* Add a trusted certificate */
117117
int wh_Client_CertAddTrustedRequest(whClientContext* c, whNvmId id,
118-
const uint8_t* cert, uint32_t cert_len)
118+
const uint8_t* cert, uint32_t cert_len,
119+
whNvmFlags flags)
119120
{
120121
whMessageCert_AddTrustedRequest req;
121122
uint8_t buffer[WOLFHSM_CFG_COMM_DATA_LEN] = {0};
@@ -130,6 +131,7 @@ int wh_Client_CertAddTrustedRequest(whClientContext* c, whNvmId id,
130131
/* Prepare request */
131132
req.id = id;
132133
req.cert_len = cert_len;
134+
req.flags = flags;
133135

134136
/* Copy request struct and certificate data */
135137
memcpy(buffer, &req, hdr_len);
@@ -173,7 +175,7 @@ int wh_Client_CertAddTrustedResponse(whClientContext* c, int32_t* out_rc)
173175

174176
int wh_Client_CertAddTrusted(whClientContext* c, whNvmId id,
175177
const uint8_t* cert, uint32_t cert_len,
176-
int32_t* out_rc)
178+
whNvmFlags flags, int32_t* out_rc)
177179
{
178180
int rc = 0;
179181

@@ -182,7 +184,7 @@ int wh_Client_CertAddTrusted(whClientContext* c, whNvmId id,
182184
}
183185

184186
do {
185-
rc = wh_Client_CertAddTrustedRequest(c, id, cert, cert_len);
187+
rc = wh_Client_CertAddTrustedRequest(c, id, cert, cert_len, flags);
186188
} while (rc == WH_ERROR_NOTREADY);
187189

188190
if (rc == 0) {
@@ -491,7 +493,8 @@ int wh_Client_CertVerifyAndCacheLeafPubKey(
491493
#ifdef WOLFHSM_CFG_DMA
492494

493495
int wh_Client_CertAddTrustedDmaRequest(whClientContext* c, whNvmId id,
494-
const void* cert, uint32_t cert_len)
496+
const void* cert, uint32_t cert_len,
497+
whNvmFlags flags)
495498
{
496499
whMessageCert_AddTrustedDmaRequest req;
497500

@@ -503,6 +506,7 @@ int wh_Client_CertAddTrustedDmaRequest(whClientContext* c, whNvmId id,
503506
req.id = id;
504507
req.cert_addr = (uint64_t)(uintptr_t)cert;
505508
req.cert_len = cert_len;
509+
req.flags = flags;
506510
return wh_Client_SendRequest(c, WH_MESSAGE_GROUP_CERT,
507511
WH_MESSAGE_CERT_ACTION_ADDTRUSTED_DMA,
508512
sizeof(req), &req);
@@ -540,7 +544,7 @@ int wh_Client_CertAddTrustedDmaResponse(whClientContext* c, int32_t* out_rc)
540544

541545
int wh_Client_CertAddTrustedDma(whClientContext* c, whNvmId id,
542546
const void* cert, uint32_t cert_len,
543-
int32_t* out_rc)
547+
whNvmFlags flags, int32_t* out_rc)
544548
{
545549
int rc = 0;
546550

@@ -549,7 +553,7 @@ int wh_Client_CertAddTrustedDma(whClientContext* c, whNvmId id,
549553
}
550554

551555
do {
552-
rc = wh_Client_CertAddTrustedDmaRequest(c, id, cert, cert_len);
556+
rc = wh_Client_CertAddTrustedDmaRequest(c, id, cert, cert_len, flags);
553557
} while (rc == WH_ERROR_NOTREADY);
554558

555559
if (rc == 0) {

src/wh_message_cert.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ int wh_MessageCert_TranslateAddTrustedRequest(
5454
}
5555
WH_T16(magic, dest, src, id);
5656
WH_T32(magic, dest, src, cert_len);
57+
WH_T16(magic, dest, src, flags);
5758
return 0;
5859
}
5960

@@ -128,6 +129,7 @@ int wh_MessageCert_TranslateAddTrustedDmaRequest(
128129
WH_T16(magic, dest, src, id);
129130
WH_T64(magic, dest, src, cert_addr);
130131
WH_T32(magic, dest, src, cert_len);
132+
WH_T16(magic, dest, src, flags);
131133
return 0;
132134
}
133135

src/wh_server_cert.c

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,11 @@ int wh_Server_CertInit(whServerContext* server)
175175

176176
/* Add a trusted certificate to NVM storage */
177177
int wh_Server_CertAddTrusted(whServerContext* server, whNvmId id,
178-
const uint8_t* cert, uint32_t cert_len)
178+
const uint8_t* cert, uint32_t cert_len,
179+
whNvmFlags flags)
179180
{
180-
int rc;
181-
/* TODO: Properly set access and flags */
181+
int rc;
182182
whNvmAccess access = WH_NVM_ACCESS_ANY;
183-
whNvmFlags flags = WH_NVM_FLAGS_IMMUTABLE;
184183
uint8_t label[WH_NVM_LABEL_LEN] = "trusted_cert";
185184
whNvmMetadata metadata;
186185

@@ -388,7 +387,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
388387

389388
/* Process the add trusted action */
390389
rc = wh_Server_CertAddTrusted(server, req.id, cert_data,
391-
req.cert_len);
390+
req.cert_len, req.flags);
392391
resp.rc = rc;
393392

394393
/* Convert the response struct */
@@ -416,29 +415,50 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
416415
}; break;
417416

418417
case WH_MESSAGE_CERT_ACTION_READTRUSTED: {
418+
const uint32_t max_transport_cert_len =
419+
WOLFHSM_CFG_COMM_DATA_LEN -
420+
sizeof(whMessageCert_ReadTrustedResponse);
419421
whMessageCert_ReadTrustedRequest req = {0};
420422
whMessageCert_ReadTrustedResponse resp = {0};
421423
uint8_t* cert_data;
422424
uint32_t cert_len;
425+
whNvmMetadata meta;
423426

424427
/* Convert request struct */
425428
wh_MessageCert_TranslateReadTrustedRequest(
426429
magic, (whMessageCert_ReadTrustedRequest*)req_packet, &req);
427430

428431
/* Get pointer to certificate data buffer */
429432
cert_data = (uint8_t*)resp_packet + sizeof(resp);
430-
cert_len = WOLFHSM_CFG_COMM_DATA_LEN - sizeof(resp);
431-
432-
/* Process the get trusted action */
433-
rc =
434-
wh_Server_CertReadTrusted(server, req.id, cert_data, &cert_len);
435-
resp.rc = rc;
436-
resp.cert_len = cert_len;
433+
cert_len = WOLFHSM_CFG_MAX_CERT_SIZE > max_transport_cert_len
434+
? max_transport_cert_len
435+
: WOLFHSM_CFG_MAX_CERT_SIZE;
436+
437+
/* Check metadata to check if the certificate is non-exportable.
438+
* This is unfortunately redundant since metadata is checked in
439+
* wh_Server_CertReadTrusted(). */
440+
rc = wh_Nvm_GetMetadata(server->nvm, req.id, &meta);
441+
if (rc == WH_ERROR_OK) {
442+
/* Check if the certificate is non-exportable */
443+
if (meta.flags & WH_NVM_FLAGS_NONEXPORTABLE) {
444+
resp.rc = WH_ERROR_ACCESS;
445+
}
446+
else {
447+
rc = wh_Server_CertReadTrusted(server, req.id, cert_data,
448+
&cert_len);
449+
resp.rc = rc;
450+
resp.cert_len = cert_len;
451+
}
452+
}
453+
else {
454+
resp.rc = rc;
455+
resp.cert_len = 0;
456+
}
437457

438458
/* Convert the response struct */
439459
wh_MessageCert_TranslateReadTrustedResponse(
440460
magic, &resp, (whMessageCert_ReadTrustedResponse*)resp_packet);
441-
*out_resp_size = sizeof(resp) + cert_len;
461+
*out_resp_size = sizeof(resp) + resp.cert_len;
442462
}; break;
443463

444464
case WH_MESSAGE_CERT_ACTION_VERIFY: {
@@ -487,7 +507,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
487507
/* Request is malformed */
488508
resp.rc = WH_ERROR_ABORTED;
489509
}
490-
if (resp.rc == 0) {
510+
if (resp.rc == WH_ERROR_OK) {
491511
/* Convert request struct */
492512
wh_MessageCert_TranslateAddTrustedDmaRequest(
493513
magic, (whMessageCert_AddTrustedDmaRequest*)req_packet,
@@ -498,12 +518,12 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
498518
server, req.cert_addr, &cert_data, req.cert_len,
499519
WH_DMA_OPER_CLIENT_READ_PRE, (whServerDmaFlags){0});
500520
}
501-
if (resp.rc == 0) {
521+
if (resp.rc == WH_ERROR_OK) {
502522
/* Process the add trusted action */
503523
resp.rc = wh_Server_CertAddTrusted(server, req.id, cert_data,
504-
req.cert_len);
524+
req.cert_len, req.flags);
505525
}
506-
if (resp.rc == 0) {
526+
if (resp.rc == WH_ERROR_OK) {
507527
/* Post-process client address */
508528
resp.rc = wh_Server_DmaProcessClientAddress(
509529
server, req.cert_addr, &cert_data, req.cert_len,
@@ -521,12 +541,13 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
521541
whMessageCert_SimpleResponse resp = {0};
522542
void* cert_data = NULL;
523543
uint32_t cert_len;
544+
whNvmMetadata meta;
524545

525546
if (req_size != sizeof(req)) {
526547
/* Request is malformed */
527548
resp.rc = WH_ERROR_ABORTED;
528549
}
529-
if (resp.rc == 0) {
550+
if (resp.rc == WH_ERROR_OK) {
530551
/* Convert request struct */
531552
wh_MessageCert_TranslateReadTrustedDmaRequest(
532553
magic, (whMessageCert_ReadTrustedDmaRequest*)req_packet,
@@ -537,13 +558,22 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
537558
server, req.cert_addr, &cert_data, req.cert_len,
538559
WH_DMA_OPER_CLIENT_WRITE_PRE, (whServerDmaFlags){0});
539560
}
540-
if (resp.rc == 0) {
541-
/* Process the get trusted action */
542-
cert_len = req.cert_len;
543-
resp.rc = wh_Server_CertReadTrusted(server, req.id, cert_data,
544-
&cert_len);
561+
if (resp.rc == WH_ERROR_OK) {
562+
/* Check metadata to see if the certificate is non-exportable */
563+
resp.rc = wh_Nvm_GetMetadata(server->nvm, req.id, &meta);
564+
if (resp.rc == WH_ERROR_OK) {
565+
if ((meta.flags & WH_NVM_FLAGS_NONEXPORTABLE) != 0) {
566+
resp.rc = WH_ERROR_ACCESS;
567+
}
568+
else {
569+
/* Clamp cert_len to actual stored length */
570+
cert_len = req.cert_len;
571+
resp.rc = wh_Server_CertReadTrusted(
572+
server, req.id, cert_data, &cert_len);
573+
}
574+
}
545575
}
546-
if (resp.rc == 0) {
576+
if (resp.rc == WH_ERROR_OK) {
547577
/* Post-process client address */
548578
resp.rc = wh_Server_DmaProcessClientAddress(
549579
server, req.cert_addr, &cert_data, cert_len,
@@ -565,7 +595,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
565595
/* Request is malformed */
566596
resp.rc = WH_ERROR_ABORTED;
567597
}
568-
if (resp.rc == 0) {
598+
if (resp.rc == WH_ERROR_OK) {
569599
/* Convert request struct */
570600
wh_MessageCert_TranslateVerifyDmaRequest(
571601
magic, (whMessageCert_VerifyDmaRequest*)req_packet, &req);
@@ -575,7 +605,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
575605
server, req.cert_addr, &cert_data, req.cert_len,
576606
WH_DMA_OPER_CLIENT_READ_PRE, (whServerDmaFlags){0});
577607
}
578-
if (resp.rc == 0) {
608+
if (resp.rc == WH_ERROR_OK) {
579609
/* Map client keyId to server keyId space */
580610
whKeyId keyId = WH_MAKE_KEYID(
581611
WH_KEYTYPE_CRYPTO, server->comm->client_id, req.keyId);
@@ -588,7 +618,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
588618
/* Propagate the keyId back to the client */
589619
resp.keyId = WH_KEYID_ID(keyId);
590620
}
591-
if (resp.rc == 0) {
621+
if (resp.rc == WH_ERROR_OK) {
592622
/* Post-process client address */
593623
resp.rc = wh_Server_DmaProcessClientAddress(
594624
server, req.cert_addr, &cert_data, req.cert_len,

src/wh_server_keystore.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,15 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic,
726726
WH_MAKE_KEYID(WH_KEYTYPE_CRYPTO, server->comm->client_id,
727727
req.id),
728728
meta, out, &keySz);
729+
730+
/* Check if key is non-exportable */
731+
if (ret == WH_ERROR_OK &&
732+
(meta->flags & WH_NVM_FLAGS_NONEXPORTABLE)) {
733+
ret = WH_ERROR_ACCESS;
734+
/* Clear any key data that may have been read */
735+
memset(out, 0, keySz);
736+
}
737+
729738
resp.rc = ret;
730739
/* TODO: Are there any fatal server errors? */
731740
ret = WH_ERROR_OK;
@@ -874,6 +883,11 @@ int wh_Server_KeystoreExportKeyDma(whServerContext* server, whKeyId keyId,
874883
return ret;
875884
}
876885

886+
/* Check if key is non-exportable */
887+
if (cacheMeta->flags & WH_NVM_FLAGS_NONEXPORTABLE) {
888+
return WH_ERROR_ACCESS;
889+
}
890+
877891
if (keySz < cacheMeta->len) {
878892
return WH_ERROR_NOSPACE;
879893
}

src/wh_server_nvm.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ int wh_Server_HandleNvmRequest(whServerContext* server,
245245
uint16_t hdr_len = sizeof(resp);
246246
uint8_t* data = (uint8_t*)resp_packet + hdr_len;
247247
uint16_t data_len = 0;
248+
whNvmMetadata meta = {0};
248249

249250
if (req_size != sizeof(req)) {
250251
/* Request is malformed */
@@ -257,11 +258,20 @@ int wh_Server_HandleNvmRequest(whServerContext* server,
257258
if (req.data_len > WH_MESSAGE_NVM_MAX_READ_LEN) {
258259
resp.rc = WH_ERROR_ABORTED;
259260
} else {
260-
/* Process the Read action */
261-
resp.rc = wh_Nvm_Read(server->nvm,
262-
req.id, req.offset, req.data_len, data);
261+
/* Check metadata for non-exportable flag */
262+
resp.rc = wh_Nvm_GetMetadata(server->nvm, req.id, &meta);
263263
if (resp.rc == 0) {
264-
data_len = req.data_len;
264+
if (meta.flags & WH_NVM_FLAGS_NONEXPORTABLE) {
265+
resp.rc = WH_ERROR_ACCESS;
266+
}
267+
else {
268+
/* Process the Read action */
269+
resp.rc = wh_Nvm_Read(server->nvm, req.id, req.offset,
270+
req.data_len, data);
271+
if (resp.rc == 0) {
272+
data_len = req.data_len;
273+
}
274+
}
265275
}
266276
}
267277
}
@@ -325,9 +335,10 @@ int wh_Server_HandleNvmRequest(whServerContext* server,
325335

326336
case WH_MESSAGE_NVM_ACTION_READDMA:
327337
{
328-
whMessageNvm_ReadDmaRequest req = {0};
338+
whMessageNvm_ReadDmaRequest req = {0};
329339
whMessageNvm_SimpleResponse resp = {0};
330-
void* data = NULL;
340+
whNvmMetadata meta = {0};
341+
void* data = NULL;
331342

332343
if (req_size != sizeof(req)) {
333344
/* Request is malformed */
@@ -338,6 +349,13 @@ int wh_Server_HandleNvmRequest(whServerContext* server,
338349
wh_MessageNvm_TranslateReadDmaRequest(magic,
339350
(whMessageNvm_ReadDmaRequest*)req_packet, &req);
340351

352+
/* Check metadata for non-exportable flag */
353+
resp.rc = wh_Nvm_GetMetadata(server->nvm, req.id, &meta);
354+
if (resp.rc == 0 && (meta.flags & WH_NVM_FLAGS_NONEXPORTABLE)) {
355+
resp.rc = WH_ERROR_ACCESS;
356+
}
357+
}
358+
if (resp.rc == 0) {
341359
/* perform platform-specific host address processing */
342360
resp.rc = wh_Server_DmaProcessClientAddress(
343361
server, req.data_hostaddr, &data, req.data_len,

0 commit comments

Comments
 (0)