Skip to content

Commit 28472cc

Browse files
committed
Merge branch 'feature/enable_aes_sha_support_for_h21' into 'master'
feat: enabled aes and sha support for esp32h21 Closes IDF-11501 and IDF-11504 See merge request espressif/esp-idf!37072
2 parents b0f8342 + a6979eb commit 28472cc

File tree

7 files changed

+525
-4
lines changed

7 files changed

+525
-4
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef _ROM_AES_H_
8+
#define _ROM_AES_H_
9+
10+
#include <stdint.h>
11+
#include <stdbool.h>
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
#define AES_BLOCK_SIZE 16
18+
19+
enum AES_TYPE {
20+
AES_ENC,
21+
AES_DEC,
22+
};
23+
24+
enum AES_BITS {
25+
AES128,
26+
AES256 = 2, /* skipping enum value 1 to keep compatibility with chips that support AES-192 */
27+
};
28+
29+
void ets_aes_enable(void);
30+
31+
void ets_aes_disable(void);
32+
33+
int ets_aes_setkey(enum AES_TYPE type, const void *key, enum AES_BITS bits);
34+
35+
int ets_aes_setkey_enc(const void *key, enum AES_BITS bits);
36+
37+
int ets_aes_setkey_dec(const void *key, enum AES_BITS bits);
38+
39+
void ets_aes_block(const void *input, void *output);
40+
41+
#ifdef __cplusplus
42+
}
43+
#endif
44+
45+
#endif /* _ROM_AES_H_ */
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <stdbool.h>
10+
#include <string.h>
11+
#include "soc/hwcrypto_reg.h"
12+
#include "soc/pcr_struct.h"
13+
#include "hal/aes_types.h"
14+
15+
#ifdef __cplusplus
16+
extern "C" {
17+
#endif
18+
19+
/**
20+
* @brief State of AES accelerator, busy, idle or done
21+
*
22+
*/
23+
typedef enum {
24+
ESP_AES_STATE_IDLE = 0, /* AES accelerator is idle */
25+
ESP_AES_STATE_BUSY, /* Transform in progress */
26+
ESP_AES_STATE_DONE, /* Transform completed */
27+
} esp_aes_state_t;
28+
29+
/**
30+
* @brief Enable the bus clock for AES peripheral module
31+
*
32+
* @param enable true to enable the module, false to disable the module
33+
*/
34+
static inline void aes_ll_enable_bus_clock(bool enable)
35+
{
36+
PCR.aes_conf.aes_clk_en = enable;
37+
}
38+
39+
/**
40+
* @brief Reset the AES peripheral module
41+
*/
42+
static inline void aes_ll_reset_register(void)
43+
{
44+
PCR.aes_conf.aes_rst_en = 1;
45+
PCR.aes_conf.aes_rst_en = 0;
46+
47+
// Clear reset on digital signature also, otherwise AES is held in reset
48+
PCR.ds_conf.ds_rst_en = 0;
49+
}
50+
51+
/**
52+
* @brief Write the encryption/decryption key to hardware
53+
*
54+
* @param key Key to be written to the AES hardware
55+
* @param key_word_len Number of words in the key
56+
*
57+
* @return Number of bytes written to hardware, used for fault injection check
58+
*/
59+
static inline uint8_t aes_ll_write_key(const uint8_t *key, size_t key_word_len)
60+
{
61+
/* This variable is used for fault injection checks, so marked volatile to avoid optimisation */
62+
volatile uint8_t key_in_hardware = 0;
63+
/* Memcpy to avoid potential unaligned access */
64+
uint32_t key_word;
65+
for (int i = 0; i < key_word_len; i++) {
66+
memcpy(&key_word, key + 4 * i, 4);
67+
REG_WRITE(AES_KEY_0_REG + i * 4, key_word);
68+
key_in_hardware += 4;
69+
}
70+
return key_in_hardware;
71+
}
72+
73+
/**
74+
* @brief Sets the mode
75+
*
76+
* @param mode ESP_AES_ENCRYPT = 1, or ESP_AES_DECRYPT = 0
77+
* @param key_bytes Number of bytes in the key
78+
*/
79+
static inline void aes_ll_set_mode(int mode, uint8_t key_bytes)
80+
{
81+
const uint32_t MODE_DECRYPT_BIT = 4;
82+
unsigned mode_reg_base = (mode == ESP_AES_ENCRYPT) ? 0 : MODE_DECRYPT_BIT;
83+
84+
/* See TRM for the mapping between keylength and mode bit */
85+
REG_WRITE(AES_MODE_REG, mode_reg_base + ((key_bytes / 8) - 2));
86+
}
87+
88+
/**
89+
* @brief Writes message block to AES hardware
90+
*
91+
* @param input Block to be written
92+
*/
93+
static inline void aes_ll_write_block(const void *input)
94+
{
95+
uint32_t input_word;
96+
97+
for (int i = 0; i < AES_BLOCK_WORDS; i++) {
98+
memcpy(&input_word, (uint8_t*)input + 4 * i, 4);
99+
REG_WRITE(AES_TEXT_IN_0_REG + i * 4, input_word);
100+
}
101+
}
102+
103+
/**
104+
* @brief Read the AES block
105+
*
106+
* @param output the output of the transform, length = AES_BLOCK_BYTES
107+
*/
108+
static inline void aes_ll_read_block(void *output)
109+
{
110+
uint32_t output_word;
111+
const size_t REG_WIDTH = sizeof(uint32_t);
112+
113+
for (size_t i = 0; i < AES_BLOCK_WORDS; i++) {
114+
output_word = REG_READ(AES_TEXT_OUT_0_REG + (i * REG_WIDTH));
115+
/* Memcpy to avoid potential unaligned access */
116+
memcpy( (uint8_t*)output + i * 4, &output_word, sizeof(output_word));
117+
}
118+
}
119+
120+
/**
121+
* @brief Starts block transform
122+
*
123+
*/
124+
static inline void aes_ll_start_transform(void)
125+
{
126+
REG_WRITE(AES_TRIGGER_REG, 1);
127+
}
128+
129+
130+
/**
131+
* @brief Read state of AES accelerator
132+
*
133+
* @return esp_aes_state_t
134+
*/
135+
static inline esp_aes_state_t aes_ll_get_state(void)
136+
{
137+
return (esp_aes_state_t)REG_READ(AES_STATE_REG);
138+
}
139+
140+
141+
/**
142+
* @brief Set mode of operation
143+
*
144+
* @note Only used for DMA transforms
145+
*
146+
* @param mode
147+
*/
148+
static inline void aes_ll_set_block_mode(esp_aes_mode_t mode)
149+
{
150+
REG_WRITE(AES_BLOCK_MODE_REG, mode);
151+
}
152+
153+
/**
154+
* @brief Set AES-CTR counter to INC32
155+
*
156+
* @note Only affects AES-CTR mode
157+
*
158+
*/
159+
static inline void aes_ll_set_inc(void)
160+
{
161+
REG_WRITE(AES_INC_SEL_REG, 0);
162+
}
163+
164+
/**
165+
* @brief Release the DMA
166+
*
167+
*/
168+
static inline void aes_ll_dma_exit(void)
169+
{
170+
REG_WRITE(AES_DMA_EXIT_REG, 0);
171+
}
172+
173+
/**
174+
* @brief Sets the number of blocks to be transformed
175+
*
176+
* @note Only used for DMA transforms
177+
*
178+
* @param num_blocks Number of blocks to transform
179+
*/
180+
static inline void aes_ll_set_num_blocks(size_t num_blocks)
181+
{
182+
REG_WRITE(AES_BLOCK_NUM_REG, num_blocks);
183+
}
184+
185+
/*
186+
* Write IV to hardware iv registers
187+
*/
188+
static inline void aes_ll_set_iv(const uint8_t *iv)
189+
{
190+
uint32_t *reg_addr_buf = (uint32_t *)(AES_IV_MEM);
191+
uint32_t iv_word;
192+
193+
for (int i = 0; i < IV_WORDS; i++ ) {
194+
/* Memcpy to avoid potential unaligned access */
195+
memcpy(&iv_word, iv + 4 * i, sizeof(iv_word));
196+
REG_WRITE(&reg_addr_buf[i], iv_word);
197+
}
198+
}
199+
200+
/*
201+
* Read IV from hardware iv registers
202+
*/
203+
static inline void aes_ll_read_iv(uint8_t *iv)
204+
{
205+
uint32_t iv_word;
206+
const size_t REG_WIDTH = sizeof(uint32_t);
207+
208+
for (size_t i = 0; i < IV_WORDS; i++) {
209+
iv_word = REG_READ(AES_IV_MEM + (i * REG_WIDTH));
210+
/* Memcpy to avoid potential unaligned access */
211+
memcpy(iv + i * 4, &iv_word, sizeof(iv_word));
212+
}
213+
}
214+
215+
/**
216+
* @brief Enable or disable DMA mode
217+
*
218+
* @param enable true to enable, false to disable.
219+
*/
220+
static inline void aes_ll_dma_enable(bool enable)
221+
{
222+
REG_WRITE(AES_DMA_ENABLE_REG, enable);
223+
}
224+
225+
/**
226+
* @brief Enable or disable transform completed interrupt
227+
*
228+
* @param enable true to enable, false to disable.
229+
*/
230+
static inline void aes_ll_interrupt_enable(bool enable)
231+
{
232+
REG_WRITE(AES_INT_ENA_REG, enable);
233+
}
234+
235+
/**
236+
* @brief Clears the interrupt
237+
*
238+
*/
239+
static inline void aes_ll_interrupt_clear(void)
240+
{
241+
REG_WRITE(AES_INT_CLEAR_REG, 1);
242+
}
243+
244+
/**
245+
* @brief Enable the pseudo-round function during AES operations
246+
*
247+
* @param enable true to enable, false to disable
248+
* @param base basic number of pseudo rounds, zero if disable
249+
* @param increment increment number of pseudo rounds, zero if disable
250+
* @param key_rng_cnt update frequency of the pseudo-key, zero if disable
251+
*/
252+
static inline void aes_ll_enable_pseudo_rounds(bool enable, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
253+
{
254+
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_EN, enable);
255+
256+
if (enable) {
257+
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_BASE, base);
258+
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_INC, increment);
259+
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_RNG_CNT, key_rng_cnt);
260+
} else {
261+
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_BASE, 0);
262+
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_INC, 0);
263+
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_RNG_CNT, 0);
264+
}
265+
}
266+
267+
/**
268+
* @brief Check if the pseudo round function is supported
269+
*/
270+
static inline bool aes_ll_is_pseudo_rounds_function_supported(void)
271+
{
272+
return true;
273+
}
274+
275+
#ifdef __cplusplus
276+
}
277+
#endif

0 commit comments

Comments
 (0)