From 8776290f7330ea26fa0af9a1049a4b9a20b61081 Mon Sep 17 00:00:00 2001 From: Konstantin Kondrashov Date: Tue, 6 Nov 2018 13:37:49 +0800 Subject: [PATCH] aes/sha: Bugfix a filling of AES_KEY_BASE and eap_sha function Fixed filling of AES_KEY_BASE. Fixed esp_sha function. --- components/esp32/hwcrypto/aes.c | 5 +- components/esp32/hwcrypto/sha.c | 4 +- components/esp32/test/test_aes_sha_rsa.c | 287 +++++++++++++++++++++++ 3 files changed, 292 insertions(+), 4 deletions(-) create mode 100644 components/esp32/test/test_aes_sha_rsa.c diff --git a/components/esp32/hwcrypto/aes.c b/components/esp32/hwcrypto/aes.c index 716bc636f..125f54337 100644 --- a/components/esp32/hwcrypto/aes.c +++ b/components/esp32/hwcrypto/aes.c @@ -122,7 +122,10 @@ static inline void esp_aes_setkey_hardware( esp_aes_context *ctx, int mode) const uint32_t MODE_DECRYPT_BIT = 4; unsigned mode_reg_base = (mode == ESP_AES_ENCRYPT) ? 0 : MODE_DECRYPT_BIT; - memcpy((uint32_t *)AES_KEY_BASE, ctx->key, ctx->key_bytes); + for (int i = 0; i < ctx->key_bytes/4; ++i) { + DPORT_REG_WRITE(AES_KEY_BASE + i * 4, *(((uint32_t *)ctx->key) + i)); + } + DPORT_REG_WRITE(AES_MODE_REG, mode_reg_base + ((ctx->key_bytes / 8) - 2)); } diff --git a/components/esp32/hwcrypto/sha.c b/components/esp32/hwcrypto/sha.c index 305b476a8..c23580461 100644 --- a/components/esp32/hwcrypto/sha.c +++ b/components/esp32/hwcrypto/sha.c @@ -288,9 +288,9 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns SHA_CTX ctx; ets_sha_init(&ctx); + esp_sha_lock_memory_block(); while(ilen > 0) { size_t chunk_len = (ilen > block_len) ? block_len : ilen; - esp_sha_lock_memory_block(); esp_sha_wait_idle(); DPORT_STALL_OTHER_CPU_START(); { @@ -298,11 +298,9 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns ets_sha_update(&ctx, sha_type, input, chunk_len * 8); } DPORT_STALL_OTHER_CPU_END(); - esp_sha_unlock_memory_block(); input += chunk_len; ilen -= chunk_len; } - esp_sha_lock_memory_block(); esp_sha_wait_idle(); DPORT_STALL_OTHER_CPU_START(); { diff --git a/components/esp32/test/test_aes_sha_rsa.c b/components/esp32/test/test_aes_sha_rsa.c new file mode 100644 index 000000000..75452252c --- /dev/null +++ b/components/esp32/test/test_aes_sha_rsa.c @@ -0,0 +1,287 @@ +#include +#include +#include +#include "esp_types.h" +#include "esp_clk.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/xtensa_timer.h" +#include "soc/cpu.h" +#include "unity.h" +#include "rom/uart.h" +#include "rom/sha.h" +#include "soc/uart_reg.h" +#include "soc/dport_reg.h" +#include "soc/rtc.h" +#include "esp_log.h" +#include "mbedtls/sha256.h" +#include "hwcrypto/sha.h" +#include "hwcrypto/aes.h" +#include "mbedtls/rsa.h" + +static const char *TAG = "test"; +static volatile bool exit_flag = false; +#define TASK_STACK_SIZE (8*1024) + +static void aes_task(void *pvParameters) +{ + xSemaphoreHandle *sema = (xSemaphoreHandle *) pvParameters; + ESP_LOGI(TAG, "aes_task is started"); + esp_aes_context ctx = { + .key_bytes = 16, + .key = {101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116} + }; + const unsigned char input[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + unsigned char output[16]; + unsigned char output2[16]; + while (exit_flag == false) { + memset(output, 0, sizeof(output)); + memset(output, 0, sizeof(output2)); + esp_aes_encrypt(&ctx, input, output); + esp_aes_decrypt(&ctx, output, output2); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(input, output2, sizeof(input), "AES must match"); + } + xSemaphoreGive(*sema); + vTaskDelete(NULL); +} + +static void sha_task(void *pvParameters) +{ + xSemaphoreHandle *sema = (xSemaphoreHandle *) pvParameters; + ESP_LOGI(TAG, "sha_task is started"); + const char *input = "Space!#$%&()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz~DEL0123456789"; + unsigned char output[64]; + unsigned char output_origin[64]; + esp_sha(SHA2_512, (const unsigned char *)input, sizeof(input), output); + memcpy(output_origin, output, sizeof(output)); + while (exit_flag == false) { + memset(output, 0, sizeof(output)); + esp_sha(SHA2_512, (const unsigned char *)input, sizeof(input), output); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(output, output_origin, sizeof(output), "SHA256 must match"); + } + xSemaphoreGive(*sema); + vTaskDelete(NULL); +} + +static void mbedtls_sha256_task(void *pvParameters) +{ + xSemaphoreHandle *sema = (xSemaphoreHandle *) pvParameters; + ESP_LOGI(TAG, "mbedtls_sha256_task is started"); + const char *input = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz~DEL0123456789Space!#$%&()*+,-.0123456789:;<=>?"; + mbedtls_sha256_context sha256_ctx; + unsigned char output[32]; + unsigned char output_origin[32]; + + mbedtls_sha256_init(&sha256_ctx); + memset(output, 0, sizeof(output)); + mbedtls_sha256_starts(&sha256_ctx, false); + for (int i = 0; i < 3; ++i) { + mbedtls_sha256_update(&sha256_ctx, (unsigned char *)input, 100); + } + mbedtls_sha256_finish(&sha256_ctx, output); + memcpy(output_origin, output, sizeof(output)); + + while (exit_flag == false) { + mbedtls_sha256_init(&sha256_ctx); + memset(output, 0, sizeof(output)); + mbedtls_sha256_starts(&sha256_ctx, false); + for (int i = 0; i < 3; ++i) { + mbedtls_sha256_update(&sha256_ctx, (unsigned char *)input, 100); + } + mbedtls_sha256_finish(&sha256_ctx, output); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(output, output_origin, sizeof(output), "MBEDTLS SHA256 must match"); + } + xSemaphoreGive(*sema); + vTaskDelete(NULL); +} + +TEST_CASE("Test shared using AES SHA512 SHA256", "[hw_crypto]") +{ +#ifndef CONFIG_FREERTOS_UNICORE + const int max_tasks = 6; +#else + const int max_tasks = 3; +#endif + xSemaphoreHandle exit_sema[max_tasks]; + + for (int i = 0; i < max_tasks; ++i) { + exit_sema[i] = xSemaphoreCreateBinary(); + } + exit_flag = false; +#ifndef CONFIG_FREERTOS_UNICORE + xTaskCreatePinnedToCore(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 1); + xTaskCreatePinnedToCore(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 0); + xTaskCreatePinnedToCore(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[2], UNITY_FREERTOS_PRIORITY - 1, NULL, 1); + xTaskCreatePinnedToCore(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[3], UNITY_FREERTOS_PRIORITY - 1, NULL, 0); + xTaskCreatePinnedToCore(&mbedtls_sha256_task, "mbedtls_sha256_task", TASK_STACK_SIZE, &exit_sema[4], UNITY_FREERTOS_PRIORITY - 1, NULL, 1); + xTaskCreatePinnedToCore(&mbedtls_sha256_task, "mbedtls_sha256_task", TASK_STACK_SIZE, &exit_sema[5], UNITY_FREERTOS_PRIORITY - 1, NULL, 0); +#else + xTaskCreate(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL); + xTaskCreate(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL); + xTaskCreate(&mbedtls_sha256_task, "mbedtls_sha256_task", TASK_STACK_SIZE, &exit_sema[2], UNITY_FREERTOS_PRIORITY - 1, NULL); +#endif + + ESP_LOGI(TAG, "Waiting for 10s ..."); + vTaskDelay(10000 / portTICK_PERIOD_MS); + + // set exit flag to let thread exit + exit_flag = true; + for (int i = 0; i < max_tasks; ++i) { + if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) { + TEST_FAIL_MESSAGE("exit_sema not released by test task"); + } + vSemaphoreDelete(exit_sema[i]); + } +} + +static void rsa_task(void *pvParameters) +{ + xSemaphoreHandle *sema = (xSemaphoreHandle *) pvParameters; + ESP_LOGI(TAG, "rsa_task is started"); + while (exit_flag == false) { + mbedtls_rsa_self_test(0); + } + xSemaphoreGive(*sema); + vTaskDelete(NULL); +} + +TEST_CASE("Test shared using AES RSA", "[hw_crypto]") +{ +#ifndef CONFIG_FREERTOS_UNICORE + const int max_tasks = 2; +#else + const int max_tasks = 2; +#endif + xSemaphoreHandle exit_sema[max_tasks]; + + for (int i = 0; i < max_tasks; ++i) { + exit_sema[i] = xSemaphoreCreateBinary(); + } + exit_flag = false; +#ifndef CONFIG_FREERTOS_UNICORE + xTaskCreatePinnedToCore(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 1); + xTaskCreatePinnedToCore(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 0); +#else + xTaskCreate(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL); + xTaskCreate(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL); +#endif + + ESP_LOGI(TAG, "Waiting for 10s ..."); + vTaskDelay(10000 / portTICK_PERIOD_MS); + + // set exit flag to let thread exit + exit_flag = true; + for (int i = 0; i < max_tasks; ++i) { + if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) { + TEST_FAIL_MESSAGE("exit_sema not released by test task"); + } + vSemaphoreDelete(exit_sema[i]); + } +} + +TEST_CASE("Test shared using SHA512 RSA", "[hw_crypto]") +{ +#ifndef CONFIG_FREERTOS_UNICORE + const int max_tasks = 2; +#else + const int max_tasks = 2; +#endif + xSemaphoreHandle exit_sema[max_tasks]; + + for (int i = 0; i < max_tasks; ++i) { + exit_sema[i] = xSemaphoreCreateBinary(); + } + exit_flag = false; +#ifndef CONFIG_FREERTOS_UNICORE + xTaskCreatePinnedToCore(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 2, NULL, 1); + xTaskCreatePinnedToCore(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 0); +#else + xTaskCreate(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL); + xTaskCreate(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL); +#endif + + ESP_LOGI(TAG, "Waiting for 10s ..."); + vTaskDelay(10000 / portTICK_PERIOD_MS); + + // set exit flag to let thread exit + exit_flag = true; + for (int i = 0; i < max_tasks; ++i) { + if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) { + TEST_FAIL_MESSAGE("exit_sema not released by test task"); + } + vSemaphoreDelete(exit_sema[i]); + } +} + +TEST_CASE("Test shared using SHA256 RSA", "[hw_crypto]") +{ +#ifndef CONFIG_FREERTOS_UNICORE + const int max_tasks = 2; +#else + const int max_tasks = 2; +#endif + xSemaphoreHandle exit_sema[max_tasks]; + + for (int i = 0; i < max_tasks; ++i) { + exit_sema[i] = xSemaphoreCreateBinary(); + } + exit_flag = false; +#ifndef CONFIG_FREERTOS_UNICORE + xTaskCreatePinnedToCore(&mbedtls_sha256_task, "mbedtls_sha256_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 1); + xTaskCreatePinnedToCore(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 0); +#else + xTaskCreate(&mbedtls_sha256_task, "mbedtls_sha256_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL); + xTaskCreate(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL); +#endif + + ESP_LOGI(TAG, "Waiting for 10s ..."); + vTaskDelay(10000 / portTICK_PERIOD_MS); + + // set exit flag to let thread exit + exit_flag = true; + for (int i = 0; i < max_tasks; ++i) { + if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) { + TEST_FAIL_MESSAGE("exit_sema not released by test task"); + } + vSemaphoreDelete(exit_sema[i]); + } +} + +TEST_CASE("Test shared using AES SHA RSA", "[hw_crypto]") +{ +#ifndef CONFIG_FREERTOS_UNICORE + const int max_tasks = 3; +#else + const int max_tasks = 3; +#endif + xSemaphoreHandle exit_sema[max_tasks]; + + for (int i = 0; i < max_tasks; ++i) { + exit_sema[i] = xSemaphoreCreateBinary(); + } + exit_flag = false; +#ifndef CONFIG_FREERTOS_UNICORE + xTaskCreatePinnedToCore(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 0); + xTaskCreatePinnedToCore(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 0); + xTaskCreatePinnedToCore(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[2], UNITY_FREERTOS_PRIORITY - 1, NULL, 1); +#else + xTaskCreate(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL); + xTaskCreate(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL); + xTaskCreate(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[2], UNITY_FREERTOS_PRIORITY - 1, NULL); +#endif + + ESP_LOGI(TAG, "Waiting for 10s ..."); + vTaskDelay(10000 / portTICK_PERIOD_MS); + + // set exit flag to let thread exit + exit_flag = true; + for (int i = 0; i < max_tasks; ++i) { + if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) { + TEST_FAIL_MESSAGE("exit_sema not released by test task"); + } + vSemaphoreDelete(exit_sema[i]); + } +}