diff --git a/src/wh_client_keywrap.c b/src/wh_client_keywrap.c index 8945c20fc..84dbe5ceb 100644 --- a/src/wh_client_keywrap.c +++ b/src/wh_client_keywrap.c @@ -17,17 +17,18 @@ int wh_Client_KeyWrapRequest(whClientContext* ctx, uint16_t serverKeyId, void* key, uint16_t keySz, whNvmMetadata* metadata) { - uint16_t group = WH_MESSAGE_GROUP_KEY; - uint16_t action = WH_KEY_WRAP; - whMessageKeystore_WrapRequest* req = NULL; - uint8_t* reqData; + uint16_t group = WH_MESSAGE_GROUP_KEY; + uint16_t action = WH_KEY_KEYWRAP; + whMessageKeystore_KeyWrapRequest* req = NULL; + uint8_t* reqData; if (ctx == NULL || key == NULL || metadata == NULL) { return WH_ERROR_BADARGS; } /* Set the request pointer to the shared comm data memory region */ - req = (whMessageKeystore_WrapRequest*)wh_CommClient_GetDataPtr(ctx->comm); + req = + (whMessageKeystore_KeyWrapRequest*)wh_CommClient_GetDataPtr(ctx->comm); if (req == NULL) { return WH_ERROR_BADARGS; } @@ -51,19 +52,20 @@ int wh_Client_KeyWrapResponse(whClientContext* ctx, enum wc_CipherType cipherType, void* wrappedKeyOut, uint16_t wrappedKeySz) { - int ret; - uint16_t group; - uint16_t action; - uint16_t size; - whMessageKeystore_WrapResponse* resp = NULL; - uint8_t* respData; + int ret; + uint16_t group; + uint16_t action; + uint16_t size; + whMessageKeystore_KeyWrapResponse* resp = NULL; + uint8_t* respData; if (ctx == NULL || wrappedKeyOut == NULL) { return WH_ERROR_BADARGS; } /* Set the response pointer to the shared comm data memory region */ - resp = (whMessageKeystore_WrapResponse*)wh_CommClient_GetDataPtr(ctx->comm); + resp = + (whMessageKeystore_KeyWrapResponse*)wh_CommClient_GetDataPtr(ctx->comm); if (resp == NULL) { return WH_ERROR_BADARGS; } @@ -74,7 +76,7 @@ int wh_Client_KeyWrapResponse(whClientContext* ctx, return ret; } - if (group != WH_MESSAGE_GROUP_KEY || action != WH_KEY_WRAP || + if (group != WH_MESSAGE_GROUP_KEY || action != WH_KEY_KEYWRAP || size < sizeof(*resp) || size > sizeof(*resp) + wrappedKeySz || resp->wrappedKeySz != wrappedKeySz || resp->cipherType != cipherType) { return WH_ERROR_ABORTED; @@ -124,18 +126,19 @@ int wh_Client_KeyUnwrapAndExportRequest(whClientContext* ctx, uint16_t wrappedKeySz) { - uint16_t group = WH_MESSAGE_GROUP_KEY; - uint16_t action = WH_KEY_UNWRAPEXPORT; - whMessageKeystore_UnwrapAndExportRequest* req = NULL; - uint8_t* reqData; + uint16_t group = WH_MESSAGE_GROUP_KEY; + uint16_t action = WH_KEY_KEYUNWRAPEXPORT; + whMessageKeystore_KeyUnwrapAndExportRequest* req = NULL; + uint8_t* reqData; if (ctx == NULL || wrappedKeyIn == NULL) { return WH_ERROR_BADARGS; } /* Set the request pointer to the shared comm data memory region */ - req = (whMessageKeystore_UnwrapAndExportRequest*)wh_CommClient_GetDataPtr( - ctx->comm); + req = + (whMessageKeystore_KeyUnwrapAndExportRequest*)wh_CommClient_GetDataPtr( + ctx->comm); if (req == NULL) { return WH_ERROR_BADARGS; } @@ -158,20 +161,21 @@ int wh_Client_KeyUnwrapAndExportResponse(whClientContext* ctx, whNvmMetadata* metadataOut, void* keyOut, uint16_t keySz) { - int ret; - uint16_t group; - uint16_t action; - uint16_t size; - whMessageKeystore_UnwrapAndExportResponse* resp = NULL; - uint8_t* respData; + int ret; + uint16_t group; + uint16_t action; + uint16_t size; + whMessageKeystore_KeyUnwrapAndExportResponse* resp = NULL; + uint8_t* respData; if (ctx == NULL || metadataOut == NULL || keyOut == NULL) { return WH_ERROR_BADARGS; } /* Set the response pointer to the shared comm data memory region */ - resp = (whMessageKeystore_UnwrapAndExportResponse*)wh_CommClient_GetDataPtr( - ctx->comm); + resp = + (whMessageKeystore_KeyUnwrapAndExportResponse*)wh_CommClient_GetDataPtr( + ctx->comm); if (resp == NULL) { return WH_ERROR_BADARGS; } @@ -182,7 +186,7 @@ int wh_Client_KeyUnwrapAndExportResponse(whClientContext* ctx, return ret; } - if (group != WH_MESSAGE_GROUP_KEY || action != WH_KEY_UNWRAPEXPORT || + if (group != WH_MESSAGE_GROUP_KEY || action != WH_KEY_KEYUNWRAPEXPORT || size < sizeof(*resp) || size > sizeof(*resp) + sizeof(*metadataOut) + keySz || resp->cipherType != cipherType) { @@ -238,16 +242,16 @@ int wh_Client_KeyUnwrapAndCacheRequest(whClientContext* ctx, uint16_t wrappedKeySz) { uint16_t group = WH_MESSAGE_GROUP_KEY; - uint16_t action = WH_KEY_UNWRAPCACHE; + uint16_t action = WH_KEY_KEYUNWRAPCACHE; - whMessageKeystore_UnwrapAndCacheRequest* req = NULL; - uint8_t* reqData; + whMessageKeystore_KeyUnwrapAndCacheRequest* req = NULL; + uint8_t* reqData; if (ctx == NULL || wrappedKeyIn == NULL) return WH_ERROR_BADARGS; /* Set the request pointer to the shared comm data memory region */ - req = (whMessageKeystore_UnwrapAndCacheRequest*)wh_CommClient_GetDataPtr( + req = (whMessageKeystore_KeyUnwrapAndCacheRequest*)wh_CommClient_GetDataPtr( ctx->comm); if (req == NULL) { return WH_ERROR_BADARGS; @@ -270,18 +274,19 @@ int wh_Client_KeyUnwrapAndCacheResponse(whClientContext* ctx, enum wc_CipherType cipherType, uint16_t* keyIdOut) { - int ret; - uint16_t group; - uint16_t action; - uint16_t size; - whMessageKeystore_UnwrapAndCacheResponse* resp = NULL; + int ret; + uint16_t group; + uint16_t action; + uint16_t size; + whMessageKeystore_KeyUnwrapAndCacheResponse* resp = NULL; if (ctx == NULL || keyIdOut == NULL) return WH_ERROR_BADARGS; /* Set the response pointer to the shared comm data memory region */ - resp = (whMessageKeystore_UnwrapAndCacheResponse*)wh_CommClient_GetDataPtr( - ctx->comm); + resp = + (whMessageKeystore_KeyUnwrapAndCacheResponse*)wh_CommClient_GetDataPtr( + ctx->comm); if (resp == NULL) { return WH_ERROR_BADARGS; } @@ -292,7 +297,7 @@ int wh_Client_KeyUnwrapAndCacheResponse(whClientContext* ctx, return ret; } - if (group != WH_MESSAGE_GROUP_KEY || action != WH_KEY_UNWRAPCACHE || + if (group != WH_MESSAGE_GROUP_KEY || action != WH_KEY_KEYUNWRAPCACHE || size < sizeof(*resp) || resp->cipherType != cipherType) { return WH_ERROR_ABORTED; } @@ -331,5 +336,211 @@ int wh_Client_KeyUnwrapAndCache(whClientContext* ctx, return ret; } +int wh_Client_DataWrapRequest(whClientContext* ctx, + enum wc_CipherType cipherType, + uint16_t serverKeyId, void* dataIn, + uint32_t dataInSz) +{ + uint16_t group = WH_MESSAGE_GROUP_KEY; + uint16_t action = WH_KEY_DATAWRAP; + + whMessageKeystore_DataWrapRequest* req = NULL; + uint8_t* reqData; + + if (ctx == NULL || dataIn == NULL) { + return WH_ERROR_BADARGS; + } + + /* Set the request pointer to the shared comm data memory region */ + req = + (whMessageKeystore_DataWrapRequest*)wh_CommClient_GetDataPtr(ctx->comm); + if (req == NULL) { + return WH_ERROR_BADARGS; + } + + req->dataSz = dataInSz; + req->serverKeyId = serverKeyId; + req->cipherType = cipherType; + + /* Place the wrapped key right after the request */ + reqData = (uint8_t*)(req + 1); + memcpy(reqData, dataIn, dataInSz); + + return wh_Client_SendRequest(ctx, group, action, sizeof(*req) + dataInSz, + (uint8_t*)req); +} + +int wh_Client_DataWrapResponse(whClientContext* ctx, + enum wc_CipherType cipherType, + void* wrappedDataOut, uint32_t wrappedDataSz) +{ + int ret; + uint16_t group; + uint16_t action; + uint16_t size; + whMessageKeystore_DataWrapResponse* resp = NULL; + uint8_t* respData; + + if (ctx == NULL || wrappedDataOut == NULL) { + return WH_ERROR_BADARGS; + } + + /* Set the response pointer to the shared comm data memory region */ + resp = (whMessageKeystore_DataWrapResponse*)wh_CommClient_GetDataPtr( + ctx->comm); + if (resp == NULL) { + return WH_ERROR_BADARGS; + } + + /* Receive the response */ + ret = wh_Client_RecvResponse(ctx, &group, &action, &size, (uint8_t*)resp); + if (ret != WH_ERROR_OK) { + return ret; + } + + if (group != WH_MESSAGE_GROUP_KEY || action != WH_KEY_DATAWRAP || + size < sizeof(*resp) || size > sizeof(*resp) + wrappedDataSz || + resp->wrappedDataSz != wrappedDataSz || + resp->cipherType != cipherType) { + return WH_ERROR_ABORTED; + } + + if (resp->rc != 0) { + return resp->rc; + } + + /* Copy the wrapped key from the response data into wrappedKeyOut */ + respData = (uint8_t*)(resp + 1); + memcpy(wrappedDataOut, respData, wrappedDataSz); + + return WH_ERROR_OK; +} + +int wh_Client_DataWrap(whClientContext* ctx, enum wc_CipherType cipherType, + uint16_t serverKeyId, void* dataIn, uint32_t dataInSz, + void* wrappedDataOut, uint32_t wrappedDataOutSz) +{ + int ret; + if (ctx == NULL || wrappedDataOut == NULL || dataIn == NULL) { + return WH_ERROR_BADARGS; + } + + ret = wh_Client_DataWrapRequest(ctx, cipherType, serverKeyId, dataIn, + dataInSz); + if (ret != WH_ERROR_OK) { + return ret; + } + + do { + ret = wh_Client_DataWrapResponse(ctx, cipherType, wrappedDataOut, + wrappedDataOutSz); + + } while (ret == WH_ERROR_NOTREADY); + + return ret; +} + +int wh_Client_DataUnwrapRequest(whClientContext* ctx, + enum wc_CipherType cipherType, + uint16_t serverKeyId, void* wrappedDataIn, + uint32_t wrappedDataInSz) +{ + uint16_t group = WH_MESSAGE_GROUP_KEY; + uint16_t action = WH_KEY_DATAUNWRAP; + + whMessageKeystore_DataUnwrapRequest* req = NULL; + uint8_t* reqData; + + if (ctx == NULL || wrappedDataIn == NULL) { + return WH_ERROR_BADARGS; + } + + /* Set the request pointer to the shared comm data memory region */ + req = (whMessageKeystore_DataUnwrapRequest*)wh_CommClient_GetDataPtr( + ctx->comm); + if (req == NULL) { + return WH_ERROR_BADARGS; + } + + req->wrappedDataSz = wrappedDataInSz; + req->serverKeyId = serverKeyId; + req->cipherType = cipherType; + + /* Place the wrapped data right after the request */ + reqData = (uint8_t*)(req + 1); + memcpy(reqData, wrappedDataIn, wrappedDataInSz); + + return wh_Client_SendRequest(ctx, group, action, + sizeof(*req) + wrappedDataInSz, (uint8_t*)req); +} + +int wh_Client_DataUnwrapResponse(whClientContext* ctx, + enum wc_CipherType cipherType, void* dataOut, + uint32_t dataSz) +{ + int ret; + uint16_t group; + uint16_t action; + uint16_t size; + whMessageKeystore_DataUnwrapResponse* resp = NULL; + uint8_t* respData; + + if (ctx == NULL || dataOut == NULL) { + return WH_ERROR_BADARGS; + } + + /* Set the response pointer to the shared comm data memory region */ + resp = (whMessageKeystore_DataUnwrapResponse*)wh_CommClient_GetDataPtr( + ctx->comm); + if (resp == NULL) { + return WH_ERROR_BADARGS; + } + + /* Receive the response */ + ret = wh_Client_RecvResponse(ctx, &group, &action, &size, (uint8_t*)resp); + if (ret != WH_ERROR_OK) { + return ret; + } + + if (group != WH_MESSAGE_GROUP_KEY || action != WH_KEY_DATAUNWRAP || + size < sizeof(*resp) || size > sizeof(*resp) + dataSz || + resp->dataSz != dataSz || resp->cipherType != cipherType) { + return WH_ERROR_ABORTED; + } + + if (resp->rc != 0) { + return resp->rc; + } + + /* Copy the wrapped key from the response data into wrappedKeyOut */ + respData = (uint8_t*)(resp + 1); + memcpy(dataOut, respData, dataSz); + + return WH_ERROR_OK; +} +int wh_Client_DataUnwrap(whClientContext* ctx, enum wc_CipherType cipherType, + uint16_t serverKeyId, void* wrappedDataIn, + uint32_t wrappedDataInSz, void* dataOut, + uint32_t dataOutSz) +{ + int ret; + if (ctx == NULL || wrappedDataIn == NULL || dataOut == NULL) { + return WH_ERROR_BADARGS; + } + + ret = wh_Client_DataUnwrapRequest(ctx, cipherType, serverKeyId, + wrappedDataIn, wrappedDataInSz); + if (ret != WH_ERROR_OK) { + return ret; + } + + do { + ret = wh_Client_DataUnwrapResponse(ctx, cipherType, dataOut, dataOutSz); + + } while (ret == WH_ERROR_NOTREADY); + + return ret; +} + #endif /* WOLFHSM_CFG_ENABLE_CLIENT */ #endif /* WOLFHSM_CFG_KEYWRAP */ diff --git a/src/wh_message_keystore.c b/src/wh_message_keystore.c index 3c544e623..3463b7606 100644 --- a/src/wh_message_keystore.c +++ b/src/wh_message_keystore.c @@ -239,9 +239,9 @@ int wh_MessageKeystore_TranslateExportDmaResponse( #endif /* WOLFHSM_CFG_DMA */ /* Key Wrap Request translation */ -int wh_MessageKeystore_TranslateWrapRequest( - uint16_t magic, const whMessageKeystore_WrapRequest* src, - whMessageKeystore_WrapRequest* dest) +int wh_MessageKeystore_TranslateKeyWrapRequest( + uint16_t magic, const whMessageKeystore_KeyWrapRequest* src, + whMessageKeystore_KeyWrapRequest* dest) { if ((src == NULL) || (dest == NULL)) { return WH_ERROR_BADARGS; @@ -253,9 +253,9 @@ int wh_MessageKeystore_TranslateWrapRequest( } /* Key Wrap Response translation */ -int wh_MessageKeystore_TranslateWrapResponse( - uint16_t magic, const whMessageKeystore_WrapResponse* src, - whMessageKeystore_WrapResponse* dest) +int wh_MessageKeystore_TranslateKeyWrapResponse( + uint16_t magic, const whMessageKeystore_KeyWrapResponse* src, + whMessageKeystore_KeyWrapResponse* dest) { if ((src == NULL) || (dest == NULL)) { return WH_ERROR_BADARGS; @@ -267,9 +267,9 @@ int wh_MessageKeystore_TranslateWrapResponse( } /* Key Unwrap Request translation */ -int wh_MessageKeystore_TranslateUnwrapAndExportRequest( - uint16_t magic, const whMessageKeystore_UnwrapAndExportRequest* src, - whMessageKeystore_UnwrapAndExportRequest* dest) +int wh_MessageKeystore_TranslateKeyUnwrapAndExportRequest( + uint16_t magic, const whMessageKeystore_KeyUnwrapAndExportRequest* src, + whMessageKeystore_KeyUnwrapAndExportRequest* dest) { if ((src == NULL) || (dest == NULL)) { return WH_ERROR_BADARGS; @@ -281,9 +281,9 @@ int wh_MessageKeystore_TranslateUnwrapAndExportRequest( } /* Key Unwrap Response translation */ -int wh_MessageKeystore_TranslateUnwrapAndExportResponse( - uint16_t magic, const whMessageKeystore_UnwrapAndExportResponse* src, - whMessageKeystore_UnwrapAndExportResponse* dest) +int wh_MessageKeystore_TranslateKeyUnwrapAndExportResponse( + uint16_t magic, const whMessageKeystore_KeyUnwrapAndExportResponse* src, + whMessageKeystore_KeyUnwrapAndExportResponse* dest) { if ((src == NULL) || (dest == NULL)) { return WH_ERROR_BADARGS; @@ -295,9 +295,9 @@ int wh_MessageKeystore_TranslateUnwrapAndExportResponse( } /* Wrapped Key Cache Request translation */ -int wh_MessageKeystore_TranslateUnwrapAndCacheRequest( - uint16_t magic, const whMessageKeystore_UnwrapAndCacheRequest* src, - whMessageKeystore_UnwrapAndCacheRequest* dest) +int wh_MessageKeystore_TranslateKeyUnwrapAndCacheRequest( + uint16_t magic, const whMessageKeystore_KeyUnwrapAndCacheRequest* src, + whMessageKeystore_KeyUnwrapAndCacheRequest* dest) { if ((src == NULL) || (dest == NULL)) { return WH_ERROR_BADARGS; @@ -309,9 +309,9 @@ int wh_MessageKeystore_TranslateUnwrapAndCacheRequest( } /* Key Cache Response translation */ -int wh_MessageKeystore_TranslateUnwrapAndCacheResponse( - uint16_t magic, const whMessageKeystore_UnwrapAndCacheResponse* src, - whMessageKeystore_UnwrapAndCacheResponse* dest) +int wh_MessageKeystore_TranslateKeyUnwrapAndCacheResponse( + uint16_t magic, const whMessageKeystore_KeyUnwrapAndCacheResponse* src, + whMessageKeystore_KeyUnwrapAndCacheResponse* dest) { if ((src == NULL) || (dest == NULL)) { return WH_ERROR_BADARGS; @@ -321,3 +321,59 @@ int wh_MessageKeystore_TranslateUnwrapAndCacheResponse( WH_T16(magic, dest, src, cipherType); return 0; } + +/* Data Wrap Request translation */ +int wh_MessageKeystore_TranslateDataWrapRequest( + uint16_t magic, const whMessageKeystore_DataWrapRequest* src, + whMessageKeystore_DataWrapRequest* dest) +{ + if ((src == NULL) || (dest == NULL)) { + return WH_ERROR_BADARGS; + } + WH_T32(magic, dest, src, dataSz); + WH_T16(magic, dest, src, serverKeyId); + WH_T16(magic, dest, src, cipherType); + return 0; +} + +/* Data Wrap Response translation */ +int wh_MessageKeystore_TranslateDataWrapResponse( + uint16_t magic, const whMessageKeystore_DataWrapResponse* src, + whMessageKeystore_DataWrapResponse* dest) +{ + if ((src == NULL) || (dest == NULL)) { + return WH_ERROR_BADARGS; + } + WH_T32(magic, dest, src, rc); + WH_T32(magic, dest, src, wrappedDataSz); + WH_T16(magic, dest, src, cipherType); + return 0; +} + +/* Data Unwrap Request translation */ +int wh_MessageKeystore_TranslateDataUnwrapRequest( + uint16_t magic, const whMessageKeystore_DataUnwrapRequest* src, + whMessageKeystore_DataUnwrapRequest* dest) +{ + if ((src == NULL) || (dest == NULL)) { + return WH_ERROR_BADARGS; + } + WH_T32(magic, dest, src, wrappedDataSz); + WH_T16(magic, dest, src, serverKeyId); + WH_T16(magic, dest, src, cipherType); + return 0; +} + +/* Data Unwrap Response translation */ +int wh_MessageKeystore_TranslateDataUnwrapResponse( + uint16_t magic, const whMessageKeystore_DataUnwrapResponse* src, + whMessageKeystore_DataUnwrapResponse* dest) +{ + if ((src == NULL) || (dest == NULL)) { + return WH_ERROR_BADARGS; + } + WH_T32(magic, dest, src, rc); + WH_T32(magic, dest, src, dataSz); + WH_T16(magic, dest, src, cipherType); + return 0; +} diff --git a/src/wh_nvm.c b/src/wh_nvm.c index c91667562..5c81981d1 100644 --- a/src/wh_nvm.c +++ b/src/wh_nvm.c @@ -51,7 +51,7 @@ int wh_Nvm_Init(whNvmContext* context, const whNvmConfig *config) memset(&context->globalCache, 0, sizeof(context->globalCache)); #endif - if (context->cb->Init != NULL) { + if (context->cb != NULL && context->cb->Init != NULL) { rc = context->cb->Init(context->context, config->config); if (rc != 0) { context->cb = NULL; diff --git a/src/wh_server.c b/src/wh_server.c index a21c48152..3ca4fa3e5 100644 --- a/src/wh_server.c +++ b/src/wh_server.c @@ -404,6 +404,7 @@ int wh_Server_HandleRequestMessage(whServerContext* server) } while (rc == WH_ERROR_NOTREADY); } } + return rc; } diff --git a/src/wh_server_keystore.c b/src/wh_server_keystore.c index 898ad4f75..ea33d50ea 100644 --- a/src/wh_server_keystore.c +++ b/src/wh_server_keystore.c @@ -499,11 +499,6 @@ int wh_Server_KeystoreFreshenKey(whServerContext* server, whKeyId keyId, return WH_ERROR_BADARGS; } - /* Reject attempts to freshen wrapped keys from NVM */ - if (WH_KEYID_TYPE(keyId) == WH_KEYTYPE_WRAPPED) { - return WH_ERROR_ABORTED; - } - ret = _FindInCache(server, keyId, &foundIndex, &foundBigIndex, outBuf, outMeta); if (ret != WH_ERROR_OK) { @@ -690,10 +685,7 @@ int wh_Server_KeystoreEraseKey(whServerContext* server, whNvmId keyId) #ifndef NO_AES #ifdef HAVE_AESGCM -#define WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE 16 -#define WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE 12 - -static int _AesGcmWrapKey(whServerContext* server, whKeyId serverKeyId, +static int _AesGcmKeyWrap(whServerContext* server, whKeyId serverKeyId, uint8_t* keyIn, uint16_t keySz, whNvmMetadata* metadataIn, uint8_t* wrappedKeyOut, uint16_t wrappedKeySz) @@ -702,8 +694,9 @@ static int _AesGcmWrapKey(whServerContext* server, whKeyId serverKeyId, Aes aes[1]; uint8_t authTag[WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE]; uint8_t iv[WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE]; - uint8_t serverKey[AES_MAX_KEY_SIZE]; - uint32_t serverKeySz = sizeof(serverKey); + uint8_t* serverKey; + uint32_t serverKeySz; + whNvmMetadata* serverKeyMetadata; uint8_t plainBlob[sizeof(*metadataIn) + WOLFHSM_CFG_KEYWRAP_MAX_KEY_SIZE]; uint32_t plainBlobSz = sizeof(*metadataIn) + keySz; uint8_t* encBlob; @@ -720,14 +713,12 @@ static int _AesGcmWrapKey(whServerContext* server, whKeyId serverKeyId, } /* Get the server side key */ - ret = wh_Server_KeystoreReadKey( - server, - wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, server->comm->client_id, - serverKeyId), - NULL, serverKey, &serverKeySz); + ret = wh_Server_KeystoreFreshenKey(server, serverKeyId, + &serverKey, &serverKeyMetadata); if (ret != WH_ERROR_OK) { return ret; } + serverKeySz = serverKeyMetadata->len; /* Initialize AES context and set it to use the server side key */ ret = wc_AesInit(aes, NULL, server->crypto->devId); @@ -772,7 +763,7 @@ static int _AesGcmWrapKey(whServerContext* server, whKeyId serverKeyId, return WH_ERROR_OK; } -static int _AesGcmUnwrapKey(whServerContext* server, uint16_t serverKeyId, +static int _AesGcmKeyUnwrap(whServerContext* server, uint16_t serverKeyId, void* wrappedKeyIn, uint16_t wrappedKeySz, whNvmMetadata* metadataOut, void* keyOut, uint16_t keySz) @@ -781,8 +772,9 @@ static int _AesGcmUnwrapKey(whServerContext* server, uint16_t serverKeyId, Aes aes[1]; uint8_t authTag[WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE]; uint8_t iv[WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE]; - uint8_t serverKey[AES_MAX_KEY_SIZE]; - uint32_t serverKeySz = sizeof(serverKey); + uint8_t* serverKey; + uint32_t serverKeySz; + whNvmMetadata* serverKeyMetadata; uint8_t* encBlob = (uint8_t*)wrappedKeyIn + sizeof(iv) + sizeof(authTag); uint16_t encBlobSz = wrappedKeySz - sizeof(iv) - sizeof(authTag); uint8_t plainBlob[sizeof(*metadataOut) + WOLFHSM_CFG_KEYWRAP_MAX_KEY_SIZE]; @@ -793,14 +785,12 @@ static int _AesGcmUnwrapKey(whServerContext* server, uint16_t serverKeyId, } /* Get the server side key */ - ret = wh_Server_KeystoreReadKey( - server, - wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, server->comm->client_id, - serverKeyId), - NULL, serverKey, &serverKeySz); + ret = wh_Server_KeystoreFreshenKey(server, serverKeyId, + &serverKey, &serverKeyMetadata); if (ret != WH_ERROR_OK) { return ret; } + serverKeySz = serverKeyMetadata->len; /* Initialize AES context and set it to use the server side key */ ret = wc_AesInit(aes, NULL, server->crypto->devId); @@ -833,13 +823,136 @@ static int _AesGcmUnwrapKey(whServerContext* server, uint16_t serverKeyId, return WH_ERROR_OK; } +static int _AesGcmDataWrap(whServerContext* server, whKeyId serverKeyId, + uint8_t* dataIn, uint16_t dataSz, + uint8_t* wrappedDataOut, uint16_t wrappedDataSz) +{ + int ret = 0; + Aes aes[1]; + uint8_t authTag[WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE]; + uint8_t iv[WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE]; + uint8_t* serverKey; + uint32_t serverKeySz; + whNvmMetadata* serverKeyMetadata; + uint8_t* encBlob; + + if (server == NULL || dataIn == NULL || wrappedDataOut == NULL) { + return WH_ERROR_BADARGS; + } + + /* Check if the buffer is big enough to hold the wrapped data */ + if (wrappedDataSz < sizeof(iv) + sizeof(authTag) + dataSz) { + return WH_ERROR_BUFFER_SIZE; + } + + /* Get the server side key */ + ret = wh_Server_KeystoreFreshenKey(server, serverKeyId, + &serverKey, &serverKeyMetadata); + if (ret != WH_ERROR_OK) { + return ret; + } + serverKeySz = serverKeyMetadata->len; + + /* Initialize AES context and set it to use the server side key */ + ret = wc_AesInit(aes, NULL, server->crypto->devId); + if (ret != 0) { + return ret; + } + + ret = wc_AesGcmSetKey(aes, serverKey, serverKeySz); + if (ret != 0) { + wc_AesFree(aes); + return ret; + } + + /* Generate the IV */ + ret = wc_RNG_GenerateBlock(server->crypto->rng, iv, sizeof(iv)); + if (ret != 0) { + wc_AesFree(aes); + return ret; + } + + /* Place the encrypted blob after the IV and Auth Tag */ + encBlob = (uint8_t*)wrappedDataOut + sizeof(iv) + sizeof(authTag); + + /* Encrypt the blob */ + ret = wc_AesGcmEncrypt(aes, encBlob, dataIn, dataSz, iv, sizeof(iv), + authTag, sizeof(authTag), NULL, 0); + if (ret != 0) { + wc_AesFree(aes); + return ret; + } + + /* Prepend IV + authTag to encrypted blob */ + memcpy(wrappedDataOut, iv, sizeof(iv)); + memcpy(wrappedDataOut + sizeof(iv), authTag, sizeof(authTag)); + + wc_AesFree(aes); + + return WH_ERROR_OK; +} + +static int _AesGcmDataUnwrap(whServerContext* server, uint16_t serverKeyId, + void* wrappedDataIn, uint16_t wrappedDataSz, + void* dataOut, uint16_t dataSz) +{ + int ret = 0; + Aes aes[1]; + uint8_t authTag[WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE]; + uint8_t iv[WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE]; + uint8_t* serverKey; + uint32_t serverKeySz; + whNvmMetadata* serverKeyMetadata; + uint8_t* encBlob = (uint8_t*)wrappedDataIn + sizeof(iv) + sizeof(authTag); + uint16_t encBlobSz = wrappedDataSz - sizeof(iv) - sizeof(authTag); + + if (server == NULL || wrappedDataIn == NULL || dataOut == NULL || + dataSz > WOLFHSM_CFG_KEYWRAP_MAX_DATA_SIZE) { + return WH_ERROR_BADARGS; + } + + /* Get the server side key */ + ret = wh_Server_KeystoreFreshenKey(server, serverKeyId, + &serverKey, &serverKeyMetadata); + if (ret != WH_ERROR_OK) { + return ret; + } + serverKeySz = serverKeyMetadata->len; + + /* Initialize AES context and set it to use the server side key */ + ret = wc_AesInit(aes, NULL, server->crypto->devId); + if (ret != 0) { + return ret; + } + + ret = wc_AesGcmSetKey(aes, serverKey, serverKeySz); + if (ret != 0) { + return ret; + } + + /* Extract IV and authTag from wrappedDataIn */ + memcpy(iv, wrappedDataIn, sizeof(iv)); + memcpy(authTag, wrappedDataIn + sizeof(iv), sizeof(authTag)); + + /* Decrypt the encrypted blob */ + ret = wc_AesGcmDecrypt(aes, dataOut, encBlob, encBlobSz, iv, sizeof(iv), + authTag, sizeof(authTag), NULL, 0); + if (ret != 0) { + wc_AesFree(aes); + return ret; + } + + wc_AesFree(aes); + return WH_ERROR_OK; +} + #endif /* HAVE_AESGCM */ #endif /* !NO_AES */ -static int _HandleWrapKeyRequest(whServerContext* server, - whMessageKeystore_WrapRequest* req, +static int _HandleKeyWrapRequest(whServerContext* server, + whMessageKeystore_KeyWrapRequest* req, uint8_t* reqData, uint32_t reqDataSz, - whMessageKeystore_WrapResponse* resp, + whMessageKeystore_KeyWrapResponse* resp, uint8_t* respData, uint32_t respDataSz) { @@ -847,9 +960,12 @@ static int _HandleWrapKeyRequest(whServerContext* server, uint8_t* wrappedKey; whNvmMetadata metadata; uint8_t key[WOLFHSM_CFG_KEYWRAP_MAX_KEY_SIZE]; + whKeyId serverKeyId; - if (server == NULL || req == NULL || reqData == NULL || resp == NULL || - respData == NULL || req->keySz > WOLFHSM_CFG_KEYWRAP_MAX_KEY_SIZE) { + if (server == NULL || req == NULL || reqData == NULL || + resp == NULL || respData == NULL || + req->keySz > WOLFHSM_CFG_KEYWRAP_MAX_KEY_SIZE) + { return WH_ERROR_BADARGS; } @@ -867,6 +983,12 @@ static int _HandleWrapKeyRequest(whServerContext* server, return WH_ERROR_BADARGS; } + /* Translate the server key id passed in from the client */ + serverKeyId = wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, + server->comm->client_id, + req->serverKeyId); + + /* Store the wrapped key in the response data */ wrappedKey = respData; @@ -885,7 +1007,7 @@ static int _HandleWrapKeyRequest(whServerContext* server, } /* Wrap the key */ - ret = _AesGcmWrapKey(server, req->serverKeyId, key, req->keySz, + ret = _AesGcmKeyWrap(server, serverKeyId, key, req->keySz, &metadata, wrappedKey, wrappedKeySz); if (ret != WH_ERROR_OK) { return ret; @@ -906,21 +1028,22 @@ static int _HandleWrapKeyRequest(whServerContext* server, return WH_ERROR_OK; } -static int _HandleUnwrapAndExportKeyRequest( - whServerContext* server, whMessageKeystore_UnwrapAndExportRequest* req, +static int _HandleKeyUnwrapAndExportRequest( + whServerContext* server, whMessageKeystore_KeyUnwrapAndExportRequest* req, uint8_t* reqData, uint32_t reqDataSz, - whMessageKeystore_UnwrapAndExportResponse* resp, uint8_t* respData, + whMessageKeystore_KeyUnwrapAndExportResponse* resp, uint8_t* respData, uint32_t respDataSz) { - if (server == NULL || req == NULL || reqData == NULL || resp == NULL || - respData == NULL) { - return WH_ERROR_BADARGS; - } - int ret; uint8_t* wrappedKey; whNvmMetadata* metadata; uint8_t* key; + whKeyId serverKeyId; + + if (server == NULL || req == NULL || reqData == NULL || resp == NULL || + respData == NULL) { + return WH_ERROR_BADARGS; + } /* Check if the reqData is big enough to hold the wrapped key */ if (reqDataSz < req->wrappedKeySz) { @@ -930,6 +1053,11 @@ static int _HandleUnwrapAndExportKeyRequest( /* Set the wrapped key to the request data */ wrappedKey = reqData; + /* Translate the server key id passed in from the client */ + serverKeyId = wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, + server->comm->client_id, + req->serverKeyId); + /* Store the metadata and key in the respData */ metadata = (whNvmMetadata*)respData; key = respData + sizeof(*metadata); @@ -953,7 +1081,7 @@ static int _HandleUnwrapAndExportKeyRequest( } /* Unwrap the key */ - ret = _AesGcmUnwrapKey(server, req->serverKeyId, wrappedKey, + ret = _AesGcmKeyUnwrap(server, serverKeyId, wrappedKey, req->wrappedKeySz, metadata, key, keySz); if (ret != WH_ERROR_OK) { return ret; @@ -1000,12 +1128,11 @@ static int _HandleUnwrapAndExportKeyRequest( return ret; } -static int -_HandleUnwrapAndCacheKeyRequest(whServerContext* server, - whMessageKeystore_UnwrapAndCacheRequest* req, - uint8_t* reqData, uint32_t reqDataSz, - whMessageKeystore_UnwrapAndCacheResponse* resp, - uint8_t* respData, uint32_t respDataSz) +static int _HandleKeyUnwrapAndCacheRequest( + whServerContext* server, whMessageKeystore_KeyUnwrapAndCacheRequest* req, + uint8_t* reqData, uint32_t reqDataSz, + whMessageKeystore_KeyUnwrapAndCacheResponse* resp, uint8_t* respData, + uint32_t respDataSz) { /* The server doesn't have any extra response data to send back to the * client */ @@ -1021,6 +1148,7 @@ _HandleUnwrapAndCacheKeyRequest(whServerContext* server, whNvmMetadata metadata = {0}; uint16_t keySz = 0; uint8_t key[WOLFHSM_CFG_KEYWRAP_MAX_KEY_SIZE]; + whKeyId serverKeyId; /* Check if the reqData is big enough to hold the wrapped key */ if (reqDataSz < req->wrappedKeySz) { @@ -1030,6 +1158,11 @@ _HandleUnwrapAndCacheKeyRequest(whServerContext* server, /* Set the wrapped key to the request data */ wrappedKey = reqData; + /* Translate the server key id passed in from the client */ + serverKeyId = wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, + server->comm->client_id, + req->serverKeyId); + /* Unwrap the key based on the cipher type */ switch (req->cipherType) { #ifndef NO_AES @@ -1039,7 +1172,7 @@ _HandleUnwrapAndCacheKeyRequest(whServerContext* server, WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE - sizeof(metadata); resp->cipherType = WC_CIPHER_AES_GCM; - ret = _AesGcmUnwrapKey(server, req->serverKeyId, wrappedKey, + ret = _AesGcmKeyUnwrap(server, serverKeyId, wrappedKey, req->wrappedKeySz, &metadata, key, keySz); if (ret != WH_ERROR_OK) { return ret; @@ -1100,6 +1233,144 @@ _HandleUnwrapAndCacheKeyRequest(whServerContext* server, /* Cache the key */ return wh_Server_KeystoreCacheKey(server, &metadata, key); } + +static int _HandleDataWrapRequest(whServerContext* server, + whMessageKeystore_DataWrapRequest* req, + uint8_t* reqData, uint32_t reqDataSz, + whMessageKeystore_DataWrapResponse* resp, + uint8_t* respData, uint32_t respDataSz) +{ + + int ret; + uint8_t* wrappedData; + uint8_t data[WOLFHSM_CFG_KEYWRAP_MAX_DATA_SIZE]; + whKeyId serverKeyId; + + if (server == NULL || req == NULL || reqData == NULL || resp == NULL || + respData == NULL || req->dataSz > WOLFHSM_CFG_KEYWRAP_MAX_DATA_SIZE) { + return WH_ERROR_BADARGS; + } + + /* Check if the reqData is big enough to hold the data */ + if (reqDataSz < req->dataSz) { + return WH_ERROR_BUFFER_SIZE; + } + + /* Extract the metadata and data from reqData */ + memcpy(data, reqData, req->dataSz); + + /* Translate the server key id passed in from the client */ + serverKeyId = wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, + server->comm->client_id, + req->serverKeyId); + + /* Store the wrapped data in the response data */ + wrappedData = respData; + + switch (req->cipherType) { + +#ifndef NO_AES +#ifdef HAVE_AESGCM + case WC_CIPHER_AES_GCM: { + uint16_t wrappedDataSz = WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE + + WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE + + req->dataSz; + + /* Check if the response data can fit the wrapped data */ + if (respDataSz < wrappedDataSz) { + return WH_ERROR_BUFFER_SIZE; + } + + /* Wrap the data */ + ret = _AesGcmDataWrap(server, serverKeyId, data, req->dataSz, + wrappedData, wrappedDataSz); + if (ret != WH_ERROR_OK) { + return ret; + } + + /* Tell the client how big the wrapped data is */ + resp->wrappedDataSz = wrappedDataSz; + resp->cipherType = WC_CIPHER_AES_GCM; + + } break; +#endif /* HAVE_AESGCM */ +#endif /* !NO_AES */ + + default: + return WH_ERROR_BADARGS; + } + + return WH_ERROR_OK; +} + +static int _HandleDataUnwrapRequest(whServerContext* server, + whMessageKeystore_DataUnwrapRequest* req, + uint8_t* reqData, uint32_t reqDataSz, + whMessageKeystore_DataUnwrapResponse* resp, + uint8_t* respData, uint32_t respDataSz) +{ + + int ret; + uint8_t* wrappedData; + uint8_t* data; + whKeyId serverKeyId; + + if (server == NULL || req == NULL || reqData == NULL || resp == NULL || + respData == NULL) { + return WH_ERROR_BADARGS; + } + + /* Check if the reqData is big enough to hold the data */ + if (reqDataSz < req->wrappedDataSz) { + return WH_ERROR_BUFFER_SIZE; + } + + /* Set the wrapped data to the reqData */ + wrappedData = reqData; + + /* Translate the server key id passed in from the client */ + serverKeyId = wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, + server->comm->client_id, + req->serverKeyId); + + /* Store the unwrapped data in the respData */ + data = respData; + + switch (req->cipherType) { + +#ifndef NO_AES +#ifdef HAVE_AESGCM + case WC_CIPHER_AES_GCM: { + uint16_t dataSz = req->wrappedDataSz - + WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE - + WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE; + + /* Check if the response data can fit the unwrapped data */ + if (respDataSz < dataSz) { + return WH_ERROR_BUFFER_SIZE; + } + + /* Unwrap the data */ + ret = _AesGcmDataUnwrap(server, serverKeyId, wrappedData, + req->wrappedDataSz, data, dataSz); + if (ret != WH_ERROR_OK) { + return ret; + } + + /* Tell the client how big the unwrapped data is */ + resp->dataSz = dataSz; + resp->cipherType = WC_CIPHER_AES_GCM; + + } break; +#endif /* HAVE_AESGCM */ +#endif /* !NO_AES */ + + default: + return WH_ERROR_BADARGS; + } + + return WH_ERROR_OK; +} #endif /* WOLFHSM_CFG_KEYWRAP */ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, @@ -1389,9 +1660,9 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, } break; #ifdef WOLFHSM_CFG_KEYWRAP - case WH_KEY_WRAP: { - whMessageKeystore_WrapRequest wrapReq = {0}; - whMessageKeystore_WrapResponse wrapResp = {0}; + case WH_KEY_KEYWRAP: { + whMessageKeystore_KeyWrapRequest wrapReq = {0}; + whMessageKeystore_KeyWrapResponse wrapResp = {0}; uint8_t* reqData; uint8_t* respData; uint32_t reqDataSz = WOLFHSM_CFG_COMM_DATA_LEN - sizeof(wrapReq); @@ -1403,30 +1674,31 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, } /* Translate request */ - (void)wh_MessageKeystore_TranslateWrapRequest(magic, req_packet, - &wrapReq); + (void)wh_MessageKeystore_TranslateKeyWrapRequest(magic, req_packet, + &wrapReq); /* Set the request data pointer directly after the request */ reqData = - (uint8_t*)req_packet + sizeof(whMessageKeystore_WrapRequest); + (uint8_t*)req_packet + sizeof(whMessageKeystore_KeyWrapRequest); /* Set the response data pointer directly after the response */ - respData = - (uint8_t*)resp_packet + sizeof(whMessageKeystore_WrapResponse); + respData = (uint8_t*)resp_packet + + sizeof(whMessageKeystore_KeyWrapResponse); wrapResp.rc = - _HandleWrapKeyRequest(server, &wrapReq, reqData, reqDataSz, + _HandleKeyWrapRequest(server, &wrapReq, reqData, reqDataSz, &wrapResp, respData, respDataSz); - (void)wh_MessageKeystore_TranslateWrapResponse(magic, &wrapResp, - resp_packet); + + (void)wh_MessageKeystore_TranslateKeyWrapResponse(magic, &wrapResp, + resp_packet); *out_resp_size = sizeof(wrapResp) + wrapResp.wrappedKeySz; } break; - case WH_KEY_UNWRAPEXPORT: { - whMessageKeystore_UnwrapAndExportRequest unwrapReq = {0}; - whMessageKeystore_UnwrapAndExportResponse unwrapResp = {0}; + case WH_KEY_KEYUNWRAPEXPORT: { + whMessageKeystore_KeyUnwrapAndExportRequest unwrapReq = {0}; + whMessageKeystore_KeyUnwrapAndExportResponse unwrapResp = {0}; uint8_t* reqData; uint8_t* respData; uint32_t reqDataSz = WOLFHSM_CFG_COMM_DATA_LEN - sizeof(unwrapReq); @@ -1439,31 +1711,31 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, } /* Translate request */ - (void)wh_MessageKeystore_TranslateUnwrapAndExportRequest( + (void)wh_MessageKeystore_TranslateKeyUnwrapAndExportRequest( magic, req_packet, &unwrapReq); /* Set the request data pointer directly after the request */ reqData = (uint8_t*)req_packet + - sizeof(whMessageKeystore_UnwrapAndExportRequest); + sizeof(whMessageKeystore_KeyUnwrapAndExportRequest); /* Set the response data pointer directly after the response */ respData = (uint8_t*)resp_packet + - sizeof(whMessageKeystore_UnwrapAndExportResponse); + sizeof(whMessageKeystore_KeyUnwrapAndExportResponse); - unwrapResp.rc = _HandleUnwrapAndExportKeyRequest( + unwrapResp.rc = _HandleKeyUnwrapAndExportRequest( server, &unwrapReq, reqData, reqDataSz, &unwrapResp, respData, respDataSz); - (void)wh_MessageKeystore_TranslateUnwrapAndExportResponse( + (void)wh_MessageKeystore_TranslateKeyUnwrapAndExportResponse( magic, &unwrapResp, resp_packet); *out_resp_size = sizeof(unwrapResp) + sizeof(whNvmMetadata) + unwrapResp.keySz; } break; - case WH_KEY_UNWRAPCACHE: { - whMessageKeystore_UnwrapAndCacheRequest cacheReq = {0}; - whMessageKeystore_UnwrapAndCacheResponse cacheResp = {0}; + case WH_KEY_KEYUNWRAPCACHE: { + whMessageKeystore_KeyUnwrapAndCacheRequest cacheReq = {0}; + whMessageKeystore_KeyUnwrapAndCacheResponse cacheResp = {0}; uint8_t* reqData; uint8_t* respData; uint32_t reqDataSz = WOLFHSM_CFG_COMM_DATA_LEN - sizeof(cacheReq); @@ -1475,27 +1747,100 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, } /* Translate request */ - (void)wh_MessageKeystore_TranslateUnwrapAndCacheRequest( + (void)wh_MessageKeystore_TranslateKeyUnwrapAndCacheRequest( magic, req_packet, &cacheReq); /* Set the request data pointer directly after the request */ reqData = (uint8_t*)req_packet + - sizeof(whMessageKeystore_UnwrapAndCacheRequest); + sizeof(whMessageKeystore_KeyUnwrapAndCacheRequest); /* Set the response data pointer directly after the response */ respData = (uint8_t*)resp_packet + - sizeof(whMessageKeystore_UnwrapAndCacheResponse); + sizeof(whMessageKeystore_KeyUnwrapAndCacheResponse); - cacheResp.rc = _HandleUnwrapAndCacheKeyRequest( + cacheResp.rc = _HandleKeyUnwrapAndCacheRequest( server, &cacheReq, reqData, reqDataSz, &cacheResp, respData, respDataSz); - (void)wh_MessageKeystore_TranslateUnwrapAndCacheResponse( + (void)wh_MessageKeystore_TranslateKeyUnwrapAndCacheResponse( magic, &cacheResp, resp_packet); *out_resp_size = sizeof(cacheResp); } break; + case WH_KEY_DATAWRAP: { + whMessageKeystore_DataWrapRequest wrapReq = {0}; + whMessageKeystore_DataWrapResponse wrapResp = {0}; + uint8_t* reqData; + uint8_t* respData; + uint32_t reqDataSz = WOLFHSM_CFG_COMM_DATA_LEN - sizeof(wrapReq); + uint32_t respDataSz = WOLFHSM_CFG_COMM_DATA_LEN - sizeof(wrapResp); + + /* Validate the bounds of the request data */ + if (reqDataSz < req_size) { + return WH_ERROR_BUFFER_SIZE; + } + + /* Translate request */ + (void)wh_MessageKeystore_TranslateDataWrapRequest(magic, req_packet, + &wrapReq); + + + /* Set the request data pointer directly after the request */ + reqData = (uint8_t*)req_packet + + sizeof(whMessageKeystore_DataWrapRequest); + + /* Set the response data pointer directly after the response */ + respData = (uint8_t*)resp_packet + + sizeof(whMessageKeystore_DataWrapResponse); + + wrapResp.rc = + _HandleDataWrapRequest(server, &wrapReq, reqData, reqDataSz, + &wrapResp, respData, respDataSz); + + (void)wh_MessageKeystore_TranslateDataWrapResponse(magic, &wrapResp, + resp_packet); + *out_resp_size = sizeof(wrapResp) + wrapResp.wrappedDataSz; + + } break; + + case WH_KEY_DATAUNWRAP: { + whMessageKeystore_DataUnwrapRequest unwrapReq = {0}; + whMessageKeystore_DataUnwrapResponse unwrapResp = {0}; + uint8_t* reqData; + uint8_t* respData; + uint32_t reqDataSz = WOLFHSM_CFG_COMM_DATA_LEN - sizeof(unwrapReq); + uint32_t respDataSz = + WOLFHSM_CFG_COMM_DATA_LEN - sizeof(unwrapResp); + + /* Validate the bounds of the request data */ + if (reqDataSz < req_size) { + return WH_ERROR_BUFFER_SIZE; + } + + /* Translate request */ + (void)wh_MessageKeystore_TranslateDataUnwrapRequest( + magic, req_packet, &unwrapReq); + + + /* Set the request data pointer directly after the request */ + reqData = (uint8_t*)req_packet + + sizeof(whMessageKeystore_DataUnwrapRequest); + + /* Set the response data pointer directly after the response */ + respData = (uint8_t*)resp_packet + + sizeof(whMessageKeystore_DataUnwrapResponse); + + unwrapResp.rc = + _HandleDataUnwrapRequest(server, &unwrapReq, reqData, reqDataSz, + &unwrapResp, respData, respDataSz); + + (void)wh_MessageKeystore_TranslateDataUnwrapResponse( + magic, &unwrapResp, resp_packet); + *out_resp_size = sizeof(unwrapResp) + unwrapResp.dataSz; + + } break; + #endif /* WOLFHSM_CFG_KEYWRAP */ default: diff --git a/test/wh_test_keywrap.c b/test/wh_test_keywrap.c index 84f4563d1..9c3373a4d 100644 --- a/test/wh_test_keywrap.c +++ b/test/wh_test_keywrap.c @@ -48,11 +48,9 @@ #define WH_TEST_AESGCM_KEYID 2 #define WH_TEST_AES_KEYSIZE 32 #define WH_TEST_AES_TEXTSIZE 16 -#define WH_TEST_AES_IVSIZE 12 -#define WH_TEST_AES_TAGSIZE 16 -#define WH_TEST_AES_WRAPPED_KEYSIZE \ - (WH_TEST_AES_IVSIZE + WH_TEST_AES_TAGSIZE + WH_TEST_AES_KEYSIZE + \ - sizeof(whNvmMetadata)) +#define WH_TEST_AES_WRAPPED_KEYSIZE \ + (WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE + WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE + \ + WH_TEST_AES_KEYSIZE + sizeof(whNvmMetadata)) #endif /* HAVE_AESGCM */ @@ -75,12 +73,12 @@ static int _InitServerKek(whClientContext* client) static int _CleanupServerKek(whClientContext* client) { - return wh_Client_KeyErase(client, WH_TEST_KEKID); + return wh_Client_KeyEvict(client, WH_TEST_KEKID); } #ifdef HAVE_AESGCM -static int _AesGcm_KeyWrap(whClientContext* client, WC_RNG* rng) +static int _AesGcm_TestKeyWrap(whClientContext* client, WC_RNG* rng) { int ret = 0; @@ -89,7 +87,7 @@ static int _AesGcm_KeyWrap(whClientContext* client, WC_RNG* rng) uint8_t wrappedKey[WH_TEST_AES_WRAPPED_KEYSIZE]; whKeyId wrappedKeyId = WH_KEYID_ERASED; whNvmMetadata metadata = { - .id = WH_CLIENT_KEYID_MAKE_WRAPPED_META(WH_TEST_DEFAULT_CLIENT_ID, + .id = WH_CLIENT_KEYID_MAKE_WRAPPED_META(client->comm->client_id, WH_TEST_AESGCM_KEYID), .label = "AES Key Label", .len = WH_TEST_AES_KEYSIZE, @@ -102,8 +100,8 @@ static int _AesGcm_KeyWrap(whClientContext* client, WC_RNG* rng) uint8_t ciphertext[sizeof(plaintext)]; uint8_t decrypted[sizeof(plaintext)]; - uint8_t tag[WH_TEST_AES_TAGSIZE]; - uint8_t iv[WH_TEST_AES_IVSIZE]; + uint8_t tag[WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE]; + uint8_t iv[WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE]; const uint8_t aad[] = {0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2}; @@ -191,12 +189,12 @@ static int _AesGcm_KeyWrap(whClientContext* client, WC_RNG* rng) if (memcmp(plainKey, tmpPlainKey, sizeof(plainKey)) != 0) { WH_ERROR_PRINT("AES GCM wrap/unwrap key failed to match\n"); - return ret; + return -1; } if (memcmp(&metadata, &tmpMetadata, sizeof(metadata)) != 0) { WH_ERROR_PRINT("AES GCM wrap/unwrap metadata failed to match\n"); - return ret; + return -1; } /* Cache a local key using the same numeric ID to confirm coexistence */ @@ -218,15 +216,46 @@ static int _AesGcm_KeyWrap(whClientContext* client, WC_RNG* rng) WH_TEST_AESGCM_KEYID, localKeyId); return WH_ERROR_ABORTED; } - WH_TEST_RETURN_ON_FAIL(wh_Client_KeyErase(client, localKeyId)); + WH_TEST_RETURN_ON_FAIL(wh_Client_KeyEvict(client, localKeyId)); } - wh_Client_KeyErase(client, wrappedKeyId); + wh_Client_KeyEvict(client, wrappedKeyId); wc_AesFree(aes); return ret; } +static int _AesGcm_TestDataWrap(whClientContext* client) +{ + int ret = 0; + uint8_t data[] = "Example data!"; + uint8_t unwrappedData[sizeof(data)] = {0}; + uint8_t wrappedData[sizeof(data) + WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE + + WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE] = {0}; + + ret = wh_Client_DataWrap(client, WC_CIPHER_AES_GCM, WH_TEST_KEKID, data, + sizeof(data), wrappedData, sizeof(wrappedData)); + if (ret != WH_ERROR_OK) { + WH_ERROR_PRINT("Failed to wh_Client_DataWrap %d\n", ret); + return ret; + } + + ret = wh_Client_DataUnwrap(client, WC_CIPHER_AES_GCM, WH_TEST_KEKID, + wrappedData, sizeof(wrappedData), unwrappedData, + sizeof(unwrappedData)); + if (ret != WH_ERROR_OK) { + WH_ERROR_PRINT("Failed to wh_Client_DataUnwrap %d\n", ret); + return ret; + } + + if (memcmp(data, unwrappedData, sizeof(data)) != 0) { + WH_ERROR_PRINT("Unwrapped data failed to match input data\n"); + return -1; + } + + return ret; +} + #endif /* HAVE_AESGCM */ int whTest_Client_KeyWrap(whClientContext* client) @@ -247,9 +276,9 @@ int whTest_Client_KeyWrap(whClientContext* client) } #ifdef HAVE_AESGCM - ret = _AesGcm_KeyWrap(client, rng); + ret = _AesGcm_TestKeyWrap(client, rng); if (ret != WH_ERROR_OK) { - WH_ERROR_PRINT("Failed to _AesGcm_KeyWrap %d\n", ret); + WH_ERROR_PRINT("Failed to _AesGcm_TestKeyWrap %d\n", ret); } #endif @@ -259,6 +288,28 @@ int whTest_Client_KeyWrap(whClientContext* client) return ret; } +int whTest_Client_DataWrap(whClientContext* client) +{ + int ret = 0; + + ret = _InitServerKek(client); + if (ret != WH_ERROR_OK) { + WH_ERROR_PRINT("Failed to _InitServerKek %d\n", ret); + return ret; + } + +#ifdef HAVE_AESGCM + ret = _AesGcm_TestDataWrap(client); + if (ret != WH_ERROR_OK) { + WH_ERROR_PRINT("Failed to _AesGcm_TestDataWrap %d\n", ret); + } +#endif + + _CleanupServerKek(client); + + return ret; +} + int whTest_KeyWrapClientConfig(whClientConfig* clientCfg) { int ret = 0; @@ -284,6 +335,14 @@ int whTest_KeyWrapClientConfig(whClientConfig* clientCfg) printf("KEYWRAP TESTS SUCCESS\n"); } + ret = whTest_Client_DataWrap(client); + if (ret != 0) { + WH_ERROR_PRINT("Failed to whTest_Client_DataWrap %d\n", ret); + } + else { + printf("DATAWRAP TESTS SUCCESS\n"); + } + /* Clean up used resources */ cleanup_and_exit: (void)wh_Client_CommClose(client); diff --git a/wolfhsm/wh_client.h b/wolfhsm/wh_client.h index 12b02c68a..80885f02e 100644 --- a/wolfhsm/wh_client.h +++ b/wolfhsm/wh_client.h @@ -1060,6 +1060,48 @@ int wh_Client_KeyUnwrapAndCacheResponse(whClientContext* ctx, enum wc_CipherType cipherType, uint16_t* keyIdOut); +/** + * @brief Helper function to wrap a data object using a specified key + * + * This helper function uses existing calls in wolfHSM and wolfCrypt to + * construct a wrapped data object using a specified cipher and key id + * + * @param[in] ctx Pointer to the client context. + * @param[in] cipherType Cipher used when wrapping the data. + * @param[in] serverKeyId Key ID to be used for wrapping the data. + * @param[in] dataIn Pointer to the plaintext data you want to wrap. + * @param[in] dataInSz The size in bytes of the plaintext data. + * @param[out] wrappedDataOut The pointer to the buffer that stores the + * resulting wrapped data. + * @param[out] wrappedDataOutSz The size in bytes of the wrapped data buffer. + * @return int Returns 0 on success, or a negative error code on failure. + */ +int wh_Client_DataWrap(whClientContext* ctx, enum wc_CipherType cipherType, + uint16_t serverKeyId, void* dataIn, uint32_t dataInSz, + void* wrappedDataOut, uint32_t wrappedDataOutSz); + +/** + * @brief Helper function to unwrap a wrapped data object using a specified key + * + * This helper function uses existing calls in wolfHSM and wolfCrypt to + * unwrap a wrapped data object using a specified cipher and key id + * + * @param[in] ctx Pointer to the client context. + * @param[in] cipherType Cipher used when unwrapping the data. + * @param[in] serverKeyId Key ID to be used for wrapping the data. + * @param[in] wrappedDataIn Pointer to the wrapped data object you want to + * unwrap. + * @param[in] wrappedDataInSz The size in bytes of the wrapped data object. + * @param[out] dataOut The pointer to the buffer that stores the + * resulting unwrapped data. + * @param[out] dataOutSz The size in bytes of the unwrapped data buffer. + * @return int Returns 0 on success, or a negative error code on failure. + */ +int wh_Client_DataUnwrap(whClientContext* ctx, enum wc_CipherType cipherType, + uint16_t serverKeyId, void* wrappedDataIn, + uint32_t wrappedDataInSz, void* dataOut, + uint32_t dataOutSz); + /* Counter functions */ int wh_Client_CounterInitRequest(whClientContext* c, whNvmId counterId, uint32_t counter); diff --git a/wolfhsm/wh_common.h b/wolfhsm/wh_common.h index 13bfb995c..029613a2a 100644 --- a/wolfhsm/wh_common.h +++ b/wolfhsm/wh_common.h @@ -98,4 +98,7 @@ typedef uint16_t whCertFlags; /* Cache public key belonging to the leaf certificate */ #define WH_CERT_FLAGS_CACHE_LEAF_PUBKEY ((whCertFlags)1 << 0) +#define WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE 16 +#define WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE 12 + #endif /* !WOLFHSM_WH_COMMON_H_ */ diff --git a/wolfhsm/wh_message.h b/wolfhsm/wh_message.h index 6b7f1b2f4..1b34c2efc 100644 --- a/wolfhsm/wh_message.h +++ b/wolfhsm/wh_message.h @@ -61,9 +61,11 @@ enum WH_KEY_ENUM { WH_KEY_ERASE, WH_KEY_CACHE_DMA, WH_KEY_EXPORT_DMA, - WH_KEY_WRAP, - WH_KEY_UNWRAPEXPORT, - WH_KEY_UNWRAPCACHE + WH_KEY_KEYWRAP, + WH_KEY_KEYUNWRAPEXPORT, + WH_KEY_KEYUNWRAPCACHE, + WH_KEY_DATAWRAP, + WH_KEY_DATAUNWRAP, }; /* SHE actions */ diff --git a/wolfhsm/wh_message_keystore.h b/wolfhsm/wh_message_keystore.h index 48659cf0f..a0588c3a4 100644 --- a/wolfhsm/wh_message_keystore.h +++ b/wolfhsm/wh_message_keystore.h @@ -232,7 +232,7 @@ typedef struct { * whNvmMetadata metadata * uint8_t key[keySz] */ -} whMessageKeystore_WrapRequest; +} whMessageKeystore_KeyWrapRequest; /* Wrap Key Response */ typedef struct { @@ -242,16 +242,16 @@ typedef struct { /* Data follows: * uint8_t wrappedKey[wrappedKeySz] */ -} whMessageKeystore_WrapResponse; +} whMessageKeystore_KeyWrapResponse; /* Wrap key translation functions */ -int wh_MessageKeystore_TranslateWrapRequest( - uint16_t magic, const whMessageKeystore_WrapRequest* src, - whMessageKeystore_WrapRequest* dest); +int wh_MessageKeystore_TranslateKeyWrapRequest( + uint16_t magic, const whMessageKeystore_KeyWrapRequest* src, + whMessageKeystore_KeyWrapRequest* dest); -int wh_MessageKeystore_TranslateWrapResponse( - uint16_t magic, const whMessageKeystore_WrapResponse* src, - whMessageKeystore_WrapResponse* dest); +int wh_MessageKeystore_TranslateKeyWrapResponse( + uint16_t magic, const whMessageKeystore_KeyWrapResponse* src, + whMessageKeystore_KeyWrapResponse* dest); /* Unwrap Key export Request */ typedef struct { @@ -262,7 +262,7 @@ typedef struct { /* Data follows: * uint8_t wrappedKey[wrappedKeySz] */ -} whMessageKeystore_UnwrapAndExportRequest; +} whMessageKeystore_KeyUnwrapAndExportRequest; /* Unwrap Key export Response*/ typedef struct { @@ -273,17 +273,17 @@ typedef struct { * whNvmMetadata metadata * uint8_t key[keySz] */ -} whMessageKeystore_UnwrapAndExportResponse; +} whMessageKeystore_KeyUnwrapAndExportResponse; /* Unwrap Key export translation functions */ -int wh_MessageKeystore_TranslateUnwrapAndExportRequest( - uint16_t magic, const whMessageKeystore_UnwrapAndExportRequest* src, - whMessageKeystore_UnwrapAndExportRequest* dest); +int wh_MessageKeystore_TranslateKeyUnwrapAndExportRequest( + uint16_t magic, const whMessageKeystore_KeyUnwrapAndExportRequest* src, + whMessageKeystore_KeyUnwrapAndExportRequest* dest); -int wh_MessageKeystore_TranslateUnwrapAndExportResponse( - uint16_t magic, const whMessageKeystore_UnwrapAndExportResponse* src, - whMessageKeystore_UnwrapAndExportResponse* dest); +int wh_MessageKeystore_TranslateKeyUnwrapAndExportResponse( + uint16_t magic, const whMessageKeystore_KeyUnwrapAndExportResponse* src, + whMessageKeystore_KeyUnwrapAndExportResponse* dest); /* Unwrap Key Cache Request */ typedef struct { @@ -294,23 +294,83 @@ typedef struct { /* Data follows: * uint8_t wrappedKey[wrappedKeySz] */ -} whMessageKeystore_UnwrapAndCacheRequest; +} whMessageKeystore_KeyUnwrapAndCacheRequest; /* Unwrap Key Cache Response*/ typedef struct { uint32_t rc; uint16_t keyId; uint16_t cipherType; -} whMessageKeystore_UnwrapAndCacheResponse; +} whMessageKeystore_KeyUnwrapAndCacheResponse; /* Unwrap Key Cache translation functions */ -int wh_MessageKeystore_TranslateUnwrapAndCacheRequest( - uint16_t magic, const whMessageKeystore_UnwrapAndCacheRequest* src, - whMessageKeystore_UnwrapAndCacheRequest* dest); +int wh_MessageKeystore_TranslateKeyUnwrapAndCacheRequest( + uint16_t magic, const whMessageKeystore_KeyUnwrapAndCacheRequest* src, + whMessageKeystore_KeyUnwrapAndCacheRequest* dest); -int wh_MessageKeystore_TranslateUnwrapAndCacheResponse( - uint16_t magic, const whMessageKeystore_UnwrapAndCacheResponse* src, - whMessageKeystore_UnwrapAndCacheResponse* dest); +int wh_MessageKeystore_TranslateKeyUnwrapAndCacheResponse( + uint16_t magic, const whMessageKeystore_KeyUnwrapAndCacheResponse* src, + whMessageKeystore_KeyUnwrapAndCacheResponse* dest); +/* Wrap Data Request */ +typedef struct { + uint32_t dataSz; + uint16_t serverKeyId; + uint16_t cipherType; + /* Data follows: + * uint8_t data[dataSz] + */ +} whMessageKeystore_DataWrapRequest; + +/* Wrap Data Response */ +typedef struct { + uint32_t rc; + uint32_t wrappedDataSz; + uint16_t cipherType; + uint8_t WH_PAD[2]; + /* Data follows: + * uint8_t wrappedData[wrappedDataSz] + */ +} whMessageKeystore_DataWrapResponse; + +/* Wrap key translation functions */ +int wh_MessageKeystore_TranslateDataWrapRequest( + uint16_t magic, const whMessageKeystore_DataWrapRequest* src, + whMessageKeystore_DataWrapRequest* dest); + +int wh_MessageKeystore_TranslateDataWrapResponse( + uint16_t magic, const whMessageKeystore_DataWrapResponse* src, + whMessageKeystore_DataWrapResponse* dest); + +/* Unwrap Data export Request */ +typedef struct { + uint32_t wrappedDataSz; + uint16_t serverKeyId; + uint16_t cipherType; + /* Data follows: + * uint8_t wrappedData[wrappedDataSz] + */ +} whMessageKeystore_DataUnwrapRequest; + +/* Unwrap Data Response*/ +typedef struct { + uint32_t rc; + uint32_t dataSz; + uint16_t cipherType; + uint8_t WH_PAD[2]; + /* Data follows: + * uint8_t data[dataSz] + */ +} whMessageKeystore_DataUnwrapResponse; + + +/* Unwrap Data export translation functions */ +int wh_MessageKeystore_TranslateDataUnwrapRequest( + uint16_t magic, const whMessageKeystore_DataUnwrapRequest* src, + whMessageKeystore_DataUnwrapRequest* dest); + +int wh_MessageKeystore_TranslateDataUnwrapResponse( + uint16_t magic, const whMessageKeystore_DataUnwrapResponse* src, + whMessageKeystore_DataUnwrapResponse* dest); #endif /* !WOLFHSM_WH_MESSAGE_KEYSTORE_H_ */ diff --git a/wolfhsm/wh_settings.h b/wolfhsm/wh_settings.h index f92047d34..d74416159 100644 --- a/wolfhsm/wh_settings.h +++ b/wolfhsm/wh_settings.h @@ -252,6 +252,10 @@ #define WOLFHSM_CFG_KEYWRAP_MAX_KEY_SIZE 2000 #endif +#ifndef WOLFHSM_CFG_KEYWRAP_MAX_DATA_SIZE +#define WOLFHSM_CFG_KEYWRAP_MAX_DATA_SIZE 2000 +#endif + #if defined(NO_AES) || !defined(HAVE_AESGCM) #error \ "WOLFHSM_CFG_KEYWRAP requires NO_AES to be undefined and HAVE_AESGCM to be defined"