1 /*
2  * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sdkconfig.h>
10 
11 #if CONFIG_IDF_TARGET_ESP32
12 
13 #include "esp_types.h"
14 #include "freertos/FreeRTOS.h"
15 #include "freertos/task.h"
16 #include "freertos/semphr.h"
17 #include "freertos/xtensa_timer.h"
18 #include "unity.h"
19 #include "test_utils.h"
20 #include "esp32/rom/sha.h"
21 #include "soc/uart_periph.h"
22 #include "soc/dport_reg.h"
23 #include "soc/rtc.h"
24 #include "esp_log.h"
25 #include "sha/sha_parallel_engine.h"
26 #include "aes/esp_aes.h"
27 #include "mbedtls/rsa.h"
28 #include "mbedtls/sha256.h"
29 
30 static const char *TAG = "test";
31 static volatile bool exit_flag = false;
32 #define TASK_STACK_SIZE (8*1024)
33 
aes_task(void * pvParameters)34 static void aes_task(void *pvParameters)
35 {
36     SemaphoreHandle_t *sema = (SemaphoreHandle_t *) pvParameters;
37     ESP_LOGI(TAG, "aes_task is started");
38     esp_aes_context ctx = {
39             .key_bytes = 16,
40             .key = {101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116}
41     };
42     const unsigned char input[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
43     unsigned char output[16];
44     unsigned char output2[16];
45     while (exit_flag == false) {
46         memset(output, 0, sizeof(output));
47         memset(output, 0, sizeof(output2));
48         esp_internal_aes_encrypt(&ctx, input, output);
49         esp_internal_aes_decrypt(&ctx, output, output2);
50         TEST_ASSERT_EQUAL_MEMORY_MESSAGE(input, output2, sizeof(input), "AES must match");
51     }
52     xSemaphoreGive(*sema);
53     vTaskDelete(NULL);
54 }
55 
sha_task(void * pvParameters)56 static void sha_task(void *pvParameters)
57 {
58     SemaphoreHandle_t *sema = (SemaphoreHandle_t *) pvParameters;
59     ESP_LOGI(TAG, "sha_task is started");
60     const char *input = "Space!#$%&()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz~DEL0123456789";
61     unsigned char output[64];
62     unsigned char output_origin[64];
63     esp_sha(SHA2_512, (const unsigned char *)input, sizeof(input), output);
64     memcpy(output_origin, output, sizeof(output));
65     while (exit_flag == false) {
66         memset(output, 0, sizeof(output));
67         esp_sha(SHA2_512, (const unsigned char *)input, sizeof(input), output);
68         TEST_ASSERT_EQUAL_MEMORY_MESSAGE(output, output_origin, sizeof(output), "SHA256 must match");
69     }
70     xSemaphoreGive(*sema);
71     vTaskDelete(NULL);
72 }
73 
mbedtls_sha256_task(void * pvParameters)74 static void mbedtls_sha256_task(void *pvParameters)
75 {
76     SemaphoreHandle_t *sema = (SemaphoreHandle_t *) pvParameters;
77     ESP_LOGI(TAG, "mbedtls_sha256_task is started");
78     const char *input = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz~DEL0123456789Space!#$%&()*+,-.0123456789:;<=>?";
79     mbedtls_sha256_context sha256_ctx;
80     unsigned char output[32];
81     unsigned char output_origin[32];
82 
83     mbedtls_sha256_init(&sha256_ctx);
84     memset(output, 0, sizeof(output));
85     mbedtls_sha256_starts(&sha256_ctx, false);
86     for (int i = 0; i < 3; ++i) {
87         mbedtls_sha256_update(&sha256_ctx, (unsigned char *)input, 100);
88     }
89     mbedtls_sha256_finish(&sha256_ctx, output);
90     memcpy(output_origin, output, sizeof(output));
91 
92     while (exit_flag == false) {
93         mbedtls_sha256_init(&sha256_ctx);
94         memset(output, 0, sizeof(output));
95         mbedtls_sha256_starts(&sha256_ctx, false);
96         for (int i = 0; i < 3; ++i) {
97             mbedtls_sha256_update(&sha256_ctx, (unsigned char *)input, 100);
98         }
99         mbedtls_sha256_finish(&sha256_ctx, output);
100 
101         TEST_ASSERT_EQUAL_MEMORY_MESSAGE(output, output_origin, sizeof(output), "MBEDTLS SHA256 must match");
102     }
103     xSemaphoreGive(*sema);
104     vTaskDelete(NULL);
105 }
106 
107 TEST_CASE("Test shared using AES SHA512 SHA256", "[hw_crypto]")
108 {
109 #ifndef CONFIG_FREERTOS_UNICORE
110     const int max_tasks = 6;
111 #else
112     const int max_tasks = 3;
113 #endif
114     SemaphoreHandle_t exit_sema[max_tasks];
115 
116     for (int i = 0; i < max_tasks; ++i) {
117         exit_sema[i] = xSemaphoreCreateBinary();
118     }
119     exit_flag = false;
120 #ifndef CONFIG_FREERTOS_UNICORE
121     xTaskCreatePinnedToCore(&aes_task,            "aes_task",            TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
122     xTaskCreatePinnedToCore(&aes_task,            "aes_task",            TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
123     xTaskCreatePinnedToCore(&sha_task,            "sha_task",            TASK_STACK_SIZE, &exit_sema[2], UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
124     xTaskCreatePinnedToCore(&sha_task,            "sha_task",            TASK_STACK_SIZE, &exit_sema[3], UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
125     xTaskCreatePinnedToCore(&mbedtls_sha256_task, "mbedtls_sha256_task", TASK_STACK_SIZE, &exit_sema[4], UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
126     xTaskCreatePinnedToCore(&mbedtls_sha256_task, "mbedtls_sha256_task", TASK_STACK_SIZE, &exit_sema[5], UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
127 #else
128     xTaskCreate(&aes_task,            "aes_task",            TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL);
129     xTaskCreate(&sha_task,            "sha_task",            TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL);
130     xTaskCreate(&mbedtls_sha256_task, "mbedtls_sha256_task", TASK_STACK_SIZE, &exit_sema[2], UNITY_FREERTOS_PRIORITY - 1, NULL);
131 #endif
132 
133     ESP_LOGI(TAG, "Waiting for 10s ...");
134     vTaskDelay(10000 / portTICK_PERIOD_MS);
135 
136     // set exit flag to let thread exit
137     exit_flag = true;
138     for (int i = 0; i < max_tasks; ++i) {
139         if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) {
140             TEST_FAIL_MESSAGE("exit_sema not released by test task");
141         }
142         vSemaphoreDelete(exit_sema[i]);
143     }
144 }
145 
rsa_task(void * pvParameters)146 static void rsa_task(void *pvParameters)
147 {
148     SemaphoreHandle_t *sema = (SemaphoreHandle_t *) pvParameters;
149     ESP_LOGI(TAG, "rsa_task is started");
150     while (exit_flag == false) {
151         mbedtls_rsa_self_test(0);
152     }
153     xSemaphoreGive(*sema);
154     vTaskDelete(NULL);
155 }
156 
157 TEST_CASE("Test shared using AES RSA", "[hw_crypto]")
158 {
159 #ifndef CONFIG_FREERTOS_UNICORE
160     const int max_tasks = 2;
161 #else
162     const int max_tasks = 2;
163 #endif
164     SemaphoreHandle_t exit_sema[max_tasks];
165 
166     for (int i = 0; i < max_tasks; ++i) {
167         exit_sema[i] = xSemaphoreCreateBinary();
168     }
169     exit_flag = false;
170 #ifndef CONFIG_FREERTOS_UNICORE
171     xTaskCreatePinnedToCore(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
172     xTaskCreatePinnedToCore(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
173 #else
174     xTaskCreate(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL);
175     xTaskCreate(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL);
176 #endif
177 
178     ESP_LOGI(TAG, "Waiting for 10s ...");
179     vTaskDelay(10000 / portTICK_PERIOD_MS);
180 
181     // set exit flag to let thread exit
182     exit_flag = true;
183     for (int i = 0; i < max_tasks; ++i) {
184         if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) {
185             TEST_FAIL_MESSAGE("exit_sema not released by test task");
186         }
187         vSemaphoreDelete(exit_sema[i]);
188     }
189 }
190 
191 TEST_CASE("Test shared using SHA512 RSA", "[hw_crypto]")
192 {
193 #ifndef CONFIG_FREERTOS_UNICORE
194     const int max_tasks = 2;
195 #else
196     const int max_tasks = 2;
197 #endif
198     SemaphoreHandle_t exit_sema[max_tasks];
199 
200     for (int i = 0; i < max_tasks; ++i) {
201         exit_sema[i] = xSemaphoreCreateBinary();
202     }
203     exit_flag = false;
204 #ifndef CONFIG_FREERTOS_UNICORE
205     xTaskCreatePinnedToCore(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 2, NULL, 1);
206     xTaskCreatePinnedToCore(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
207 #else
208     xTaskCreate(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL);
209     xTaskCreate(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL);
210 #endif
211 
212     ESP_LOGI(TAG, "Waiting for 10s ...");
213     vTaskDelay(10000 / portTICK_PERIOD_MS);
214 
215     // set exit flag to let thread exit
216     exit_flag = true;
217     for (int i = 0; i < max_tasks; ++i) {
218         if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) {
219             TEST_FAIL_MESSAGE("exit_sema not released by test task");
220         }
221         vSemaphoreDelete(exit_sema[i]);
222     }
223 }
224 
225 TEST_CASE("Test shared using SHA256 RSA", "[hw_crypto]")
226 {
227 #ifndef CONFIG_FREERTOS_UNICORE
228     const int max_tasks = 2;
229 #else
230     const int max_tasks = 2;
231 #endif
232     SemaphoreHandle_t exit_sema[max_tasks];
233 
234     for (int i = 0; i < max_tasks; ++i) {
235         exit_sema[i] = xSemaphoreCreateBinary();
236     }
237     exit_flag = false;
238 #ifndef CONFIG_FREERTOS_UNICORE
239     xTaskCreatePinnedToCore(&mbedtls_sha256_task, "mbedtls_sha256_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
240     xTaskCreatePinnedToCore(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
241 #else
242     xTaskCreate(&mbedtls_sha256_task, "mbedtls_sha256_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL);
243     xTaskCreate(&rsa_task,            "rsa_task",            TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL);
244 #endif
245 
246     ESP_LOGI(TAG, "Waiting for 10s ...");
247     vTaskDelay(10000 / portTICK_PERIOD_MS);
248 
249     // set exit flag to let thread exit
250     exit_flag = true;
251     for (int i = 0; i < max_tasks; ++i) {
252         if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) {
253             TEST_FAIL_MESSAGE("exit_sema not released by test task");
254         }
255         vSemaphoreDelete(exit_sema[i]);
256     }
257 }
258 
259 TEST_CASE("Test shared using AES SHA RSA", "[hw_crypto]")
260 {
261 #ifndef CONFIG_FREERTOS_UNICORE
262     const int max_tasks = 3;
263 #else
264     const int max_tasks = 3;
265 #endif
266     SemaphoreHandle_t exit_sema[max_tasks];
267 
268     for (int i = 0; i < max_tasks; ++i) {
269         exit_sema[i] = xSemaphoreCreateBinary();
270     }
271     exit_flag = false;
272 #ifndef CONFIG_FREERTOS_UNICORE
273     xTaskCreatePinnedToCore(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
274     xTaskCreatePinnedToCore(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
275     xTaskCreatePinnedToCore(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[2], UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
276 #else
277     xTaskCreate(&aes_task, "aes_task", TASK_STACK_SIZE, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL);
278     xTaskCreate(&sha_task, "sha_task", TASK_STACK_SIZE, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL);
279     xTaskCreate(&rsa_task, "rsa_task", TASK_STACK_SIZE, &exit_sema[2], UNITY_FREERTOS_PRIORITY - 1, NULL);
280 #endif
281 
282     ESP_LOGI(TAG, "Waiting for 10s ...");
283     vTaskDelay(10000 / portTICK_PERIOD_MS);
284 
285     // set exit flag to let thread exit
286     exit_flag = true;
287     for (int i = 0; i < max_tasks; ++i) {
288         if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) {
289             TEST_FAIL_MESSAGE("exit_sema not released by test task");
290         }
291         vSemaphoreDelete(exit_sema[i]);
292     }
293 }
294 
295 #endif // CONFIG_IDF_TARGET_ESP32
296