From fb6375551bea27b20b54980e616f47c0febda459 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Mon, 18 Aug 2025 13:38:26 -0600 Subject: [PATCH] updating unwrap/wrap with use of DHUK --- wolfcrypt/src/aes.c | 210 +++++++++++++++++++++++++++++- wolfcrypt/src/port/st/stm32.c | 92 ++++++++++++- wolfssl/wolfcrypt/port/st/stm32.h | 5 + 3 files changed, 298 insertions(+), 9 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index e46de6f22..6b2598cca 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -150,7 +150,44 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits return ret; #endif - #ifdef WOLFSSL_STM32_CUBEMX + #ifdef WOLFSSL_STM32U5_DHUK + ret = wolfSSL_CryptHwMutexLock(); + if (ret != 0) + return ret; + + /* Handle making use of wrapped key */ + if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) { + CRYP_ConfigTypeDef Config = {0}; + + ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, + aes->keylen, NULL); + if (ret != HAL_OK) { + ret = WC_TIMEOUT_E; + } + /* reconfigure for using unwrapped key now */ + HAL_CRYP_GetConfig(&hcryp, &Config); + Config.KeyMode = CRYP_KEYMODE_NORMAL; + Config.KeySelect = CRYP_KEYSEL_NORMAL; + Config.Algorithm = CRYP_AES_ECB; + Config.DataType = CRYP_DATATYPE_8B; + Config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE; + HAL_CRYP_SetConfig(&hcryp, &Config); + } + else { + ret = wc_Stm32_Aes_Init(aes, &hcryp); + hcryp.Init.Algorithm = CRYP_AES_ECB; + if (HAL_CRYP_Init(&hcryp) != HAL_OK) { + ret = BAD_FUNC_ARG; + } + } + + ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE, + (uint32_t*)outBlock, STM32_HAL_TIMEOUT); + if (ret != HAL_OK) { + ret = WC_TIMEOUT_E; + } + HAL_CRYP_DeInit(&hcryp); + #elif defined(WOLFSSL_STM32_CUBEMX) ret = wc_Stm32_Aes_Init(aes, &hcryp); if (ret != 0) return ret; @@ -255,7 +292,44 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits return ret; #endif - #ifdef WOLFSSL_STM32_CUBEMX + #ifdef WOLFSSL_STM32U5_DHUK + ret = wolfSSL_CryptHwMutexLock(); + if (ret != 0) + return ret; + + /* Handle making use of wrapped key */ + if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) { + CRYP_ConfigTypeDef Config = {0}; + + ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, + aes->keylen, NULL); + if (ret != HAL_OK) { + ret = WC_TIMEOUT_E; + } + /* reconfigure for using unwrapped key now */ + HAL_CRYP_GetConfig(&hcryp, &Config); + Config.KeyMode = CRYP_KEYMODE_NORMAL; + Config.KeySelect = CRYP_KEYSEL_NORMAL; + Config.Algorithm = CRYP_AES_ECB; + Config.DataType = CRYP_DATATYPE_8B; + Config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE; + HAL_CRYP_SetConfig(&hcryp, &Config); + } + else { + ret = wc_Stm32_Aes_Init(aes, &hcryp); + hcryp.Init.Algorithm = CRYP_AES_ECB; + if (HAL_CRYP_Init(&hcryp) != HAL_OK) { + ret = BAD_FUNC_ARG; + } + } + + ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE, + (uint32_t*)outBlock, STM32_HAL_TIMEOUT); + if (ret != HAL_OK) { + ret = WC_TIMEOUT_E; + } + HAL_CRYP_DeInit(&hcryp); + #elif defined(WOLFSSL_STM32_CUBEMX) ret = wc_Stm32_Aes_Init(aes, &hcryp); if (ret != 0) return ret; @@ -4967,7 +5041,137 @@ int wc_AesSetIV(Aes* aes, const byte* iv) #ifdef HAVE_AES_CBC #if defined(STM32_CRYPTO) -#ifdef WOLFSSL_STM32_CUBEMX +#ifdef WOLFSSL_STM32U5_DHUK + int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + int ret = 0; + CRYP_HandleTypeDef hcryp; + word32 blocks = (sz / WC_AES_BLOCK_SIZE); + +#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + if (sz % WC_AES_BLOCK_SIZE) { + return BAD_LENGTH_E; + } +#endif + if (blocks == 0) + return 0; + + ret = wolfSSL_CryptHwMutexLock(); + if (ret != 0) { + return ret; + } + + if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) { + CRYP_ConfigTypeDef Config = {0}; + + ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, aes->keylen, NULL); + + /* reconfigure for using unwrapped key now */ + HAL_CRYP_GetConfig(&hcryp, &Config); + Config.KeyMode = CRYP_KEYMODE_NORMAL; + Config.KeySelect = CRYP_KEYSEL_NORMAL; + Config.Algorithm = CRYP_AES_CBC; + ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE); + Config.pInitVect = (STM_CRYPT_TYPE*)aes->reg; + HAL_CRYP_SetConfig(&hcryp, &Config); + } + else { + ret = wc_Stm32_Aes_Init(aes, &hcryp); + if (ret != 0) { + return ret; + } + hcryp.Init.Algorithm = CRYP_AES_CBC; + ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE); + hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg; + ret = HAL_CRYP_Init(&hcryp); + } + + if (ret == HAL_OK) { + ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE, + (uint32_t*)out, STM32_HAL_TIMEOUT); + } + if (ret != HAL_OK) { + ret = WC_TIMEOUT_E; + } + + /* store iv for next call */ + XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE); + + HAL_CRYP_DeInit(&hcryp); + + wolfSSL_CryptHwMutexUnLock(); + wc_Stm32_Aes_Cleanup(); + + return ret; + } + #ifdef HAVE_AES_DECRYPT + int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + int ret = 0; + CRYP_HandleTypeDef hcryp; + word32 blocks = (sz / WC_AES_BLOCK_SIZE); + +#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + if (sz % WC_AES_BLOCK_SIZE) { + return BAD_LENGTH_E; + } +#endif + if (blocks == 0) + return 0; + + ret = wolfSSL_CryptHwMutexLock(); + if (ret != 0) { + return ret; + } + + if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) { + CRYP_ConfigTypeDef Config = {0}; + + ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, aes->keylen, NULL); + + /* reconfigure for using unwrapped key now */ + HAL_CRYP_GetConfig(&hcryp, &Config); + Config.KeyMode = CRYP_KEYMODE_NORMAL; + Config.KeySelect = CRYP_KEYSEL_NORMAL; + Config.Algorithm = CRYP_AES_CBC; + ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE); + Config.pInitVect = (STM_CRYPT_TYPE*)aes->reg; + HAL_CRYP_SetConfig(&hcryp, &Config); + } + else { + ret = wc_Stm32_Aes_Init(aes, &hcryp); + if (ret != 0) { + return ret; + } + hcryp.Init.Algorithm = CRYP_AES_CBC; + ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE); + hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg; + ret = HAL_CRYP_Init(&hcryp); + } + + /* if input and output same will overwrite input iv */ + XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE); + + if (ret == HAL_OK) { + ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE, + (uint32_t*)out, STM32_HAL_TIMEOUT); + } + if (ret != HAL_OK) { + ret = WC_TIMEOUT_E; + } + + /* store iv for next call */ + XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE); + + HAL_CRYP_DeInit(&hcryp); + wolfSSL_CryptHwMutexUnLock(); + wc_Stm32_Aes_Cleanup(); + + return ret; + } + #endif /* HAVE_AES_DECRYPT */ + +#elif defined(WOLFSSL_STM32_CUBEMX) int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { int ret = 0; diff --git a/wolfcrypt/src/port/st/stm32.c b/wolfcrypt/src/port/st/stm32.c index 2567ba5d6..74c4e7d40 100644 --- a/wolfcrypt/src/port/st/stm32.c +++ b/wolfcrypt/src/port/st/stm32.c @@ -449,6 +449,86 @@ int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo, #ifndef NO_AES #ifdef WOLFSSL_STM32_CUBEMX +#if defined(WOLFSSL_STM32U5_DHUK) + +/* Wrap an AES key using the DHUK */ +int wc_Stm32_Aes_Wrap(struct Aes* aes, const byte* in, word32 inSz, byte* out, + word32* outSz, const byte* iv) +{ + CRYP_HandleTypeDef hcryp; + int ret = 0; + byte key[AES_256_KEY_SIZE]; + + /* SAES requires use of the RNG -- HAL_RNG_DeInit() calls from random.c + turn off the RNG clock -- re-enable the clock here */ + __HAL_RCC_RNG_CLK_ENABLE(); + ByteReverseWords((word32*)key, (word32*)in, inSz); + XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef)); + if (ret == 0) { + hcryp.Instance = SAES; + hcryp.Init.DataType = CRYP_DATATYPE_8B; + hcryp.Init.KeySize = CRYP_KEYSIZE_256B; + hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE; + hcryp.Init.KeySelect = CRYP_KEYSEL_HW; /* use DHUK to unwrap with use */ + hcryp.Init.KeyMode = CRYP_KEYMODE_WRAPPED; + if (iv != NULL) { + hcryp.Init.pInitVect = (uint32_t *)iv; + hcryp.Init.Algorithm = CRYP_AES_CBC; + } + else { + hcryp.Init.Algorithm = CRYP_AES_ECB; + } + ret = HAL_CRYP_Init(&hcryp); + } + + if (ret == HAL_OK) { + ret = HAL_CRYPEx_WrapKey(&hcryp, (uint32_t*)key, (uint32_t*)out, 100); + HAL_CRYP_DeInit(&hcryp); + } + + ByteReverseWords((word32*)out, (word32*)out, inSz); + *outSz = inSz; + (void)aes; + return ret; +} + + +int wc_Stm32_Aes_UnWrap(struct Aes* aes, CRYP_HandleTypeDef* hcryp, + const byte* in, word32 inSz, const byte* iv) +{ + int ret = 0; + + /* SAES requires use of the RNG -- HAL_RNG_DeInit() calls from random.c + turn off the RNG clock -- re-enable the clock here */ + __HAL_RCC_RNG_CLK_ENABLE(); + + /* setup for key unwrapping */ + XMEMSET(hcryp, 0, sizeof(CRYP_HandleTypeDef)); + hcryp->Instance = SAES; + hcryp->Init.DataType = CRYP_DATATYPE_8B; + hcryp->Init.KeySize = CRYP_KEYSIZE_256B; + hcryp->Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE; + if (iv != NULL) { + hcryp->Init.pInitVect = (uint32_t *)iv; + hcryp->Init.Algorithm = CRYP_AES_CBC; + } + else { + hcryp->Init.Algorithm = CRYP_AES_ECB; + } + hcryp->Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS; + hcryp->Init.KeySelect = CRYP_KEYSEL_HW; /* use DHUK to unwrap with use */ + hcryp->Init.KeyMode = CRYP_KEYMODE_WRAPPED; + ret = HAL_CRYP_Init(hcryp); + if (ret == HAL_OK) { + /* On success the key is placed into a location where the next encrypt/decrypt + * calls using hcryp make use of the key */ + ret = HAL_CRYPEx_UnwrapKey(hcryp, (uint32_t*)in, 100); + } + return ret; +} + +#endif + int wc_Stm32_Aes_Init(Aes* aes, CRYP_HandleTypeDef* hcryp) { int ret; @@ -488,18 +568,18 @@ int wc_Stm32_Aes_Init(Aes* aes, CRYP_HandleTypeDef* hcryp) random.c turn off the RNG clock -- re-enable the clock here */ __HAL_RCC_RNG_CLK_ENABLE(); - hcryp->Instance = SAES; - hcryp->Init.DataType = CRYP_NO_SWAP; - hcryp->Init.KeyMode = CRYP_KEYMODE_NORMAL; + hcryp->Instance = SAES; + hcryp->Init.DataType = CRYP_DATATYPE_8B; + + /* Key select (HW, or Normal) */ if (aes->devId == WOLFSSL_STM32U5_DHUK_DEVID) { hcryp->Init.KeySelect = CRYP_KEYSEL_HW; } - if (aes->devId == WOLFSSL_STM32U5_SAES_DEVID) { + else { hcryp->Init.KeySelect = CRYP_KEYSEL_NORMAL; - hcryp->Init.DataType = CRYP_DATATYPE_8B; + hcryp->Init.KeyMode = CRYP_KEYMODE_NORMAL; hcryp->Init.pKey = (uint32_t*)aes->key; } - /* hcryp->Init.KeyProtection = CRYP_KEYPROT_ENABLE; */ } else #endif { diff --git a/wolfssl/wolfcrypt/port/st/stm32.h b/wolfssl/wolfcrypt/port/st/stm32.h index c6e4968fd..cb42419f3 100644 --- a/wolfssl/wolfcrypt/port/st/stm32.h +++ b/wolfssl/wolfcrypt/port/st/stm32.h @@ -219,6 +219,11 @@ int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo, #if defined(WOLFSSL_STM32U5_DHUK) && !defined(WOLFSSL_STM32U5_DHUK_DEVID) #define WOLFSSL_STM32U5_DHUK_DEVID 808 #define WOLFSSL_STM32U5_SAES_DEVID 807 + #define WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID 809 + int wc_Stm32_Aes_Wrap(struct Aes* aes, const byte* in, word32 inSz, byte* out, + word32* outSz, const byte* iv); + int wc_Stm32_Aes_UnWrap(struct Aes* aes, CRYP_HandleTypeDef* hcryp, const byte* in, + word32 inSz, const byte* iv); #endif #if defined(WOLFSSL_STM32_PKA) && defined(HAVE_ECC)