diff --git a/components/esp_hal_security/esp32s2/include/hal/crypto_dma_ll.h b/components/esp_hal_security/esp32s2/include/hal/crypto_dma_ll.h index 10f64537f85..85b4a72d6ff 100644 --- a/components/esp_hal_security/esp32s2/include/hal/crypto_dma_ll.h +++ b/components/esp_hal_security/esp32s2/include/hal/crypto_dma_ll.h @@ -20,6 +20,8 @@ extern "C" { #include "soc/crypto_dma_reg.h" #include "soc/dport_reg.h" +#define CRYPTO_DMA_LL_DESC_ALIGNMENT 4 + typedef enum { CRYPTO_DMA_AES = 0, CRYPTO_DMA_SHA, diff --git a/components/esp_hal_security/esp32s31/include/hal/aes_ll.h b/components/esp_hal_security/esp32s31/include/hal/aes_ll.h index 0178472f198..a3c5c9797bd 100644 --- a/components/esp_hal_security/esp32s31/include/hal/aes_ll.h +++ b/components/esp_hal_security/esp32s31/include/hal/aes_ll.h @@ -277,6 +277,93 @@ static inline void aes_ll_enable_pseudo_rounds(bool enable, uint8_t base, uint8_ } } +/** + * @brief Continue a previous started transform + * + * @note Only used when doing GCM + */ +static inline void aes_ll_cont_transform(void) +{ + REG_WRITE(AES_CONTINUE_REG, 1); +} + +/** + * @brief Reads the AES-GCM hash sub-key H + * + * @param gcm_hash hash value + */ +static inline void aes_ll_gcm_read_hash(uint8_t *gcm_hash) +{ + const size_t REG_WIDTH = sizeof(uint32_t); + uint32_t hash_word; + + for (size_t i = 0; i < AES_BLOCK_WORDS; i++) { + hash_word = REG_READ(AES_H_MEM + (i * REG_WIDTH)); + /* Memcpy to avoid potential unaligned access */ + memcpy(gcm_hash + i * 4, &hash_word, sizeof(hash_word)); + } +} + +/** + * @brief Sets the number of Additional Authenticated Data (AAD) blocks + * + * @note Only affects AES-GCM + + * @param aad_num_blocks the number of Additional Authenticated Data (AAD) blocks + */ +static inline void aes_ll_gcm_set_aad_num_blocks(size_t aad_num_blocks) +{ + REG_WRITE(AES_AAD_BLOCK_NUM_REG, aad_num_blocks); +} + +/** + * @brief Sets the J0 value, for more information see the GCM subchapter in the TRM + * + * @note Only affects AES-GCM + * + * @param j0 J0 value + */ +static inline void aes_ll_gcm_set_j0(const uint8_t *j0) +{ + uint32_t *reg_addr_buf = (uint32_t *)(AES_J0_MEM); + uint32_t j0_word; + + for (int i = 0; i < AES_BLOCK_WORDS; i++) { + /* Memcpy to avoid potential unaligned access */ + memcpy(&j0_word, j0 + 4 * i, sizeof(j0_word)); + REG_WRITE(®_addr_buf[i], j0_word); + } +} + +/** + * @brief Sets the number of effective bits of incomplete blocks in plaintext/ciphertext. + * + * @note Only affects AES-GCM + * + * @param num_valid_bits the number of effective bits of incomplete blocks in plaintext/ciphertext. + */ +static inline void aes_ll_gcm_set_num_valid_bit(size_t num_valid_bits) +{ + REG_WRITE(AES_REMAINDER_BIT_NUM_REG, num_valid_bits); +} + +/** + * @brief Read the tag after a AES-GCM transform + * + * @param tag Pointer to where to store the result with length TAG_WORDS + */ +static inline void aes_ll_gcm_read_tag(uint8_t *tag) +{ + uint32_t tag_word; + const size_t REG_WIDTH = sizeof(uint32_t); + + for (size_t i = 0; i < TAG_WORDS; i++) { + tag_word = REG_READ(AES_T0_MEM + (i * REG_WIDTH)); + /* Memcpy to avoid potential unaligned access */ + memcpy(tag + i * 4, &tag_word, sizeof(tag_word)); + } +} + /** * @brief Check if the pseudo round function is supported */ diff --git a/components/mbedtls/port/aes/dma/esp_aes_dma_core.c b/components/mbedtls/port/aes/dma/esp_aes_dma_core.c index 544bb3a4e58..b73a5ed9b44 100644 --- a/components/mbedtls/port/aes/dma/esp_aes_dma_core.c +++ b/components/mbedtls/port/aes/dma/esp_aes_dma_core.c @@ -1126,7 +1126,7 @@ int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsign crypto_dma_desc_num = dma_desc_get_required_num(block_bytes, DMA_DESCRIPTOR_BUFFER_MAX_SIZE_16B_ALIGNED); /* Allocate both in and out descriptors to save a malloc/free per function call */ - block_desc = heap_caps_aligned_calloc(8, crypto_dma_desc_num * 2, sizeof(crypto_dma_desc_t), MALLOC_CAP_DMA); + block_desc = heap_caps_aligned_calloc(DMA_DESC_MEM_ALIGN_SIZE, crypto_dma_desc_num * 2, sizeof(crypto_dma_desc_t), MALLOC_CAP_DMA); if (block_desc == NULL) { mbedtls_platform_zeroize(output, len); ESP_LOGE(TAG, "Failed to allocate memory"); @@ -1299,7 +1299,7 @@ int esp_aes_process_dma_gcm(esp_aes_context *ctx, const unsigned char *input, un crypto_dma_desc_num = dma_desc_get_required_num(block_bytes, DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED); /* Allocate both in and out descriptors to save a malloc/free per function call, add 1 for length descriptor */ - block_desc = heap_caps_calloc((crypto_dma_desc_num * 2) + 1, sizeof(crypto_dma_desc_t), MALLOC_CAP_DMA); + block_desc = heap_caps_aligned_calloc(DMA_DESC_MEM_ALIGN_SIZE, (crypto_dma_desc_num * 2) + 1, sizeof(crypto_dma_desc_t), MALLOC_CAP_DMA); if (block_desc == NULL) { mbedtls_platform_zeroize(output, len); ESP_LOGE(TAG, "Failed to allocate memory"); diff --git a/components/mbedtls/port/include/esp_crypto_dma.h b/components/mbedtls/port/include/esp_crypto_dma.h index d253cac7a32..8bca2e5eacc 100644 --- a/components/mbedtls/port/include/esp_crypto_dma.h +++ b/components/mbedtls/port/include/esp_crypto_dma.h @@ -12,6 +12,8 @@ #if SOC_GDMA_SUPPORTED #include "hal/gdma_ll.h" +#elif (SOC_AES_CRYPTO_DMA) || (SOC_SHA_CRYPTO_DMA) +#include "hal/crypto_dma_ll.h" #endif /* SOC_GDMA_SUPPORTED */ #ifdef __cplusplus @@ -38,7 +40,7 @@ typedef dma_descriptor_align8_t crypto_dma_desc_t; #endif /* (SOC_GDMA_TRIG_PERIPH_AES0_BUS == SOC_GDMA_BUS_AHB) || (SOC_GDMA_TRIG_PERIPH_AES0_BUS == SOC_GDMA_BUS_AHB) */ #elif (SOC_AES_CRYPTO_DMA) || (SOC_SHA_CRYPTO_DMA) -#define DMA_DESC_MEM_ALIGN_SIZE GDMA_LL_AHB_DESC_ALIGNMENT +#define DMA_DESC_MEM_ALIGN_SIZE CRYPTO_DMA_LL_DESC_ALIGNMENT typedef dma_descriptor_align4_t crypto_dma_desc_t; #endif /* (SOC_AES_GDMA) && (SOC_SHA_GDMA) */ diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index 2983a66a7ec..023070cf68a 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -1031,6 +1031,10 @@ config SOC_AES_SUPPORT_DMA bool default y +config SOC_AES_SUPPORT_GCM + bool + default y + config SOC_AES_SUPPORT_AES_128 bool default y diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index 01b558976a0..f0549b97bc7 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -386,9 +386,9 @@ /*-------------------------- AES CAPS ----------------------------------------*/ #define SOC_AES_GDMA (1) #define SOC_AES_SUPPORT_DMA (1) +#define SOC_AES_SUPPORT_GCM (1) #define SOC_AES_SUPPORT_AES_128 (1) #define SOC_AES_SUPPORT_AES_256 (1) -// TODO: [ESP32S31] IDF-14633 SOC_AES_SUPPORT_GCM not enabled: GCM control registers (AAD_BLOCK_NUM, REMAINDER_BIT_NUM, CONTINUE) non-functional on v0.0 silicon #define SOC_AES_SUPPORT_PSEUDO_ROUND_FUNCTION (1) /*-------------------------- SHA CAPS ----------------------------------------*/ diff --git a/components/soc/esp32s31/register/soc/aes_reg.h b/components/soc/esp32s31/register/soc/aes_reg.h index 6a4a8251831..d7e266596fd 100644 --- a/components/soc/esp32s31/register/soc/aes_reg.h +++ b/components/soc/esp32s31/register/soc/aes_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -231,6 +231,22 @@ extern "C" { #define AES_USE_HARDWARE_KEY_V 0x00000001U #define AES_USE_HARDWARE_KEY_S 4 +/** AES_ENDIAN_REG register + * AES Endian configure register + * This register is only for internal debugging purposes. Do not use it in + * applications. + */ +#define AES_ENDIAN_REG (DR_REG_AES_BASE + 0x44) +/** AES_ENDIAN : R/W; bitpos: [5:0]; default: 0; + * endian. [1:0] key endian, [3:2] text_in endian or in_stream endian, [5:4] text_out + * endian or out_stream endian + * This field is only for internal debugging purposes. Do not use it in applications. + */ +#define AES_ENDIAN 0x0000003FU +#define AES_ENDIAN_M (AES_ENDIAN_V << AES_ENDIAN_S) +#define AES_ENDIAN_V 0x0000003FU +#define AES_ENDIAN_S 0 + /** AES_TRIGGER_REG register * Operation start controlling register */ @@ -353,6 +369,51 @@ extern "C" { #define AES_INC_SEL_V 0x00000001U #define AES_INC_SEL_S 0 +/** AES_AAD_BLOCK_NUM_REG register + * Additional Authential Data block number register + * This register is only for internal debugging purposes. Do not use it in + * applications. + */ +#define AES_AAD_BLOCK_NUM_REG (DR_REG_AES_BASE + 0xa0) +/** AES_AAD_BLOCK_NUM : R/W; bitpos: [31:0]; default: 0; + * Those bits stores the number of AAD block. + * This field is only for internal debugging purposes. Do not use it in applications. + */ +#define AES_AAD_BLOCK_NUM 0xFFFFFFFFU +#define AES_AAD_BLOCK_NUM_M (AES_AAD_BLOCK_NUM_V << AES_AAD_BLOCK_NUM_S) +#define AES_AAD_BLOCK_NUM_V 0xFFFFFFFFU +#define AES_AAD_BLOCK_NUM_S 0 + +/** AES_REMAINDER_BIT_NUM_REG register + * AES remainder bit number register + * This register is only for internal debugging purposes. Do not use it in + * applications. + */ +#define AES_REMAINDER_BIT_NUM_REG (DR_REG_AES_BASE + 0xa4) +/** AES_REMAINDER_BIT_NUM : R/W; bitpos: [6:0]; default: 0; + * Those bits stores the number of remainder bit. + * This field is only for internal debugging purposes. Do not use it in applications. + */ +#define AES_REMAINDER_BIT_NUM 0x0000007FU +#define AES_REMAINDER_BIT_NUM_M (AES_REMAINDER_BIT_NUM_V << AES_REMAINDER_BIT_NUM_S) +#define AES_REMAINDER_BIT_NUM_V 0x0000007FU +#define AES_REMAINDER_BIT_NUM_S 0 + +/** AES_CONTINUE_REG register + * AES continue register + * This register is only for internal debugging purposes. Do not use it in + * applications. + */ +#define AES_CONTINUE_REG (DR_REG_AES_BASE + 0xa8) +/** AES_CONTINUE : WT; bitpos: [0]; default: 0; + * Set this bit to continue GCM operation. + * This field is only for internal debugging purposes. Do not use it in applications. + */ +#define AES_CONTINUE (BIT(0)) +#define AES_CONTINUE_M (AES_CONTINUE_V << AES_CONTINUE_S) +#define AES_CONTINUE_V 0x00000001U +#define AES_CONTINUE_S 0 + /** AES_INT_CLEAR_REG register * DMA-AES interrupt clear register */