Эх сурвалжийг харах

Merge branch 'feature/c3_crypto_gdma' into 'master'

AES/SHA: GDMA crypto driver

Closes IDF-2192 and IDF-2501

See merge request espressif/esp-idf!12014
Angus Gratton 5 жил өмнө
parent
commit
cfdd7f0f22

+ 0 - 1
components/driver/include/esp_private/gdma.h

@@ -147,7 +147,6 @@ typedef struct {
  *      - ESP_OK: Create DMA channel successfully
  *      - ESP_ERR_INVALID_ARG: Create DMA channel failed because of invalid argument
  *      - ESP_ERR_NO_MEM: Create DMA channel failed because out of memory
- *      - ESP_ERR_TIMEOUT: Create DMA channel failed because of time out
  *      - ESP_FAIL: Create DMA channel failed because of other error
  */
 esp_err_t gdma_new_channel(const gdma_channel_alloc_config_t *config, gdma_channel_handle_t *ret_chan);

+ 3 - 99
components/hal/aes_hal.c

@@ -20,14 +20,6 @@
 #include <string.h>
 #include "soc/soc_caps.h"
 
-#if SOC_AES_CRYPTO_DMA
-#include "soc/crypto_dma_reg.h"
-#include "hal/crypto_dma_ll.h"
-#elif SOC_AES_GENERAL_DMA
-#include "hal/gdma_ll.h"
-#include "soc/gdma_channel.h"
-#endif
-
 uint8_t aes_hal_setkey(const uint8_t *key, size_t key_bytes, int mode)
 {
     aes_ll_set_mode(mode, key_bytes);
@@ -57,83 +49,10 @@ void aes_hal_transform_block(const void *input_block, void *output_block)
 
 #if SOC_AES_SUPPORT_DMA
 
-#if SOC_AES_GENERAL_DMA
-/**
- * @brief Initialize the DMA
- *
- * @param input AES input descriptor (outlink)
- * @param output AES output descriptor (inlink)
- */
-static inline void aes_hal_dma_init(const lldesc_t *input, const lldesc_t *output)
-{
-    /* Update driver when centralized DMA interface implemented, IDF-2192 */
-    gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
-    gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
-    gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
-    gdma_ll_rx_enable_data_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
-
-    gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, SOC_GDMA_TRIG_PERIPH_AES0);
-    gdma_ll_rx_connect_to_periph(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, SOC_GDMA_TRIG_PERIPH_AES0);
-
-#if SOC_GDMA_SUPPORT_EXTMEM
-    /* An L2 FIFO bigger than 40 bytes is need when accessing external ram */
-    gdma_ll_tx_extend_fifo_size_to(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, 40);
-    gdma_ll_rx_extend_l2_fifo_size_to(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, 40);
-    gdma_ll_tx_set_block_size_psram(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
-    gdma_ll_rx_set_block_size_psram(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
-#endif //SOC_GDMA_SUPPORT_EXTMEM
-
-    /* Set descriptors */
-    gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, (uint32_t)input);
-    gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, (uint32_t)output);
-
-    gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
-    gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
-
-    /* Start transfer */
-    gdma_ll_tx_start(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
-    gdma_ll_rx_start(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
-}
 
-static inline bool aes_hal_dma_done(const lldesc_t *output)
-{
-    return (gdma_ll_rx_is_fsm_idle(&GDMA, SOC_GDMA_AES_DMA_CHANNEL) && (output->owner == 0));
-}
-#endif //SOC_AES_GENERAL_DMA
-
-
-
-#if SOC_AES_CRYPTO_DMA
-/**
- * @brief Initialize the DMA
- *
- * @param input AES input descriptor (outlink)
- * @param output AES output descriptor (inlink)
- */
-static inline void aes_hal_dma_init(const lldesc_t *input, const lldesc_t *output)
-{
-    crypto_dma_ll_reset();
-    crypto_dma_ll_set_mode(CRYPTO_DMA_AES);
-
-    /* Set descriptors, input to AES comes from outlink DMA and viceversa */
-    crypto_dma_ll_outlink_set((uint32_t)input);
-    crypto_dma_ll_inlink_set((uint32_t)output);
-
-    /* Start transfer */
-    crypto_dma_ll_outlink_start();
-    crypto_dma_ll_inlink_start();
-}
-
-static inline bool aes_hal_dma_done(lldesc_t *output)
-{
-    return (crypto_dma_ll_inlink_is_eof() && (output->owner == 0));
-}
-#endif //SOC_AES_CRYPTO_DMA
-
-void aes_hal_transform_dma_start(const lldesc_t *input, const lldesc_t *output, size_t num_blocks)
+void aes_hal_transform_dma_start(size_t num_blocks)
 {
     aes_ll_dma_enable(true);
-    aes_hal_dma_init(input, output);
 
     /* Write the number of blocks */
     aes_ll_set_num_blocks(num_blocks);
@@ -168,25 +87,11 @@ void aes_hal_read_iv(uint8_t *iv)
     aes_ll_read_iv(iv);
 }
 
-static inline void aes_hal_wait_done(void)
+void aes_hal_wait_done()
 {
     while (aes_ll_get_state() != ESP_AES_STATE_DONE) {}
 }
 
-void aes_hal_wait_dma_done(lldesc_t *output)
-{
-    /* Checking this if interrupt is used also, to avoid
-       issues with AES fault injection
-    */
-    aes_hal_wait_done();
-
-    /* Wait for DMA write operation to complete */
-    while (1) {
-        if ( aes_hal_dma_done(output) ) {
-            break;
-        }
-    }
-}
 
 #endif //SOC_AES_SUPPORT_DMA
 
@@ -202,9 +107,8 @@ void aes_hal_gcm_calc_hash(uint8_t *gcm_hash)
     aes_ll_gcm_read_hash(gcm_hash);
 }
 
-void aes_hal_transform_dma_gcm_start(const lldesc_t *input, const lldesc_t *output, size_t num_blocks)
+void aes_hal_transform_dma_gcm_start(size_t num_blocks)
 {
-    aes_hal_dma_init(input, output);
 
     /* Write the number of blocks */
     aes_ll_set_num_blocks(num_blocks);

+ 4 - 9
components/hal/include/hal/aes_hal.h

@@ -22,7 +22,6 @@
 
 #include <stddef.h>
 #include <stdbool.h>
-#include "soc/lldesc.h"
 #include "soc/soc_caps.h"
 #include "hal/aes_types.h"
 #include "hal/aes_ll.h"
@@ -76,20 +75,18 @@ void aes_hal_set_iv(const uint8_t *iv);
 void aes_hal_read_iv(uint8_t *iv);
 
 /**
- * @brief Busy waits until the DMA operation is done (descriptor owner is CPU)
+ * @brief Busy waits until the AES operation is done
  *
  * @param output pointer to inlink descriptor
  */
-void aes_hal_wait_dma_done(lldesc_t *output);
+void aes_hal_wait_done(void);
 
 /**
  * @brief Starts an already configured AES DMA transform
  *
- * @param input outlink descriptor for data to be written to the peripheral
- * @param output inlink descriptor for data to be read from the peripheral
  * @param num_blocks Number of blocks to transform
  */
-void aes_hal_transform_dma_start(const lldesc_t *input, const lldesc_t *output, size_t num_blocks);
+void aes_hal_transform_dma_start(size_t num_blocks);
 
 /**
  * @brief Finish up a AES DMA conversion, release DMA
@@ -129,11 +126,9 @@ void aes_hal_gcm_init(size_t aad_num_blocks, size_t num_valid_bit);
 /**
  * @brief Starts a AES-GCM transform
  *
- * @param input outlink descriptor for data to be written to the peripheral
- * @param output inlink descriptor for data to be read from the perihperal
  * @param num_blocks Number of blocks to transform
  */
-void aes_hal_transform_dma_gcm_start(const lldesc_t *input, const lldesc_t *output, size_t num_blocks);
+void aes_hal_transform_dma_gcm_start(size_t num_blocks);
 
 /**
  * @brief Sets the J0 value, for more information see the GCM subchapter in the TRM

+ 1 - 2
components/hal/include/hal/sha_hal.h

@@ -69,11 +69,10 @@ void sha_hal_write_digest(esp_sha_type sha_type, void *digest_state);
  * @brief Hashes a number of message blocks using DMA
  *
  * @param sha_type      SHA algorithm to hash with
- * @param input         Input message to be hashed
  * @param num_blocks    Number of blocks to hash
  * @param first_block   Is this the first block in a message or a continuation?
  */
-void sha_hal_hash_dma(esp_sha_type sha_type, lldesc_t *input, size_t num_blocks, bool first_block);
+void sha_hal_hash_dma(esp_sha_type sha_type, size_t num_blocks, bool first_block);
 #endif
 
 #if SOC_SHA_SUPPORT_SHA512_T

+ 1 - 50
components/hal/sha_hal.c

@@ -21,13 +21,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 
-#if SOC_SHA_CRYPTO_DMA
-#include "soc/crypto_dma_reg.h"
-#include "hal/crypto_dma_ll.h"
-#elif SOC_SHA_GENERAL_DMA
-#include "hal/gdma_ll.h"
-#include "soc/gdma_channel.h"
-#endif
 
 #define SHA1_STATE_LEN_WORDS    (160 / 32)
 #define SHA256_STATE_LEN_WORDS  (256 / 32)
@@ -99,53 +92,11 @@ void sha_hal_hash_block(esp_sha_type sha_type, const void *data_block, size_t bl
 
 #if SOC_SHA_SUPPORT_DMA
 
-#if SOC_SHA_GENERAL_DMA
-static inline void sha_hal_dma_init(lldesc_t *input)
-{
-    /* Update driver when centralized DMA interface implemented, IDF-2192 */
-    gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, false);
-    gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, false);
-    gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, false);
-
-    gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, SOC_GDMA_TRIG_PERIPH_SHA0);
-
-#if SOC_GDMA_SUPPORT_EXTMEM
-    /* Atleast 40 bytes when accessing external RAM */
-    gdma_ll_tx_extend_fifo_size_to(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, 40);
-    gdma_ll_tx_set_block_size_psram(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
-#endif //SOC_GDMA_SUPPORT_EXTMEM
-
-    /* Set descriptors */
-    gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, (uint32_t)input);
-
-    gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL);
-    gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL);
-
-    /* Start transfer */
-    gdma_ll_tx_start(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL);
-}
-#endif //SOC_SHA_GENERAL_DMA
-
-
-
-#if SOC_SHA_CRYPTO_DMA
-static inline void sha_hal_dma_init(lldesc_t *input)
-{
-    crypto_dma_ll_set_mode(CRYPTO_DMA_SHA);
-    crypto_dma_ll_reset();
-
-    crypto_dma_ll_outlink_set((uint32_t)input);
-    crypto_dma_ll_outlink_start();
-}
-#endif
-
 /* Hashes a number of message blocks using DMA */
-void sha_hal_hash_dma(esp_sha_type sha_type, lldesc_t *input, size_t num_blocks, bool first_block)
+void sha_hal_hash_dma(esp_sha_type sha_type, size_t num_blocks, bool first_block)
 {
     sha_hal_wait_idle();
 
-    sha_hal_dma_init(input);
-
     sha_ll_set_block_num(num_blocks);
 
     /* Start hashing */

+ 1 - 1
components/idf_test/include/esp32c3/idf_performance_target.h

@@ -14,7 +14,7 @@
 
 #pragma once
 
-#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC                            14.4
+#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC                            43
 
 // SHA256 hardware throughput at 160 MHz, threshold set lower than worst case
 #define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC                             90

+ 1 - 1
components/idf_test/include/esp32s3/idf_performance_target.h

@@ -14,7 +14,7 @@
 
 #pragma once
 
-#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC                            14.4
+#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC                            43
 
 // SHA256 hardware throughput at 240MHz, threshold set lower than worst case
 #define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC                             19.8

+ 22 - 0
components/mbedtls/CMakeLists.txt

@@ -90,6 +90,26 @@ else()
     set(AES_PERIPHERAL_TYPE "dma")
 endif()
 
+if(SHA_PERIPHERAL_TYPE STREQUAL "dma")
+    target_include_directories(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/dma/include")
+
+    if(CONFIG_IDF_TARGET_ESP32S2)
+        set(SHA_DMA_SRCS "${COMPONENT_DIR}/port/sha/dma/esp_sha_crypto_dma_impl.c")
+    else()
+        set(SHA_DMA_SRCS "${COMPONENT_DIR}/port/sha/dma/esp_sha_gdma_impl.c")
+    endif()
+endif()
+
+if(AES_PERIPHERAL_TYPE STREQUAL "dma")
+    target_include_directories(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/dma/include")
+
+    if(CONFIG_IDF_TARGET_ESP32S2)
+        set(AES_DMA_SRCS "${COMPONENT_DIR}/port/aes/dma/esp_aes_crypto_dma_impl.c")
+    else()
+        set(AES_DMA_SRCS "${COMPONENT_DIR}/port/aes/dma/esp_aes_gdma_impl.c")
+    endif()
+endif()
+
 target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c"
                                   "${COMPONENT_DIR}/port/esp_mem.c"
                                   "${COMPONENT_DIR}/port/esp_timing.c"
@@ -98,6 +118,8 @@ target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c"
                                   "${COMPONENT_DIR}/port/aes/esp_aes_common.c"
                                   "${COMPONENT_DIR}/port/aes/${AES_PERIPHERAL_TYPE}/esp_aes.c"
                                   "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/sha.c"
+                                  "${SHA_DMA_SRCS}"
+                                  "${AES_DMA_SRCS}"
 )
 
 if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL)

+ 34 - 9
components/mbedtls/port/aes/dma/esp_aes.c

@@ -38,6 +38,7 @@
 #include "esp_crypto_lock.h"
 #include "hal/aes_hal.h"
 #include "aes/esp_aes_internal.h"
+#include "esp_aes_dma_priv.h"
 
 #if CONFIG_IDF_TARGET_ESP32S2
 #include "esp32s2/rom/cache.h"
@@ -52,7 +53,7 @@
 #include "aes/esp_aes_gcm.h"
 #endif
 
-#if SOC_AES_GENERAL_DMA
+#if SOC_AES_GDMA
 #define AES_LOCK() esp_crypto_aes_lock_acquire()
 #define AES_RELEASE() esp_crypto_aes_lock_release()
 #elif SOC_AES_CRYPTO_DMA
@@ -80,6 +81,17 @@ static esp_pm_lock_handle_t s_pm_sleep_lock;
 
 static const char *TAG = "esp-aes";
 
+
+static inline void esp_aes_wait_dma_done(lldesc_t *output)
+{
+    /* Wait for DMA write operation to complete */
+    while (1) {
+        if ( esp_aes_dma_done(output) ) {
+            break;
+        }
+    }
+}
+
 /* Append a descriptor to the chain, set head if chain empty */
 static inline void lldesc_append(lldesc_t **head, lldesc_t *item)
 {
@@ -106,9 +118,8 @@ void esp_aes_acquire_hardware( void )
     /* Enable AES and DMA hardware */
 #if SOC_AES_CRYPTO_DMA
     periph_module_enable(PERIPH_AES_DMA_MODULE);
-#elif SOC_AES_GENERAL_DMA
+#elif SOC_AES_GDMA
     periph_module_enable(PERIPH_AES_MODULE);
-    periph_module_enable(PERIPH_GDMA_MODULE);
 #endif
 }
 
@@ -118,9 +129,8 @@ void esp_aes_release_hardware( void )
     /* Disable AES and DMA hardware */
 #if SOC_AES_CRYPTO_DMA
     periph_module_disable(PERIPH_AES_DMA_MODULE);
-#elif SOC_AES_GENERAL_DMA
+#elif SOC_AES_GDMA
     periph_module_disable(PERIPH_AES_MODULE);
-    periph_module_disable(PERIPH_GDMA_MODULE);
 #endif
 
     AES_RELEASE();
@@ -189,8 +199,12 @@ static void esp_aes_dma_wait_complete(bool use_intr, lldesc_t *output_desc)
 #endif  // CONFIG_PM_ENABLE
     }
 #endif
+    /* Checking this if interrupt is used also, to avoid
+       issues with AES fault injection
+    */
+    aes_hal_wait_done();
 
-    aes_hal_wait_dma_done(output_desc);
+    esp_aes_wait_dma_done(output_desc);
 }
 
 
@@ -380,7 +394,13 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
         aes_hal_interrupt_enable(false);
     }
 
-    aes_hal_transform_dma_start(in_desc_head, out_desc_head, blocks);
+    if (esp_aes_dma_start(in_desc_head, out_desc_head) != ESP_OK) {
+        ESP_LOGE(TAG, "esp_aes_dma_start failed, no DMA channel available");
+        ret = -1;
+        goto cleanup;
+    }
+
+    aes_hal_transform_dma_start(blocks);
     esp_aes_dma_wait_complete(use_intr, out_desc_head);
 
 #if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
@@ -390,7 +410,6 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
         }
     }
 #endif
-
     aes_hal_transform_dma_finish();
 
     if (stream_bytes > 0) {
@@ -499,7 +518,13 @@ int esp_aes_process_dma_gcm(esp_aes_context *ctx, const unsigned char *input, un
     }
 
     /* Start AES operation */
-    aes_hal_transform_dma_gcm_start(in_desc_head, out_desc_head, blocks);
+    if (esp_aes_dma_start(in_desc_head, out_desc_head) != ESP_OK) {
+        ESP_LOGE(TAG, "esp_aes_dma_start failed, no DMA channel available");
+        ret = -1;
+        goto cleanup;
+    }
+
+    aes_hal_transform_dma_gcm_start(blocks);
 
     esp_aes_dma_wait_complete(use_intr, out_desc_head);
 

+ 42 - 0
components/mbedtls/port/aes/dma/esp_aes_crypto_dma_impl.c

@@ -0,0 +1,42 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#include "esp_aes_dma_priv.h"
+
+#include "soc/soc_caps.h"
+#include "soc/crypto_dma_reg.h"
+#include "hal/crypto_dma_ll.h"
+
+
+esp_err_t esp_aes_dma_start(const lldesc_t *input, const lldesc_t *output)
+{
+    crypto_dma_ll_reset();
+    crypto_dma_ll_set_mode(CRYPTO_DMA_AES);
+
+    /* Set descriptors, input to AES comes from outlink DMA and viceversa */
+    crypto_dma_ll_outlink_set((uint32_t)input);
+    crypto_dma_ll_inlink_set((uint32_t)output);
+
+    /* Start transfer */
+    crypto_dma_ll_outlink_start();
+    crypto_dma_ll_inlink_start();
+
+    return ESP_OK;
+}
+
+bool esp_aes_dma_done(const lldesc_t *output)
+{
+    return (crypto_dma_ll_inlink_is_eof() && (output->owner == 0));
+}

+ 168 - 0
components/mbedtls/port/aes/dma/esp_aes_gdma_impl.c

@@ -0,0 +1,168 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include "esp_aes_dma_priv.h"
+
+#include <sys/lock.h>
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+
+#include "driver/periph_ctrl.h"
+#include "hal/gdma_ll.h"
+#include "soc/soc_caps.h"
+#include "esp_private/gdma.h"
+#include "esp_log.h"
+
+#define NEW_CHANNEL_TIMEOUT_MS  1000
+#define NEW_CHANNEL_DELAY_MS    100
+
+static const char *TAG = "esp_aes_gdma";
+
+static _lock_t gdma_ch_lock;
+/* For GDMA we allocate and reserve a single DMA pair for AES at esp_aes_init
+   and release it esp_aes_free
+   This is done to avoid the GDMA associated overhead when doing multiple AES transforms in a row.
+
+    The channel is shared between any AES operations that are running in parallel,
+    access will be limited by the peripheral lock
+ */
+static uint8_t ref_counts;
+
+/* The GDMA channel is protected from concurrent access by the general AES peripheral lock */
+static gdma_channel_handle_t tx_channel;
+static gdma_channel_handle_t rx_channel;
+
+/* Allocate a new GDMA channel, will keep trying until NEW_CHANNEL_TIMEOUT_MS */
+static inline esp_err_t esp_aes_gdma_new_channel(gdma_channel_alloc_config_t *channel_config, gdma_channel_handle_t *channel)
+{
+    esp_err_t ret;
+    int time_waited_ms = 0;
+
+    while(1) {
+        ret = gdma_new_channel(channel_config, channel);
+
+        if (ret == ESP_OK) {
+            break;
+        } else if (time_waited_ms >= NEW_CHANNEL_TIMEOUT_MS) {
+            *channel = NULL;
+            break;
+        }
+
+        time_waited_ms += NEW_CHANNEL_DELAY_MS;
+        vTaskDelay(NEW_CHANNEL_DELAY_MS / portTICK_PERIOD_MS);
+    }
+    return ret;
+}
+
+/* Initialize GDMA module and channels */
+static inline void esp_aes_gdma_init(void)
+{
+    esp_err_t ret;
+
+    gdma_channel_alloc_config_t channel_config = {
+        .direction = GDMA_CHANNEL_DIRECTION_TX,
+    };
+
+    ret = esp_aes_gdma_new_channel(&channel_config, &tx_channel);
+    if (ret != ESP_OK) {
+        goto err;
+    }
+
+    channel_config.direction = GDMA_CHANNEL_DIRECTION_RX;
+    ret = esp_aes_gdma_new_channel(&channel_config, &rx_channel);
+    if (ret != ESP_OK) {
+        gdma_del_channel(tx_channel); // Clean up already allocated TX channel
+        goto err;
+    }
+
+    gdma_connect(tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_AES, 0));
+    gdma_connect(rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_AES, 0));
+
+    return;
+
+err:
+    /* mbedtls_aes_init do not have a way of signaling errors to the caller
+       so we set the channel to NULL and detect it in esp_aes_dma_start */
+    ESP_LOGE(TAG, "Failed to acquire DMA channel, Err=0x%X", ret);
+    tx_channel = NULL;
+    rx_channel = NULL;
+}
+
+void esp_aes_dma_init()
+{
+
+    _lock_acquire(&gdma_ch_lock);
+    if (ref_counts == 0) {
+        esp_aes_gdma_init();
+    }
+    ref_counts++;
+    _lock_release(&gdma_ch_lock);
+}
+
+static inline void esp_aes_gdma_free(void)
+{
+    gdma_disconnect(tx_channel);
+    gdma_disconnect(rx_channel);
+    gdma_del_channel(tx_channel);
+    gdma_del_channel(rx_channel);
+
+    tx_channel = NULL;
+    rx_channel = NULL;
+}
+
+void esp_aes_dma_free()
+{
+    _lock_acquire(&gdma_ch_lock);
+    ref_counts--;
+    if (ref_counts == 0) {
+        esp_aes_gdma_free();
+    }
+    _lock_release(&gdma_ch_lock);
+}
+
+
+esp_err_t esp_aes_dma_start(const lldesc_t *input, const lldesc_t *output)
+{
+#if SOC_GDMA_SUPPORT_EXTMEM
+    int tx_ch_id = 0;
+    int rx_ch_id = 0;
+#endif //SOC_GDMA_SUPPORT_EXTMEM
+
+    if (!tx_channel || !rx_channel) {
+        /* Will happen if no channel was acquired before timeout */
+        return ESP_FAIL;
+    }
+
+#if SOC_GDMA_SUPPORT_EXTMEM
+    gdma_get_channel_id(tx_channel, &tx_ch_id);
+    gdma_get_channel_id(rx_channel, &rx_ch_id);
+    /* An L2 FIFO bigger than 40 bytes is need when accessing external ram */
+    gdma_ll_tx_extend_fifo_size_to(&GDMA, tx_ch_id, 40);
+    gdma_ll_rx_extend_l2_fifo_size_to(&GDMA, rx_ch_id, 40);
+    gdma_ll_tx_set_block_size_psram(&GDMA, tx_ch_id, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
+    gdma_ll_rx_set_block_size_psram(&GDMA, rx_ch_id, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
+#endif //SOC_GDMA_SUPPORT_EXTMEM
+
+    gdma_start(tx_channel, (intptr_t)input);
+    gdma_start(rx_channel, (intptr_t)output);
+
+    return ESP_OK;
+}
+
+
+
+bool esp_aes_dma_done(const lldesc_t *output)
+{
+    return (output->owner == 0);
+}

+ 69 - 0
components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h

@@ -0,0 +1,69 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include "soc/lldesc.h"
+#include "soc/soc_caps.h"
+#include "esp_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if SOC_AES_GDMA
+
+/**
+ * @brief Initialize the GDMA channel
+ *
+ * @note Allocate and initialize a DMA channel (rx and tx) for the AES peripheral
+ *       Only one channel will be initialized at any given time. If two or more AES operations are
+ *       run in parallel the channel will be shared sequentially.
+ *
+ */
+void esp_aes_dma_init(void);
+
+/**
+ * @brief Free the GDMA channel
+ *
+ * @note The channel will only be freed if there are no other AES operations currently using it
+ *
+ */
+void esp_aes_dma_free(void);
+#endif //SOC_AES_GDMA
+
+/**
+ * @brief Start the DMA engine
+ *
+ * @param input AES input descriptor (outlink)
+ * @param output AES output descriptor (inlink)
+ * @return
+ *      - ESP_OK: Successfully started the DMA
+ *      - ESP_ERR_INVALID_STATE: No DMA channel available
+ */
+esp_err_t esp_aes_dma_start(const lldesc_t *input, const lldesc_t *output);
+
+/**
+ * @brief Check if the DMA engine is finished reading the result
+ *
+ * @param output AES output descriptor (inlink)
+ * @return
+ *      - true: DMA finished
+ *      - false: DMA not yet finished
+ */
+bool esp_aes_dma_done(const lldesc_t *output);
+
+#ifdef __cplusplus
+}
+#endif

+ 12 - 0
components/mbedtls/port/aes/esp_aes_common.c

@@ -35,6 +35,10 @@
 #include <string.h>
 #include "mbedtls/platform.h"
 
+#if SOC_AES_GDMA
+#include "esp_aes_dma_priv.h"
+#endif
+
 bool valid_key_length(const esp_aes_context *ctx)
 {
     bool valid_len = (ctx->key_bytes == AES_128_KEY_BYTES) || (ctx->key_bytes == AES_256_KEY_BYTES);
@@ -50,6 +54,10 @@ bool valid_key_length(const esp_aes_context *ctx)
 void esp_aes_init( esp_aes_context *ctx )
 {
     bzero( ctx, sizeof( esp_aes_context ) );
+
+#if SOC_AES_GDMA
+    esp_aes_dma_init();
+#endif
 }
 
 void esp_aes_free( esp_aes_context *ctx )
@@ -58,6 +66,10 @@ void esp_aes_free( esp_aes_context *ctx )
         return;
     }
 
+#if SOC_AES_GDMA
+    esp_aes_dma_free();
+#endif
+
     bzero( ctx, sizeof( esp_aes_context ) );
 }
 

+ 11 - 0
components/mbedtls/port/sha/dma/esp_sha1.c

@@ -47,6 +47,10 @@
 
 #include "sha/sha_dma.h"
 
+#if SOC_SHA_GDMA
+#include "esp_sha_dma_priv.h"
+#endif
+
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n )
 {
@@ -73,6 +77,10 @@ static void mbedtls_zeroize( void *v, size_t n )
 void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
+
+#if SOC_SHA_GDMA
+    esp_sha_dma_init();
+#endif
 }
 
 void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
@@ -80,6 +88,9 @@ void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
     if ( ctx == NULL ) {
         return;
     }
+#if SOC_SHA_GDMA
+    esp_sha_dma_free();
+#endif
 
     mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
 }

+ 12 - 0
components/mbedtls/port/sha/dma/esp_sha256.c

@@ -48,6 +48,10 @@
 
 #include "sha/sha_dma.h"
 
+#if SOC_SHA_GDMA
+#include "esp_sha_dma_priv.h"
+#endif
+
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n )
 {
@@ -83,6 +87,10 @@ do {                                                    \
 void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
+
+#if SOC_SHA_GDMA
+    esp_sha_dma_init();
+#endif
 }
 
 void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
@@ -91,6 +99,10 @@ void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
         return;
     }
 
+#if SOC_SHA_GDMA
+    esp_sha_dma_free();
+#endif
+
     mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
 }
 

+ 12 - 0
components/mbedtls/port/sha/dma/esp_sha512.c

@@ -54,6 +54,10 @@
 
 #include "sha/sha_dma.h"
 
+#if SOC_SHA_GDMA
+#include "esp_sha_dma_priv.h"
+#endif
+
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n )
 {
@@ -105,6 +109,10 @@ void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val)
 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
+
+#if SOC_SHA_GDMA
+    esp_sha_dma_init();
+#endif
 }
 
 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
@@ -113,6 +121,10 @@ void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
         return;
     }
 
+#if SOC_SHA_GDMA
+    esp_sha_dma_free();
+#endif
+
     mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
 }
 

+ 32 - 0
components/mbedtls/port/sha/dma/esp_sha_crypto_dma_impl.c

@@ -0,0 +1,32 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#include "esp_sha_dma_priv.h"
+
+#include "soc/soc_caps.h"
+#include "soc/crypto_dma_reg.h"
+#include "hal/crypto_dma_ll.h"
+
+
+esp_err_t esp_sha_dma_start(const lldesc_t *input)
+{
+    crypto_dma_ll_set_mode(CRYPTO_DMA_SHA);
+    crypto_dma_ll_reset();
+
+    crypto_dma_ll_outlink_set((intptr_t)input);
+    crypto_dma_ll_outlink_start();
+
+    return ESP_OK;
+}

+ 140 - 0
components/mbedtls/port/sha/dma/esp_sha_gdma_impl.c

@@ -0,0 +1,140 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include "esp_sha_dma_priv.h"
+
+#include <sys/lock.h>
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+
+#include "driver/periph_ctrl.h"
+#include "hal/gdma_ll.h"
+#include "soc/soc_caps.h"
+#include "esp_private/gdma.h"
+#include "esp_log.h"
+
+#define NEW_CHANNEL_TIMEOUT_MS  1000
+#define NEW_CHANNEL_DELAY_MS    100
+
+static const char *TAG = "esp_sha_gdma";
+
+static _lock_t gdma_ch_lock;
+/* For GDMA we allocate and reserve a single DMA pair for sha at esp_sha_init
+   and release it esp_sha_free
+   This is done to avoid the GDMA associated overhead when doing multiple sha transforms in a row.
+
+    The channel is shared between any sha operations that are running in parallel,
+    access will be limited by the peripheral lock
+ */
+static uint8_t ref_counts;
+
+/* The GDMA channel is protected from concurrent access by the general sha peripheral lock */
+static gdma_channel_handle_t tx_channel;
+
+/* Allocate a new GDMA channel, will keep trying until NEW_CHANNEL_TIMEOUT_MS */
+static inline esp_err_t esp_sha_gdma_new_channel(gdma_channel_alloc_config_t *channel_config, gdma_channel_handle_t *channel)
+{
+    esp_err_t ret;
+    int time_waited_ms = 0;
+
+    while(1) {
+        ret = gdma_new_channel(channel_config, channel);
+
+        if (ret == ESP_OK) {
+            break;
+        } else if (time_waited_ms >= 1
+        ) {
+            *channel = NULL;
+            break;
+        }
+
+        time_waited_ms += NEW_CHANNEL_DELAY_MS;
+        vTaskDelay(NEW_CHANNEL_DELAY_MS / portTICK_PERIOD_MS);
+    }
+    return ret;
+}
+
+/* Initialize GDMA module and channels */
+static inline void esp_sha_gdma_init(void)
+{
+    esp_err_t ret;
+
+    gdma_channel_alloc_config_t channel_config = {
+        .direction = GDMA_CHANNEL_DIRECTION_TX,
+    };
+
+    ret = esp_sha_gdma_new_channel(&channel_config, &tx_channel);
+    if (ret != ESP_OK) {
+
+        /* mbedtls_sha_init do not have a way of signaling errors to the caller
+        so we set the channel to NULL and detect it in esp_sha_dma_start */
+        ESP_LOGE(TAG, "Failed to acquire DMA channel, Err=0x%X", ret);
+        tx_channel = NULL;
+        return;
+    }
+
+    gdma_connect(tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SHA, 0));
+}
+
+void esp_sha_dma_init()
+{
+
+    _lock_acquire(&gdma_ch_lock);
+    if (ref_counts == 0) {
+        esp_sha_gdma_init();
+    }
+    ref_counts++;
+    _lock_release(&gdma_ch_lock);
+}
+
+static inline void esp_sha_gdma_free(void)
+{
+    gdma_disconnect(tx_channel);
+    gdma_del_channel(tx_channel);
+    tx_channel = NULL;
+}
+
+void esp_sha_dma_free()
+{
+    _lock_acquire(&gdma_ch_lock);
+    ref_counts--;
+    if (ref_counts == 0) {
+        esp_sha_gdma_free();
+    }
+    _lock_release(&gdma_ch_lock);
+}
+
+
+esp_err_t esp_sha_dma_start(const lldesc_t *input)
+{
+#if SOC_GDMA_SUPPORT_EXTMEM
+    int tx_ch_id = 0;
+#endif //SOC_GDMA_SUPPORT_EXTMEM
+
+    if (!tx_channel) {
+        /* Will happen if no channel was acquired before timeout */
+        return ESP_FAIL;
+    }
+
+#if SOC_GDMA_SUPPORT_EXTMEM
+    gdma_get_channel_id(tx_channel, &tx_ch_id);
+    /* An L2 FIFO bigger than 40 bytes is need when accessing external ram */
+    gdma_ll_tx_extend_fifo_size_to(&GDMA, tx_ch_id, 40);
+    gdma_ll_tx_set_block_size_psram(&GDMA, tx_ch_id, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
+#endif //SOC_GDMA_SUPPORT_EXTMEM
+
+    gdma_start(tx_channel, (intptr_t)input);
+
+    return ESP_OK;
+}

+ 59 - 0
components/mbedtls/port/sha/dma/include/esp_sha_dma_priv.h

@@ -0,0 +1,59 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include "soc/lldesc.h"
+#include "soc/soc_caps.h"
+#include "esp_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if SOC_SHA_GDMA
+
+/**
+ * @brief Initialize the GDMA channel
+ *
+ * @note Allocate and initialize a DMA channel (tx) for the SHA peripheral
+ *       Only one channel will be initialized at any given time. If two or more SHA operations are
+ *       run in parallel the channel will be shared sequentially.
+ *
+ */
+void esp_sha_dma_init(void);
+
+/**
+ * @brief Free the GDMA channel
+ *
+ * @note The channel will only be freed if there are no other SHA operations currently using it
+ *
+ */
+void esp_sha_dma_free(void);
+#endif //SOC_SHA_GDMA
+
+/**
+ * @brief Start the DMA engine
+ *
+ * @param input SHA input descriptor (outlink)
+ * @return
+ *      - ESP_OK: Successfully started the DMA
+ *      - ESP_ERR_INVALID_STATE: No DMA channel available
+ */
+esp_err_t esp_sha_dma_start(const lldesc_t *input);
+
+
+#ifdef __cplusplus
+}
+#endif

+ 10 - 6
components/mbedtls/port/sha/dma/sha.c

@@ -44,6 +44,7 @@
 #include "sha/sha_dma.h"
 #include "hal/sha_hal.h"
 #include "soc/soc_caps.h"
+#include "esp_sha_dma_priv.h"
 
 #if CONFIG_IDF_TARGET_ESP32S2
 #include "esp32s2/rom/cache.h"
@@ -53,7 +54,7 @@
 #include "esp32s3/rom/cache.h"
 #endif
 
-#if SOC_SHA_GENERAL_DMA
+#if SOC_SHA_GDMA
 #define SHA_LOCK() esp_crypto_sha_lock_acquire()
 #define SHA_RELEASE() esp_crypto_sha_lock_release()
 #elif SOC_SHA_CRYPTO_DMA
@@ -110,9 +111,8 @@ void esp_sha_acquire_hardware()
     /* Enable SHA and DMA hardware */
 #if SOC_SHA_CRYPTO_DMA
     periph_module_enable(PERIPH_SHA_DMA_MODULE);
-#elif SOC_SHA_GENERAL_DMA
+#elif SOC_SHA_GDMA
     periph_module_enable(PERIPH_SHA_MODULE);
-    periph_module_enable(PERIPH_GDMA_MODULE);
 #endif
 }
 
@@ -122,9 +122,8 @@ void esp_sha_release_hardware()
     /* Disable SHA and DMA hardware */
 #if SOC_SHA_CRYPTO_DMA
     periph_module_disable(PERIPH_SHA_DMA_MODULE);
-#elif SOC_SHA_GENERAL_DMA
+#elif SOC_SHA_GDMA
     periph_module_disable(PERIPH_SHA_MODULE);
-    periph_module_disable(PERIPH_GDMA_MODULE);
 #endif
 
     SHA_RELEASE();
@@ -306,7 +305,12 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u
         dma_descr_buf.empty = (uint32_t)(&dma_descr_input);
     }
 
-    sha_hal_hash_dma(sha_type, dma_descr_head, num_blks, is_first_block);
+    if (esp_sha_dma_start(dma_descr_head) != ESP_OK) {
+        ESP_LOGE(TAG, "esp_sha_dma_start failed, no DMA channel available");
+        return -1;
+    }
+
+    sha_hal_hash_dma(sha_type, num_blks, is_first_block);
 
     sha_hal_wait_idle();
 

+ 17 - 0
components/mbedtls/test/test_aes.c

@@ -98,6 +98,7 @@ TEST_CASE("mbedtls CBC AES-256 test", "[aes]")
 
     TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
 
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -146,6 +147,7 @@ TEST_CASE("mbedtls CTR AES-256 test", "[aes]")
 
     TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
 
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -193,6 +195,7 @@ TEST_CASE("mbedtls OFB AES-256 test", "[aes]")
 
     TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
 
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -238,6 +241,7 @@ TEST_CASE("mbedtls CFB-8 AES-256 test", "[aes]")
 
     TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
 
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -285,6 +289,7 @@ TEST_CASE("mbedtls CFB-128 AES-256 test", "[aes]")
 
     TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
 
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -378,6 +383,8 @@ TEST_CASE("mbedtls CTR stream test", "[aes]")
         }
         TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
     }
+
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -465,6 +472,8 @@ TEST_CASE("mbedtls OFB stream test", "[aes]")
         }
         TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
     }
+
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -548,6 +557,8 @@ TEST_CASE("mbedtls CFB8 stream test", "[aes]")
         }
         TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
     }
+
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -634,6 +645,7 @@ TEST_CASE("mbedtls CFB128 stream test", "[aes]")
     }
     TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
 
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -697,6 +709,7 @@ TEST_CASE("mbedtls CTR, input buf = output buf", "[aes]")
         TEST_ASSERT_EQUAL_HEX8(0x3A, buf[i]);
     }
 
+    mbedtls_aes_free(&ctx);
     free(buf);
 }
 
@@ -744,6 +757,7 @@ TEST_CASE("mbedtls OFB, chained DMA descriptors", "[aes]")
 
     TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
 
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -805,6 +819,7 @@ void aes_psram_ctr_test(uint32_t input_buf_caps, uint32_t output_buf_caps)
 
     }
 
+    mbedtls_aes_free(&ctx);
     free(plaintext);
     free(chipertext);
     free(decryptedtext);
@@ -850,6 +865,7 @@ void aes_psram_one_buf_ctr_test(void)
         TEST_ASSERT_EACH_EQUAL_HEX8(0x26, buf + i, SZ - i);
 
     }
+    mbedtls_aes_free(&ctx);
     free(buf);
 }
 
@@ -1412,6 +1428,7 @@ void aes_ext_flash_ctr_test(uint32_t output_buf_caps)
 
     TEST_ASSERT_EQUAL_HEX8_ARRAY(long_input, decryptedtext, SZ);
 
+    mbedtls_aes_free(&ctx);
     free(chipertext);
     free(decryptedtext);
 }

+ 1 - 0
components/mbedtls/test/test_aes_perf.c

@@ -57,6 +57,7 @@ TEST_CASE("mbedtls AES performance", "[aes][timeout=60]")
     };
     TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16, 16);
 
+    mbedtls_aes_free(&ctx);
     free(buf);
 
     // bytes/usec = MB/sec

+ 24 - 1
components/mbedtls/test/test_mbedtls_sha.c

@@ -80,6 +80,10 @@ TEST_CASE("mbedtls SHA interleaving", "[mbedtls]")
     TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&sha256_ctx, sha256));
     TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&sha512_ctx, sha512));
 
+    mbedtls_sha1_free(&sha1_ctx);
+    mbedtls_sha256_free(&sha256_ctx);
+    mbedtls_sha512_free(&sha512_ctx);
+
     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 calculation");
     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 calculation");
     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation");
@@ -98,6 +102,7 @@ static void tskRunSHA1Test(void *pvParameters)
             TEST_ASSERT_EQUAL(0, mbedtls_sha1_update_ret(&sha1_ctx, (unsigned char *)one_hundred_as, 100));
         }
         TEST_ASSERT_EQUAL(0, mbedtls_sha1_finish_ret(&sha1_ctx, sha1));
+        mbedtls_sha1_free(&sha1_ctx);
         TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation");
     }
     xSemaphoreGive(done_sem);
@@ -116,7 +121,7 @@ static void tskRunSHA256Test(void *pvParameters)
             TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&sha256_ctx, (unsigned char *)one_hundred_bs, 100));
         }
         TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&sha256_ctx, sha256));
-
+        mbedtls_sha256_free(&sha256_ctx);
         TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_bs, sha256, 32, "SHA256 calculation");
     }
     xSemaphoreGive(done_sem);
@@ -198,16 +203,20 @@ TEST_CASE("mbedtls SHA512 clone", "[mbedtls]")
         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
     }
 
+    mbedtls_sha512_init(&clone);
     mbedtls_sha512_clone(&clone, &ctx);
     for (int i = 0; i < 5; i++) {
         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&clone, one_hundred_bs, 100));
     }
     TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&ctx, sha512));
+    mbedtls_sha512_free(&ctx);
 
     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 original calculation");
 
     TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&clone, sha512));
+    mbedtls_sha512_free(&clone);
+
     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 cloned calculation");
 }
 
@@ -224,6 +233,7 @@ TEST_CASE("mbedtls SHA384 clone", "[mbedtls][")
         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
     }
 
+    mbedtls_sha512_init(&clone);
     mbedtls_sha512_clone(&clone, &ctx);
 
     for (int i = 0; i < 5; i++) {
@@ -231,9 +241,13 @@ TEST_CASE("mbedtls SHA384 clone", "[mbedtls][")
         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&clone, one_hundred_bs, 100));
     }
     TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&ctx, sha384));
+    mbedtls_sha512_free(&ctx);
+
     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 original calculation");
 
     TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&clone, sha384));
+    mbedtls_sha512_free(&clone);
+
     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 cloned calculation");
 }
 
@@ -250,16 +264,20 @@ TEST_CASE("mbedtls SHA256 clone", "[mbedtls]")
         TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&ctx, one_hundred_as, 100));
     }
 
+    mbedtls_sha256_init(&clone);
     mbedtls_sha256_clone(&clone, &ctx);
     for (int i = 0; i < 5; i++) {
         TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&ctx, one_hundred_as, 100));
         TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&clone, one_hundred_as, 100));
     }
     TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&ctx, sha256));
+    mbedtls_sha256_free(&ctx);
 
     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 original calculation");
 
     TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&clone, sha256));
+    mbedtls_sha256_free(&clone);
+
     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 cloned calculation");
 }
 
@@ -279,6 +297,8 @@ static void tskFinaliseSha(void *v_param)
     }
 
     param->ret = mbedtls_sha256_finish_ret(&param->ctx, param->result);
+    mbedtls_sha256_free(&param->ctx);
+
     param->done = true;
     vTaskDelete(NULL);
 }
@@ -364,6 +384,7 @@ TEST_CASE("mbedtls SHA, input in flash", "[mbedtls]")
     TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&sha256_ctx, false));
     TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&sha256_ctx, test_vector, sizeof(test_vector)));
     TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&sha256_ctx, sha256));
+    mbedtls_sha256_free(&sha256_ctx);
 
     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(test_vector_digest, sha256, 32, "SHA256 calculation");
 }
@@ -448,6 +469,8 @@ TEST_CASE("mbedtls SHA512/t", "[mbedtls]")
             }
             TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&sha512_ctx, sha512T_test_buf[j], sha512T_test_buflen[j]));
             TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&sha512_ctx, sha512));
+            mbedtls_sha512_free(&sha512_ctx);
+
             TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_test_sum[k], sha512, sha512T_t_len[i] / 8, "SHA512t calculation");
         }
     }

+ 2 - 4
components/soc/esp32c3/include/soc/soc_caps.h

@@ -13,8 +13,6 @@
 // There are 3 DMA channels on ESP32-C3
 // Attention: These fixed DMA channels are temporarily workaround before we have a centralized DMA controller API to help alloc the channel dynamically
 // Remove them when GDMA driver API is ready
-#define SOC_GDMA_AES_DMA_CHANNEL    (0)
-#define SOC_GDMA_SHA_DMA_CHANNEL    (1)
 #define SOC_GDMA_SPI2_DMA_CHANNEL   (2)
 #define SOC_GDMA_ADC_DMA_CHANNEL    (0)
 
@@ -77,7 +75,7 @@
 #define SOC_SHA_SUPPORT_RESUME          (1)
 
 /* Has a centralized DMA, which is shared with all peripherals */
-#define SOC_SHA_GENERAL_DMA             (1)
+#define SOC_SHA_GDMA             (1)
 
 /* Supported HW algorithms */
 #define SOC_SHA_SUPPORT_SHA1            (1)
@@ -94,7 +92,7 @@
 #define SOC_AES_SUPPORT_DMA     (1)
 
 /* Has a centralized DMA, which is shared with all peripherals */
-#define SOC_AES_GENERAL_DMA     (1)
+#define SOC_AES_GDMA            (1)
 
 #define SOC_AES_SUPPORT_AES_128 (1)
 #define SOC_AES_SUPPORT_AES_256 (1)

+ 2 - 4
components/soc/esp32s3/include/soc/soc_caps.h

@@ -116,7 +116,7 @@
 #define SOC_SHA_SUPPORT_RESUME          (1)
 
 /* Has a centralized DMA, which is shared with all peripherals */
-#define SOC_SHA_GENERAL_DMA             (1)
+#define SOC_SHA_GDMA             (1)
 
 /* Supported HW algorithms */
 #define SOC_SHA_SUPPORT_SHA1            (1)
@@ -151,7 +151,7 @@
 #define SOC_PM_SUPPORT_BT_WAKEUP        (1)
 
 /* Has a centralized DMA, which is shared with all peripherals */
-#define SOC_AES_GENERAL_DMA     (1)
+#define SOC_AES_GDMA            (1)
 
 #define SOC_AES_SUPPORT_AES_128 (1)
 #define SOC_AES_SUPPORT_AES_256 (1)
@@ -160,5 +160,3 @@
 // Remove them when GDMA driver API is ready
 #define SOC_GDMA_SPI2_DMA_CHANNEL (1)
 #define SOC_GDMA_SPI3_DMA_CHANNEL (2)
-#define SOC_GDMA_SHA_DMA_CHANNEL  (3)
-#define SOC_GDMA_AES_DMA_CHANNEL  (4)