diff --git a/components/driver/include/esp_private/gdma.h b/components/driver/include/esp_private/gdma.h index ee954bd769..dc27f58269 100644 --- a/components/driver/include/esp_private/gdma.h +++ b/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); diff --git a/components/hal/aes_hal.c b/components/hal/aes_hal.c index fc0da87884..26df0640ca 100644 --- a/components/hal/aes_hal.c +++ b/components/hal/aes_hal.c @@ -20,14 +20,6 @@ #include #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); diff --git a/components/hal/include/hal/aes_hal.h b/components/hal/include/hal/aes_hal.h index 08502df93f..988313899f 100644 --- a/components/hal/include/hal/aes_hal.h +++ b/components/hal/include/hal/aes_hal.h @@ -22,7 +22,6 @@ #include #include -#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 diff --git a/components/hal/include/hal/sha_hal.h b/components/hal/include/hal/sha_hal.h index 6a3cf1be4c..775063a42d 100644 --- a/components/hal/include/hal/sha_hal.h +++ b/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 diff --git a/components/hal/sha_hal.c b/components/hal/sha_hal.c index b42d6533c4..7a4f94d834 100644 --- a/components/hal/sha_hal.c +++ b/components/hal/sha_hal.c @@ -21,13 +21,6 @@ #include #include -#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 */ diff --git a/components/idf_test/include/esp32c3/idf_performance_target.h b/components/idf_test/include/esp32c3/idf_performance_target.h index 21c0fa1e6f..f7d3bba6ad 100644 --- a/components/idf_test/include/esp32c3/idf_performance_target.h +++ b/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 diff --git a/components/idf_test/include/esp32s3/idf_performance_target.h b/components/idf_test/include/esp32s3/idf_performance_target.h index bc29a85e8a..ec8de51a9a 100644 --- a/components/idf_test/include/esp32s3/idf_performance_target.h +++ b/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 diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 75702bb9de..ee95cd8406 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/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) diff --git a/components/mbedtls/port/aes/dma/esp_aes.c b/components/mbedtls/port/aes/dma/esp_aes.c index 1c78c30d4f..67c1bf5f41 100644 --- a/components/mbedtls/port/aes/dma/esp_aes.c +++ b/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); diff --git a/components/mbedtls/port/aes/dma/esp_aes_crypto_dma_impl.c b/components/mbedtls/port/aes/dma/esp_aes_crypto_dma_impl.c new file mode 100644 index 0000000000..df8fd4bf49 --- /dev/null +++ b/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)); +} diff --git a/components/mbedtls/port/aes/dma/esp_aes_gdma_impl.c b/components/mbedtls/port/aes/dma/esp_aes_gdma_impl.c new file mode 100644 index 0000000000..0c25bc4a32 --- /dev/null +++ b/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 + +#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); +} diff --git a/components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h b/components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h new file mode 100644 index 0000000000..7dc1e6a6b0 --- /dev/null +++ b/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 diff --git a/components/mbedtls/port/aes/esp_aes_common.c b/components/mbedtls/port/aes/esp_aes_common.c index c196fa81d6..55b873bac1 100644 --- a/components/mbedtls/port/aes/esp_aes_common.c +++ b/components/mbedtls/port/aes/esp_aes_common.c @@ -35,6 +35,10 @@ #include #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 ) ); } diff --git a/components/mbedtls/port/sha/dma/esp_sha1.c b/components/mbedtls/port/sha/dma/esp_sha1.c index 32b74ba448..5d22de58f6 100644 --- a/components/mbedtls/port/sha/dma/esp_sha1.c +++ b/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 ) ); } diff --git a/components/mbedtls/port/sha/dma/esp_sha256.c b/components/mbedtls/port/sha/dma/esp_sha256.c index 307b338498..3797cd28f3 100644 --- a/components/mbedtls/port/sha/dma/esp_sha256.c +++ b/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 ) ); } diff --git a/components/mbedtls/port/sha/dma/esp_sha512.c b/components/mbedtls/port/sha/dma/esp_sha512.c index fa4465d0f8..950c9298bc 100644 --- a/components/mbedtls/port/sha/dma/esp_sha512.c +++ b/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 ) ); } diff --git a/components/mbedtls/port/sha/dma/esp_sha_crypto_dma_impl.c b/components/mbedtls/port/sha/dma/esp_sha_crypto_dma_impl.c new file mode 100644 index 0000000000..a30803195c --- /dev/null +++ b/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; +} diff --git a/components/mbedtls/port/sha/dma/esp_sha_gdma_impl.c b/components/mbedtls/port/sha/dma/esp_sha_gdma_impl.c new file mode 100644 index 0000000000..31fe219a70 --- /dev/null +++ b/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 + +#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; +} diff --git a/components/mbedtls/port/sha/dma/include/esp_sha_dma_priv.h b/components/mbedtls/port/sha/dma/include/esp_sha_dma_priv.h new file mode 100644 index 0000000000..6909a6f91e --- /dev/null +++ b/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 diff --git a/components/mbedtls/port/sha/dma/sha.c b/components/mbedtls/port/sha/dma/sha.c index b58fc88dd9..e17e6ce232 100644 --- a/components/mbedtls/port/sha/dma/sha.c +++ b/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(); diff --git a/components/mbedtls/test/test_aes.c b/components/mbedtls/test/test_aes.c index f677639e2f..d3d8ed524f 100644 --- a/components/mbedtls/test/test_aes.c +++ b/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); } diff --git a/components/mbedtls/test/test_aes_perf.c b/components/mbedtls/test/test_aes_perf.c index 6224ed7b40..00a6247bf4 100644 --- a/components/mbedtls/test/test_aes_perf.c +++ b/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 diff --git a/components/mbedtls/test/test_mbedtls_sha.c b/components/mbedtls/test/test_mbedtls_sha.c index b49378cb54..190769592a 100644 --- a/components/mbedtls/test/test_mbedtls_sha.c +++ b/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(¶m->ctx, param->result); + mbedtls_sha256_free(¶m->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"); } } diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 8d3295bf46..223257fa0b 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/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) @@ -76,7 +74,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) @@ -93,7 +91,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) diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 51c01861a8..efc89cda3d 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/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) @@ -144,7 +144,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) @@ -153,5 +153,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)