From aab3f604ecac78cefc3350df5255e4310c6670ad Mon Sep 17 00:00:00 2001 From: "nilesh.kale" Date: Mon, 16 Oct 2023 17:30:36 +0530 Subject: [PATCH] feat(hal/testapps): Added AES and SHA testcases with DMA support --- components/hal/.build-test-rules.yml | 8 + .../components/mbedtls/include/CMakeLists.txt | 14 + .../crypto/components/mbedtls/include/aes.h | 11 + .../components/mbedtls/include/cipher.h | 6 + .../crypto/components/mbedtls/include/error.h | 6 + .../mbedtls/include/platform_util.h | 11 + .../components/mbedtls/include/sha256.h | 29 + .../hal/test_apps/crypto/main/CMakeLists.txt | 35 +- .../test_apps/crypto/main/Kconfig.projbuild | 8 + .../hal/test_apps/crypto/main/aes/test_aes.c | 521 +++++++++++++++ .../crypto/main/aes/test_aes_block.c | 128 ---- .../test_apps/crypto/main/aes/test_params.h | 2 + .../hal/test_apps/crypto/main/sha/sha_dma.c | 610 ++++++++++++++++++ .../hal/test_apps/crypto/main/sha/sha_dma.h | 49 ++ .../test_apps/crypto/main/sha/test_params.h | 13 +- .../main/sha/{test_sha_block.c => test_sha.c} | 217 +++++-- .../hal/test_apps/crypto/pytest_crypto.py | 16 +- .../crypto/sdkconfig.ci.long_aes_operations | 5 + components/mbedtls/port/aes/dma/esp_aes.c | 1 + .../port/aes/dma/include/esp_aes_dma_priv.h | 2 +- components/mbedtls/port/aes/esp_aes_common.c | 1 - components/mbedtls/port/aes/esp_aes_gcm.c | 2 +- .../mbedtls/port/include/aes/esp_aes_gcm.h | 2 +- 23 files changed, 1516 insertions(+), 181 deletions(-) create mode 100644 components/hal/test_apps/crypto/components/mbedtls/include/CMakeLists.txt create mode 100644 components/hal/test_apps/crypto/components/mbedtls/include/aes.h create mode 100644 components/hal/test_apps/crypto/components/mbedtls/include/cipher.h create mode 100644 components/hal/test_apps/crypto/components/mbedtls/include/error.h create mode 100644 components/hal/test_apps/crypto/components/mbedtls/include/platform_util.h create mode 100644 components/hal/test_apps/crypto/components/mbedtls/include/sha256.h create mode 100644 components/hal/test_apps/crypto/main/aes/test_aes.c delete mode 100644 components/hal/test_apps/crypto/main/aes/test_aes_block.c create mode 100644 components/hal/test_apps/crypto/main/sha/sha_dma.c create mode 100644 components/hal/test_apps/crypto/main/sha/sha_dma.h rename components/hal/test_apps/crypto/main/sha/{test_sha_block.c => test_sha.c} (64%) create mode 100644 components/hal/test_apps/crypto/sdkconfig.ci.long_aes_operations diff --git a/components/hal/.build-test-rules.yml b/components/hal/.build-test-rules.yml index 00c6033be3b5..38b4d9e94b4c 100644 --- a/components/hal/.build-test-rules.yml +++ b/components/hal/.build-test-rules.yml @@ -1,3 +1,11 @@ +components/hal/test_apps/crypto: + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: test not pass, should be re-enable # TODO: IDF-8982 + depends_components: + - efuse + components/hal/test_apps/hal_i2c: disable: - if: SOC_I2C_SUPPORTED != 1 diff --git a/components/hal/test_apps/crypto/components/mbedtls/include/CMakeLists.txt b/components/hal/test_apps/crypto/components/mbedtls/include/CMakeLists.txt new file mode 100644 index 000000000000..a9c693ff0cc5 --- /dev/null +++ b/components/hal/test_apps/crypto/components/mbedtls/include/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# The mbedtls component gets pulled in during the build(due to a dependency of component bootloader_support), +# but we needed to avoid inclusion of mbedtls in this hal layer test app, thus creating a "dummy" mbedtls component. +# This dummy mbedtls component will get the priority during the build stage and thus the "real" mbedtls component +# does not get pulled. +# +idf_build_get_property(idf_target IDF_TARGET) +idf_build_get_property(python PYTHON) + +set(mbedtls_srcs ".") +set(mbedtls_include_dirs include) + +idf_component_register(SRCS "${mbedtls_srcs}" + INCLUDE_DIRS "${mbedtls_include_dirs}") diff --git a/components/hal/test_apps/crypto/components/mbedtls/include/aes.h b/components/hal/test_apps/crypto/components/mbedtls/include/aes.h new file mode 100644 index 000000000000..f8a57fe713d1 --- /dev/null +++ b/components/hal/test_apps/crypto/components/mbedtls/include/aes.h @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -1 +#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -2 +#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -3 + +#define MBEDTLS_AES_ENCRYPT ESP_AES_ENCRYPT +#define MBEDTLS_AES_DECRYPT ESP_AES_DECRYPT diff --git a/components/hal/test_apps/crypto/components/mbedtls/include/cipher.h b/components/hal/test_apps/crypto/components/mbedtls/include/cipher.h new file mode 100644 index 000000000000..0029bcc0d4e5 --- /dev/null +++ b/components/hal/test_apps/crypto/components/mbedtls/include/cipher.h @@ -0,0 +1,6 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +typedef int mbedtls_cipher_id_t; diff --git a/components/hal/test_apps/crypto/components/mbedtls/include/error.h b/components/hal/test_apps/crypto/components/mbedtls/include/error.h new file mode 100644 index 000000000000..9b3cf91ec02a --- /dev/null +++ b/components/hal/test_apps/crypto/components/mbedtls/include/error.h @@ -0,0 +1,6 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -1 diff --git a/components/hal/test_apps/crypto/components/mbedtls/include/platform_util.h b/components/hal/test_apps/crypto/components/mbedtls/include/platform_util.h new file mode 100644 index 000000000000..8a09f3095001 --- /dev/null +++ b/components/hal/test_apps/crypto/components/mbedtls/include/platform_util.h @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include + +static inline void mbedtls_platform_zeroize( void *buf, size_t len ) +{ + bzero(buf, len); +} diff --git a/components/hal/test_apps/crypto/components/mbedtls/include/sha256.h b/components/hal/test_apps/crypto/components/mbedtls/include/sha256.h new file mode 100644 index 000000000000..63f71a8fe04b --- /dev/null +++ b/components/hal/test_apps/crypto/components/mbedtls/include/sha256.h @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include + +typedef void *bootloader_sha256_handle_t; + +bootloader_sha256_handle_t bootloader_sha256_start(void); + +void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len); + +void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest); + +typedef void mbedtls_sha256_context; + +void mbedtls_sha256_init(mbedtls_sha256_context *ctx); + +void mbedtls_sha256_free(mbedtls_sha256_context *ctx); + +int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224); + +int mbedtls_sha256_update(mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen); +int mbedtls_sha256_finish(mbedtls_sha256_context *ctx, + unsigned char *output); diff --git a/components/hal/test_apps/crypto/main/CMakeLists.txt b/components/hal/test_apps/crypto/main/CMakeLists.txt index d782ffb32e75..d2e4647dfd3f 100644 --- a/components/hal/test_apps/crypto/main/CMakeLists.txt +++ b/components/hal/test_apps/crypto/main/CMakeLists.txt @@ -1,4 +1,5 @@ set(srcs "app_main.c") +set(priv_include_dirs ".") if(CONFIG_SOC_MPI_SUPPORTED) list(APPEND srcs "mpi/test_mpi.c") @@ -21,19 +22,41 @@ if(CONFIG_SOC_ECDSA_SUPPORTED) endif() if(CONFIG_SOC_AES_SUPPORTED) - list(APPEND srcs "aes/aes_block.c") - list(APPEND srcs "aes/test_aes_block.c") + list(APPEND srcs "aes/test_aes.c" + "$ENV{IDF_PATH}/components/mbedtls/port/aes/esp_aes_common.c" + "aes/aes_block.c") + list(APPEND priv_include_dirs "$ENV{IDF_PATH}/components/mbedtls/port/include") + + if(CONFIG_SOC_AES_SUPPORT_DMA) + list(APPEND priv_include_dirs "$ENV{IDF_PATH}/components/mbedtls/port/aes/dma/include") + list(APPEND srcs "$ENV{IDF_PATH}/components/mbedtls/port/aes/dma/esp_aes.c") + + if(NOT CONFIG_SOC_AES_GDMA) + list(APPEND srcs "$ENV{IDF_PATH}/components/mbedtls/port/aes/dma/esp_aes_crypto_dma_impl.c") + else() + list(APPEND srcs "$ENV{IDF_PATH}/components/mbedtls/port/aes/dma/esp_aes_gdma_impl.c" + "$ENV{IDF_PATH}/components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c") + endif() + + if(CONFIG_SOC_AES_SUPPORT_GCM) + list(APPEND srcs "$ENV{IDF_PATH}/components/mbedtls/port/aes/esp_aes_gcm.c") + endif() + endif() endif() if(CONFIG_SOC_SHA_SUPPORTED) if(NOT CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG) - list(APPEND srcs "sha/sha_block.c") - list(APPEND srcs "sha/test_sha_block.c") + list(APPEND srcs "sha/test_sha.c" + "sha/sha_block.c") + if(CONFIG_SOC_SHA_SUPPORT_DMA) + list(APPEND srcs "sha/sha_dma.c") + endif() endif() endif() idf_component_register(SRCS ${srcs} - PRIV_REQUIRES efuse + PRIV_REQUIRES efuse mbedtls REQUIRES test_utils unity WHOLE_ARCHIVE - PRIV_INCLUDE_DIRS ".") + PRIV_INCLUDE_DIRS "${priv_include_dirs}" + ) diff --git a/components/hal/test_apps/crypto/main/Kconfig.projbuild b/components/hal/test_apps/crypto/main/Kconfig.projbuild index 6661df5810ae..051c5bae14bc 100644 --- a/components/hal/test_apps/crypto/main/Kconfig.projbuild +++ b/components/hal/test_apps/crypto/main/Kconfig.projbuild @@ -1,3 +1,4 @@ + menu "Test App Configuration" config CRYPTO_TEST_APP_ENABLE_DS_TESTS @@ -19,4 +20,11 @@ menu "Test App Configuration" help Enabling this option includes ECDSA Peripheral related test cases in the build for supported targets. + config CRYPTO_TESTAPP_USE_AES_INTERRUPT + bool "Use interrupt for long AES operations" + depends on SOC_AES_SUPPORTED + default n + help + Use an interrupt to coordinate long AES operations. + endmenu diff --git a/components/hal/test_apps/crypto/main/aes/test_aes.c b/components/hal/test_apps/crypto/main/aes/test_aes.c new file mode 100644 index 000000000000..7b7d185c0fee --- /dev/null +++ b/components/hal/test_apps/crypto/main/aes/test_aes.c @@ -0,0 +1,521 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#include +#include +#include "soc/soc_caps.h" +#include "esp_heap_caps.h" +#include "unity.h" +#include "test_params.h" +#include "memory_checks.h" +#include "unity_fixture.h" +#include "esp_log.h" +#include "aes/esp_aes.h" +#include "aes/esp_aes_gcm.h" + +#if SOC_AES_SUPPORTED + +#include "aes_block.h" + +#define AES_BUFFER_SIZE 1600 +#define AES_LONG_BUFFER_SIZE 8000 + +TEST_GROUP(aes); + +TEST_SETUP(aes) +{ + test_utils_record_free_mem(); + TEST_ESP_OK(test_utils_set_leak_level(400, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); +} + +TEST_TEAR_DOWN(aes) +{ + test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL), + test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL)); +} + +static void test_cbc_aes(bool is_dma, size_t buffer_size, const uint8_t expected_cipher_end[32]) +{ + esp_aes_context ctx; + unsigned int key_bits = 256; + uint8_t nonce[16]; + + esp_aes_init(&ctx); + esp_aes_setkey(&ctx, key_256, key_bits); + + uint8_t *chipertext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(chipertext); + uint8_t *plaintext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(plaintext); + uint8_t *decryptedtext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(decryptedtext); + + memset(plaintext, 0x3A, buffer_size); + memset(decryptedtext, 0x0, buffer_size); + + // Encrypt + memcpy(nonce, iv, 16); +#ifdef SOC_AES_SUPPORT_DMA + if (is_dma) { + esp_aes_crypt_cbc(&ctx, ESP_AES_ENCRYPT, buffer_size, nonce, plaintext, chipertext); + } + else +#endif + { + aes_crypt_cbc_block(ESP_AES_ENCRYPT, key_bits / 8, key_256, buffer_size, nonce, plaintext, chipertext); + } + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, chipertext + buffer_size - 32, 32); + + // Decrypt + memcpy(nonce, iv, 16); +#ifdef SOC_AES_SUPPORT_DMA + if (is_dma) { + esp_aes_crypt_cbc(&ctx, ESP_AES_DECRYPT, buffer_size, nonce, chipertext, decryptedtext); + } + else +#endif + { + aes_crypt_cbc_block(ESP_AES_DECRYPT, key_bits / 8, key_256, buffer_size, nonce, chipertext, decryptedtext); + } + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, buffer_size); + + esp_aes_free(&ctx); + + // Free dynamically allocated memory + heap_caps_free(chipertext); + heap_caps_free(plaintext); + heap_caps_free(decryptedtext); +} + +static void test_ctr_aes(bool is_dma, size_t buffer_size, const uint8_t expected_cipher_end[32]) +{ + + esp_aes_context ctx; + unsigned int key_bits = 256; + uint8_t nonce[16]; + uint8_t stream_block[16]; + size_t nc_off = 0; + + esp_aes_init(&ctx); + esp_aes_setkey(&ctx, key_256, key_bits); + + uint8_t *chipertext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(chipertext); + uint8_t *plaintext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(plaintext); + uint8_t *decryptedtext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(decryptedtext); + + memset(plaintext, 0x3A, buffer_size); + memset(decryptedtext, 0x0, buffer_size); + + // Encrypt + memcpy(nonce, iv, 16); +#ifdef SOC_AES_SUPPORT_DMA + if (is_dma) { + esp_aes_crypt_ctr(&ctx, buffer_size, &nc_off, nonce, stream_block, plaintext, chipertext); + } + else +#endif + { + aes_crypt_ctr_block(key_bits / 8, key_256, buffer_size, &nc_off, nonce, stream_block, plaintext, chipertext); + } + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, chipertext + buffer_size - 32, 32); + + // Decrypt + memcpy(nonce, iv, 16); + nc_off = 0; +#ifdef SOC_AES_SUPPORT_DMA + if (is_dma) { + esp_aes_crypt_ctr(&ctx, buffer_size, &nc_off, nonce, stream_block, chipertext, decryptedtext); + } + else +#endif + { + aes_crypt_ctr_block(key_bits / 8, key_256, buffer_size, &nc_off, nonce, stream_block, chipertext, decryptedtext); + } + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, buffer_size); + + esp_aes_free(&ctx); + + // Free dynamically allocated memory + heap_caps_free(chipertext); + heap_caps_free(plaintext); + heap_caps_free(decryptedtext); +} + +#ifdef SOC_AES_SUPPORT_DMA + +static void test_ofb_aes(size_t buffer_size, const uint8_t expected_cipher_end[32]) +{ + esp_aes_context ctx; + unsigned int key_bits = 256; + uint8_t nonce[16]; + size_t nc_off = 0; + + esp_aes_init(&ctx); + esp_aes_setkey(&ctx, key_256, key_bits); + + uint8_t *chipertext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(chipertext); + uint8_t *plaintext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(plaintext); + uint8_t *decryptedtext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(decryptedtext); + + memset(plaintext, 0x3A, buffer_size); + memset(decryptedtext, 0x0, buffer_size); + + // Encrypt + memcpy(nonce, iv, 16); + esp_aes_crypt_ofb(&ctx, buffer_size, &nc_off, nonce, plaintext, chipertext); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, chipertext + buffer_size - 32, 32); + + // Decrypt + memcpy(nonce, iv, 16); + nc_off = 0; + esp_aes_crypt_ofb(&ctx, buffer_size, &nc_off, nonce, chipertext, decryptedtext); + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, buffer_size); + + esp_aes_free(&ctx); + + // Free dynamically allocated memory + heap_caps_free(chipertext); + heap_caps_free(plaintext); + heap_caps_free(decryptedtext); +} + +static void test_cfb8_aes(size_t buffer_size, const uint8_t expected_cipher_end[32]) +{ + esp_aes_context ctx; + unsigned int key_bits = 256; + uint8_t nonce[16]; + + esp_aes_init(&ctx); + esp_aes_setkey(&ctx, key_256, key_bits); + + uint8_t *chipertext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(chipertext); + uint8_t *plaintext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(plaintext); + uint8_t *decryptedtext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(decryptedtext); + + memset(plaintext, 0x3A, buffer_size); + memset(decryptedtext, 0x0, buffer_size); + + // Encrypt + memcpy(nonce, iv, 16); + esp_aes_crypt_cfb8(&ctx, ESP_AES_ENCRYPT, buffer_size, nonce, plaintext, chipertext); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, chipertext + buffer_size - 32, 32); + + // Decrypt + memcpy(nonce, iv, 16); + esp_aes_crypt_cfb8(&ctx, ESP_AES_DECRYPT, buffer_size, nonce, chipertext, decryptedtext); + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, buffer_size); + + esp_aes_free(&ctx); + + // Free dynamically allocated memory + heap_caps_free(chipertext); + heap_caps_free(plaintext); + heap_caps_free(decryptedtext); +} + +static void test_cfb128_aes(size_t buffer_size, const uint8_t expected_cipher_end[32]) +{ + esp_aes_context ctx; + unsigned int key_bits = 256; + uint8_t nonce[16]; + size_t nc_off = 0; + + esp_aes_init(&ctx); + esp_aes_setkey(&ctx, key_256, key_bits); + + uint8_t *chipertext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(chipertext); + uint8_t *plaintext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(plaintext); + uint8_t *decryptedtext = heap_caps_calloc(buffer_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(decryptedtext); + + memset(plaintext, 0x3A, buffer_size); + memset(decryptedtext, 0x0, buffer_size); + + // Encrypt + memcpy(nonce, iv, 16); + esp_aes_crypt_cfb128(&ctx, ESP_AES_ENCRYPT, buffer_size, &nc_off, nonce, plaintext, chipertext); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, chipertext + buffer_size - 32, 32); + + // Decrypt + nc_off = 0; + memcpy(nonce, iv, 16); + esp_aes_crypt_cfb128(&ctx, ESP_AES_DECRYPT, buffer_size, &nc_off, nonce, chipertext, decryptedtext); + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, buffer_size); + + esp_aes_free(&ctx); + + // Free dynamically allocated memory + heap_caps_free(chipertext); + heap_caps_free(plaintext); + heap_caps_free(decryptedtext); +} + +#if SOC_AES_SUPPORT_GCM +static void test_gcm_aes(size_t length, const uint8_t expected_last_block[16], const uint8_t expected_tag[16]) +{ + uint8_t iv[16]; + uint8_t key[16]; + uint8_t add[30]; + size_t tag_len = 16; + esp_gcm_context ctx; + uint8_t iv_buf[16] = {}; + size_t iv_length = sizeof(iv); + size_t add_length = sizeof(add); + uint8_t tag_buf_encrypt[16] = {}; + + uint8_t *plaintext = heap_caps_malloc(length, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(plaintext); + uint8_t *ciphertext = heap_caps_malloc(length, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(ciphertext); + uint8_t *decryptedtext = heap_caps_malloc(length, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(decryptedtext); + + memset(iv, 0xB1, iv_length); + memset(key, 0x27, sizeof(key)); + memset(add, 0x90, add_length); + memset(plaintext, 0x36, length); + memset(ciphertext, 0, length); + memset(decryptedtext, 0, length); + memcpy(iv_buf, iv, iv_length); + + esp_aes_gcm_init(&ctx); + esp_aes_gcm_setkey(&ctx, 0, key, 8 * sizeof(key)); + + /* Encrypt and authenticate */ + esp_aes_gcm_crypt_and_tag(&ctx, ESP_AES_ENCRYPT, length, iv_buf, iv_length, add, add_length, plaintext, ciphertext, tag_len, tag_buf_encrypt); + size_t offset = length > 16 ? length - 16 : 0; + /* Sanity check: make sure the last ciphertext block matches what we expect to see. */ + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, ciphertext + offset, MIN(16, length)); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_tag, tag_buf_encrypt, tag_len); + + /* Decrypt and authenticate */ + TEST_ASSERT(esp_aes_gcm_auth_decrypt(&ctx, length, iv_buf, iv_length, add, add_length, expected_tag, tag_len, ciphertext, decryptedtext) == 0); + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, length); + + esp_aes_gcm_free(&ctx); + + heap_caps_free(plaintext); + heap_caps_free(ciphertext); + heap_caps_free(decryptedtext); +} +#endif /* SOC_AES_SUPPORT_GCM */ +#endif /* SOC_AES_SUPPORT_DMA */ + +TEST(aes, cbc_aes_256_block_test) +{ + const uint8_t expected_cipher_end[32] = { + 0x3e, 0x68, 0x8a, 0x02, 0xe6, 0xf2, 0x6a, 0x9e, + 0x9b, 0xb2, 0xc0, 0xc4, 0x63, 0x63, 0xd9, 0x25, + 0x51, 0xdc, 0xc2, 0x71, 0x96, 0xb3, 0xe5, 0xcd, + 0xbd, 0x0e, 0xf2, 0xef, 0xa9, 0xab, 0xab, 0x2d, + }; + + test_cbc_aes(0,AES_BUFFER_SIZE, expected_cipher_end); +} + +TEST(aes, ctr_aes_256_block_test) +{ + const uint8_t expected_cipher_end[32] = { + 0xed, 0xa4, 0xa4, 0xe0, 0xee, 0x1d, 0x73, 0x96, + 0xd3, 0xde, 0xaa, 0xe0, 0xb7, 0x76, 0x7f, 0xcb, + 0x0f, 0xe8, 0x64, 0xf0, 0xd3, 0xf1, 0xab, 0x14, + 0x5a, 0x89, 0x47, 0xb4, 0x32, 0xed, 0x41, 0x9c, + }; + + test_ctr_aes(0, AES_BUFFER_SIZE, expected_cipher_end); +} + +#if SOC_AES_SUPPORT_DMA + +TEST(aes, cbc_aes_256_dma_test) +{ + const uint8_t expected_cipher_end[32] = { + 0x3e, 0x68, 0x8a, 0x02, 0xe6, 0xf2, 0x6a, 0x9e, + 0x9b, 0xb2, 0xc0, 0xc4, 0x63, 0x63, 0xd9, 0x25, + 0x51, 0xdc, 0xc2, 0x71, 0x96, 0xb3, 0xe5, 0xcd, + 0xbd, 0x0e, 0xf2, 0xef, 0xa9, 0xab, 0xab, 0x2d, + }; + test_cbc_aes(1, AES_BUFFER_SIZE, expected_cipher_end); +} + +TEST(aes, ctr_aes_256_dma_test) +{ + const uint8_t expected_cipher_end[32] = { + 0xed, 0xa4, 0xa4, 0xe0, 0xee, 0x1d, 0x73, 0x96, + 0xd3, 0xde, 0xaa, 0xe0, 0xb7, 0x76, 0x7f, 0xcb, + 0x0f, 0xe8, 0x64, 0xf0, 0xd3, 0xf1, 0xab, 0x14, + 0x5a, 0x89, 0x47, 0xb4, 0x32, 0xed, 0x41, 0x9c, + }; + test_ctr_aes(1, AES_BUFFER_SIZE, expected_cipher_end); +} + +TEST(aes, ofb_aes_256_dma_test) +{ + const uint8_t expected_cipher_end[] = { + 0x9e, 0x12, 0x10, 0xf0, 0x3f, 0xbf, 0xf8, 0x34, + 0x08, 0x86, 0x7c, 0x02, 0x6b, 0x8a, 0x76, 0xa6, + 0x25, 0x9f, 0x34, 0x61, 0x8b, 0x89, 0x60, 0x16, + 0xe6, 0xa0, 0xa5, 0xb6, 0x5b, 0x0a, 0xeb, 0x1f, + }; + test_ofb_aes(AES_BUFFER_SIZE, expected_cipher_end); +} + +TEST(aes, cfb8_aes_256_dma_test) +{ + const uint8_t expected_cipher_end[] = { + 0x76, 0x95, 0x22, 0x72, 0x3f, 0x44, 0x2d, 0x32, + 0x3e, 0x85, 0xb8, 0xe8, 0xf7, 0x38, 0x04, 0xd6, + 0x4a, 0xc5, 0xdb, 0x2c, 0x46, 0x5f, 0x5b, 0xa2, + 0x24, 0x4a, 0x35, 0xcb, 0xe5, 0x94, 0x71, 0x21, + }; + test_cfb8_aes(AES_BUFFER_SIZE, expected_cipher_end); +} + +TEST(aes, cfb128_aes_256_dma_test) +{ + const uint8_t expected_cipher_end[] = { + 0xd0, 0x9b, 0x2e, 0x25, 0xd5, 0xeb, 0x08, 0xbd, + 0xd8, 0x7e, 0x64, 0xde, 0x35, 0x2b, 0xb1, 0x53, + 0xf8, 0x3a, 0xf7, 0xa8, 0x1e, 0x96, 0xaa, 0xce, + 0xa4, 0xf2, 0x8a, 0x2d, 0x01, 0xd5, 0x62, 0xa0, + }; + test_cfb128_aes(AES_BUFFER_SIZE, expected_cipher_end); +} + +#if CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT + +TEST(aes, cbc_aes_256_long_dma_test) +{ + const uint8_t expected_cipher_end[32] = { + 0xd1, 0x32, 0x62, 0x9d, 0x2f, 0x0e, 0x1d, 0x27, + 0x0e, 0x2b, 0x53, 0x0b, 0x81, 0x53, 0x92, 0x69, + 0x8a, 0x9c, 0x25, 0xb1, 0x77, 0x2b, 0xe4, 0x80, + 0x3a, 0xee, 0xdc, 0xbb, 0x80, 0xd6, 0x1a, 0x42, + }; + test_cbc_aes(1, AES_LONG_BUFFER_SIZE, expected_cipher_end); +} + +TEST(aes, ctr_aes_256_long_dma_test) +{ + const uint8_t expected_cipher_end[32] = { + 0x30, 0x8e, 0x3b, 0x27, 0x54, 0x85, 0x58, 0x20, + 0x1a, 0xa6, 0xca, 0x81, 0x12, 0x23, 0x7f, 0x01, + 0xba, 0x27, 0x72, 0x44, 0xa9, 0x00, 0x42, 0x8a, + 0x4e, 0xda, 0x26, 0xf9, 0xd9, 0x0b, 0xb1, 0xa5, + }; + test_ctr_aes(1, AES_LONG_BUFFER_SIZE, expected_cipher_end); +} + +TEST(aes, ofb_aes_256_long_dma_test) +{ + const uint8_t expected_cipher_end[] = { + 0xdc, 0xd1, 0x8a, 0x5c, 0x38, 0xb4, 0xce, 0xdf, + 0x21, 0xa0, 0xa4, 0x0b, 0x87, 0xbb, 0xdf, 0xf5, + 0x42, 0xc6, 0xe2, 0x1f, 0x9f, 0x93, 0x3b, 0xa4, + 0xdd, 0xb0, 0xce, 0xf0, 0x98, 0x47, 0x23, 0x20, + }; + test_ofb_aes(AES_LONG_BUFFER_SIZE, expected_cipher_end); +} + +TEST(aes, cfb8_aes_256_long_dma_test) +{ + const uint8_t expected_cipher_end[] = { + 0x9a, 0x2a, 0xaf, 0xec, 0xd1, 0xf3, 0xd2, 0xe2, + 0xf5, 0x62, 0x16, 0x5c, 0x42, 0x8f, 0xc1, 0xa3, + 0x34, 0x05, 0x9b, 0xa5, 0x44, 0x02, 0xff, 0xf4, + 0x6b, 0xca, 0x3c, 0xac, 0xff, 0x6e, 0xb6, 0x7a, + }; + test_cfb8_aes(AES_LONG_BUFFER_SIZE, expected_cipher_end); +} + +TEST(aes, cfb128_aes_256_long_dma_test) +{ + const uint8_t expected_cipher_end[] = { + 0x6c, 0x63, 0xa9, 0x19, 0x12, 0x89, 0x57, 0xeb, + 0xbe, 0x73, 0x17, 0x62, 0xc6, 0xfc, 0xf0, 0x43, + 0x6d, 0x49, 0x6b, 0xc6, 0x35, 0xf8, 0xc1, 0x48, + 0xe2, 0xb7, 0xb1, 0x6f, 0x26, 0x9f, 0x04, 0x8b, + }; + test_cfb128_aes(AES_LONG_BUFFER_SIZE, expected_cipher_end); +} + +#endif + +#if SOC_AES_SUPPORT_GCM + +TEST(aes, gcm_aes_dma_test) +{ + size_t length = 16; + const uint8_t expected_last_block[16] = { + 0x37, 0x99, 0x4b, 0x16, 0x5f, 0x8d, 0x27, 0xb1, + 0x60, 0x72, 0x9a, 0x81, 0x8d, 0x3c, 0x69, 0x66}; + + const uint8_t expected_tag[16] = { + 0x45, 0xc2, 0xa8, 0xfe, 0xff, 0x49, 0x1f, 0x45, + 0x8e, 0x29, 0x74, 0x41, 0xed, 0x9b, 0x54, 0x28}; + + test_gcm_aes(length, expected_last_block, expected_tag); +} + +#if CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT + +TEST(aes, gcm_aes_long_dma_test) +{ + size_t length = 5000; + const uint8_t expected_last_block[16] = { + 0xee, 0xfd, 0xab, 0x2a, 0x09, 0x44, 0x41, 0x6a, + 0x91, 0xb0, 0x74, 0x24, 0xee, 0x35, 0xb1, 0x39}; + + const uint8_t expected_tag[16] = { + 0x22, 0xe1, 0x22, 0x34, 0x0c, 0x91, 0x0b, 0xcf, + 0xa3, 0x42, 0xe0, 0x48, 0xe6, 0xfe, 0x2e, 0x28}; + + test_gcm_aes(length, expected_last_block, expected_tag); +} +#endif /* CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT */ +#endif /* SOC_AES_SUPPORT_GCM */ +#endif /* SOC_AES_SUPPORT_DMA */ + +TEST_GROUP_RUNNER(aes) +{ + RUN_TEST_CASE(aes, cbc_aes_256_block_test); + RUN_TEST_CASE(aes, ctr_aes_256_block_test); +#if SOC_AES_SUPPORT_DMA + RUN_TEST_CASE(aes, cbc_aes_256_dma_test); + RUN_TEST_CASE(aes, ctr_aes_256_dma_test); + RUN_TEST_CASE(aes, ofb_aes_256_dma_test); + RUN_TEST_CASE(aes, cfb8_aes_256_dma_test); + RUN_TEST_CASE(aes, cfb128_aes_256_dma_test); +#if CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT + RUN_TEST_CASE(aes, cbc_aes_256_long_dma_test); + RUN_TEST_CASE(aes, ctr_aes_256_long_dma_test); + RUN_TEST_CASE(aes, ofb_aes_256_long_dma_test); + RUN_TEST_CASE(aes, cfb8_aes_256_long_dma_test); + RUN_TEST_CASE(aes, cfb128_aes_256_long_dma_test); +#endif /* CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT */ +#if SOC_AES_SUPPORT_GCM + RUN_TEST_CASE(aes, gcm_aes_dma_test); +#if CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT + RUN_TEST_CASE(aes, gcm_aes_long_dma_test); +#endif /* CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT */ +#endif /* SOC_AES_SUPPORT_GCM */ +#endif /* SOC_AES_SUPPORT_DMA */ +} + +#endif // SOC_AES_SUPPORTED diff --git a/components/hal/test_apps/crypto/main/aes/test_aes_block.c b/components/hal/test_apps/crypto/main/aes/test_aes_block.c deleted file mode 100644 index 271ffd25a201..000000000000 --- a/components/hal/test_apps/crypto/main/aes/test_aes_block.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: CC0-1.0 - */ - -#include -#include -#include -#include "soc/soc_caps.h" -#include "esp_heap_caps.h" -#include "unity.h" -#include "test_params.h" -#include "memory_checks.h" -#include "unity_fixture.h" - - -#define CBC_AES_BUFFER_SIZE 1600 -#define CTR_AES_BUFFER_SIZE 1000 - -#if SOC_AES_SUPPORTED - -#include "aes_block.h" - -TEST_GROUP(aes); - -TEST_SETUP(aes) -{ - test_utils_record_free_mem(); - TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); -} - -TEST_TEAR_DOWN(aes) -{ - test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL), - test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL)); -} - - -TEST(aes, cbc_aes_256_test) -{ - uint8_t key_bytes = 256 / 8; - uint8_t nonce[16]; - - const uint8_t expected_cipher_end[] = { - 0x3e, 0x68, 0x8a, 0x02, 0xe6, 0xf2, 0x6a, 0x9e, - 0x9b, 0xb2, 0xc0, 0xc4, 0x63, 0x63, 0xd9, 0x25, - 0x51, 0xdc, 0xc2, 0x71, 0x96, 0xb3, 0xe5, 0xcd, - 0xbd, 0x0e, 0xf2, 0xef, 0xa9, 0xab, 0xab, 0x2d, - }; - - uint8_t *chipertext = heap_caps_calloc(CBC_AES_BUFFER_SIZE, sizeof(uint8_t), MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(chipertext); - uint8_t *plaintext = heap_caps_calloc(CBC_AES_BUFFER_SIZE, sizeof(uint8_t), MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(plaintext); - uint8_t *decryptedtext = heap_caps_calloc(CBC_AES_BUFFER_SIZE, sizeof(uint8_t), MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(decryptedtext); - - memset(plaintext, 0x3A, CBC_AES_BUFFER_SIZE); - memset(decryptedtext, 0x0, CBC_AES_BUFFER_SIZE); - - // Encrypt - memcpy(nonce, iv, 16); - aes_crypt_cbc_block(ESP_AES_ENCRYPT, key_bytes, key_256, CBC_AES_BUFFER_SIZE, nonce, plaintext, chipertext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, chipertext + CBC_AES_BUFFER_SIZE - 32, 32); - - // Decrypt - memcpy(nonce, iv, 16); - aes_crypt_cbc_block(ESP_AES_DECRYPT, key_bytes, key_256, CBC_AES_BUFFER_SIZE, nonce, chipertext, decryptedtext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, CBC_AES_BUFFER_SIZE); - - // Free dynamically allocated memory - heap_caps_free(chipertext); - heap_caps_free(plaintext); - heap_caps_free(decryptedtext); -} - - -TEST(aes, ctr_aes_256_test) -{ - uint8_t key_bytes = 256 / 8; - uint8_t nonce[16]; - uint8_t stream_block[16]; - size_t nc_off = 0; - - const uint8_t expected_cipher_end[] = { - 0xd4, 0xdc, 0x4f, 0x8f, 0xfe, 0x86, 0xee, 0xb5, - 0x14, 0x7f, 0xba, 0x30, 0x25, 0xa6, 0x7f, 0x6c, - 0xb5, 0x73, 0xaf, 0x90, 0xd7, 0xff, 0x36, 0xba, - 0x2b, 0x1d, 0xec, 0xb9, 0x38, 0xfa, 0x0d, 0xeb, - }; - - uint8_t *chipertext = heap_caps_calloc(CTR_AES_BUFFER_SIZE, sizeof(uint8_t), MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(chipertext); - uint8_t *plaintext = heap_caps_calloc(CTR_AES_BUFFER_SIZE, sizeof(uint8_t), MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(plaintext); - uint8_t *decryptedtext = heap_caps_calloc(CTR_AES_BUFFER_SIZE, sizeof(uint8_t), MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(decryptedtext); - - memset(plaintext, 0x3A, CTR_AES_BUFFER_SIZE); - memset(decryptedtext, 0x0, CTR_AES_BUFFER_SIZE); - - // Encrypt - memcpy(nonce, iv, 16); - aes_crypt_ctr_block(key_bytes, key_256, CTR_AES_BUFFER_SIZE, &nc_off, nonce, stream_block, plaintext, chipertext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, chipertext + CTR_AES_BUFFER_SIZE - 32, 32); - - // Decrypt - nc_off = 0; - memcpy(nonce, iv, 16); - aes_crypt_ctr_block(key_bytes, key_256, CTR_AES_BUFFER_SIZE, &nc_off, nonce, stream_block, chipertext, decryptedtext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, CTR_AES_BUFFER_SIZE); - - // Free dynamically allocated memory - heap_caps_free(chipertext); - heap_caps_free(plaintext); - heap_caps_free(decryptedtext); -} - -#endif // SOC_AES_SUPPORTED - -TEST_GROUP_RUNNER(aes) -{ -#if SOC_AES_SUPPORTED - RUN_TEST_CASE(aes, cbc_aes_256_test); - RUN_TEST_CASE(aes, ctr_aes_256_test); -#endif // SOC_AES_SUPPORTED -} diff --git a/components/hal/test_apps/crypto/main/aes/test_params.h b/components/hal/test_apps/crypto/main/aes/test_params.h index 9296fe71fcbc..38285935b9f0 100644 --- a/components/hal/test_apps/crypto/main/aes/test_params.h +++ b/components/hal/test_apps/crypto/main/aes/test_params.h @@ -12,6 +12,8 @@ #define ESP_AES_ENCRYPT 1 /**< AES encryption. */ #define ESP_AES_DECRYPT 0 /**< AES decryption. */ +#define TEST_AES_MALLOC_CAPS (MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA) + static const uint8_t key_256[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, diff --git a/components/hal/test_apps/crypto/main/sha/sha_dma.c b/components/hal/test_apps/crypto/main/sha/sha_dma.c new file mode 100644 index 000000000000..f6ffe5e72a69 --- /dev/null +++ b/components/hal/test_apps/crypto/main/sha/sha_dma.c @@ -0,0 +1,610 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ +#include +#include +#include +#include "soc/soc_caps.h" + +#include "esp_log.h" +#include "esp_memory_utils.h" +#include "esp_heap_caps.h" +#include "sys/param.h" +#include "soc/lldesc.h" + +#if SOC_SHA_SUPPORTED +#if SOC_SHA_SUPPORT_DMA + +#include "soc/periph_defs.h" +#include "esp_private/periph_ctrl.h" +#include "hal/sha_hal.h" +#include "hal/clk_gate_ll.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) +{ +#if SOC_AES_CRYPTO_DMA + periph_ll_enable_clk_clear_rst(PERIPH_SHA_DMA_MODULE); +#elif SOC_AES_GDMA + periph_ll_enable_clk_clear_rst(PERIPH_SHA_MODULE); +#endif +} + +static void release_hardware(void) +{ +#if SOC_AES_CRYPTO_DMA + periph_ll_disable_clk_set_rst(PERIPH_SHA_DMA_MODULE); +#elif SOC_AES_GDMA + periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); +#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) +{ + if (ctx->sha_state == ESP_SHA_STATE_INIT) { + ctx->first_block = true; + ctx->sha_state = ESP_SHA_STATE_IN_PROCESS; + } else if (ctx->sha_state == ESP_SHA_STATE_IN_PROCESS) { + ctx->first_block = false; + sha_hal_write_digest(sha_type, ctx->state); + } +} + +static void sha1_update_dma(sha1_ctx* ctx, esp_sha_type sha_type, const unsigned char *input, size_t ilen) +{ + size_t fill; + uint32_t left, len, local_len = 0; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if ( ctx->total[0] < (uint32_t) ilen ) { + ctx->total[1]++; + } + + if ( left && ilen >= fill ) { + memcpy( (void *) (ctx->buffer + left), input, fill ); + input += fill; + ilen -= fill; + left = 0; + local_len = 64; + } + + len = (ilen / 64) * 64; + if ( len || local_len) { + /* Enable peripheral module */ + 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(); + return ; + } + + /* Reads the current message digest from the SHA engine */ + sha_hal_read_digest(sha_type, ctx->state); + + /* Disable peripheral module */ + release_hardware(); + } + + if ( ilen > 0 ) { + memcpy( (void *) (ctx->buffer + left), input + len, ilen - len ); + } +} + +void sha1_dma(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output) +{ + + sha1_ctx ctx; + ctx.total[0] = 0; + ctx.total[1] = 0; + + memset(&ctx, 0, sizeof( sha1_ctx ) ); + ctx.mode = SHA1; + + sha1_update_dma(&ctx, sha_type, input, ilen); + + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx.total[0] >> 29 ) + | ( ctx.total[1] << 3 ); + low = ( ctx.total[0] << 3 ); + + PUT_UINT32_BE( high, msglen, 0 ); + PUT_UINT32_BE( low, msglen, 4 ); + + last = ctx.total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha1_update_dma(&ctx, sha_type, sha1_padding, padn); + + sha1_update_dma(&ctx, sha_type, msglen, 8); + + memcpy(output, ctx.state, 20); +} + +#endif /* defined(SOC_SHA_SUPPORT_SHA1) */ + +#if defined(SOC_SHA_SUPPORT_SHA224) || defined(SOC_SHA_SUPPORT_SHA256) + +static void esp_internal_sha256_update_state(sha256_ctx *ctx) +{ + if (ctx->sha_state == ESP_SHA_STATE_INIT) { + ctx->first_block = true; + ctx->sha_state = ESP_SHA_STATE_IN_PROCESS; + } else if (ctx->sha_state == ESP_SHA_STATE_IN_PROCESS) { + ctx->first_block = false; + sha_hal_write_digest(ctx->mode, ctx->state); + } +} + +static void sha256_update_dma(sha256_ctx* ctx, esp_sha_type sha_type, const unsigned char *input, size_t ilen) +{ + size_t fill; + uint32_t left, len, local_len = 0; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if ( ctx->total[0] < (uint32_t) ilen ) { + ctx->total[1]++; + } + + if ( left && ilen >= fill ) { + memcpy( (void *) (ctx->buffer + left), input, fill ); + input += fill; + ilen -= fill; + left = 0; + local_len = 64; + } + + len = (ilen / 64) * 64; + if ( len || local_len) { + /* Enable peripheral module */ + acquire_hardware(); + + esp_internal_sha256_update_state(ctx); + + int ret = esp_sha_dma(ctx->mode, input, len, ctx->buffer, local_len, ctx->first_block); + + if (ret != 0) { + /* Disable peripheral module */ + release_hardware(); + return; + } + + /* Reads the current message digest from the SHA engine */ + sha_hal_read_digest(sha_type, ctx->state); + + /* Disable peripheral module */ + release_hardware(); + } + + if ( ilen > 0 ) { + memcpy( (void *) (ctx->buffer + left), input + len, ilen - len ); + } +} + +void sha256_dma(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output) +{ + + sha256_ctx ctx; + memset(&ctx, 0, sizeof(sha256_ctx)); + ctx.mode = sha_type; + + sha256_update_dma(&ctx, sha_type, input, ilen); + + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx.total[0] >> 29 ) + | ( ctx.total[1] << 3 ); + low = ( ctx.total[0] << 3 ); + + PUT_UINT32_BE( high, msglen, 0 ); + PUT_UINT32_BE( low, msglen, 4 ); + + last = ctx.total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha256_update_dma(&ctx, sha_type, sha256_padding, padn); + + sha256_update_dma(&ctx, sha_type, msglen, 8); + + if (sha_type == SHA2_256) { + memcpy(output, ctx.state, 32); + } else if (sha_type == SHA2_224) { + memcpy(output, ctx.state, 28); + } +} + +#endif /* defined(SOC_SHA_SUPPORT_SHA224) || defined(SOC_SHA_SUPPORT_SHA256) */ + +#if defined(SOC_SHA_SUPPORT_SHA384) || defined(SOC_SHA_SUPPORT_SHA512) + +#if SOC_SHA_SUPPORT_SHA512_T + +int sha_512_t_init_hash_dma(uint16_t t) +{ + uint32_t t_string = 0; + uint8_t t0, t1, t2, t_len; + + if (t == 384) { + return -1; + } + + if (t <= 9) { + t_string = (uint32_t)((1 << 23) | ((0x30 + t) << 24)); + t_len = 0x48; + } else if (t <= 99) { + t0 = t % 10; + t1 = (t / 10) % 10; + t_string = (uint32_t)((1 << 15) | ((0x30 + t0) << 16) | + (((0x30 + t1) << 24))); + t_len = 0x50; + } else if (t <= 512) { + t0 = t % 10; + t1 = (t / 10) % 10; + t2 = t / 100; + t_string = (uint32_t)((1 << 7) | ((0x30 + t0) << 8) | + (((0x30 + t1) << 16) + ((0x30 + t2) << 24))); + t_len = 0x58; + } else { + return -1; + } + + /* Calculates and sets the initial digiest for SHA512_t */ + sha_hal_sha512_init_hash(t_string, t_len); + + return 0; +} + +#endif //SOC_SHA_SUPPORT_SHA512_T + +static void esp_internal_sha512_update_state(sha512_ctx *ctx) +{ + if (ctx->sha_state == ESP_SHA_STATE_INIT) { + if (ctx->mode == SHA2_512T) { + int ret = -1; + if ((ret = sha_512_t_init_hash_dma(ctx->t_val)) != 0) { + release_hardware(); + return; + } + ctx->first_block = false; + } else { + ctx->first_block = true; + } + ctx->sha_state = ESP_SHA_STATE_IN_PROCESS; + } else if (ctx->sha_state == ESP_SHA_STATE_IN_PROCESS) { + ctx->first_block = false; + sha_hal_write_digest(ctx->mode, ctx->state); + } +} + +static void sha512_update_dma(sha512_ctx* ctx, esp_sha_type sha_type, const unsigned char *input, size_t ilen) +{ + + size_t fill; + unsigned int left, len, local_len = 0; + + left = (unsigned int) (ctx->total[0] & 0x7F); + fill = 128 - left; + + ctx->total[0] += (uint64_t) ilen; + + if ( ctx->total[0] < (uint64_t) ilen ) { + ctx->total[1]++; + } + + if ( left && ilen >= fill ) { + memcpy( (void *) (ctx->buffer + left), input, fill ); + input += fill; + ilen -= fill; + left = 0; + local_len = 128; + } + + len = (ilen / 128) * 128; + + if ( len || local_len) { + + /* Enable peripheral module */ + 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(); + return; + } + + /* Reads the current message digest from the SHA engine */ + sha_hal_read_digest(sha_type, ctx->state); + + /* Disable peripheral module */ + release_hardware(); + } + + if ( ilen > 0 ) { + memcpy( (void *) (ctx->buffer + left), input + len, ilen - len ); + } +} + +void sha512_dma(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output) +{ + + sha512_ctx ctx; + memset(&ctx, 0, sizeof(sha512_ctx)); + ctx.mode = sha_type; + + sha512_update_dma(&ctx, sha_type, input, ilen); + + size_t last, padn; + uint64_t high, low; + unsigned char msglen[16]; + + high = ( ctx.total[0] >> 61 ) + | ( ctx.total[1] << 3 ); + low = ( ctx.total[0] << 3 ); + + PUT_UINT64_BE( high, msglen, 0 ); + PUT_UINT64_BE( low, msglen, 8 ); + + last = (size_t)( ctx.total[0] & 0x7F ); + padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); + + sha512_update_dma( &ctx, sha_type, sha512_padding, padn ); + + sha512_update_dma( &ctx, sha_type, msglen, 16 ); + + if (sha_type == SHA2_384) { + memcpy(output, ctx.state, 48); + } else { + memcpy(output, ctx.state, 64); + } + +} + +#endif /* defined(SOC_SHA_SUPPORT_SHA384) || defined(SOC_SHA_SUPPORT_SHA512) */ + +#if SOC_SHA_SUPPORT_SHA512_T + +void sha512t_dma(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output, uint32_t t_val) +{ + sha512_ctx ctx; + memset(&ctx, 0, sizeof(sha512_ctx)); + ctx.t_val = t_val; + ctx.mode = sha_type; + + sha512_update_dma(&ctx, sha_type, input, ilen); + + size_t last, padn; + uint64_t high, low; + unsigned char msglen[16]; + + high = ( ctx.total[0] >> 61 ) + | ( ctx.total[1] << 3 ); + low = ( ctx.total[0] << 3 ); + + PUT_UINT64_BE( high, msglen, 0 ); + PUT_UINT64_BE( low, msglen, 8 ); + + last = (size_t)( ctx.total[0] & 0x7F ); + padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); + + sha512_update_dma( &ctx, sha_type, sha512_padding, padn ); + + sha512_update_dma( &ctx, sha_type, msglen, 16 ); + + if (sha_type == SHA2_384) { + memcpy(output, ctx.state, 48); + } else { + memcpy(output, ctx.state, 64); + } +} + +#endif /*SOC_SHA_SUPPORT_SHA512_T*/ + +#endif /* SOC_SHA_SUPPORT_DMA*/ +#endif /*SOC_SHA_SUPPORTED*/ diff --git a/components/hal/test_apps/crypto/main/sha/sha_dma.h b/components/hal/test_apps/crypto/main/sha/sha_dma.h new file mode 100644 index 000000000000..6622d4d0263f --- /dev/null +++ b/components/hal/test_apps/crypto/main/sha/sha_dma.h @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include + +#if SOC_SHA_SUPPORTED + +#include "soc/periph_defs.h" +#include "esp_private/periph_ctrl.h" +#include "hal/sha_hal.h" +#include "test_params.h" + +#if defined(SOC_SHA_SUPPORT_SHA1) + +void sha1_dma(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output); + +#endif /* defined(SOC_SHA_SUPPORT_SHA1) */ + +#if defined(SOC_SHA_SUPPORT_SHA224) || defined(SOC_SHA_SUPPORT_SHA256) + +void sha256_dma(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output); + +#endif /* defined(SOC_SHA_SUPPORT_SHA224) || defined(SOC_SHA_SUPPORT_SHA256) */ + +#if defined(SOC_SHA_SUPPORT_SHA384) || defined(SOC_SHA_SUPPORT_SHA512) + +#if SOC_SHA_SUPPORT_SHA512_T + +int sha_512_t_init_hash_dma(uint16_t t); + +#endif //SOC_SHA_SUPPORT_SHA512_T + +void sha512_dma(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output); + +#endif /* defined(SOC_SHA_SUPPORT_SHA384) || defined(SOC_SHA_SUPPORT_SHA512) */ + +#if SOC_SHA_SUPPORT_SHA512_T + +void sha512t_dma(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output, uint32_t t_val); + +#endif /*SOC_SHA_SUPPORT_SHA512_T*/ + +#endif /*SOC_SHA_SUPPORTED*/ diff --git a/components/hal/test_apps/crypto/main/sha/test_params.h b/components/hal/test_apps/crypto/main/sha/test_params.h index 99184fe2fcb0..1b1ab9710d6a 100644 --- a/components/hal/test_apps/crypto/main/sha/test_params.h +++ b/components/hal/test_apps/crypto/main/sha/test_params.h @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 * */ - +#pragma once #include "soc/soc_caps.h" #include "hal/sha_types.h" @@ -65,11 +65,18 @@ static const unsigned char sha1_padding[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +typedef enum { + ESP_SHA_STATE_INIT, + ESP_SHA_STATE_IN_PROCESS +} esp_sha_state; + typedef struct { uint32_t total[2]; /*!< number of bytes processed */ uint32_t state[5]; /*!< intermediate digest state */ unsigned char buffer[64]; /*!< data block being processed */ int first_block; /*!< if first then true else false */ + esp_sha_type mode; + esp_sha_state sha_state; } sha1_ctx; #endif /* defined(SOC_SHA_SUPPORT_SHA1) */ @@ -89,6 +96,8 @@ typedef struct { uint32_t state[8]; /*!< intermediate digest state */ unsigned char buffer[64]; /*!< data block being processed */ int first_block; /*!< if first then true, else false */ + esp_sha_type mode; + esp_sha_state sha_state; } sha256_ctx; #endif /* defined(SOC_SHA_SUPPORT_SHA224) || defined(SOC_SHA_SUPPORT_SHA256) */ @@ -112,6 +121,8 @@ typedef struct { unsigned char buffer[128]; /*!< data block being processed */ int first_block; uint32_t t_val; /*!< t_val for 512/t mode */ + esp_sha_type mode; + esp_sha_state sha_state; } sha512_ctx; #if SOC_SHA_SUPPORT_SHA512_T diff --git a/components/hal/test_apps/crypto/main/sha/test_sha_block.c b/components/hal/test_apps/crypto/main/sha/test_sha.c similarity index 64% rename from components/hal/test_apps/crypto/main/sha/test_sha_block.c rename to components/hal/test_apps/crypto/main/sha/test_sha.c index f44316d4741b..ce345590587d 100644 --- a/components/hal/test_apps/crypto/main/sha/test_sha_block.c +++ b/components/hal/test_apps/crypto/main/sha/test_sha.c @@ -10,33 +10,19 @@ #include #include "esp_types.h" #include "soc/soc_caps.h" -#include "esp_heap_caps.h" #include "unity.h" #include "esp_heap_caps.h" #include "memory_checks.h" #include "unity_fixture.h" #include "sha_block.h" +#include "sha_dma.h" #if SOC_SHA_SUPPORTED -TEST_GROUP(sha); - -TEST_SETUP(sha) -{ - test_utils_record_free_mem(); - TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); -} - -TEST_TEAR_DOWN(sha) -{ - test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL), - test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL)); -} - #if SOC_SHA_SUPPORT_SHA1 -TEST(sha, test_sha1) +static void test_sha1(bool is_dma) { uint8_t sha1_result[20] = { 0 }; uint8_t *buffer = heap_caps_calloc(BUFFER_SZ, sizeof(uint8_t), MALLOC_CAP_INTERNAL); @@ -47,17 +33,24 @@ TEST(sha, test_sha1) 0xc5, 0xfa, 0xd5, 0x8f, 0xdb, 0xc3, 0x8d, 0x5c, 0x97, 0xd6, 0x17, 0xee }; - sha1_block(SHA1, buffer, BUFFER_SZ, sha1_result); +#if SOC_SHA_SUPPORT_DMA + if(is_dma) { + sha1_dma(SHA1, buffer, BUFFER_SZ, sha1_result); + } + else +#endif + { + sha1_block(SHA1, buffer, BUFFER_SZ, sha1_result); + } TEST_ASSERT_EQUAL_HEX8_ARRAY(sha1_expected, sha1_result, sizeof(sha1_expected)); heap_caps_free(buffer); } #endif /* SOC_SHA_SUPPORT_SHA1 */ - #if SOC_SHA_SUPPORT_SHA224 -TEST(sha, test_sha224) +static void test_sha224(bool is_dma) { uint8_t sha224_result[28] = { 0 }; uint8_t *buffer = heap_caps_calloc(BUFFER_SZ, sizeof(uint8_t), MALLOC_CAP_INTERNAL); @@ -69,17 +62,24 @@ TEST(sha, test_sha224) 0x4b, 0xfa, 0x5f, 0x2c, 0xa0, 0x72, 0x5f, 0x6b, 0xec, 0xd1, 0x47, 0xf9}; - sha256_block(SHA2_224, buffer, BUFFER_SZ, sha224_result); +#if SOC_SHA_SUPPORT_DMA + if(is_dma) { + sha256_dma(SHA2_224, buffer, BUFFER_SZ, sha224_result); + } + else +#endif + { + sha256_block(SHA2_224, buffer, BUFFER_SZ, sha224_result); + } TEST_ASSERT_EQUAL_HEX8_ARRAY(sha224_expected, sha224_result, sizeof(sha224_expected)); heap_caps_free(buffer); } #endif /* SOC_SHA_SUPPORT_SHA224 */ - #if SOC_SHA_SUPPORT_SHA256 -TEST(sha, test_sha256) +static void test_sha256(bool is_dma) { uint8_t sha256_result[32] = { 0 }; uint8_t *buffer = heap_caps_calloc(BUFFER_SZ, sizeof(uint8_t), MALLOC_CAP_INTERNAL); @@ -91,17 +91,24 @@ TEST(sha, test_sha256) 0xd6, 0x11, 0x2a, 0xec, 0x4c, 0x72, 0x9b, 0x2c, 0xa4, 0xc6, 0x04, 0x80, 0x93, 0x4d, 0xc9, 0x99 }; - sha256_block(SHA2_256, buffer, BUFFER_SZ, sha256_result); +#if SOC_SHA_SUPPORT_DMA + if(is_dma) { + sha256_dma(SHA2_256, buffer, BUFFER_SZ, sha256_result); + } + else +#endif + { + sha256_block(SHA2_256, buffer, BUFFER_SZ, sha256_result); + } TEST_ASSERT_EQUAL_HEX8_ARRAY(sha256_expected, sha256_result, sizeof(sha256_expected)); heap_caps_free(buffer); } -#endif /* SOC_SHA_SUPPORT_SHA256 */ - +#endif /*SOC_SHA_SUPPORT_SHA256 */ #if SOC_SHA_SUPPORT_SHA384 -TEST(sha, test_sha384) +static void test_sha384(bool is_dma) { uint8_t sha384_result[48] = { 0 }; uint8_t *buffer = heap_caps_calloc(BUFFER_SZ, sizeof(uint8_t), MALLOC_CAP_INTERNAL); @@ -115,15 +122,24 @@ TEST(sha, test_sha384) 0xfe, 0xec, 0xd5, 0x38, 0x59, 0x28, 0x93, 0xc7, 0x1c, 0x1a, 0x0b, 0x3b, 0x4e, 0x06, 0x48, 0xa7 }; - sha512_block(SHA2_384, buffer, BUFFER_SZ, sha384_result); +#if SOC_SHA_SUPPORT_DMA + if(is_dma) { + sha512_dma(SHA2_384, buffer, BUFFER_SZ, sha384_result); + } + else +#endif + { + sha512_block(SHA2_384, buffer, BUFFER_SZ, sha384_result); + } TEST_ASSERT_EQUAL_HEX8_ARRAY(sha384_expected, sha384_result, sizeof(sha384_expected)); heap_caps_free(buffer); } + #endif /* SOC_SHA_SUPPORT_SHA384 */ #if SOC_SHA_SUPPORT_SHA512 -TEST(sha, test_sha512) +static void test_sha512(bool is_dma) { uint8_t sha512_result[64] = { 0 }; uint8_t *buffer = heap_caps_calloc(BUFFER_SZ, sizeof(uint8_t), MALLOC_CAP_INTERNAL); @@ -139,17 +155,24 @@ TEST(sha, test_sha512) 0x9d, 0x75, 0xb5, 0x57, 0x74, 0x8d, 0xb9, 0x4b, 0x69, 0x1a, 0x9c, 0x5f, 0x30, 0x61, 0xca, 0x3b }; - - sha512_block(SHA2_512, buffer, BUFFER_SZ, sha512_result); +#if SOC_SHA_SUPPORT_DMA + if(is_dma) { + sha512_dma(SHA2_512, buffer, BUFFER_SZ, sha512_result); + } + else +#endif + { + sha512_block(SHA2_512, buffer, BUFFER_SZ, sha512_result); + } TEST_ASSERT_EQUAL_HEX8_ARRAY(sha512_expected, sha512_result, sizeof(sha512_expected)); heap_caps_free(buffer); } -#endif /* SOC_SHA_SUPPORT_SHA512 */ +#endif /* SOC_SHA_SUPPORT_SHA512 */ #if SOC_SHA_SUPPORT_SHA512_T -TEST(sha, test_sha512t) +static void test_sha512t(bool is_dma) { unsigned char sha512[64], k; @@ -160,13 +183,121 @@ TEST(sha, test_sha512t) k = (i - 2) * 2 + j; } - sha512t_block(sha512T_algo[i], sha512T_test_buf[j], sha512T_test_buflen[j], sha512, sha512T_t_len[i]); - +#if SOC_SHA_SUPPORT_DMA + if(is_dma) { + sha512t_dma(sha512T_algo[i], sha512T_test_buf[j], sha512T_test_buflen[j], sha512, sha512T_t_len[i]); + } + else +#endif + { + sha512t_block(sha512T_algo[i], sha512T_test_buf[j], sha512T_test_buflen[j], sha512, sha512T_t_len[i]); + } TEST_ASSERT_EQUAL_HEX8_ARRAY(sha512_test_sum[k], sha512, sha512T_t_len[i] / 8); } } } +#endif /* SOC_SHA_SUPPORT_SHA512_T */ + + +TEST_GROUP(sha); + +TEST_SETUP(sha) +{ + test_utils_record_free_mem(); + TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); +} + +TEST_TEAR_DOWN(sha) +{ + test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL), + test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL)); +} + +#if SOC_SHA_SUPPORT_SHA1 + +TEST(sha, test_sha1_block) +{ + test_sha1(0); +} + +TEST(sha, test_sha1_dma) +{ + test_sha1(1); +} + +#endif /* SOC_SHA_SUPPORT_SHA1 */ + + +#if SOC_SHA_SUPPORT_SHA224 + +TEST(sha, test_sha224_block) +{ + test_sha224(0); +} + +TEST(sha, test_sha224_dma) +{ + test_sha224(1); +} + +#endif /* SOC_SHA_SUPPORT_SHA224 */ + + +#if SOC_SHA_SUPPORT_SHA256 + +TEST(sha, test_sha256_block) +{ + test_sha256(0); +} + +TEST(sha, test_sha256_dma) +{ + test_sha256(1); +} + +#endif /* SOC_SHA_SUPPORT_SHA256 */ + + +#if SOC_SHA_SUPPORT_SHA384 + +TEST(sha, test_sha384_block) +{ + test_sha384(0); +} + +TEST(sha, test_sha384_dma) +{ + test_sha384(1); +} +#endif /* SOC_SHA_SUPPORT_SHA384 */ + +#if SOC_SHA_SUPPORT_SHA512 + +TEST(sha, test_sha512_block) +{ + test_sha512(0); +} + +TEST(sha, test_sha512_dma) +{ + test_sha512(1); +} +#endif /* SOC_SHA_SUPPORT_SHA512 */ + + +#if SOC_SHA_SUPPORT_SHA512_T + +TEST(sha, test_sha512t_block) +{ + test_sha512t(0); +} + +TEST(sha, test_sha512t_dma) +{ + test_sha512t(1); +} + #endif // SOC_SHA_SUPPORT_SHA512_T #endif // SOC_SHA_SUPPORTED @@ -176,27 +307,33 @@ TEST_GROUP_RUNNER(sha) #if SOC_SHA_SUPPORTED #if SOC_SHA_SUPPORT_SHA1 - RUN_TEST_CASE(sha, test_sha1); + RUN_TEST_CASE(sha, test_sha1_block); + RUN_TEST_CASE(sha, test_sha1_dma); #endif /* SOC_SHA_SUPPORT_SHA1 */ #if SOC_SHA_SUPPORT_SHA224 - RUN_TEST_CASE(sha, test_sha224); + RUN_TEST_CASE(sha, test_sha224_block); + RUN_TEST_CASE(sha, test_sha224_dma); #endif /* SOC_SHA_SUPPORT_SHA224 */ #if SOC_SHA_SUPPORT_SHA256 - RUN_TEST_CASE(sha, test_sha256); + RUN_TEST_CASE(sha, test_sha256_block); + RUN_TEST_CASE(sha, test_sha256_dma); #endif /* SOC_SHA_SUPPORT_SHA256 */ #if SOC_SHA_SUPPORT_SHA384 - RUN_TEST_CASE(sha, test_sha384); + RUN_TEST_CASE(sha, test_sha384_block); + RUN_TEST_CASE(sha, test_sha384_dma); #endif /* SOC_SHA_SUPPORT_SHA384 */ #if SOC_SHA_SUPPORT_SHA512 - RUN_TEST_CASE(sha, test_sha512); + RUN_TEST_CASE(sha, test_sha512_block); + RUN_TEST_CASE(sha, test_sha512_dma); #endif /* SOC_SHA_SUPPORT_SHA512 */ #if SOC_SHA_SUPPORT_SHA512_T - RUN_TEST_CASE(sha, test_sha512t); + RUN_TEST_CASE(sha, test_sha512t_block); + RUN_TEST_CASE(sha, test_sha512t_dma); #endif // SOC_SHA_SUPPORT_SHA512_T #endif /* SOC_SHA_SUPPORTED */ diff --git a/components/hal/test_apps/crypto/pytest_crypto.py b/components/hal/test_apps/crypto/pytest_crypto.py index 7887c65f2b19..447bff843f7f 100644 --- a/components/hal/test_apps/crypto/pytest_crypto.py +++ b/components/hal/test_apps/crypto/pytest_crypto.py @@ -1,12 +1,12 @@ # SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import os import pytest from pytest_embedded import Dut +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8982 @pytest.mark.supported_targets @pytest.mark.generic def test_crypto(dut: Dut) -> None: @@ -14,4 +14,16 @@ def test_crypto(dut: Dut) -> None: # as tests for efuses burning security peripherals would be run timeout = 600 if os.environ.get('IDF_ENV_FPGA') else 60 - dut.expect('main_task: Returned from app_main()', timeout=timeout) + dut.expect('Tests finished', timeout=timeout) + + +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8982 +@pytest.mark.supported_targets +@pytest.mark.generic +@pytest.mark.parametrize('config', ['long_aes_operations'], indirect=True) +def test_crypto_long_aes_operations(dut: Dut) -> None: + # if the env variable IDF_FPGA_ENV is set, we would need a longer timeout + # as tests for efuses burning security peripherals would be run + timeout = 600 if os.environ.get('IDF_ENV_FPGA') else 60 + + dut.expect('Tests finished', timeout=timeout) diff --git a/components/hal/test_apps/crypto/sdkconfig.ci.long_aes_operations b/components/hal/test_apps/crypto/sdkconfig.ci.long_aes_operations new file mode 100644 index 000000000000..0107f9db6461 --- /dev/null +++ b/components/hal/test_apps/crypto/sdkconfig.ci.long_aes_operations @@ -0,0 +1,5 @@ +# +# Example Configuration +# +CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT=y +# end of Example Configuration diff --git a/components/mbedtls/port/aes/dma/esp_aes.c b/components/mbedtls/port/aes/dma/esp_aes.c index c2e4d33e103e..8f0e33c95340 100644 --- a/components/mbedtls/port/aes/dma/esp_aes.c +++ b/components/mbedtls/port/aes/dma/esp_aes.c @@ -28,6 +28,7 @@ #include #include "mbedtls/aes.h" +#include "mbedtls/platform_util.h" #include "esp_intr_alloc.h" #include "esp_private/periph_ctrl.h" #include "esp_log.h" 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 index d8ddac8d2883..c219a9a77ebb 100644 --- a/components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h +++ b/components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/mbedtls/port/aes/esp_aes_common.c b/components/mbedtls/port/aes/esp_aes_common.c index 578ec6656c1b..4bc8b25ceefe 100644 --- a/components/mbedtls/port/aes/esp_aes_common.c +++ b/components/mbedtls/port/aes/esp_aes_common.c @@ -23,7 +23,6 @@ #include "mbedtls/error.h" #include -#include "mbedtls/platform.h" #if SOC_AES_SUPPORT_DMA #include "esp_aes_dma_priv.h" diff --git a/components/mbedtls/port/aes/esp_aes_gcm.c b/components/mbedtls/port/aes/esp_aes_gcm.c index 0ed37cb2768b..646a3547d239 100644 --- a/components/mbedtls/port/aes/esp_aes_gcm.c +++ b/components/mbedtls/port/aes/esp_aes_gcm.c @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2016-2024 Espressif Systems (Shanghai) CO LTD */ /* * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. diff --git a/components/mbedtls/port/include/aes/esp_aes_gcm.h b/components/mbedtls/port/include/aes/esp_aes_gcm.h index 192f251b73ec..79def328cfa5 100644 --- a/components/mbedtls/port/include/aes/esp_aes_gcm.h +++ b/components/mbedtls/port/include/aes/esp_aes_gcm.h @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2016-2024 Espressif Systems (Shanghai) CO LTD */ #pragma once