Skip to content

Commit bef1fba

Browse files
Harshal5espressif-bot
authored andcommitted
fix(mbedtls/crypto_shared_gdma): Enable AXI-DMA enable external memory AES-ECC access
- When external memory encryption is enabled, set the aes_ecc bit of AXI-DMA to enable memory access
1 parent 4ec0065 commit bef1fba

File tree

8 files changed

+220
-31
lines changed

8 files changed

+220
-31
lines changed

components/hal/esp32p4/include/hal/axi_dma_ll.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,14 @@ static inline void axi_dma_ll_rx_enable_etm_task(axi_dma_dev_t *dev, uint32_t ch
273273
dev->in[channel].conf.in_conf0.in_etm_en_chn = enable;
274274
}
275275

276+
/**
277+
* @brief Whether to enable the mean access ecc or aes domain
278+
*/
279+
static inline void axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(axi_dma_dev_t *dev, uint32_t channel, bool enable)
280+
{
281+
dev->in[channel].conf.in_conf0.in_ecc_aec_en_chn = enable;
282+
}
283+
276284
///////////////////////////////////// TX /////////////////////////////////////////
277285
/**
278286
* @brief Get DMA TX channel interrupt status word
@@ -471,6 +479,14 @@ static inline void axi_dma_ll_tx_enable_etm_task(axi_dma_dev_t *dev, uint32_t ch
471479
dev->out[channel].conf.out_conf0.out_etm_en_chn = enable;
472480
}
473481

482+
/**
483+
* @brief Whether to enable the mean access ecc or aes domain
484+
*/
485+
static inline void axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(axi_dma_dev_t *dev, uint32_t channel, bool enable)
486+
{
487+
dev->out[channel].conf.out_conf0.out_ecc_aec_en_chn = enable;
488+
}
489+
474490
///////////////////////////////////// CRC-TX /////////////////////////////////////////
475491

476492
/**

components/hal/test_apps/crypto/main/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ if(CONFIG_SOC_SHA_SUPPORTED)
6868
endif()
6969

7070
idf_component_register(SRCS ${srcs}
71-
PRIV_REQUIRES efuse mbedtls esp_mm
71+
PRIV_REQUIRES efuse mbedtls esp_mm bootloader_support
7272
REQUIRES test_utils unity
7373
WHOLE_ARCHIVE
7474
PRIV_INCLUDE_DIRS "${priv_include_dirs}"

components/mbedtls/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ if(SHA_PERIPHERAL_TYPE STREQUAL "dma" OR AES_PERIPHERAL_TYPE STREQUAL "dma")
201201
target_link_libraries(mbedcrypto PRIVATE idf::esp_mm)
202202
if(CONFIG_SOC_SHA_GDMA OR CONFIG_SOC_AES_GDMA)
203203
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/crypto_shared_gdma/esp_crypto_shared_gdma.c")
204+
if(CONFIG_SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT)
205+
target_link_libraries(mbedcrypto PRIVATE idf::spi_flash idf::bootloader_support)
206+
endif()
204207
endif()
205208
endif()
206209

components/mbedtls/port/aes/dma/esp_aes_dma_core.c

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include "esp_memory_utils.h"
1717
#include "esp_private/esp_cache_private.h"
1818
#include "esp_private/periph_ctrl.h"
19+
#include "soc/soc_caps.h"
20+
#include "sdkconfig.h"
1921

2022
#if CONFIG_PM_ENABLE
2123
#include "esp_pm.h"
@@ -36,10 +38,19 @@
3638
#include "aes/esp_aes_gcm.h"
3739
#endif
3840

41+
#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT
42+
#include "esp_flash_encrypt.h"
43+
#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */
44+
3945
/* Max size of each chunk to process when output buffer is in unaligned external ram
4046
must be a multiple of block size
4147
*/
48+
#if (CONFIG_IDF_TARGET_ESP32P4 && CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE)
49+
/* As P4 has larger memory than other targets, thus we can support a larger chunk write size */
50+
#define AES_MAX_CHUNK_WRITE_SIZE 8*1024
51+
#else
4252
#define AES_MAX_CHUNK_WRITE_SIZE 1600
53+
#endif
4354

4455
/* Input over this length will yield and wait for interrupt instead of
4556
busy-waiting, 30000 bytes is approx 0.5 ms */
@@ -163,6 +174,26 @@ static int esp_aes_dma_wait_complete(bool use_intr, crypto_dma_desc_t *output_de
163174
return 0;
164175
}
165176

177+
static inline size_t get_cache_line_size(const void *addr)
178+
{
179+
esp_err_t ret = ESP_FAIL;
180+
size_t cache_line_size = 0;
181+
182+
#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE)
183+
if (esp_ptr_external_ram(addr)) {
184+
ret = esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &cache_line_size);
185+
} else
186+
#endif
187+
{
188+
ret = esp_cache_get_alignment(MALLOC_CAP_DMA, &cache_line_size);
189+
}
190+
191+
if (ret != ESP_OK) {
192+
return 0;
193+
}
194+
195+
return cache_line_size;
196+
}
166197

167198
/* Output buffers in external ram needs to be 16-byte aligned and DMA can't access input in the iCache mem range,
168199
reallocate them into internal memory and encrypt in chunks to avoid
@@ -176,14 +207,32 @@ static int esp_aes_process_dma_ext_ram(esp_aes_context *ctx, const unsigned char
176207
size_t chunk_len;
177208
int ret = 0;
178209
int offset = 0;
210+
uint32_t input_heap_caps = MALLOC_CAP_DMA;
211+
uint32_t output_heap_caps = MALLOC_CAP_DMA;
179212
unsigned char *input_buf = NULL;
180213
unsigned char *output_buf = NULL;
181214
const unsigned char *dma_input;
182215
chunk_len = MIN(AES_MAX_CHUNK_WRITE_SIZE, len);
183216

184-
if (realloc_input) {
185-
input_buf = heap_caps_malloc(chunk_len, MALLOC_CAP_DMA);
217+
size_t input_alignment = 1;
218+
size_t output_alignment = 1;
186219

220+
/* When AES-DMA operations are carried out using external memory with external memory encryption enabled,
221+
we need to make sure that the addresses and the sizes of the buffers on which the DMA operates are 16 byte-aligned. */
222+
#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT
223+
if (esp_flash_encryption_enabled()) {
224+
if (esp_ptr_external_ram(input) || esp_ptr_external_ram(output) || esp_ptr_in_drom(input) || esp_ptr_in_drom(output)) {
225+
input_alignment = MAX(get_cache_line_size(input), SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT);
226+
output_alignment = MAX(get_cache_line_size(output), SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT);
227+
228+
input_heap_caps = MALLOC_CAP_8BIT | (esp_ptr_external_ram(input) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
229+
output_heap_caps = MALLOC_CAP_8BIT | (esp_ptr_external_ram(output) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
230+
}
231+
}
232+
#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */
233+
234+
if (realloc_input) {
235+
input_buf = heap_caps_aligned_alloc(input_alignment, chunk_len, input_heap_caps);
187236
if (input_buf == NULL) {
188237
mbedtls_platform_zeroize(output, len);
189238
ESP_LOGE(TAG, "Failed to allocate memory");
@@ -192,8 +241,7 @@ static int esp_aes_process_dma_ext_ram(esp_aes_context *ctx, const unsigned char
192241
}
193242

194243
if (realloc_output) {
195-
output_buf = heap_caps_malloc(chunk_len, MALLOC_CAP_DMA);
196-
244+
output_buf = heap_caps_aligned_alloc(output_alignment, chunk_len, output_heap_caps);
197245
if (output_buf == NULL) {
198246
mbedtls_platform_zeroize(output, len);
199247
ESP_LOGE(TAG, "Failed to allocate memory");
@@ -284,27 +332,6 @@ static inline void *aes_dma_calloc(size_t num, size_t size, uint32_t caps, size_
284332
return ptr;
285333
}
286334

287-
static inline size_t get_cache_line_size(const void *addr)
288-
{
289-
esp_err_t ret = ESP_FAIL;
290-
size_t cache_line_size = 0;
291-
292-
#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE)
293-
if (esp_ptr_external_ram(addr)) {
294-
ret = esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &cache_line_size);
295-
} else
296-
#endif
297-
{
298-
ret = esp_cache_get_alignment(MALLOC_CAP_DMA, &cache_line_size);
299-
}
300-
301-
if (ret != ESP_OK) {
302-
return 0;
303-
}
304-
305-
return cache_line_size;
306-
}
307-
308335
static inline esp_err_t dma_desc_link(crypto_dma_desc_t *dmadesc, size_t crypto_dma_desc_num, size_t cache_line_size)
309336
{
310337
esp_err_t ret = ESP_OK;
@@ -404,7 +431,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le
404431
dma_descs_needed = (unaligned_start_bytes ? 1 : 0) + dma_desc_get_required_num(aligned_block_bytes, max_desc_size) + (unaligned_end_bytes ? 1 : 0);
405432

406433
/* Allocate memory for DMA descriptors of total size aligned up to a multiple of cache line size */
407-
dma_descriptors = (crypto_dma_desc_t *) aes_dma_calloc(dma_descs_needed, sizeof(crypto_dma_desc_t), MALLOC_CAP_DMA, NULL);
434+
dma_descriptors = (crypto_dma_desc_t *) aes_dma_calloc(dma_descs_needed, sizeof(crypto_dma_desc_t), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL, NULL);
408435
if (dma_descriptors == NULL) {
409436
ESP_LOGE(TAG, "Failed to allocate memory for the array of DMA descriptors");
410437
return ESP_FAIL;
@@ -413,7 +440,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le
413440
size_t populated_dma_descs = 0;
414441

415442
if (unaligned_start_bytes) {
416-
start_alignment_stream_buffer = aes_dma_calloc(alignment_buffer_size, sizeof(uint8_t), AES_DMA_ALLOC_CAPS, NULL);
443+
start_alignment_stream_buffer = aes_dma_calloc(alignment_buffer_size, sizeof(uint8_t), AES_DMA_ALLOC_CAPS | (esp_ptr_external_ram(buffer) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_INTERNAL) , NULL);
417444
if (start_alignment_stream_buffer == NULL) {
418445
ESP_LOGE(TAG, "Failed to allocate memory for start alignment buffer");
419446
return ESP_FAIL;
@@ -435,7 +462,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le
435462
}
436463

437464
if (unaligned_end_bytes) {
438-
end_alignment_stream_buffer = aes_dma_calloc(alignment_buffer_size, sizeof(uint8_t), AES_DMA_ALLOC_CAPS, NULL);
465+
end_alignment_stream_buffer = aes_dma_calloc(alignment_buffer_size, sizeof(uint8_t), AES_DMA_ALLOC_CAPS | (esp_ptr_external_ram(buffer) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_INTERNAL), NULL);
439466
if (end_alignment_stream_buffer == NULL) {
440467
ESP_LOGE(TAG, "Failed to allocate memory for end alignment buffer");
441468
return ESP_FAIL;
@@ -499,6 +526,20 @@ int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsign
499526
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
500527
}
501528

529+
#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT
530+
if (esp_flash_encryption_enabled()) {
531+
if (esp_ptr_external_ram(input) || esp_ptr_external_ram(output) || esp_ptr_in_drom(input) || esp_ptr_in_drom(output)) {
532+
if (((intptr_t)(input) & (SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT - 1)) != 0) {
533+
input_needs_realloc = true;
534+
}
535+
536+
if (((intptr_t)(output) & (SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT - 1)) != 0) {
537+
output_needs_realloc = true;
538+
}
539+
}
540+
}
541+
#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */
542+
502543
/* DMA cannot access memory in the iCache range, copy input to internal ram */
503544
if (!s_check_dma_capable(input)) {
504545
input_needs_realloc = true;

components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -13,7 +13,13 @@
1313
#include "esp_cache.h"
1414
#include "esp_crypto_dma.h"
1515
#include "esp_crypto_lock.h"
16+
#include "esp_memory_utils.h"
1617
#include "soc/soc_caps.h"
18+
#include "sdkconfig.h"
19+
20+
#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT
21+
#include "esp_flash_encrypt.h"
22+
#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */
1723

1824
#if SOC_AHB_GDMA_VERSION == 1
1925
#include "hal/gdma_ll.h"
@@ -140,6 +146,22 @@ esp_err_t esp_crypto_shared_gdma_start(const lldesc_t *input, const lldesc_t *ou
140146
return ESP_OK;
141147
}
142148

149+
/* The external memory ecc-aes access must be enabled when there exists
150+
at least one buffer in the DMA descriptors that resides in external memory. */
151+
#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT
152+
static bool check_dma_descs_need_ext_mem_ecc_aes_access(const crypto_dma_desc_t *dmadesc)
153+
{
154+
crypto_dma_desc_t* desc = (crypto_dma_desc_t*) dmadesc;
155+
while (desc) {
156+
if (esp_ptr_in_drom(desc->buffer) || esp_ptr_external_ram(desc->buffer)) {
157+
return true;
158+
}
159+
desc = desc->next;
160+
}
161+
return false;
162+
}
163+
#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */
164+
143165
esp_err_t esp_crypto_shared_gdma_start_axi_ahb(const crypto_dma_desc_t *input, const crypto_dma_desc_t *output, gdma_trigger_peripheral_t peripheral)
144166
{
145167
int rx_ch_id = 0;
@@ -173,6 +195,23 @@ esp_err_t esp_crypto_shared_gdma_start_axi_ahb(const crypto_dma_desc_t *input, c
173195
axi_dma_ll_rx_reset_channel(&AXI_DMA, rx_ch_id);
174196
#endif /* SOC_AHB_GDMA_VERSION */
175197

198+
/* When GDMA operations are carried out using external memory with external memory encryption enabled,
199+
we need to enable AXI-DMA's AES-ECC mean access bit. */
200+
#if (SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT)
201+
if (esp_flash_encryption_enabled()) {
202+
int tx_ch_id = 0;
203+
gdma_get_channel_id(tx_channel, &tx_ch_id);
204+
205+
if (check_dma_descs_need_ext_mem_ecc_aes_access(input) || check_dma_descs_need_ext_mem_ecc_aes_access(output)) {
206+
axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(&AXI_DMA, rx_ch_id, true);
207+
axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(&AXI_DMA, tx_ch_id, true);
208+
} else {
209+
axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(&AXI_DMA, rx_ch_id, false);
210+
axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(&AXI_DMA, tx_ch_id, false);
211+
}
212+
}
213+
#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */
214+
176215
gdma_start(tx_channel, (intptr_t)input);
177216
gdma_start(rx_channel, (intptr_t)output);
178217

0 commit comments

Comments
 (0)