]> granicus.if.org Git - esp-idf/commitdiff
aes/sha/mpi: Bugfix a use of shared registers.
authorKonstantin Kondrashov <konstantin@espressif.com>
Mon, 29 Oct 2018 15:55:02 +0000 (23:55 +0800)
committerbot <bot@espressif.com>
Mon, 5 Nov 2018 04:22:47 +0000 (04:22 +0000)
This commit resolves a blocking in esp_aes_block function.

Introduce:
The problem was in the fact that AES is switched off at the moment when he should give out the processed data. But because of the disabled, the operation can not be completed successfully, there is an infinite hang. The reason for this behavior is that the registers for controlling the inclusion of AES, SHA, MPI have shared registers and they were not protected from sharing.

Fix some related issue with shared using of AES SHA RSA accelerators.

Closes: https://github.com/espressif/esp-idf/issues/2295#issuecomment-432898137
.gitlab-ci.yml
components/driver/periph_ctrl.c
components/esp32/hwcrypto/aes.c
components/esp32/hwcrypto/sha.c
components/esp32/test/test_aes_sha_rsa.c [new file with mode: 0644]
components/mbedtls/port/esp_bignum.c
components/soc/esp32/include/soc/periph_defs.h

index 8605c5393d0ac9b089b6fdc0ceccb7f1fe49d77c..d92ee8f805b76601f3ff7e6088cfce8a458e253b 100644 (file)
@@ -1198,6 +1198,12 @@ UT_001_38:
     - ESP32_IDF
     - UT_T1_1
 
+UT_001_39:
+  <<: *unit_test_template
+  tags:
+    - ESP32_IDF
+    - UT_T1_1
+
 UT_002_01:
   <<: *unit_test_template
   tags:
index 376444a2cadc34436b676376a8dce65c76990795..0b06ed1bc72a031dce14d9828e2a74cc67325e85 100644 (file)
@@ -23,7 +23,7 @@ static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED;
 
 /* Static functions to return register address & mask for clk_en / rst of each peripheral */
 static uint32_t get_clk_en_mask(periph_module_t periph);
-static uint32_t get_rst_en_mask(periph_module_t periph);
+static uint32_t get_rst_en_mask(periph_module_t periph, bool enable);
 static uint32_t get_clk_en_reg(periph_module_t periph);
 static uint32_t get_rst_en_reg(periph_module_t periph);
 
@@ -31,7 +31,7 @@ void periph_module_enable(periph_module_t periph)
 {
     portENTER_CRITICAL(&periph_spinlock);
     DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph), get_clk_en_mask(periph));
-    DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph));
+    DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph, true));
     portEXIT_CRITICAL(&periph_spinlock);
 }
 
@@ -39,15 +39,15 @@ void periph_module_disable(periph_module_t periph)
 {
     portENTER_CRITICAL(&periph_spinlock);
     DPORT_CLEAR_PERI_REG_MASK(get_clk_en_reg(periph), get_clk_en_mask(periph));
-    DPORT_SET_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph));
+    DPORT_SET_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph, false));
     portEXIT_CRITICAL(&periph_spinlock);
 }
 
 void periph_module_reset(periph_module_t periph)
 {
     portENTER_CRITICAL(&periph_spinlock);
-    DPORT_SET_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph));
-    DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph));
+    DPORT_SET_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph, false));
+    DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph, false));
     portEXIT_CRITICAL(&periph_spinlock);
 }
 
@@ -118,12 +118,18 @@ static uint32_t get_clk_en_mask(periph_module_t periph)
             return DPORT_BT_BASEBAND_EN;
         case PERIPH_BT_LC_MODULE:
             return DPORT_BT_LC_EN;
+        case PERIPH_AES_MODULE:
+            return DPORT_PERI_EN_AES;
+        case PERIPH_SHA_MODULE:
+            return DPORT_PERI_EN_SHA;
+        case PERIPH_RSA_MODULE:
+            return DPORT_PERI_EN_RSA;
         default:
             return 0;
     }
 }
 
-static uint32_t get_rst_en_mask(periph_module_t periph)
+static uint32_t get_rst_en_mask(periph_module_t periph, bool enable)
 {
     switch(periph) {
         case PERIPH_RMT_MODULE:
@@ -178,6 +184,30 @@ static uint32_t get_rst_en_mask(periph_module_t periph)
             return DPORT_CAN_RST;
         case PERIPH_EMAC_MODULE:
             return DPORT_EMAC_RST;
+        case PERIPH_AES_MODULE:
+            if (enable == true) {
+                // Clear reset on digital signature & secure boot units, otherwise AES unit is held in reset also.
+                return (DPORT_PERI_EN_AES | DPORT_PERI_EN_DIGITAL_SIGNATURE | DPORT_PERI_EN_SECUREBOOT);
+            } else {
+                //Don't return other units to reset, as this pulls reset on RSA & SHA units, respectively.
+                return DPORT_PERI_EN_AES;
+            }
+        case PERIPH_SHA_MODULE:
+            if (enable == true) {
+                // Clear reset on secure boot, otherwise SHA is held in reset
+                return (DPORT_PERI_EN_SHA | DPORT_PERI_EN_SECUREBOOT);
+            } else {
+                // Don't assert reset on secure boot, otherwise AES is held in reset
+                return DPORT_PERI_EN_SHA;
+            }
+        case PERIPH_RSA_MODULE:
+            if (enable == true) {
+                // Also clear reset on digital signature, otherwise RSA is held in reset
+                return (DPORT_PERI_EN_RSA | DPORT_PERI_EN_DIGITAL_SIGNATURE);
+            } else {
+                // Don't reset digital signature unit, as this resets AES also
+                return DPORT_PERI_EN_RSA;
+            }
         case PERIPH_WIFI_MODULE:
         case PERIPH_BT_MODULE:
         case PERIPH_WIFI_BT_COMMON_MODULE:
@@ -211,12 +241,20 @@ static bool is_wifi_clk_peripheral(periph_module_t periph)
 
 static uint32_t get_clk_en_reg(periph_module_t periph)
 {
-    return is_wifi_clk_peripheral(periph) ? DPORT_WIFI_CLK_EN_REG : DPORT_PERIP_CLK_EN_REG;
+    if (periph == PERIPH_AES_MODULE || periph == PERIPH_SHA_MODULE || periph == PERIPH_RSA_MODULE) {
+        return DPORT_PERI_CLK_EN_REG;
+    } else {
+        return is_wifi_clk_peripheral(periph) ? DPORT_WIFI_CLK_EN_REG : DPORT_PERIP_CLK_EN_REG;
+    }
 }
 
 static uint32_t get_rst_en_reg(periph_module_t periph)
 {
-    return is_wifi_clk_peripheral(periph) ? DPORT_CORE_RST_EN_REG : DPORT_PERIP_RST_EN_REG;
+    if (periph == PERIPH_AES_MODULE || periph == PERIPH_SHA_MODULE || periph == PERIPH_RSA_MODULE) {
+        return DPORT_PERI_RST_EN_REG;
+    } else {
+        return is_wifi_clk_peripheral(periph) ? DPORT_CORE_RST_EN_REG : DPORT_PERIP_RST_EN_REG;
+    }
 }
 
 
index 9c449d821c92f69c97e47a7dceb84c41ab63fe26..ce9a276586d89bc957117bd176c7aa742fa83842 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "soc/cpu.h"
 #include <stdio.h>
+#include "driver/periph_ctrl.h"
 
 
 /* AES uses a spinlock mux not a lock as the underlying block operation
@@ -50,26 +51,16 @@ static portMUX_TYPE aes_spinlock = portMUX_INITIALIZER_UNLOCKED;
 
 void esp_aes_acquire_hardware( void )
 {
-    /* newlib locks lazy initialize on ESP-IDF */
     portENTER_CRITICAL(&aes_spinlock);
 
     /* Enable AES hardware */
-    DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
-    /* Clear reset on digital signature & secure boot units,
-       otherwise AES unit is held in reset also. */
-    DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
-                       DPORT_PERI_EN_AES
-                       | DPORT_PERI_EN_DIGITAL_SIGNATURE
-                       | DPORT_PERI_EN_SECUREBOOT);
+    periph_module_enable(PERIPH_AES_MODULE);
 }
 
 void esp_aes_release_hardware( void )
 {
     /* Disable AES hardware */
-    DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_AES);
-    /* Don't return other units to reset, as this pulls
-       reset on RSA & SHA units, respectively. */
-    DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
+    periph_module_disable(PERIPH_AES_MODULE);
 
     portEXIT_CRITICAL(&aes_spinlock);
 }
@@ -116,7 +107,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));
 }
 
index df0086be5d3a24c1fcb80c613c67f327894efef8..ca3badf3d942c2280fce1f429e84986de2977ce3 100644 (file)
@@ -35,6 +35,7 @@
 #include "rom/ets_sys.h"
 #include "soc/dport_reg.h"
 #include "soc/hwcrypto_reg.h"
+#include "driver/periph_ctrl.h"
 
 inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type) {
     return SHA_1_LOAD_REG + sha_type * 0x10;
@@ -160,11 +161,7 @@ static void esp_sha_lock_engine_inner(sha_engine_state *engine)
 
     if (sha_engines_all_idle()) {
         /* Enable SHA hardware */
-        DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
-        /* also clear reset on secure boot, otherwise SHA is held in reset */
-        DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
-                           DPORT_PERI_EN_SHA
-                           | DPORT_PERI_EN_SECUREBOOT);
+        periph_module_enable(PERIPH_SHA_MODULE);
         DPORT_STALL_OTHER_CPU_START();
         ets_sha_enable();
         DPORT_STALL_OTHER_CPU_END();
@@ -188,9 +185,7 @@ void esp_sha_unlock_engine(esp_sha_type sha_type)
 
     if (sha_engines_all_idle()) {
         /* Disable SHA hardware */
-        /* Don't assert reset on secure boot, otherwise AES is held in reset */
-        DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA);
-        DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
+        periph_module_disable(PERIPH_SHA_MODULE);
     }
 
     _lock_release(&state_change_lock);
@@ -276,9 +271,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();
         {
@@ -286,11 +281,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 (file)
index 0000000..7ee06ac
--- /dev/null
@@ -0,0 +1,287 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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_internal_aes_encrypt(&ctx, input, output);
+        esp_internal_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_ret(&sha256_ctx, false);
+    for (int i = 0; i < 3; ++i) {
+        mbedtls_sha256_update_ret(&sha256_ctx, (unsigned char *)input, 100);
+    }
+    mbedtls_sha256_finish_ret(&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_ret(&sha256_ctx, false);
+        for (int i = 0; i < 3; ++i) {
+            mbedtls_sha256_update_ret(&sha256_ctx, (unsigned char *)input, 100);
+        }
+        mbedtls_sha256_finish_ret(&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]);
+    }
+}
index b8f2cf8bf852054dd8752816ef36736c7a48849d..4dac2b5102aa8f6b3902bc8683a18d7b3ced8590 100644 (file)
@@ -41,6 +41,7 @@
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
 #include "freertos/semphr.h"
+#include "driver/periph_ctrl.h"
 
 /* Some implementation notes:
  *
@@ -91,12 +92,8 @@ void esp_mpi_acquire_hardware( void )
     /* newlib locks lazy initialize on ESP-IDF */
     _lock_acquire(&mpi_lock);
 
-    DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA);
-    /* also clear reset on digital signature, otherwise RSA is held in reset */
-    DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
-                       DPORT_PERI_EN_RSA
-                       | DPORT_PERI_EN_DIGITAL_SIGNATURE);
-
+    /* Enable RSA hardware */
+    periph_module_enable(PERIPH_RSA_MODULE);
     DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
 
     while(DPORT_REG_READ(RSA_CLEAN_REG) != 1);
@@ -111,9 +108,8 @@ void esp_mpi_release_hardware( void )
 {
     DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
 
-    /* don't reset digital signature unit, as this resets AES also */
-    DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_RSA);
-    DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA);
+    /* Disable RSA hardware */
+    periph_module_disable(PERIPH_RSA_MODULE);
 
     _lock_release(&mpi_lock);
 }
index 7aa21fc963e137cb774d35553e8ccbadcb0d7825..c4ad589c9ddf99752368dde81878aeb54a85a631 100644 (file)
@@ -52,6 +52,9 @@ typedef enum {
     PERIPH_WIFI_BT_COMMON_MODULE,
     PERIPH_BT_BASEBAND_MODULE,
     PERIPH_BT_LC_MODULE,
+    PERIPH_AES_MODULE,
+    PERIPH_SHA_MODULE,
+    PERIPH_RSA_MODULE,
 } periph_module_t;
 
 #ifdef __cplusplus