mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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
This commit is contained in:
commit
cfdd7f0f22
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
components/mbedtls/port/aes/dma/esp_aes_crypto_dma_impl.c
Normal file
42
components/mbedtls/port/aes/dma/esp_aes_crypto_dma_impl.c
Normal file
@ -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
components/mbedtls/port/aes/dma/esp_aes_gdma_impl.c
Normal file
168
components/mbedtls/port/aes/dma/esp_aes_gdma_impl.c
Normal file
@ -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
components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h
Normal file
69
components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h
Normal file
@ -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
|
@ -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 ) );
|
||||
}
|
||||
|
||||
|
@ -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 ) );
|
||||
}
|
||||
|
@ -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 ) );
|
||||
}
|
||||
|
||||
|
@ -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
components/mbedtls/port/sha/dma/esp_sha_crypto_dma_impl.c
Normal file
32
components/mbedtls/port/sha/dma/esp_sha_crypto_dma_impl.c
Normal file
@ -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
components/mbedtls/port/sha/dma/esp_sha_gdma_impl.c
Normal file
140
components/mbedtls/port/sha/dma/esp_sha_gdma_impl.c
Normal file
@ -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
components/mbedtls/port/sha/dma/include/esp_sha_dma_priv.h
Normal file
59
components/mbedtls/port/sha/dma/include/esp_sha_dma_priv.h
Normal file
@ -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
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user