Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions examples/demo/client/wh_demo_client_nvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ int wh_DemoClient_Nvm(whClientContext* clientContext)
* against what we wrote */
for (int i = 0; i < NUM_OBJECTS; i++) {
/* Add an object */
rc = wh_Client_NvmAddObject(clientContext, objectIds[i],
WH_NVM_ACCESS_ANY,
WH_NVM_FLAGS_ANY, sizeof(labels[i]),
labels[i], dataLen, data[i], &serverRc);
rc = wh_Client_NvmAddObject(
clientContext, objectIds[i], WH_NVM_ACCESS_ANY, WH_NVM_FLAGS_NONE,
sizeof(labels[i]), labels[i], dataLen, data[i], &serverRc);
if (rc != 0 || serverRc != 0) {
printf("Add Object %d failed with error code: %d, server error "
"code: %d\n",
Expand Down
2 changes: 1 addition & 1 deletion examples/demo/client/wh_demo_client_secboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static int _showNvm(whClientContext* clientContext)
{
int ret = 0;
whNvmAccess access = WH_NVM_ACCESS_ANY;
whNvmFlags flags = WH_NVM_FLAGS_ANY;
whNvmFlags flags = WH_NVM_FLAGS_NONE;
whNvmId id = 0;
whNvmId count = 0;

Expand Down
35 changes: 30 additions & 5 deletions src/wh_client_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ int wh_Client_CertInit(whClientContext* c, int32_t* out_rc)

/* Add a trusted certificate */
int wh_Client_CertAddTrustedRequest(whClientContext* c, whNvmId id,
whNvmAccess access, whNvmFlags flags,
uint8_t* label, whNvmSize label_len,
const uint8_t* cert, uint32_t cert_len)
{
whMessageCert_AddTrustedRequest req;
Expand All @@ -128,8 +130,16 @@ int wh_Client_CertAddTrustedRequest(whClientContext* c, whNvmId id,
}

/* Prepare request */
memset(&req, 0, sizeof(req));
req.id = id;
req.access = access;
req.flags = flags;
req.cert_len = cert_len;
if (label != NULL && label_len > 0) {
whNvmSize copy_len =
(label_len > WH_NVM_LABEL_LEN) ? WH_NVM_LABEL_LEN : label_len;
memcpy(req.label, label, copy_len);
}

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

int wh_Client_CertAddTrusted(whClientContext* c, whNvmId id,
const uint8_t* cert, uint32_t cert_len,
int32_t* out_rc)
int wh_Client_CertAddTrusted(whClientContext* c, whNvmId id, whNvmAccess access,
whNvmFlags flags, uint8_t* label,
whNvmSize label_len, const uint8_t* cert,
uint32_t cert_len, int32_t* out_rc)
{
int rc = 0;

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

do {
rc = wh_Client_CertAddTrustedRequest(c, id, cert, cert_len);
rc = wh_Client_CertAddTrustedRequest(c, id, access, flags, label,
label_len, cert, cert_len);
} while (rc == WH_ERROR_NOTREADY);

if (rc == 0) {
Expand Down Expand Up @@ -491,6 +503,8 @@ int wh_Client_CertVerifyAndCacheLeafPubKey(
#ifdef WOLFHSM_CFG_DMA

int wh_Client_CertAddTrustedDmaRequest(whClientContext* c, whNvmId id,
whNvmAccess access, whNvmFlags flags,
uint8_t* label, whNvmSize label_len,
const void* cert, uint32_t cert_len)
{
whMessageCert_AddTrustedDmaRequest req;
Expand All @@ -500,9 +514,17 @@ int wh_Client_CertAddTrustedDmaRequest(whClientContext* c, whNvmId id,
}

/* Prepare and send request */
memset(&req, 0, sizeof(req));
req.id = id;
req.access = access;
req.flags = flags;
req.cert_addr = (uint64_t)(uintptr_t)cert;
req.cert_len = cert_len;
if (label != NULL && label_len > 0) {
whNvmSize copy_len =
(label_len > WH_NVM_LABEL_LEN) ? WH_NVM_LABEL_LEN : label_len;
memcpy(req.label, label, copy_len);
}
return wh_Client_SendRequest(c, WH_MESSAGE_GROUP_CERT,
WH_MESSAGE_CERT_ACTION_ADDTRUSTED_DMA,
sizeof(req), &req);
Expand Down Expand Up @@ -539,6 +561,8 @@ int wh_Client_CertAddTrustedDmaResponse(whClientContext* c, int32_t* out_rc)
}

int wh_Client_CertAddTrustedDma(whClientContext* c, whNvmId id,
whNvmAccess access, whNvmFlags flags,
uint8_t* label, whNvmSize label_len,
const void* cert, uint32_t cert_len,
int32_t* out_rc)
{
Expand All @@ -549,7 +573,8 @@ int wh_Client_CertAddTrustedDma(whClientContext* c, whNvmId id,
}

do {
rc = wh_Client_CertAddTrustedDmaRequest(c, id, cert, cert_len);
rc = wh_Client_CertAddTrustedDmaRequest(c, id, access, flags, label,
label_len, cert, cert_len);
} while (rc == WH_ERROR_NOTREADY);

if (rc == 0) {
Expand Down
12 changes: 10 additions & 2 deletions src/wh_message_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ int wh_MessageCert_TranslateAddTrustedRequest(
if ((src == NULL) || (dest == NULL)) {
return WH_ERROR_BADARGS;
}
WH_T16(magic, dest, src, id);
WH_T32(magic, dest, src, cert_len);
WH_T16(magic, dest, src, id);
WH_T16(magic, dest, src, access);
WH_T16(magic, dest, src, flags);
/* Label array doesn't need byte-order translation */
memcpy(dest->label, src->label, WH_NVM_LABEL_LEN);
return 0;
}

Expand Down Expand Up @@ -125,9 +129,13 @@ int wh_MessageCert_TranslateAddTrustedDmaRequest(
if ((src == NULL) || (dest == NULL)) {
return WH_ERROR_BADARGS;
}
WH_T16(magic, dest, src, id);
WH_T64(magic, dest, src, cert_addr);
WH_T32(magic, dest, src, cert_len);
WH_T16(magic, dest, src, id);
WH_T16(magic, dest, src, access);
WH_T16(magic, dest, src, flags);
/* Label array doesn't need byte-order translation */
memcpy(dest->label, src->label, WH_NVM_LABEL_LEN);
return 0;
}

Expand Down
102 changes: 71 additions & 31 deletions src/wh_server_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,11 @@ int wh_Server_CertInit(whServerContext* server)

/* Add a trusted certificate to NVM storage */
int wh_Server_CertAddTrusted(whServerContext* server, whNvmId id,
whNvmAccess access, whNvmFlags flags,
const uint8_t* label, whNvmSize label_len,
const uint8_t* cert, uint32_t cert_len)
{
int rc;
/* TODO: Properly set access and flags */
whNvmAccess access = WH_NVM_ACCESS_ANY;
whNvmFlags flags = WH_NVM_FLAGS_IMMUTABLE;
uint8_t label[WH_NVM_LABEL_LEN] = "trusted_cert";
int rc;
whNvmMetadata metadata;

if ((server == NULL) || (cert == NULL) || (cert_len == 0)) {
Expand All @@ -193,7 +191,16 @@ int wh_Server_CertAddTrusted(whServerContext* server, whNvmId id,
metadata.access = access;
metadata.flags = flags;
metadata.len = cert_len;
memcpy(metadata.label, label, sizeof(label));
memset(metadata.label, 0, WH_NVM_LABEL_LEN);
if (label != NULL && label_len > 0) {
whNvmSize copy_len =
(label_len > WH_NVM_LABEL_LEN) ? WH_NVM_LABEL_LEN : label_len;
memcpy(metadata.label, label, copy_len);
}
else {
/* Default label if none provided */
memcpy(metadata.label, "trusted_cert", sizeof("trusted_cert"));
}

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

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

/* Process the add trusted action */
rc = wh_Server_CertAddTrusted(server, req.id, cert_data,
req.cert_len);
rc = wh_Server_CertAddTrusted(server, req.id, req.access, req.flags,
req.label, WH_NVM_LABEL_LEN,
cert_data, req.cert_len);
resp.rc = rc;

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

case WH_MESSAGE_CERT_ACTION_READTRUSTED: {
const uint32_t max_transport_cert_len =
WOLFHSM_CFG_COMM_DATA_LEN -
sizeof(whMessageCert_ReadTrustedResponse);
whMessageCert_ReadTrustedRequest req = {0};
whMessageCert_ReadTrustedResponse resp = {0};
uint8_t* cert_data;
uint32_t cert_len;
whNvmMetadata meta;

/* Convert request struct */
wh_MessageCert_TranslateReadTrustedRequest(
magic, (whMessageCert_ReadTrustedRequest*)req_packet, &req);

/* Get pointer to certificate data buffer */
cert_data = (uint8_t*)resp_packet + sizeof(resp);
cert_len = WOLFHSM_CFG_COMM_DATA_LEN - sizeof(resp);

/* Process the get trusted action */
rc =
wh_Server_CertReadTrusted(server, req.id, cert_data, &cert_len);
resp.rc = rc;
resp.cert_len = cert_len;
cert_len = WOLFHSM_CFG_MAX_CERT_SIZE > max_transport_cert_len
? max_transport_cert_len
: WOLFHSM_CFG_MAX_CERT_SIZE;

/* Check metadata to check if the certificate is non-exportable.
* This is unfortunately redundant since metadata is checked in
* wh_Server_CertReadTrusted(). */
rc = wh_Nvm_GetMetadata(server->nvm, req.id, &meta);
if (rc == WH_ERROR_OK) {
/* Check if the certificate is non-exportable */
if (meta.flags & WH_NVM_FLAGS_NONEXPORTABLE) {
resp.rc = WH_ERROR_ACCESS;
}
else {
rc = wh_Server_CertReadTrusted(server, req.id, cert_data,
&cert_len);
resp.rc = rc;
resp.cert_len = cert_len;
}
}
else {
resp.rc = rc;
resp.cert_len = 0;
}

/* Convert the response struct */
wh_MessageCert_TranslateReadTrustedResponse(
magic, &resp, (whMessageCert_ReadTrustedResponse*)resp_packet);
*out_resp_size = sizeof(resp) + cert_len;
*out_resp_size = sizeof(resp) + resp.cert_len;
}; break;

case WH_MESSAGE_CERT_ACTION_VERIFY: {
Expand Down Expand Up @@ -487,7 +516,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
/* Request is malformed */
resp.rc = WH_ERROR_ABORTED;
}
if (resp.rc == 0) {
if (resp.rc == WH_ERROR_OK) {
/* Convert request struct */
wh_MessageCert_TranslateAddTrustedDmaRequest(
magic, (whMessageCert_AddTrustedDmaRequest*)req_packet,
Expand All @@ -498,12 +527,13 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
server, req.cert_addr, &cert_data, req.cert_len,
WH_DMA_OPER_CLIENT_READ_PRE, (whServerDmaFlags){0});
}
if (resp.rc == 0) {
if (resp.rc == WH_ERROR_OK) {
/* Process the add trusted action */
resp.rc = wh_Server_CertAddTrusted(server, req.id, cert_data,
req.cert_len);
resp.rc = wh_Server_CertAddTrusted(
server, req.id, req.access, req.flags, req.label,
WH_NVM_LABEL_LEN, cert_data, req.cert_len);
}
if (resp.rc == 0) {
if (resp.rc == WH_ERROR_OK) {
/* Post-process client address */
resp.rc = wh_Server_DmaProcessClientAddress(
server, req.cert_addr, &cert_data, req.cert_len,
Expand All @@ -521,12 +551,13 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
whMessageCert_SimpleResponse resp = {0};
void* cert_data = NULL;
uint32_t cert_len;
whNvmMetadata meta;

if (req_size != sizeof(req)) {
/* Request is malformed */
resp.rc = WH_ERROR_ABORTED;
}
if (resp.rc == 0) {
if (resp.rc == WH_ERROR_OK) {
/* Convert request struct */
wh_MessageCert_TranslateReadTrustedDmaRequest(
magic, (whMessageCert_ReadTrustedDmaRequest*)req_packet,
Expand All @@ -537,13 +568,22 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
server, req.cert_addr, &cert_data, req.cert_len,
WH_DMA_OPER_CLIENT_WRITE_PRE, (whServerDmaFlags){0});
}
if (resp.rc == 0) {
/* Process the get trusted action */
cert_len = req.cert_len;
resp.rc = wh_Server_CertReadTrusted(server, req.id, cert_data,
&cert_len);
if (resp.rc == WH_ERROR_OK) {
/* Check metadata to see if the certificate is non-exportable */
resp.rc = wh_Nvm_GetMetadata(server->nvm, req.id, &meta);
if (resp.rc == WH_ERROR_OK) {
if ((meta.flags & WH_NVM_FLAGS_NONEXPORTABLE) != 0) {
resp.rc = WH_ERROR_ACCESS;
}
else {
/* Clamp cert_len to actual stored length */
cert_len = req.cert_len;
resp.rc = wh_Server_CertReadTrusted(
server, req.id, cert_data, &cert_len);
}
}
}
if (resp.rc == 0) {
if (resp.rc == WH_ERROR_OK) {
/* Post-process client address */
resp.rc = wh_Server_DmaProcessClientAddress(
server, req.cert_addr, &cert_data, cert_len,
Expand All @@ -565,7 +605,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
/* Request is malformed */
resp.rc = WH_ERROR_ABORTED;
}
if (resp.rc == 0) {
if (resp.rc == WH_ERROR_OK) {
/* Convert request struct */
wh_MessageCert_TranslateVerifyDmaRequest(
magic, (whMessageCert_VerifyDmaRequest*)req_packet, &req);
Expand All @@ -575,7 +615,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
server, req.cert_addr, &cert_data, req.cert_len,
WH_DMA_OPER_CLIENT_READ_PRE, (whServerDmaFlags){0});
}
if (resp.rc == 0) {
if (resp.rc == WH_ERROR_OK) {
/* Map client keyId to server keyId space */
whKeyId keyId = WH_MAKE_KEYID(
WH_KEYTYPE_CRYPTO, server->comm->client_id, req.keyId);
Expand All @@ -588,7 +628,7 @@ int wh_Server_HandleCertRequest(whServerContext* server, uint16_t magic,
/* Propagate the keyId back to the client */
resp.keyId = WH_KEYID_ID(keyId);
}
if (resp.rc == 0) {
if (resp.rc == WH_ERROR_OK) {
/* Post-process client address */
resp.rc = wh_Server_DmaProcessClientAddress(
server, req.cert_addr, &cert_data, req.cert_len,
Expand Down
14 changes: 14 additions & 0 deletions src/wh_server_keystore.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,15 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic,
WH_MAKE_KEYID(WH_KEYTYPE_CRYPTO, server->comm->client_id,
req.id),
meta, out, &keySz);

/* Check if key is non-exportable */
if (ret == WH_ERROR_OK &&
(meta->flags & WH_NVM_FLAGS_NONEXPORTABLE)) {
ret = WH_ERROR_ACCESS;
/* Clear any key data that may have been read */
memset(out, 0, keySz);
}

resp.rc = ret;
/* TODO: Are there any fatal server errors? */
ret = WH_ERROR_OK;
Expand Down Expand Up @@ -874,6 +883,11 @@ int wh_Server_KeystoreExportKeyDma(whServerContext* server, whKeyId keyId,
return ret;
}

/* Check if key is non-exportable */
if (cacheMeta->flags & WH_NVM_FLAGS_NONEXPORTABLE) {
return WH_ERROR_ACCESS;
}

if (keySz < cacheMeta->len) {
return WH_ERROR_NOSPACE;
}
Expand Down
Loading