Skip to content

Commit de53cde

Browse files
authored
Merge pull request #147 from bigbrett/nvm-basic-access-control
non-exportable NVM
2 parents dc88f06 + f8342c4 commit de53cde

File tree

13 files changed

+597
-77
lines changed

13 files changed

+597
-77
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: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +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+
whNvmAccess access, whNvmFlags flags,
119+
uint8_t* label, whNvmSize label_len,
118120
const uint8_t* cert, uint32_t cert_len)
119121
{
120122
whMessageCert_AddTrustedRequest req;
@@ -128,8 +130,16 @@ int wh_Client_CertAddTrustedRequest(whClientContext* c, whNvmId id,
128130
}
129131

130132
/* Prepare request */
133+
memset(&req, 0, sizeof(req));
131134
req.id = id;
135+
req.access = access;
136+
req.flags = flags;
132137
req.cert_len = cert_len;
138+
if (label != NULL && label_len > 0) {
139+
whNvmSize copy_len =
140+
(label_len > WH_NVM_LABEL_LEN) ? WH_NVM_LABEL_LEN : label_len;
141+
memcpy(req.label, label, copy_len);
142+
}
133143

134144
/* Copy request struct and certificate data */
135145
memcpy(buffer, &req, hdr_len);
@@ -171,9 +181,10 @@ int wh_Client_CertAddTrustedResponse(whClientContext* c, int32_t* out_rc)
171181
return rc;
172182
}
173183

174-
int wh_Client_CertAddTrusted(whClientContext* c, whNvmId id,
175-
const uint8_t* cert, uint32_t cert_len,
176-
int32_t* out_rc)
184+
int wh_Client_CertAddTrusted(whClientContext* c, whNvmId id, whNvmAccess access,
185+
whNvmFlags flags, uint8_t* label,
186+
whNvmSize label_len, const uint8_t* cert,
187+
uint32_t cert_len, int32_t* out_rc)
177188
{
178189
int rc = 0;
179190

@@ -182,7 +193,8 @@ int wh_Client_CertAddTrusted(whClientContext* c, whNvmId id,
182193
}
183194

184195
do {
185-
rc = wh_Client_CertAddTrustedRequest(c, id, cert, cert_len);
196+
rc = wh_Client_CertAddTrustedRequest(c, id, access, flags, label,
197+
label_len, cert, cert_len);
186198
} while (rc == WH_ERROR_NOTREADY);
187199

188200
if (rc == 0) {
@@ -491,6 +503,8 @@ int wh_Client_CertVerifyAndCacheLeafPubKey(
491503
#ifdef WOLFHSM_CFG_DMA
492504

493505
int wh_Client_CertAddTrustedDmaRequest(whClientContext* c, whNvmId id,
506+
whNvmAccess access, whNvmFlags flags,
507+
uint8_t* label, whNvmSize label_len,
494508
const void* cert, uint32_t cert_len)
495509
{
496510
whMessageCert_AddTrustedDmaRequest req;
@@ -500,9 +514,17 @@ int wh_Client_CertAddTrustedDmaRequest(whClientContext* c, whNvmId id,
500514
}
501515

502516
/* Prepare and send request */
517+
memset(&req, 0, sizeof(req));
503518
req.id = id;
519+
req.access = access;
520+
req.flags = flags;
504521
req.cert_addr = (uint64_t)(uintptr_t)cert;
505522
req.cert_len = cert_len;
523+
if (label != NULL && label_len > 0) {
524+
whNvmSize copy_len =
525+
(label_len > WH_NVM_LABEL_LEN) ? WH_NVM_LABEL_LEN : label_len;
526+
memcpy(req.label, label, copy_len);
527+
}
506528
return wh_Client_SendRequest(c, WH_MESSAGE_GROUP_CERT,
507529
WH_MESSAGE_CERT_ACTION_ADDTRUSTED_DMA,
508530
sizeof(req), &req);
@@ -539,6 +561,8 @@ int wh_Client_CertAddTrustedDmaResponse(whClientContext* c, int32_t* out_rc)
539561
}
540562

541563
int wh_Client_CertAddTrustedDma(whClientContext* c, whNvmId id,
564+
whNvmAccess access, whNvmFlags flags,
565+
uint8_t* label, whNvmSize label_len,
542566
const void* cert, uint32_t cert_len,
543567
int32_t* out_rc)
544568
{
@@ -549,7 +573,8 @@ int wh_Client_CertAddTrustedDma(whClientContext* c, whNvmId id,
549573
}
550574

551575
do {
552-
rc = wh_Client_CertAddTrustedDmaRequest(c, id, cert, cert_len);
576+
rc = wh_Client_CertAddTrustedDmaRequest(c, id, access, flags, label,
577+
label_len, cert, cert_len);
553578
} while (rc == WH_ERROR_NOTREADY);
554579

555580
if (rc == 0) {

src/wh_message_cert.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,12 @@ int wh_MessageCert_TranslateAddTrustedRequest(
5252
if ((src == NULL) || (dest == NULL)) {
5353
return WH_ERROR_BADARGS;
5454
}
55-
WH_T16(magic, dest, src, id);
5655
WH_T32(magic, dest, src, cert_len);
56+
WH_T16(magic, dest, src, id);
57+
WH_T16(magic, dest, src, access);
58+
WH_T16(magic, dest, src, flags);
59+
/* Label array doesn't need byte-order translation */
60+
memcpy(dest->label, src->label, WH_NVM_LABEL_LEN);
5761
return 0;
5862
}
5963

@@ -125,9 +129,13 @@ int wh_MessageCert_TranslateAddTrustedDmaRequest(
125129
if ((src == NULL) || (dest == NULL)) {
126130
return WH_ERROR_BADARGS;
127131
}
128-
WH_T16(magic, dest, src, id);
129132
WH_T64(magic, dest, src, cert_addr);
130133
WH_T32(magic, dest, src, cert_len);
134+
WH_T16(magic, dest, src, id);
135+
WH_T16(magic, dest, src, access);
136+
WH_T16(magic, dest, src, flags);
137+
/* Label array doesn't need byte-order translation */
138+
memcpy(dest->label, src->label, WH_NVM_LABEL_LEN);
131139
return 0;
132140
}
133141

src/wh_server_cert.c

Lines changed: 71 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +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+
whNvmAccess access, whNvmFlags flags,
179+
const uint8_t* label, whNvmSize label_len,
178180
const uint8_t* cert, uint32_t cert_len)
179181
{
180-
int rc;
181-
/* TODO: Properly set access and flags */
182-
whNvmAccess access = WH_NVM_ACCESS_ANY;
183-
whNvmFlags flags = WH_NVM_FLAGS_IMMUTABLE;
184-
uint8_t label[WH_NVM_LABEL_LEN] = "trusted_cert";
182+
int rc;
185183
whNvmMetadata metadata;
186184

187185
if ((server == NULL) || (cert == NULL) || (cert_len == 0)) {
@@ -193,7 +191,16 @@ int wh_Server_CertAddTrusted(whServerContext* server, whNvmId id,
193191
metadata.access = access;
194192
metadata.flags = flags;
195193
metadata.len = cert_len;
196-
memcpy(metadata.label, label, sizeof(label));
194+
memset(metadata.label, 0, WH_NVM_LABEL_LEN);
195+
if (label != NULL && label_len > 0) {
196+
whNvmSize copy_len =
197+
(label_len > WH_NVM_LABEL_LEN) ? WH_NVM_LABEL_LEN : label_len;
198+
memcpy(metadata.label, label, copy_len);
199+
}
200+
else {
201+
/* Default label if none provided */
202+
memcpy(metadata.label, "trusted_cert", sizeof("trusted_cert"));
203+
}
197204

198205
rc = wh_Nvm_AddObject(server->nvm, &metadata, cert_len, cert);
199206

@@ -387,8 +394,9 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
387394
cert_data = (const uint8_t*)req_packet + sizeof(req);
388395

389396
/* Process the add trusted action */
390-
rc = wh_Server_CertAddTrusted(server, req.id, cert_data,
391-
req.cert_len);
397+
rc = wh_Server_CertAddTrusted(server, req.id, req.access, req.flags,
398+
req.label, WH_NVM_LABEL_LEN,
399+
cert_data, req.cert_len);
392400
resp.rc = rc;
393401

394402
/* Convert the response struct */
@@ -416,29 +424,50 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
416424
}; break;
417425

418426
case WH_MESSAGE_CERT_ACTION_READTRUSTED: {
427+
const uint32_t max_transport_cert_len =
428+
WOLFHSM_CFG_COMM_DATA_LEN -
429+
sizeof(whMessageCert_ReadTrustedResponse);
419430
whMessageCert_ReadTrustedRequest req = {0};
420431
whMessageCert_ReadTrustedResponse resp = {0};
421432
uint8_t* cert_data;
422433
uint32_t cert_len;
434+
whNvmMetadata meta;
423435

424436
/* Convert request struct */
425437
wh_MessageCert_TranslateReadTrustedRequest(
426438
magic, (whMessageCert_ReadTrustedRequest*)req_packet, &req);
427439

428440
/* Get pointer to certificate data buffer */
429441
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;
442+
cert_len = WOLFHSM_CFG_MAX_CERT_SIZE > max_transport_cert_len
443+
? max_transport_cert_len
444+
: WOLFHSM_CFG_MAX_CERT_SIZE;
445+
446+
/* Check metadata to check if the certificate is non-exportable.
447+
* This is unfortunately redundant since metadata is checked in
448+
* wh_Server_CertReadTrusted(). */
449+
rc = wh_Nvm_GetMetadata(server->nvm, req.id, &meta);
450+
if (rc == WH_ERROR_OK) {
451+
/* Check if the certificate is non-exportable */
452+
if (meta.flags & WH_NVM_FLAGS_NONEXPORTABLE) {
453+
resp.rc = WH_ERROR_ACCESS;
454+
}
455+
else {
456+
rc = wh_Server_CertReadTrusted(server, req.id, cert_data,
457+
&cert_len);
458+
resp.rc = rc;
459+
resp.cert_len = cert_len;
460+
}
461+
}
462+
else {
463+
resp.rc = rc;
464+
resp.cert_len = 0;
465+
}
437466

438467
/* Convert the response struct */
439468
wh_MessageCert_TranslateReadTrustedResponse(
440469
magic, &resp, (whMessageCert_ReadTrustedResponse*)resp_packet);
441-
*out_resp_size = sizeof(resp) + cert_len;
470+
*out_resp_size = sizeof(resp) + resp.cert_len;
442471
}; break;
443472

444473
case WH_MESSAGE_CERT_ACTION_VERIFY: {
@@ -487,7 +516,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
487516
/* Request is malformed */
488517
resp.rc = WH_ERROR_ABORTED;
489518
}
490-
if (resp.rc == 0) {
519+
if (resp.rc == WH_ERROR_OK) {
491520
/* Convert request struct */
492521
wh_MessageCert_TranslateAddTrustedDmaRequest(
493522
magic, (whMessageCert_AddTrustedDmaRequest*)req_packet,
@@ -498,12 +527,13 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
498527
server, req.cert_addr, &cert_data, req.cert_len,
499528
WH_DMA_OPER_CLIENT_READ_PRE, (whServerDmaFlags){0});
500529
}
501-
if (resp.rc == 0) {
530+
if (resp.rc == WH_ERROR_OK) {
502531
/* Process the add trusted action */
503-
resp.rc = wh_Server_CertAddTrusted(server, req.id, cert_data,
504-
req.cert_len);
532+
resp.rc = wh_Server_CertAddTrusted(
533+
server, req.id, req.access, req.flags, req.label,
534+
WH_NVM_LABEL_LEN, cert_data, req.cert_len);
505535
}
506-
if (resp.rc == 0) {
536+
if (resp.rc == WH_ERROR_OK) {
507537
/* Post-process client address */
508538
resp.rc = wh_Server_DmaProcessClientAddress(
509539
server, req.cert_addr, &cert_data, req.cert_len,
@@ -521,12 +551,13 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
521551
whMessageCert_SimpleResponse resp = {0};
522552
void* cert_data = NULL;
523553
uint32_t cert_len;
554+
whNvmMetadata meta;
524555

525556
if (req_size != sizeof(req)) {
526557
/* Request is malformed */
527558
resp.rc = WH_ERROR_ABORTED;
528559
}
529-
if (resp.rc == 0) {
560+
if (resp.rc == WH_ERROR_OK) {
530561
/* Convert request struct */
531562
wh_MessageCert_TranslateReadTrustedDmaRequest(
532563
magic, (whMessageCert_ReadTrustedDmaRequest*)req_packet,
@@ -537,13 +568,22 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
537568
server, req.cert_addr, &cert_data, req.cert_len,
538569
WH_DMA_OPER_CLIENT_WRITE_PRE, (whServerDmaFlags){0});
539570
}
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);
571+
if (resp.rc == WH_ERROR_OK) {
572+
/* Check metadata to see if the certificate is non-exportable */
573+
resp.rc = wh_Nvm_GetMetadata(server->nvm, req.id, &meta);
574+
if (resp.rc == WH_ERROR_OK) {
575+
if ((meta.flags & WH_NVM_FLAGS_NONEXPORTABLE) != 0) {
576+
resp.rc = WH_ERROR_ACCESS;
577+
}
578+
else {
579+
/* Clamp cert_len to actual stored length */
580+
cert_len = req.cert_len;
581+
resp.rc = wh_Server_CertReadTrusted(
582+
server, req.id, cert_data, &cert_len);
583+
}
584+
}
545585
}
546-
if (resp.rc == 0) {
586+
if (resp.rc == WH_ERROR_OK) {
547587
/* Post-process client address */
548588
resp.rc = wh_Server_DmaProcessClientAddress(
549589
server, req.cert_addr, &cert_data, cert_len,
@@ -565,7 +605,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
565605
/* Request is malformed */
566606
resp.rc = WH_ERROR_ABORTED;
567607
}
568-
if (resp.rc == 0) {
608+
if (resp.rc == WH_ERROR_OK) {
569609
/* Convert request struct */
570610
wh_MessageCert_TranslateVerifyDmaRequest(
571611
magic, (whMessageCert_VerifyDmaRequest*)req_packet, &req);
@@ -575,7 +615,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
575615
server, req.cert_addr, &cert_data, req.cert_len,
576616
WH_DMA_OPER_CLIENT_READ_PRE, (whServerDmaFlags){0});
577617
}
578-
if (resp.rc == 0) {
618+
if (resp.rc == WH_ERROR_OK) {
579619
/* Map client keyId to server keyId space */
580620
whKeyId keyId = WH_MAKE_KEYID(
581621
WH_KEYTYPE_CRYPTO, server->comm->client_id, req.keyId);
@@ -588,7 +628,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
588628
/* Propagate the keyId back to the client */
589629
resp.keyId = WH_KEYID_ID(keyId);
590630
}
591-
if (resp.rc == 0) {
631+
if (resp.rc == WH_ERROR_OK) {
592632
/* Post-process client address */
593633
resp.rc = wh_Server_DmaProcessClientAddress(
594634
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
}

0 commit comments

Comments
 (0)