Merge branch 'feature/add_dma_suppport_for_aes_and_sha' into 'master'

feat(hal/testapps): Added AES and SHA testcases with DMA support

Closes IDF-7986 and IDF-7987

See merge request espressif/esp-idf!26497
This commit is contained in:
Mahavir Jain 2024-02-13 16:12:07 +08:00
commit 4d90eedb6e
23 changed files with 1568 additions and 233 deletions

View File

@ -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: components/hal/test_apps/hal_i2c:
disable: disable:
- if: SOC_I2C_SUPPORTED != 1 - if: SOC_I2C_SUPPORTED != 1

View File

@ -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}")

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -0,0 +1,11 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stddef.h>
static inline void mbedtls_platform_zeroize( void *buf, size_t len )
{
bzero(buf, len);
}

View File

@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stddef.h>
#include <stdint.h>
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);

View File

@ -1,4 +1,5 @@
set(srcs "app_main.c") set(srcs "app_main.c")
set(priv_include_dirs ".")
if(CONFIG_SOC_MPI_SUPPORTED) if(CONFIG_SOC_MPI_SUPPORTED)
list(APPEND srcs "mpi/test_mpi.c") list(APPEND srcs "mpi/test_mpi.c")
@ -21,19 +22,41 @@ if(CONFIG_SOC_ECDSA_SUPPORTED)
endif() endif()
if(CONFIG_SOC_AES_SUPPORTED) if(CONFIG_SOC_AES_SUPPORTED)
list(APPEND srcs "aes/aes_block.c") list(APPEND srcs "aes/test_aes.c"
list(APPEND srcs "aes/test_aes_block.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() endif()
if(CONFIG_SOC_SHA_SUPPORTED) if(CONFIG_SOC_SHA_SUPPORTED)
if(NOT CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG) if(NOT CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG)
list(APPEND srcs "sha/sha_block.c") list(APPEND srcs "sha/test_sha.c"
list(APPEND srcs "sha/test_sha_block.c") "sha/sha_block.c")
if(CONFIG_SOC_SHA_SUPPORT_DMA)
list(APPEND srcs "sha/sha_dma.c")
endif()
endif() endif()
endif() endif()
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}
PRIV_REQUIRES efuse PRIV_REQUIRES efuse mbedtls
REQUIRES test_utils unity REQUIRES test_utils unity
WHOLE_ARCHIVE WHOLE_ARCHIVE
PRIV_INCLUDE_DIRS ".") PRIV_INCLUDE_DIRS "${priv_include_dirs}"
)

View File

@ -1,3 +1,4 @@
menu "Test App Configuration" menu "Test App Configuration"
config CRYPTO_TEST_APP_ENABLE_DS_TESTS config CRYPTO_TEST_APP_ENABLE_DS_TESTS
@ -19,4 +20,11 @@ menu "Test App Configuration"
help help
Enabling this option includes ECDSA Peripheral related test cases in the build for supported targets. 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 endmenu

View File

@ -0,0 +1,521 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#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

View File

@ -1,128 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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
}

View File

@ -12,6 +12,8 @@
#define ESP_AES_ENCRYPT 1 /**< AES encryption. */ #define ESP_AES_ENCRYPT 1 /**< AES encryption. */
#define ESP_AES_DECRYPT 0 /**< AES decryption. */ #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[] = { static const uint8_t key_256[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,

View File

@ -0,0 +1,610 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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*/

View File

@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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*/

View File

@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
*/ */
#pragma once
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "hal/sha_types.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 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 { typedef struct {
uint32_t total[2]; /*!< number of bytes processed */ uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */ uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */ unsigned char buffer[64]; /*!< data block being processed */
int first_block; /*!< if first then true else false */ int first_block; /*!< if first then true else false */
esp_sha_type mode;
esp_sha_state sha_state;
} sha1_ctx; } sha1_ctx;
#endif /* defined(SOC_SHA_SUPPORT_SHA1) */ #endif /* defined(SOC_SHA_SUPPORT_SHA1) */
@ -89,6 +96,8 @@ typedef struct {
uint32_t state[8]; /*!< intermediate digest state */ uint32_t state[8]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */ unsigned char buffer[64]; /*!< data block being processed */
int first_block; /*!< if first then true, else false */ int first_block; /*!< if first then true, else false */
esp_sha_type mode;
esp_sha_state sha_state;
} sha256_ctx; } sha256_ctx;
#endif /* defined(SOC_SHA_SUPPORT_SHA224) || defined(SOC_SHA_SUPPORT_SHA256) */ #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 */ unsigned char buffer[128]; /*!< data block being processed */
int first_block; int first_block;
uint32_t t_val; /*!< t_val for 512/t mode */ uint32_t t_val; /*!< t_val for 512/t mode */
esp_sha_type mode;
esp_sha_state sha_state;
} sha512_ctx; } sha512_ctx;
#if SOC_SHA_SUPPORT_SHA512_T #if SOC_SHA_SUPPORT_SHA512_T

View File

@ -10,16 +10,196 @@
#include <inttypes.h> #include <inttypes.h>
#include "esp_types.h" #include "esp_types.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "esp_heap_caps.h"
#include "unity.h" #include "unity.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "memory_checks.h" #include "memory_checks.h"
#include "unity_fixture.h" #include "unity_fixture.h"
#include "sha_block.h" #include "sha_block.h"
#include "sha_dma.h"
#if SOC_SHA_SUPPORTED #if SOC_SHA_SUPPORTED
#if SOC_SHA_SUPPORT_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);
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha1_expected[20] = { 0x09, 0x23, 0x02, 0xfb, 0x2d, 0x36, 0x42, 0xec,
0xc5, 0xfa, 0xd5, 0x8f, 0xdb, 0xc3, 0x8d, 0x5c,
0x97, 0xd6, 0x17, 0xee };
#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
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);
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha224_expected[28] = { 0x69, 0xfd, 0x84, 0x30, 0xd9, 0x4a, 0x44, 0x96,
0x41, 0xc4, 0xab, 0xab, 0x89, 0x53, 0xa9, 0x1f,
0x4b, 0xfa, 0x5f, 0x2c, 0xa0, 0x72, 0x5f, 0x6b,
0xec, 0xd1, 0x47, 0xf9};
#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
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);
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha256_expected[32] = { 0x0c, 0x67, 0x8d, 0x7b, 0x8a, 0x3e, 0x9e, 0xc0,
0xb5, 0x61, 0xaa, 0x51, 0xd8, 0xfd, 0x42, 0x70,
0xd6, 0x11, 0x2a, 0xec, 0x4c, 0x72, 0x9b, 0x2c,
0xa4, 0xc6, 0x04, 0x80, 0x93, 0x4d, 0xc9, 0x99 };
#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 */
#if SOC_SHA_SUPPORT_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);
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha384_expected[48] = { 0xf2, 0x7c, 0x75, 0x16, 0xa9, 0xe6, 0xe5, 0xe2,
0x4d, 0x8b, 0xe4, 0x6b, 0xc5, 0xb3, 0x25, 0xb1,
0x10, 0xc2, 0xb4, 0x7d, 0xb7, 0xe1, 0xee, 0x1c,
0xbd, 0xde, 0x52, 0x9d, 0xaa, 0x31, 0xda, 0x88,
0xfe, 0xec, 0xd5, 0x38, 0x59, 0x28, 0x93, 0xc7,
0x1c, 0x1a, 0x0b, 0x3b, 0x4e, 0x06, 0x48, 0xa7 };
#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
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);
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha512_expected[64] = { 0x7f, 0xca, 0x1c, 0x81, 0xc6, 0xc7, 0x1e, 0x49,
0x1f, 0x4a, 0x35, 0x50, 0xb0, 0x0c, 0xd9, 0xbf,
0x3e, 0xba, 0x90, 0x31, 0x08, 0xc7, 0xb3, 0xf0,
0x58, 0x11, 0xd3, 0x29, 0xee, 0xa0, 0x4f, 0x3b,
0xe4, 0x60, 0xd2, 0xc7, 0x2e, 0x50, 0x39, 0x68,
0xf7, 0x27, 0x2e, 0x71, 0xbc, 0x9f, 0x10, 0xfc,
0x9d, 0x75, 0xb5, 0x57, 0x74, 0x8d, 0xb9, 0x4b,
0x69, 0x1a, 0x9c, 0x5f, 0x30, 0x61, 0xca, 0x3b };
#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 */
#if SOC_SHA_SUPPORT_SHA512_T
static void test_sha512t(bool is_dma)
{
unsigned char sha512[64], k;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 2; j++) {
k = i * 2 + j;
if (i > 1) {
k = (i - 2) * 2 + j;
}
#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_GROUP(sha);
TEST_SETUP(sha) TEST_SETUP(sha)
@ -36,20 +216,14 @@ TEST_TEAR_DOWN(sha)
#if SOC_SHA_SUPPORT_SHA1 #if SOC_SHA_SUPPORT_SHA1
TEST(sha, test_sha1) TEST(sha, test_sha1_block)
{ {
uint8_t sha1_result[20] = { 0 }; test_sha1(0);
uint8_t *buffer = heap_caps_calloc(BUFFER_SZ, sizeof(uint8_t), MALLOC_CAP_INTERNAL); }
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha1_expected[20] = { 0x09, 0x23, 0x02, 0xfb, 0x2d, 0x36, 0x42, 0xec, TEST(sha, test_sha1_dma)
0xc5, 0xfa, 0xd5, 0x8f, 0xdb, 0xc3, 0x8d, 0x5c, {
0x97, 0xd6, 0x17, 0xee }; test_sha1(1);
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 */ #endif /* SOC_SHA_SUPPORT_SHA1 */
@ -57,21 +231,14 @@ TEST(sha, test_sha1)
#if SOC_SHA_SUPPORT_SHA224 #if SOC_SHA_SUPPORT_SHA224
TEST(sha, test_sha224) TEST(sha, test_sha224_block)
{ {
uint8_t sha224_result[28] = { 0 }; test_sha224(0);
uint8_t *buffer = heap_caps_calloc(BUFFER_SZ, sizeof(uint8_t), MALLOC_CAP_INTERNAL); }
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha224_expected[28] = { 0x69, 0xfd, 0x84, 0x30, 0xd9, 0x4a, 0x44, 0x96, TEST(sha, test_sha224_dma)
0x41, 0xc4, 0xab, 0xab, 0x89, 0x53, 0xa9, 0x1f, {
0x4b, 0xfa, 0x5f, 0x2c, 0xa0, 0x72, 0x5f, 0x6b, test_sha224(1);
0xec, 0xd1, 0x47, 0xf9};
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 */ #endif /* SOC_SHA_SUPPORT_SHA224 */
@ -79,21 +246,14 @@ TEST(sha, test_sha224)
#if SOC_SHA_SUPPORT_SHA256 #if SOC_SHA_SUPPORT_SHA256
TEST(sha, test_sha256) TEST(sha, test_sha256_block)
{ {
uint8_t sha256_result[32] = { 0 }; test_sha256(0);
uint8_t *buffer = heap_caps_calloc(BUFFER_SZ, sizeof(uint8_t), MALLOC_CAP_INTERNAL); }
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha256_expected[32] = { 0x0c, 0x67, 0x8d, 0x7b, 0x8a, 0x3e, 0x9e, 0xc0, TEST(sha, test_sha256_dma)
0xb5, 0x61, 0xaa, 0x51, 0xd8, 0xfd, 0x42, 0x70, {
0xd6, 0x11, 0x2a, 0xec, 0x4c, 0x72, 0x9b, 0x2c, test_sha256(1);
0xa4, 0xc6, 0x04, 0x80, 0x93, 0x4d, 0xc9, 0x99 };
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 */
@ -101,70 +261,41 @@ TEST(sha, test_sha256)
#if SOC_SHA_SUPPORT_SHA384 #if SOC_SHA_SUPPORT_SHA384
TEST(sha, test_sha384) TEST(sha, test_sha384_block)
{ {
uint8_t sha384_result[48] = { 0 }; test_sha384(0);
uint8_t *buffer = heap_caps_calloc(BUFFER_SZ, sizeof(uint8_t), MALLOC_CAP_INTERNAL); }
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha384_expected[48] = { 0xf2, 0x7c, 0x75, 0x16, 0xa9, 0xe6, 0xe5, 0xe2, TEST(sha, test_sha384_dma)
0x4d, 0x8b, 0xe4, 0x6b, 0xc5, 0xb3, 0x25, 0xb1, {
0x10, 0xc2, 0xb4, 0x7d, 0xb7, 0xe1, 0xee, 0x1c, test_sha384(1);
0xbd, 0xde, 0x52, 0x9d, 0xaa, 0x31, 0xda, 0x88,
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);
TEST_ASSERT_EQUAL_HEX8_ARRAY(sha384_expected, sha384_result, sizeof(sha384_expected));
heap_caps_free(buffer);
} }
#endif /* SOC_SHA_SUPPORT_SHA384 */ #endif /* SOC_SHA_SUPPORT_SHA384 */
#if SOC_SHA_SUPPORT_SHA512 #if SOC_SHA_SUPPORT_SHA512
TEST(sha, test_sha512) TEST(sha, test_sha512_block)
{ {
uint8_t sha512_result[64] = { 0 }; test_sha512(0);
uint8_t *buffer = heap_caps_calloc(BUFFER_SZ, sizeof(uint8_t), MALLOC_CAP_INTERNAL); }
TEST_ASSERT_NOT_NULL(buffer);
memset(buffer, 0xEE, BUFFER_SZ);
const uint8_t sha512_expected[64] = { 0x7f, 0xca, 0x1c, 0x81, 0xc6, 0xc7, 0x1e, 0x49, TEST(sha, test_sha512_dma)
0x1f, 0x4a, 0x35, 0x50, 0xb0, 0x0c, 0xd9, 0xbf, {
0x3e, 0xba, 0x90, 0x31, 0x08, 0xc7, 0xb3, 0xf0, test_sha512(1);
0x58, 0x11, 0xd3, 0x29, 0xee, 0xa0, 0x4f, 0x3b,
0xe4, 0x60, 0xd2, 0xc7, 0x2e, 0x50, 0x39, 0x68,
0xf7, 0x27, 0x2e, 0x71, 0xbc, 0x9f, 0x10, 0xfc,
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);
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 #if SOC_SHA_SUPPORT_SHA512_T
TEST(sha, test_sha512t) TEST(sha, test_sha512t_block)
{ {
unsigned char sha512[64], k; test_sha512t(0);
}
for (int i = 0; i < 4; i++) { TEST(sha, test_sha512t_dma)
for (int j = 0; j < 2; j++) { {
k = i * 2 + j; test_sha512t(1);
if (i > 1) {
k = (i - 2) * 2 + j;
}
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 #endif // SOC_SHA_SUPPORT_SHA512_T
@ -176,27 +307,33 @@ TEST_GROUP_RUNNER(sha)
#if SOC_SHA_SUPPORTED #if SOC_SHA_SUPPORTED
#if SOC_SHA_SUPPORT_SHA1 #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 */ #endif /* SOC_SHA_SUPPORT_SHA1 */
#if SOC_SHA_SUPPORT_SHA224 #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 */ #endif /* SOC_SHA_SUPPORT_SHA224 */
#if SOC_SHA_SUPPORT_SHA256 #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 */ #endif /* SOC_SHA_SUPPORT_SHA256 */
#if SOC_SHA_SUPPORT_SHA384 #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 */ #endif /* SOC_SHA_SUPPORT_SHA384 */
#if SOC_SHA_SUPPORT_SHA512 #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 */ #endif /* SOC_SHA_SUPPORT_SHA512 */
#if SOC_SHA_SUPPORT_SHA512_T #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_SUPPORT_SHA512_T
#endif /* SOC_SHA_SUPPORTED */ #endif /* SOC_SHA_SUPPORTED */

View File

@ -1,12 +1,12 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
import os import os
import pytest import pytest
from pytest_embedded import Dut 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.supported_targets
@pytest.mark.generic @pytest.mark.generic
def test_crypto(dut: Dut) -> None: 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 # as tests for efuses burning security peripherals would be run
timeout = 600 if os.environ.get('IDF_ENV_FPGA') else 60 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)

View File

@ -0,0 +1,5 @@
#
# Example Configuration
#
CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT=y
# end of Example Configuration

View File

@ -28,6 +28,7 @@
#include <string.h> #include <string.h>
#include "mbedtls/aes.h" #include "mbedtls/aes.h"
#include "mbedtls/platform_util.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_log.h" #include "esp_log.h"

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */

View File

@ -23,7 +23,6 @@
#include "mbedtls/error.h" #include "mbedtls/error.h"
#include <string.h> #include <string.h>
#include "mbedtls/platform.h"
#if SOC_AES_SUPPORT_DMA #if SOC_AES_SUPPORT_DMA
#include "esp_aes_dma_priv.h" #include "esp_aes_dma_priv.h"

View File

@ -6,7 +6,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * 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. * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.

View File

@ -6,7 +6,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * 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 #pragma once