From f64a2442bdd53558372297ad9ae0afa3d7906981 Mon Sep 17 00:00:00 2001 From: Alex Lanzano Date: Thu, 23 Oct 2025 16:36:03 -0400 Subject: [PATCH 1/9] keywrap: Move AES GCM IV and tag buffer lengths to common header --- src/wh_server_keystore.c | 3 --- wolfhsm/wh_common.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wh_server_keystore.c b/src/wh_server_keystore.c index 898ad4f75..f4ffe8ef7 100644 --- a/src/wh_server_keystore.c +++ b/src/wh_server_keystore.c @@ -690,9 +690,6 @@ 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, uint8_t* keyIn, uint16_t keySz, whNvmMetadata* metadataIn, uint8_t* wrappedKeyOut, 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_ */ From 18cb378bb70a258bc84d5fc514c2334be500afc2 Mon Sep 17 00:00:00 2001 From: Alex Lanzano Date: Thu, 23 Oct 2025 16:49:03 -0400 Subject: [PATCH 2/9] Implement generic data wrap/unwrap helper functions --- src/wh_client_keywrap.c | 155 ++++++++++++++++++++++++++++++++++++++++ test/wh_test_keywrap.c | 64 ++++++++++++++++- wolfhsm/wh_client.h | 42 +++++++++++ 3 files changed, 259 insertions(+), 2 deletions(-) diff --git a/src/wh_client_keywrap.c b/src/wh_client_keywrap.c index 8945c20fc..943534ef7 100644 --- a/src/wh_client_keywrap.c +++ b/src/wh_client_keywrap.c @@ -331,5 +331,160 @@ int wh_Client_KeyUnwrapAndCache(whClientContext* ctx, return ret; } +int wh_Client_AesGcmDataWrap(whClientContext* ctx, uint16_t serverKeyId, + void* dataIn, uint32_t dataInSz, + void* wrappedDataOut, uint32_t wrappedDataOutSz) +{ + 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* encDataPtr; + + if (ctx == NULL || dataIn == NULL || dataInSz == 0 || + wrappedDataOut == NULL || wrappedDataOutSz == 0) { + return WH_ERROR_BADARGS; + } + + /* Check if the buffer is big enough to hold the wrapped key */ + if (wrappedDataOutSz < sizeof(iv) + sizeof(authTag) + dataInSz) { + return WH_ERROR_BUFFER_SIZE; + } + + /* Initialize AES context and set it to use the server side key */ + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret != 0) { + return ret; + } + + ret = wh_Client_AesSetKeyId(aes, serverKeyId); + if (ret != 0) { + wc_AesFree(aes); + return ret; + } + + /* Generate the IV */ + ret = wh_Client_RngGenerate(ctx, iv, sizeof(iv)); + if (ret != 0) { + wc_AesFree(aes); + return ret; + } + + /* Place the encrypted data after the IV and tag in the wrapped data buffer + */ + encDataPtr = wrappedDataOut + sizeof(iv) + sizeof(authTag); + + /* Encrypt the blob */ + ret = wc_AesGcmEncrypt(aes, encDataPtr, dataIn, dataInSz, iv, sizeof(iv), + authTag, sizeof(authTag), NULL, 0); + if (ret != 0) { + wc_AesFree(aes); + return ret; + } + + /* Prepend IV + authTag to the wrapped data buffer */ + memcpy(wrappedDataOut, iv, sizeof(iv)); + memcpy(wrappedDataOut + sizeof(iv), authTag, sizeof(authTag)); + + wc_AesFree(aes); + + return WH_ERROR_OK; +} + +int wh_Client_AesGcmDataUnwrap(whClientContext* ctx, uint16_t serverKeyId, + void* wrappedDataIn, uint32_t wrappedDataInSz, + void* dataOut, uint32_t dataOutSz) +{ + int ret = 0; + Aes aes[1]; + uint8_t* authTag; + uint8_t* iv; + uint8_t* encDataPtr; + + if (ctx == NULL || wrappedDataIn == NULL || wrappedDataInSz == 0 || + dataOut == NULL || dataOutSz == 0) { + return WH_ERROR_BADARGS; + } + + /* Check if the buffer is big enough to hold the unwrapped data */ + if (dataOutSz < wrappedDataInSz - (WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE + + WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE)) { + return WH_ERROR_BUFFER_SIZE; + } + + /* Initialize AES context and set it to use the server side key */ + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret != 0) { + return ret; + } + + ret = wh_Client_AesSetKeyId(aes, serverKeyId); + if (ret != 0) { + wc_AesFree(aes); + return ret; + } + + /* extract the IV, Tag, and encrypted data */ + iv = wrappedDataIn; + authTag = wrappedDataIn + WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE; + encDataPtr = wrappedDataIn + WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE + + WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE; + + /* Encrypt the blob */ + ret = wc_AesGcmDecrypt(aes, dataOut, encDataPtr, dataOutSz, iv, + WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE, authTag, + WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE, NULL, 0); + if (ret != 0) { + wc_AesFree(aes); + return ret; + } + + wc_AesFree(aes); + + 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; + + switch (cipherType) { + case WC_CIPHER_AES_GCM: + ret = wh_Client_AesGcmDataWrap(ctx, serverKeyId, dataIn, dataInSz, + wrappedDataOut, wrappedDataOutSz); + break; + + default: + ret = WH_ERROR_BADARGS; + break; + } + + return ret; +} + +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; + + switch (cipherType) { + case WC_CIPHER_AES_GCM: + ret = + wh_Client_AesGcmDataUnwrap(ctx, serverKeyId, wrappedDataIn, + wrappedDataInSz, dataOut, dataOutSz); + break; + + default: + ret = WH_ERROR_BADARGS; + break; + } + + return ret; +} + #endif /* WOLFHSM_CFG_ENABLE_CLIENT */ #endif /* WOLFHSM_CFG_KEYWRAP */ diff --git a/test/wh_test_keywrap.c b/test/wh_test_keywrap.c index 84f4563d1..4dc2a12dc 100644 --- a/test/wh_test_keywrap.c +++ b/test/wh_test_keywrap.c @@ -191,12 +191,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 */ @@ -227,6 +227,37 @@ static int _AesGcm_KeyWrap(whClientContext* client, WC_RNG* rng) return ret; } +static int _AesGcm_DataWrap(whClientContext* client) +{ + int ret = 0; + uint8_t data[] = "Example data!"; + uint8_t unwrappedData[sizeof(data)] = {0}; + uint8_t wrappedData[sizeof(data) + WH_TEST_AES_IVSIZE + + WH_TEST_AES_TAGSIZE] = {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) @@ -259,6 +290,30 @@ int whTest_Client_KeyWrap(whClientContext* client) return ret; } +int whTest_Client_DataWrap(whClientContext* client) +{ + int ret = 0; + WC_RNG rng[1]; + + ret = _InitServerKek(client); + if (ret != WH_ERROR_OK) { + WH_ERROR_PRINT("Failed to _InitServerKek %d\n", ret); + return ret; + } + +#ifdef HAVE_AESGCM + ret = _AesGcm_DataWrap(client); + if (ret != WH_ERROR_OK) { + WH_ERROR_PRINT("Failed to _AesGcm_DataWrap %d\n", ret); + } +#endif + + _CleanupServerKek(client); + + (void)wc_FreeRng(rng); + return ret; +} + int whTest_KeyWrapClientConfig(whClientConfig* clientCfg) { int ret = 0; @@ -284,6 +339,11 @@ 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); + } + /* 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..705fe7443 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 unwrapping the key. + * @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 key. + * @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); From 0d9b70be086976af16ccb68a116d09d637254851 Mon Sep 17 00:00:00 2001 From: Alex Lanzano Date: Fri, 24 Oct 2025 12:01:51 -0400 Subject: [PATCH 3/9] #226: Address comments --- src/wh_client_keywrap.c | 16 +++++++++------- test/wh_test_keywrap.c | 32 ++++++++++++++------------------ wolfhsm/wh_client.h | 4 ++-- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/wh_client_keywrap.c b/src/wh_client_keywrap.c index 943534ef7..200c6afd5 100644 --- a/src/wh_client_keywrap.c +++ b/src/wh_client_keywrap.c @@ -331,9 +331,10 @@ int wh_Client_KeyUnwrapAndCache(whClientContext* ctx, return ret; } -int wh_Client_AesGcmDataWrap(whClientContext* ctx, uint16_t serverKeyId, - void* dataIn, uint32_t dataInSz, - void* wrappedDataOut, uint32_t wrappedDataOutSz) +static int wh_Client_AesGcmDataWrap(whClientContext* ctx, uint16_t serverKeyId, + void* dataIn, uint32_t dataInSz, + void* wrappedDataOut, + uint32_t wrappedDataOutSz) { int ret = 0; Aes aes[1]; @@ -391,9 +392,10 @@ int wh_Client_AesGcmDataWrap(whClientContext* ctx, uint16_t serverKeyId, return WH_ERROR_OK; } -int wh_Client_AesGcmDataUnwrap(whClientContext* ctx, uint16_t serverKeyId, - void* wrappedDataIn, uint32_t wrappedDataInSz, - void* dataOut, uint32_t dataOutSz) +static int wh_Client_AesGcmDataUnwrap(whClientContext* ctx, + uint16_t serverKeyId, void* wrappedDataIn, + uint32_t wrappedDataInSz, void* dataOut, + uint32_t dataOutSz) { int ret = 0; Aes aes[1]; @@ -430,7 +432,7 @@ int wh_Client_AesGcmDataUnwrap(whClientContext* ctx, uint16_t serverKeyId, encDataPtr = wrappedDataIn + WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE + WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE; - /* Encrypt the blob */ + /* Decrypt the blob */ ret = wc_AesGcmDecrypt(aes, dataOut, encDataPtr, dataOutSz, iv, WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE, authTag, WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE, NULL, 0); diff --git a/test/wh_test_keywrap.c b/test/wh_test_keywrap.c index 4dc2a12dc..5a7ff3e34 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 */ @@ -80,7 +78,7 @@ static int _CleanupServerKek(whClientContext* client) #ifdef HAVE_AESGCM -static int _AesGcm_KeyWrap(whClientContext* client, WC_RNG* rng) +static int _AesGcm_TestKeyWrap(whClientContext* client, WC_RNG* rng) { int ret = 0; @@ -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}; @@ -227,13 +225,13 @@ static int _AesGcm_KeyWrap(whClientContext* client, WC_RNG* rng) return ret; } -static int _AesGcm_DataWrap(whClientContext* client) +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) + WH_TEST_AES_IVSIZE + - WH_TEST_AES_TAGSIZE] = {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)); @@ -278,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 @@ -292,8 +290,7 @@ int whTest_Client_KeyWrap(whClientContext* client) int whTest_Client_DataWrap(whClientContext* client) { - int ret = 0; - WC_RNG rng[1]; + int ret = 0; ret = _InitServerKek(client); if (ret != WH_ERROR_OK) { @@ -302,15 +299,14 @@ int whTest_Client_DataWrap(whClientContext* client) } #ifdef HAVE_AESGCM - ret = _AesGcm_DataWrap(client); + ret = _AesGcm_TestDataWrap(client); if (ret != WH_ERROR_OK) { - WH_ERROR_PRINT("Failed to _AesGcm_DataWrap %d\n", ret); + WH_ERROR_PRINT("Failed to _AesGcm_TestDataWrap %d\n", ret); } #endif _CleanupServerKek(client); - (void)wc_FreeRng(rng); return ret; } diff --git a/wolfhsm/wh_client.h b/wolfhsm/wh_client.h index 705fe7443..80885f02e 100644 --- a/wolfhsm/wh_client.h +++ b/wolfhsm/wh_client.h @@ -1067,7 +1067,7 @@ int wh_Client_KeyUnwrapAndCacheResponse(whClientContext* ctx, * 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 unwrapping the key. + * @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. @@ -1087,7 +1087,7 @@ int wh_Client_DataWrap(whClientContext* ctx, enum wc_CipherType cipherType, * 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 key. + * @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. From 0445ba1bc2ec5b850083f45fd1d46447e1cf63d4 Mon Sep 17 00:00:00 2001 From: Alex Lanzano Date: Wed, 29 Oct 2025 17:16:31 -0400 Subject: [PATCH 4/9] Handle data wrapping on the server. Use consistent naming for key/data wrap --- src/wh_client_keywrap.c | 306 ++++++++++++++---------- src/wh_message_keystore.c | 92 +++++-- src/wh_server_keystore.c | 437 +++++++++++++++++++++++++++++----- wolfhsm/wh_message.h | 8 +- wolfhsm/wh_message_keystore.h | 108 +++++++-- wolfhsm/wh_settings.h | 4 + 6 files changed, 728 insertions(+), 227 deletions(-) diff --git a/src/wh_client_keywrap.c b/src/wh_client_keywrap.c index 200c6afd5..21fadf8c7 100644 --- a/src/wh_client_keywrap.c +++ b/src/wh_client_keywrap.c @@ -18,8 +18,8 @@ int wh_Client_KeyWrapRequest(whClientContext* ctx, whNvmMetadata* metadata) { uint16_t group = WH_MESSAGE_GROUP_KEY; - uint16_t action = WH_KEY_WRAP; - whMessageKeystore_WrapRequest* req = NULL; + uint16_t action = WH_KEY_KEYWRAP; + whMessageKeystore_KeyWrapRequest* req = NULL; uint8_t* reqData; if (ctx == NULL || key == NULL || metadata == NULL) { @@ -27,7 +27,8 @@ int wh_Client_KeyWrapRequest(whClientContext* ctx, } /* 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; } @@ -55,7 +56,7 @@ int wh_Client_KeyWrapResponse(whClientContext* ctx, uint16_t group; uint16_t action; uint16_t size; - whMessageKeystore_WrapResponse* resp = NULL; + whMessageKeystore_KeyWrapResponse* resp = NULL; uint8_t* respData; if (ctx == NULL || wrappedKeyOut == NULL) { @@ -63,7 +64,8 @@ int wh_Client_KeyWrapResponse(whClientContext* ctx, } /* 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; @@ -125,8 +127,8 @@ int wh_Client_KeyUnwrapAndExportRequest(whClientContext* ctx, { uint16_t group = WH_MESSAGE_GROUP_KEY; - uint16_t action = WH_KEY_UNWRAPEXPORT; - whMessageKeystore_UnwrapAndExportRequest* req = NULL; + uint16_t action = WH_KEY_KEYUNWRAPEXPORT; + whMessageKeystore_KeyUnwrapAndExportRequest* req = NULL; uint8_t* reqData; if (ctx == NULL || wrappedKeyIn == NULL) { @@ -134,8 +136,9 @@ int wh_Client_KeyUnwrapAndExportRequest(whClientContext* ctx, } /* 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; } @@ -162,7 +165,7 @@ int wh_Client_KeyUnwrapAndExportResponse(whClientContext* ctx, uint16_t group; uint16_t action; uint16_t size; - whMessageKeystore_UnwrapAndExportResponse* resp = NULL; + whMessageKeystore_KeyUnwrapAndExportResponse* resp = NULL; uint8_t* respData; if (ctx == NULL || metadataOut == NULL || keyOut == NULL) { @@ -170,8 +173,9 @@ int wh_Client_KeyUnwrapAndExportResponse(whClientContext* ctx, } /* 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; + 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; @@ -274,14 +278,15 @@ int wh_Client_KeyUnwrapAndCacheResponse(whClientContext* ctx, uint16_t group; uint16_t action; uint16_t size; - whMessageKeystore_UnwrapAndCacheResponse* resp = NULL; + 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,160 +336,209 @@ int wh_Client_KeyUnwrapAndCache(whClientContext* ctx, return ret; } -static int wh_Client_AesGcmDataWrap(whClientContext* ctx, uint16_t serverKeyId, - void* dataIn, uint32_t dataInSz, - void* wrappedDataOut, - uint32_t wrappedDataOutSz) +int wh_Client_DataWrapRequest(whClientContext* ctx, + enum wc_CipherType cipherType, + uint16_t serverKeyId, void* dataIn, + uint32_t dataInSz) { - 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* encDataPtr; - - if (ctx == NULL || dataIn == NULL || dataInSz == 0 || - wrappedDataOut == NULL || wrappedDataOutSz == 0) { + 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; } - /* Check if the buffer is big enough to hold the wrapped key */ - if (wrappedDataOutSz < sizeof(iv) + sizeof(authTag) + dataInSz) { - return WH_ERROR_BUFFER_SIZE; + /* 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; } - /* Initialize AES context and set it to use the server side key */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); - if (ret != 0) { - return ret; + 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; } - ret = wh_Client_AesSetKeyId(aes, serverKeyId); - if (ret != 0) { - wc_AesFree(aes); - return ret; + /* 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; } - /* Generate the IV */ - ret = wh_Client_RngGenerate(ctx, iv, sizeof(iv)); - if (ret != 0) { - wc_AesFree(aes); + /* Receive the response */ + ret = wh_Client_RecvResponse(ctx, &group, &action, &size, (uint8_t*)resp); + if (ret != WH_ERROR_OK) { return ret; } - /* Place the encrypted data after the IV and tag in the wrapped data buffer - */ - encDataPtr = wrappedDataOut + sizeof(iv) + sizeof(authTag); - - /* Encrypt the blob */ - ret = wc_AesGcmEncrypt(aes, encDataPtr, dataIn, dataInSz, iv, sizeof(iv), - authTag, sizeof(authTag), NULL, 0); - if (ret != 0) { - wc_AesFree(aes); - 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; } - /* Prepend IV + authTag to the wrapped data buffer */ - memcpy(wrappedDataOut, iv, sizeof(iv)); - memcpy(wrappedDataOut + sizeof(iv), authTag, sizeof(authTag)); + if (resp->rc != 0) { + return resp->rc; + } - wc_AesFree(aes); + /* Copy the wrapped key from the response data into wrappedKeyOut */ + respData = (uint8_t*)(resp + 1); + memcpy(wrappedDataOut, respData, wrappedDataSz); return WH_ERROR_OK; } -static int wh_Client_AesGcmDataUnwrap(whClientContext* ctx, - uint16_t serverKeyId, void* wrappedDataIn, - uint32_t wrappedDataInSz, void* dataOut, - uint32_t dataOutSz) +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 = 0; - Aes aes[1]; - uint8_t* authTag; - uint8_t* iv; - uint8_t* encDataPtr; - - if (ctx == NULL || wrappedDataIn == NULL || wrappedDataInSz == 0 || - dataOut == NULL || dataOutSz == 0) { + int ret; + if (ctx == NULL || wrappedDataOut == NULL || dataIn == NULL) { return WH_ERROR_BADARGS; } - /* Check if the buffer is big enough to hold the unwrapped data */ - if (dataOutSz < wrappedDataInSz - (WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE + - WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE)) { - return WH_ERROR_BUFFER_SIZE; - } - - /* Initialize AES context and set it to use the server side key */ - ret = wc_AesInit(aes, NULL, WH_DEV_ID); - if (ret != 0) { + ret = wh_Client_DataWrapRequest(ctx, cipherType, serverKeyId, dataIn, + dataInSz); + if (ret != WH_ERROR_OK) { return ret; } - ret = wh_Client_AesSetKeyId(aes, serverKeyId); - if (ret != 0) { - wc_AesFree(aes); - return ret; - } + do { + ret = wh_Client_DataWrapResponse(ctx, cipherType, wrappedDataOut, + wrappedDataOutSz); - /* extract the IV, Tag, and encrypted data */ - iv = wrappedDataIn; - authTag = wrappedDataIn + WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE; - encDataPtr = wrappedDataIn + WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE + - WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE; + } while (ret == WH_ERROR_NOTREADY); - /* Decrypt the blob */ - ret = wc_AesGcmDecrypt(aes, dataOut, encDataPtr, dataOutSz, iv, - WOLFHSM_KEYWRAP_AES_GCM_IV_SIZE, authTag, - WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE, NULL, 0); - if (ret != 0) { - wc_AesFree(aes); - return ret; + 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; } - wc_AesFree(aes); + /* 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; + } - return WH_ERROR_OK; + 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_DataWrap(whClientContext* ctx, enum wc_CipherType cipherType, - uint16_t serverKeyId, void* dataIn, uint32_t dataInSz, - void* wrappedDataOut, uint32_t wrappedDataOutSz) +int wh_Client_DataUnwrapResponse(whClientContext* ctx, + enum wc_CipherType cipherType, void* dataOut, + uint32_t dataSz) { - int ret; + 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; + } - switch (cipherType) { - case WC_CIPHER_AES_GCM: - ret = wh_Client_AesGcmDataWrap(ctx, serverKeyId, dataIn, dataInSz, - wrappedDataOut, wrappedDataOutSz); - break; + /* Receive the response */ + ret = wh_Client_RecvResponse(ctx, &group, &action, &size, (uint8_t*)resp); + if (ret != WH_ERROR_OK) { + return ret; + } - default: - ret = WH_ERROR_BADARGS; - break; + 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; } - return ret; -} + 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; + } - switch (cipherType) { - case WC_CIPHER_AES_GCM: - ret = - wh_Client_AesGcmDataUnwrap(ctx, serverKeyId, wrappedDataIn, - wrappedDataInSz, dataOut, dataOutSz); - break; - - default: - ret = WH_ERROR_BADARGS; - break; + 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; } 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_server_keystore.c b/src/wh_server_keystore.c index f4ffe8ef7..bc6036c00 100644 --- a/src/wh_server_keystore.c +++ b/src/wh_server_keystore.c @@ -690,7 +690,7 @@ int wh_Server_KeystoreEraseKey(whServerContext* server, whNvmId keyId) #ifndef NO_AES #ifdef HAVE_AESGCM -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) @@ -769,7 +769,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) @@ -830,13 +830,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[AES_MAX_KEY_SIZE]; + uint32_t serverKeySz = sizeof(serverKey); + 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_KeystoreReadKey( + server, + WH_MAKE_KEYID(WH_KEYTYPE_CRYPTO, server->comm->client_id, serverKeyId), + NULL, serverKey, &serverKeySz); + if (ret != WH_ERROR_OK) { + return ret; + } + + /* 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[AES_MAX_KEY_SIZE]; + uint32_t serverKeySz = sizeof(serverKey); + 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_KeystoreReadKey( + server, + WH_MAKE_KEYID(WH_KEYTYPE_CRYPTO, server->comm->client_id, serverKeyId), + NULL, serverKey, &serverKeySz); + if (ret != WH_ERROR_OK) { + return ret; + } + + /* 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) { @@ -882,7 +1005,7 @@ static int _HandleWrapKeyRequest(whServerContext* server, } /* Wrap the key */ - ret = _AesGcmWrapKey(server, req->serverKeyId, key, req->keySz, + ret = _AesGcmKeyWrap(server, req->serverKeyId, key, req->keySz, &metadata, wrappedKey, wrappedKeySz); if (ret != WH_ERROR_OK) { return ret; @@ -903,22 +1026,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; + 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) { return WH_ERROR_BUFFER_SIZE; @@ -950,7 +1073,7 @@ static int _HandleUnwrapAndExportKeyRequest( } /* Unwrap the key */ - ret = _AesGcmUnwrapKey(server, req->serverKeyId, wrappedKey, + ret = _AesGcmKeyUnwrap(server, req->serverKeyId, wrappedKey, req->wrappedKeySz, metadata, key, keySz); if (ret != WH_ERROR_OK) { return ret; @@ -997,12 +1120,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 */ @@ -1036,7 +1158,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, req->serverKeyId, wrappedKey, req->wrappedKeySz, &metadata, key, keySz); if (ret != WH_ERROR_OK) { return ret; @@ -1097,6 +1219,132 @@ _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]; + + 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); + + /* 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, req->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; + + 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; + + /* 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, req->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, @@ -1386,9 +1634,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); @@ -1400,30 +1648,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); - - wrapResp.rc = - _HandleWrapKeyRequest(server, &wrapReq, reqData, reqDataSz, - &wrapResp, respData, respDataSz); - (void)wh_MessageKeystore_TranslateWrapResponse(magic, &wrapResp, - resp_packet); + respData = (uint8_t*)resp_packet + + sizeof(whMessageKeystore_KeyWrapResponse); + + ret = _HandleKeyWrapRequest(server, &wrapReq, reqData, reqDataSz, + &wrapResp, respData, respDataSz); + wrapResp.rc = ret; + + (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); @@ -1436,31 +1685,32 @@ 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( - server, &unwrapReq, reqData, reqDataSz, &unwrapResp, respData, - respDataSz); + ret = _HandleKeyUnwrapAndExportRequest(server, &unwrapReq, reqData, + reqDataSz, &unwrapResp, + respData, respDataSz); + unwrapResp.rc = ret; - (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); @@ -1472,27 +1722,102 @@ 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( - server, &cacheReq, reqData, reqDataSz, &cacheResp, respData, - respDataSz); + ret = _HandleKeyUnwrapAndCacheRequest(server, &cacheReq, reqData, + reqDataSz, &cacheResp, + respData, respDataSz); + cacheResp.rc = ret; - (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); + + ret = _HandleDataWrapRequest(server, &wrapReq, reqData, reqDataSz, + &wrapResp, respData, respDataSz); + wrapResp.rc = ret; + + (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); + + ret = + _HandleDataUnwrapRequest(server, &unwrapReq, reqData, reqDataSz, + &unwrapResp, respData, respDataSz); + unwrapResp.rc = ret; + + (void)wh_MessageKeystore_TranslateDataUnwrapResponse( + magic, &unwrapResp, resp_packet); + *out_resp_size = sizeof(unwrapResp) + unwrapResp.dataSz; + + } break; + #endif /* WOLFHSM_CFG_KEYWRAP */ default: 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" From 4e82adcb8716998aa3abe55cd1bb9f1bcb8d1791 Mon Sep 17 00:00:00 2001 From: Alex Lanzano Date: Fri, 31 Oct 2025 11:45:49 -0400 Subject: [PATCH 5/9] Fix key wrap tests --- src/wh_nvm.c | 2 +- src/wh_server.c | 1 + src/wh_server_keystore.c | 9 ++------- test/wh_test_keywrap.c | 11 +++++++---- 4 files changed, 11 insertions(+), 12 deletions(-) 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 bc6036c00..3d27a9a77 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) { @@ -854,7 +849,7 @@ static int _AesGcmDataWrap(whServerContext* server, whKeyId serverKeyId, /* Get the server side key */ ret = wh_Server_KeystoreReadKey( server, - WH_MAKE_KEYID(WH_KEYTYPE_CRYPTO, server->comm->client_id, serverKeyId), + wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, server->comm->client_id, serverKeyId), NULL, serverKey, &serverKeySz); if (ret != WH_ERROR_OK) { return ret; @@ -920,7 +915,7 @@ static int _AesGcmDataUnwrap(whServerContext* server, uint16_t serverKeyId, /* Get the server side key */ ret = wh_Server_KeystoreReadKey( server, - WH_MAKE_KEYID(WH_KEYTYPE_CRYPTO, server->comm->client_id, serverKeyId), + wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, server->comm->client_id, serverKeyId), NULL, serverKey, &serverKeySz); if (ret != WH_ERROR_OK) { return ret; diff --git a/test/wh_test_keywrap.c b/test/wh_test_keywrap.c index 5a7ff3e34..bdab0625e 100644 --- a/test/wh_test_keywrap.c +++ b/test/wh_test_keywrap.c @@ -73,7 +73,7 @@ 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 @@ -87,7 +87,7 @@ static int _AesGcm_TestKeyWrap(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, @@ -216,10 +216,10 @@ static int _AesGcm_TestKeyWrap(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; @@ -339,6 +339,9 @@ int whTest_KeyWrapClientConfig(whClientConfig* clientCfg) 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: From ede31b7ed1f8ba21a635a8033369d62e59896784 Mon Sep 17 00:00:00 2001 From: Brett Nicholas <7547222+bigbrett@users.noreply.github.com> Date: Fri, 31 Oct 2025 11:01:42 -0600 Subject: [PATCH 6/9] fix return code propagation merge artifact --- src/wh_server_keystore.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/wh_server_keystore.c b/src/wh_server_keystore.c index 3d27a9a77..709c505cc 100644 --- a/src/wh_server_keystore.c +++ b/src/wh_server_keystore.c @@ -1655,9 +1655,9 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, respData = (uint8_t*)resp_packet + sizeof(whMessageKeystore_KeyWrapResponse); - ret = _HandleKeyWrapRequest(server, &wrapReq, reqData, reqDataSz, - &wrapResp, respData, respDataSz); - wrapResp.rc = ret; + wrapResp.rc = + _HandleKeyWrapRequest(server, &wrapReq, reqData, reqDataSz, + &wrapResp, respData, respDataSz); (void)wh_MessageKeystore_TranslateKeyWrapResponse(magic, &wrapResp, resp_packet); @@ -1691,10 +1691,9 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, respData = (uint8_t*)resp_packet + sizeof(whMessageKeystore_KeyUnwrapAndExportResponse); - ret = _HandleKeyUnwrapAndExportRequest(server, &unwrapReq, reqData, - reqDataSz, &unwrapResp, - respData, respDataSz); - unwrapResp.rc = ret; + unwrapResp.rc = _HandleKeyUnwrapAndExportRequest( + server, &unwrapReq, reqData, reqDataSz, &unwrapResp, respData, + respDataSz); (void)wh_MessageKeystore_TranslateKeyUnwrapAndExportResponse( magic, &unwrapResp, resp_packet); @@ -1728,10 +1727,9 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, respData = (uint8_t*)resp_packet + sizeof(whMessageKeystore_KeyUnwrapAndCacheResponse); - ret = _HandleKeyUnwrapAndCacheRequest(server, &cacheReq, reqData, - reqDataSz, &cacheResp, - respData, respDataSz); - cacheResp.rc = ret; + cacheResp.rc = _HandleKeyUnwrapAndCacheRequest( + server, &cacheReq, reqData, reqDataSz, &cacheResp, respData, + respDataSz); (void)wh_MessageKeystore_TranslateKeyUnwrapAndCacheResponse( magic, &cacheResp, resp_packet); @@ -1765,9 +1763,9 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, respData = (uint8_t*)resp_packet + sizeof(whMessageKeystore_DataWrapResponse); - ret = _HandleDataWrapRequest(server, &wrapReq, reqData, reqDataSz, - &wrapResp, respData, respDataSz); - wrapResp.rc = ret; + wrapResp.rc = + _HandleDataWrapRequest(server, &wrapReq, reqData, reqDataSz, + &wrapResp, respData, respDataSz); (void)wh_MessageKeystore_TranslateDataWrapResponse(magic, &wrapResp, resp_packet); @@ -1802,10 +1800,9 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, respData = (uint8_t*)resp_packet + sizeof(whMessageKeystore_DataUnwrapResponse); - ret = + unwrapResp.rc = _HandleDataUnwrapRequest(server, &unwrapReq, reqData, reqDataSz, &unwrapResp, respData, respDataSz); - unwrapResp.rc = ret; (void)wh_MessageKeystore_TranslateDataUnwrapResponse( magic, &unwrapResp, resp_packet); From 526720c6704c52c4f0e7c6005c1df2157df3d8a9 Mon Sep 17 00:00:00 2001 From: Brett Nicholas <7547222+bigbrett@users.noreply.github.com> Date: Fri, 31 Oct 2025 11:03:31 -0600 Subject: [PATCH 7/9] clang-format --- src/wh_server_keystore.c | 6 ++++-- test/wh_test_keywrap.c | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/wh_server_keystore.c b/src/wh_server_keystore.c index 709c505cc..aed25dbcb 100644 --- a/src/wh_server_keystore.c +++ b/src/wh_server_keystore.c @@ -849,7 +849,8 @@ static int _AesGcmDataWrap(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), + wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, server->comm->client_id, + serverKeyId), NULL, serverKey, &serverKeySz); if (ret != WH_ERROR_OK) { return ret; @@ -915,7 +916,8 @@ static int _AesGcmDataUnwrap(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), + wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, server->comm->client_id, + serverKeyId), NULL, serverKey, &serverKeySz); if (ret != WH_ERROR_OK) { return ret; diff --git a/test/wh_test_keywrap.c b/test/wh_test_keywrap.c index bdab0625e..9c3373a4d 100644 --- a/test/wh_test_keywrap.c +++ b/test/wh_test_keywrap.c @@ -227,9 +227,9 @@ static int _AesGcm_TestKeyWrap(whClientContext* client, WC_RNG* rng) static int _AesGcm_TestDataWrap(whClientContext* client) { - int ret = 0; - uint8_t data[] = "Example data!"; - uint8_t unwrappedData[sizeof(data)] = {0}; + 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}; From aaa7ab97415d23224cd255fae95510bb0969b8ad Mon Sep 17 00:00:00 2001 From: Brett Nicholas <7547222+bigbrett@users.noreply.github.com> Date: Fri, 31 Oct 2025 11:17:03 -0600 Subject: [PATCH 8/9] clang-format --- src/wh_client_keywrap.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/wh_client_keywrap.c b/src/wh_client_keywrap.c index 21fadf8c7..84dbe5ceb 100644 --- a/src/wh_client_keywrap.c +++ b/src/wh_client_keywrap.c @@ -17,10 +17,10 @@ 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 group = WH_MESSAGE_GROUP_KEY; uint16_t action = WH_KEY_KEYWRAP; whMessageKeystore_KeyWrapRequest* req = NULL; - uint8_t* reqData; + uint8_t* reqData; if (ctx == NULL || key == NULL || metadata == NULL) { return WH_ERROR_BADARGS; @@ -52,12 +52,12 @@ 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; + int ret; + uint16_t group; + uint16_t action; + uint16_t size; whMessageKeystore_KeyWrapResponse* resp = NULL; - uint8_t* respData; + uint8_t* respData; if (ctx == NULL || wrappedKeyOut == NULL) { return WH_ERROR_BADARGS; @@ -126,10 +126,10 @@ int wh_Client_KeyUnwrapAndExportRequest(whClientContext* ctx, uint16_t wrappedKeySz) { - uint16_t group = WH_MESSAGE_GROUP_KEY; - uint16_t action = WH_KEY_KEYUNWRAPEXPORT; + uint16_t group = WH_MESSAGE_GROUP_KEY; + uint16_t action = WH_KEY_KEYUNWRAPEXPORT; whMessageKeystore_KeyUnwrapAndExportRequest* req = NULL; - uint8_t* reqData; + uint8_t* reqData; if (ctx == NULL || wrappedKeyIn == NULL) { return WH_ERROR_BADARGS; @@ -161,12 +161,12 @@ int wh_Client_KeyUnwrapAndExportResponse(whClientContext* ctx, whNvmMetadata* metadataOut, void* keyOut, uint16_t keySz) { - int ret; - uint16_t group; - uint16_t action; - uint16_t size; + int ret; + uint16_t group; + uint16_t action; + uint16_t size; whMessageKeystore_KeyUnwrapAndExportResponse* resp = NULL; - uint8_t* respData; + uint8_t* respData; if (ctx == NULL || metadataOut == NULL || keyOut == NULL) { return WH_ERROR_BADARGS; @@ -245,7 +245,7 @@ int wh_Client_KeyUnwrapAndCacheRequest(whClientContext* ctx, uint16_t action = WH_KEY_KEYUNWRAPCACHE; whMessageKeystore_KeyUnwrapAndCacheRequest* req = NULL; - uint8_t* reqData; + uint8_t* reqData; if (ctx == NULL || wrappedKeyIn == NULL) return WH_ERROR_BADARGS; @@ -274,10 +274,10 @@ int wh_Client_KeyUnwrapAndCacheResponse(whClientContext* ctx, enum wc_CipherType cipherType, uint16_t* keyIdOut) { - int ret; - uint16_t group; - uint16_t action; - uint16_t size; + int ret; + uint16_t group; + uint16_t action; + uint16_t size; whMessageKeystore_KeyUnwrapAndCacheResponse* resp = NULL; if (ctx == NULL || keyIdOut == NULL) From d0a9423dfe7e9b0e5595dc43218b6aa6038d4f8a Mon Sep 17 00:00:00 2001 From: Alex Lanzano Date: Mon, 3 Nov 2025 11:24:06 -0500 Subject: [PATCH 9/9] Use instead of in key wrap and data wrap handlers --- src/wh_server_keystore.c | 99 ++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 35 deletions(-) diff --git a/src/wh_server_keystore.c b/src/wh_server_keystore.c index aed25dbcb..ea33d50ea 100644 --- a/src/wh_server_keystore.c +++ b/src/wh_server_keystore.c @@ -694,8 +694,9 @@ static int _AesGcmKeyWrap(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; @@ -712,14 +713,12 @@ static int _AesGcmKeyWrap(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); @@ -773,8 +772,9 @@ static int _AesGcmKeyUnwrap(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]; @@ -785,14 +785,12 @@ static int _AesGcmKeyUnwrap(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,8 +831,9 @@ static int _AesGcmDataWrap(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* encBlob; if (server == NULL || dataIn == NULL || wrappedDataOut == NULL) { @@ -847,14 +846,12 @@ static int _AesGcmDataWrap(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); @@ -903,8 +900,9 @@ static int _AesGcmDataUnwrap(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*)wrappedDataIn + sizeof(iv) + sizeof(authTag); uint16_t encBlobSz = wrappedDataSz - sizeof(iv) - sizeof(authTag); @@ -914,14 +912,12 @@ static int _AesGcmDataUnwrap(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); @@ -964,9 +960,12 @@ static int _HandleKeyWrapRequest(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; } @@ -984,6 +983,12 @@ static int _HandleKeyWrapRequest(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; @@ -1002,7 +1007,7 @@ static int _HandleKeyWrapRequest(whServerContext* server, } /* Wrap the key */ - ret = _AesGcmKeyWrap(server, req->serverKeyId, key, req->keySz, + ret = _AesGcmKeyWrap(server, serverKeyId, key, req->keySz, &metadata, wrappedKey, wrappedKeySz); if (ret != WH_ERROR_OK) { return ret; @@ -1033,6 +1038,7 @@ static int _HandleKeyUnwrapAndExportRequest( uint8_t* wrappedKey; whNvmMetadata* metadata; uint8_t* key; + whKeyId serverKeyId; if (server == NULL || req == NULL || reqData == NULL || resp == NULL || respData == NULL) { @@ -1047,6 +1053,11 @@ static int _HandleKeyUnwrapAndExportRequest( /* 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); @@ -1070,7 +1081,7 @@ static int _HandleKeyUnwrapAndExportRequest( } /* Unwrap the key */ - ret = _AesGcmKeyUnwrap(server, req->serverKeyId, wrappedKey, + ret = _AesGcmKeyUnwrap(server, serverKeyId, wrappedKey, req->wrappedKeySz, metadata, key, keySz); if (ret != WH_ERROR_OK) { return ret; @@ -1137,6 +1148,7 @@ static int _HandleKeyUnwrapAndCacheRequest( 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) { @@ -1146,6 +1158,11 @@ static int _HandleKeyUnwrapAndCacheRequest( /* 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 @@ -1155,7 +1172,7 @@ static int _HandleKeyUnwrapAndCacheRequest( WOLFHSM_KEYWRAP_AES_GCM_TAG_SIZE - sizeof(metadata); resp->cipherType = WC_CIPHER_AES_GCM; - ret = _AesGcmKeyUnwrap(server, req->serverKeyId, wrappedKey, + ret = _AesGcmKeyUnwrap(server, serverKeyId, wrappedKey, req->wrappedKeySz, &metadata, key, keySz); if (ret != WH_ERROR_OK) { return ret; @@ -1227,6 +1244,7 @@ static int _HandleDataWrapRequest(whServerContext* server, 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) { @@ -1241,6 +1259,11 @@ static int _HandleDataWrapRequest(whServerContext* server, /* 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; @@ -1259,7 +1282,7 @@ static int _HandleDataWrapRequest(whServerContext* server, } /* Wrap the data */ - ret = _AesGcmDataWrap(server, req->serverKeyId, data, req->dataSz, + ret = _AesGcmDataWrap(server, serverKeyId, data, req->dataSz, wrappedData, wrappedDataSz); if (ret != WH_ERROR_OK) { return ret; @@ -1290,6 +1313,7 @@ static int _HandleDataUnwrapRequest(whServerContext* server, int ret; uint8_t* wrappedData; uint8_t* data; + whKeyId serverKeyId; if (server == NULL || req == NULL || reqData == NULL || resp == NULL || respData == NULL) { @@ -1304,6 +1328,11 @@ static int _HandleDataUnwrapRequest(whServerContext* server, /* 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; @@ -1322,7 +1351,7 @@ static int _HandleDataUnwrapRequest(whServerContext* server, } /* Unwrap the data */ - ret = _AesGcmDataUnwrap(server, req->serverKeyId, wrappedData, + ret = _AesGcmDataUnwrap(server, serverKeyId, wrappedData, req->wrappedDataSz, data, dataSz); if (ret != WH_ERROR_OK) { return ret;