diff --git a/components/hal/test_apps/crypto/main/CMakeLists.txt b/components/hal/test_apps/crypto/main/CMakeLists.txt index 40667b9033..6c1febef20 100644 --- a/components/hal/test_apps/crypto/main/CMakeLists.txt +++ b/components/hal/test_apps/crypto/main/CMakeLists.txt @@ -49,8 +49,20 @@ if(CONFIG_SOC_SHA_SUPPORTED) if(NOT CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG) list(APPEND srcs "sha/test_sha.c" "sha/sha_block.c") + list(APPEND priv_include_dirs "sha/include" + "$ENV{IDF_PATH}/components/mbedtls/port/include") + if(CONFIG_SOC_SHA_SUPPORT_DMA) - list(APPEND srcs "sha/sha_dma.c") + list(APPEND srcs "sha/sha_dma.c" + "$ENV{IDF_PATH}/components/mbedtls/port/sha/dma/sha.c") + list(APPEND priv_include_dirs "$ENV{IDF_PATH}/components/mbedtls/port/sha/dma/include") + + if(NOT CONFIG_SOC_SHA_GDMA) + list(APPEND srcs "$ENV{IDF_PATH}/components/mbedtls/port/sha/dma/esp_sha_crypto_dma_impl.c") + else() + list(APPEND srcs "$ENV{IDF_PATH}/components/mbedtls/port/sha/dma/esp_sha_gdma_impl.c" + "$ENV{IDF_PATH}/components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c") + endif() endif() endif() endif() diff --git a/components/hal/test_apps/crypto/main/sha/sha_block.h b/components/hal/test_apps/crypto/main/sha/include/sha_block.h similarity index 100% rename from components/hal/test_apps/crypto/main/sha/sha_block.h rename to components/hal/test_apps/crypto/main/sha/include/sha_block.h diff --git a/components/hal/test_apps/crypto/main/sha/sha_dma.h b/components/hal/test_apps/crypto/main/sha/include/sha_dma.h similarity index 100% rename from components/hal/test_apps/crypto/main/sha/sha_dma.h rename to components/hal/test_apps/crypto/main/sha/include/sha_dma.h diff --git a/components/hal/test_apps/crypto/main/sha/test_params.h b/components/hal/test_apps/crypto/main/sha/include/test_params.h similarity index 91% rename from components/hal/test_apps/crypto/main/sha/test_params.h rename to components/hal/test_apps/crypto/main/sha/include/test_params.h index 1b1ab9710d..a947440968 100644 --- a/components/hal/test_apps/crypto/main/sha/test_params.h +++ b/components/hal/test_apps/crypto/main/sha/include/test_params.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 * @@ -32,30 +32,6 @@ #define BUFFER_SZ 1030 // NB: not an exact multiple of SHA block size -static inline size_t block_length(esp_sha_type type) -{ - switch (type) { - case SHA1: - case SHA2_224: - case SHA2_256: - return 64; -#if SOC_SHA_SUPPORT_SHA384 - case SHA2_384: -#endif -#if SOC_SHA_SUPPORT_SHA512 - case SHA2_512: -#endif -#if SOC_SHA_SUPPORT_SHA512_T - case SHA2_512224: - case SHA2_512256: - case SHA2_512T: -#endif - return 128; - default: - return 0; - } -} - #if defined(SOC_SHA_SUPPORT_SHA1) static const unsigned char sha1_padding[64] = { diff --git a/components/hal/test_apps/crypto/main/sha/sha_block.c b/components/hal/test_apps/crypto/main/sha/sha_block.c index 63f08a9bba..ed0ebb9d24 100644 --- a/components/hal/test_apps/crypto/main/sha/sha_block.c +++ b/components/hal/test_apps/crypto/main/sha/sha_block.c @@ -17,6 +17,30 @@ #include "hal/sha_ll.h" #include "sha_block.h" +static inline size_t block_length(esp_sha_type type) +{ + switch (type) { + case SHA1: + case SHA2_224: + case SHA2_256: + return 64; +#if SOC_SHA_SUPPORT_SHA384 + case SHA2_384: +#endif +#if SOC_SHA_SUPPORT_SHA512 + case SHA2_512: +#endif +#if SOC_SHA_SUPPORT_SHA512_T + case SHA2_512224: + case SHA2_512256: + case SHA2_512T: +#endif + return 128; + default: + return 0; + } +} + #if defined(SOC_SHA_SUPPORT_SHA1) static void sha1_update_block(sha1_ctx* ctx, esp_sha_type sha_type, const unsigned char *input, size_t ilen) diff --git a/components/hal/test_apps/crypto/main/sha/sha_dma.c b/components/hal/test_apps/crypto/main/sha/sha_dma.c index 507dd5fdc0..f0a335a7ff 100644 --- a/components/hal/test_apps/crypto/main/sha/sha_dma.c +++ b/components/hal/test_apps/crypto/main/sha/sha_dma.c @@ -17,220 +17,9 @@ #if SOC_SHA_SUPPORTED #if SOC_SHA_SUPPORT_DMA -#include "soc/periph_defs.h" -#include "esp_private/periph_ctrl.h" -#include "esp_private/esp_crypto_lock_internal.h" -#include "hal/sha_hal.h" -#include "hal/sha_ll.h" +#include "sha/sha_dma.h" #include "sha_dma.h" -#if CONFIG_SOC_SHA_GDMA -#include "esp_crypto_shared_gdma.h" -#else -#include "soc/crypto_dma_reg.h" -#include "hal/crypto_dma_ll.h" -#endif /* CONFIG_SOC_SHA_GDMA */ - -#ifndef SOC_SHA_DMA_MAX_BUFFER_SIZE -#define SOC_SHA_DMA_MAX_BUFFER_SIZE (3968) -#endif - -const static char* TAG = "sha_dma"; -static bool s_check_dma_capable(const void *p); - -/* These are static due to: - * * Must be in DMA capable memory, so stack is not a safe place to put them - * * To avoid having to malloc/free them for every DMA operation - */ -static DRAM_ATTR lldesc_t s_dma_descr_input; -static DRAM_ATTR lldesc_t s_dma_descr_buf; - -#if CONFIG_SOC_SHA_GDMA - -static esp_err_t esp_sha_dma_start(const lldesc_t *input) -{ - return esp_crypto_shared_gdma_start(input, NULL, GDMA_TRIG_PERIPH_SHA); -} - -#else - -static 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; -} - -#endif - -static void acquire_hardware(void) -{ - SHA_RCC_ATOMIC() { - sha_ll_enable_bus_clock(true); -#if SOC_AES_CRYPTO_DMA - crypto_dma_ll_enable_bus_clock(true); -#endif - sha_ll_reset_register(); -#if SOC_AES_CRYPTO_DMA - crypto_dma_ll_reset_register(); -#endif - } -} - -static void release_hardware(void) -{ - SHA_RCC_ATOMIC() { - sha_ll_enable_bus_clock(false); -#if SOC_AES_CRYPTO_DMA - crypto_dma_ll_enable_bus_clock(false); -#endif - } -} - -static int esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen, - const void *buf, uint32_t buf_len, bool is_first_block); - -/* Performs SHA on multiple blocks at a time using DMA - splits up into smaller operations for inputs that exceed a single DMA list - */ -static int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen, - const void *buf, uint32_t buf_len, bool is_first_block) -{ - int ret = 0; - unsigned char *dma_cap_buf = NULL; - - if (buf_len > block_length(sha_type)) { - ESP_LOGE(TAG, "SHA DMA buf_len cannot exceed max size for a single block"); - return -1; - } - - /* DMA cannot access memory in flash, hash block by block instead of using DMA */ - if (!s_check_dma_capable(input) && (ilen != 0)) { - return 0; - } - -#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE) - if (esp_ptr_external_ram(input)) { - Cache_WriteBack_Addr((uint32_t)input, ilen); - } - if (esp_ptr_external_ram(buf)) { - Cache_WriteBack_Addr((uint32_t)buf, buf_len); - } -#endif - - /* Copy to internal buf if buf is in non DMA capable memory */ - if (!s_check_dma_capable(buf) && (buf_len != 0)) { - dma_cap_buf = heap_caps_malloc(sizeof(unsigned char) * buf_len, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); - if (dma_cap_buf == NULL) { - ESP_LOGE(TAG, "Failed to allocate buf memory"); - ret = -1; - goto cleanup; - } - memcpy(dma_cap_buf, buf, buf_len); - buf = dma_cap_buf; - } - - uint32_t dma_op_num; - - if (ilen > 0) { - /* Number of DMA operations based on maximum chunk size in single operation */ - dma_op_num = (ilen + SOC_SHA_DMA_MAX_BUFFER_SIZE - 1) / SOC_SHA_DMA_MAX_BUFFER_SIZE; - } else { - /* For zero input length, we must allow at-least 1 DMA operation to see - * if there is any pending data that is yet to be copied out */ - dma_op_num = 1; - } - - /* The max amount of blocks in a single hardware operation is 2^6 - 1 = 63 - Thus we only do a single DMA input list + dma buf list, - which is max 3968/64 + 64/64 = 63 blocks */ - for (int i = 0; i < dma_op_num; i++) { - - int dma_chunk_len = MIN(ilen, SOC_SHA_DMA_MAX_BUFFER_SIZE); - - ret = esp_sha_dma_process(sha_type, input, dma_chunk_len, buf, buf_len, is_first_block); - - if (ret != 0) { - goto cleanup; - } - - ilen -= dma_chunk_len; - input = (uint8_t *)input + dma_chunk_len; - - // Only append buf to the first operation - buf_len = 0; - is_first_block = false; - } - -cleanup: - free(dma_cap_buf); - return ret; -} - - -/* Performs SHA on multiple blocks at a time */ -static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen, - const void *buf, uint32_t buf_len, bool is_first_block) -{ - int ret = 0; - lldesc_t *dma_descr_head = NULL; - size_t num_blks = (ilen + buf_len) / block_length(sha_type); - - memset(&s_dma_descr_input, 0, sizeof(lldesc_t)); - memset(&s_dma_descr_buf, 0, sizeof(lldesc_t)); - - /* DMA descriptor for Memory to DMA-SHA transfer */ - if (ilen) { - s_dma_descr_input.length = ilen; - s_dma_descr_input.size = ilen; - s_dma_descr_input.owner = 1; - s_dma_descr_input.eof = 1; - s_dma_descr_input.buf = (uint8_t *)input; - dma_descr_head = &s_dma_descr_input; - } - /* Check after input to overide head if there is any buf*/ - if (buf_len) { - s_dma_descr_buf.length = buf_len; - s_dma_descr_buf.size = buf_len; - s_dma_descr_buf.owner = 1; - s_dma_descr_buf.eof = 1; - s_dma_descr_buf.buf = (uint8_t *)buf; - dma_descr_head = &s_dma_descr_buf; - } - - /* Link DMA lists */ - if (buf_len && ilen) { - s_dma_descr_buf.eof = 0; - s_dma_descr_buf.empty = (uint32_t)(&s_dma_descr_input); - } - - 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(); - - return ret; -} - -static bool s_check_dma_capable(const void *p) -{ - bool is_capable = false; -#if CONFIG_SPIRAM - is_capable |= esp_ptr_dma_ext_capable(p); -#endif - is_capable |= esp_ptr_dma_capable(p); - - return is_capable; -} - #if defined(SOC_SHA_SUPPORT_SHA1) static void esp_internal_sha1_update_state(sha1_ctx *ctx, esp_sha_type sha_type) @@ -270,13 +59,13 @@ static void sha1_update_dma(sha1_ctx* ctx, esp_sha_type sha_type, const unsigned len = (ilen / 64) * 64; if ( len || local_len) { /* Enable peripheral module */ - acquire_hardware(); + esp_sha_acquire_hardware(); esp_internal_sha1_update_state(ctx, sha_type); int ret = esp_sha_dma(sha_type, input, len, ctx->buffer, local_len, ctx->first_block); if (ret != 0) { - release_hardware(); + esp_sha_release_hardware(); return ; } @@ -284,7 +73,7 @@ static void sha1_update_dma(sha1_ctx* ctx, esp_sha_type sha_type, const unsigned sha_hal_read_digest(sha_type, ctx->state); /* Disable peripheral module */ - release_hardware(); + esp_sha_release_hardware(); } if ( ilen > 0 ) { @@ -366,7 +155,7 @@ static void sha256_update_dma(sha256_ctx* ctx, esp_sha_type sha_type, const unsi len = (ilen / 64) * 64; if ( len || local_len) { /* Enable peripheral module */ - acquire_hardware(); + esp_sha_acquire_hardware(); esp_internal_sha256_update_state(ctx); @@ -374,7 +163,7 @@ static void sha256_update_dma(sha256_ctx* ctx, esp_sha_type sha_type, const unsi if (ret != 0) { /* Disable peripheral module */ - release_hardware(); + esp_sha_release_hardware(); return; } @@ -382,7 +171,7 @@ static void sha256_update_dma(sha256_ctx* ctx, esp_sha_type sha_type, const unsi sha_hal_read_digest(sha_type, ctx->state); /* Disable peripheral module */ - release_hardware(); + esp_sha_release_hardware(); } if ( ilen > 0 ) { @@ -473,7 +262,7 @@ static void esp_internal_sha512_update_state(sha512_ctx *ctx) if (ctx->mode == SHA2_512T) { int ret = -1; if ((ret = sha_512_t_init_hash_dma(ctx->t_val)) != 0) { - release_hardware(); + esp_sha_release_hardware(); return; } ctx->first_block = false; @@ -515,14 +304,14 @@ static void sha512_update_dma(sha512_ctx* ctx, esp_sha_type sha_type, const unsi if ( len || local_len) { /* Enable peripheral module */ - acquire_hardware(); + esp_sha_acquire_hardware(); esp_internal_sha512_update_state(ctx); int ret = esp_sha_dma(ctx->mode, input, len, ctx->buffer, local_len, ctx->first_block); if (ret != 0) { - release_hardware(); + esp_sha_release_hardware(); return; } @@ -530,7 +319,7 @@ static void sha512_update_dma(sha512_ctx* ctx, esp_sha_type sha_type, const unsi sha_hal_read_digest(sha_type, ctx->state); /* Disable peripheral module */ - release_hardware(); + esp_sha_release_hardware(); } if ( ilen > 0 ) {