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