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"
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-
308335static 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;
0 commit comments