feat: enable AES GCM support for ESP32-S31

This commit is contained in:
nilesh.kale
2026-04-14 11:03:39 +05:30
parent 76f1151d72
commit c9e90831b8
7 changed files with 161 additions and 5 deletions

View File

@@ -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,

View File

@@ -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(&reg_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
*/

View File

@@ -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");

View File

@@ -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) */

View File

@@ -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

View File

@@ -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 ----------------------------------------*/

View File

@@ -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
*/