1 /* mbedTLS SHA unit tests
2  */
3 
4 #include <string.h>
5 #include <stdio.h>
6 #include <stdbool.h>
7 #include <esp_system.h>
8 #include "mbedtls/sha1.h"
9 #include "mbedtls/sha256.h"
10 #include "mbedtls/sha512.h"
11 #include "freertos/FreeRTOS.h"
12 #include "freertos/task.h"
13 #include "freertos/semphr.h"
14 #include "unity.h"
15 #include "sdkconfig.h"
16 #include "test_apb_dport_access.h"
17 #include "sodium/utils.h"
18 #include "soc/soc_caps.h"
19 
20 TEST_CASE("mbedtls SHA self-tests", "[mbedtls]")
21 {
22     start_apb_access_loop();
23     TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass.");
24     TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha256_self_test(1), "SHA256 self-tests should pass.");
25     TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass.");
26     verify_apb_access_loop();
27 }
28 
29 static const unsigned char *one_hundred_as = (unsigned char *)
30         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
31 
32 static const unsigned char *one_hundred_bs =  (unsigned char *)
33         "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
34 
35 static const uint8_t sha256_thousand_as[32] = {
36     0x41, 0xed, 0xec, 0xe4, 0x2d, 0x63, 0xe8, 0xd9, 0xbf, 0x51, 0x5a, 0x9b, 0xa6, 0x93, 0x2e, 0x1c,
37     0x20, 0xcb, 0xc9, 0xf5, 0xa5, 0xd1, 0x34, 0x64, 0x5a, 0xdb, 0x5d, 0xb1, 0xb9, 0x73, 0x7e, 0xa3
38 };
39 
40 static const uint8_t sha256_thousand_bs[32] = {
41     0xf6, 0xf1, 0x18, 0xe1, 0x20, 0xe5, 0x2b, 0xe0, 0xbd, 0x0c, 0xfd, 0xf2, 0x79, 0x4c, 0xd1, 0x2c, 0x07, 0x68, 0x6c, 0xc8, 0x71, 0x23, 0x5a, 0xc2, 0xf1, 0x14, 0x59, 0x37, 0x8e, 0x6d, 0x23, 0x5b
42 };
43 
44 static const uint8_t sha512_thousand_bs[64] = {
45     0xa6, 0x68, 0x68, 0xa3, 0x73, 0x53, 0x2a, 0x5c, 0xc3, 0x3f, 0xbf, 0x43, 0x4e, 0xba, 0x10, 0x86, 0xb3, 0x87, 0x09, 0xe9, 0x14, 0x3f, 0xbf, 0x37, 0x67, 0x8d, 0x43, 0xd9, 0x9b, 0x95, 0x08, 0xd5, 0x80, 0x2d, 0xbe, 0x9d, 0xe9, 0x1a, 0x54, 0xab, 0x9e, 0xbc, 0x8a, 0x08, 0xa0, 0x1a, 0x89, 0xd8, 0x72, 0x68, 0xdf, 0x52, 0x69, 0x7f, 0x1c, 0x70, 0xda, 0xe8, 0x3f, 0xe5, 0xae, 0x5a, 0xfc, 0x9d
46 };
47 
48 static const uint8_t sha384_thousand_bs[48] = {
49     0x6d, 0xe5, 0xf5, 0x88, 0x57, 0x60, 0x83, 0xff, 0x7c, 0x94, 0x61, 0x5f, 0x8d, 0x96, 0xf2, 0x76, 0xd5, 0x3f, 0x77, 0x0c, 0x8e, 0xc1, 0xbf, 0xb6, 0x04, 0x27, 0xa4, 0xba, 0xea, 0x6c, 0x68, 0x44, 0xbd, 0xb0, 0x9c, 0xef, 0x6a, 0x09, 0x28, 0xe8, 0x1f, 0xfc, 0x95, 0x03, 0x69, 0x99, 0xab, 0x1a
50 };
51 
52 static const uint8_t sha1_thousand_as[20] = {
53     0x29, 0x1e, 0x9a, 0x6c, 0x66, 0x99, 0x49, 0x49, 0xb5, 0x7b, 0xa5,
54     0xe6, 0x50, 0x36, 0x1e, 0x98, 0xfc, 0x36, 0xb1, 0xba
55 };
56 
57 
58 TEST_CASE("mbedtls SHA interleaving", "[mbedtls]")
59 {
60     mbedtls_sha1_context sha1_ctx;
61     mbedtls_sha256_context sha256_ctx;
62     mbedtls_sha512_context sha512_ctx;
63     unsigned char sha1[20], sha256[32], sha512[64];
64 
65     mbedtls_sha1_init(&sha1_ctx);
66     mbedtls_sha256_init(&sha256_ctx);
67     mbedtls_sha512_init(&sha512_ctx);
68 
69     TEST_ASSERT_EQUAL(0, mbedtls_sha1_starts_ret(&sha1_ctx));
70     TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&sha256_ctx, false));
71     TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts_ret(&sha512_ctx, false));
72 
73     for (int i = 0; i < 10; i++) {
74         TEST_ASSERT_EQUAL(0, mbedtls_sha1_update_ret(&sha1_ctx, one_hundred_as, 100));
75         TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&sha256_ctx, one_hundred_as, 100));
76         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&sha512_ctx, one_hundred_bs, 100));
77     }
78 
79     TEST_ASSERT_EQUAL(0, mbedtls_sha1_finish_ret(&sha1_ctx, sha1));
80     TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&sha256_ctx, sha256));
81     TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&sha512_ctx, sha512));
82 
83     mbedtls_sha1_free(&sha1_ctx);
84     mbedtls_sha256_free(&sha256_ctx);
85     mbedtls_sha512_free(&sha512_ctx);
86 
87     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 calculation");
88     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 calculation");
89     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation");
90 }
91 
92 static xSemaphoreHandle done_sem;
tskRunSHA1Test(void * pvParameters)93 static void tskRunSHA1Test(void *pvParameters)
94 {
95     mbedtls_sha1_context sha1_ctx;
96     unsigned char sha1[20];
97 
98     for (int i = 0; i < 1000; i++) {
99         mbedtls_sha1_init(&sha1_ctx);
100         TEST_ASSERT_EQUAL(0, mbedtls_sha1_starts_ret(&sha1_ctx));
101         for (int j = 0; j < 10; j++) {
102             TEST_ASSERT_EQUAL(0, mbedtls_sha1_update_ret(&sha1_ctx, (unsigned char *)one_hundred_as, 100));
103         }
104         TEST_ASSERT_EQUAL(0, mbedtls_sha1_finish_ret(&sha1_ctx, sha1));
105         mbedtls_sha1_free(&sha1_ctx);
106         TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation");
107     }
108     xSemaphoreGive(done_sem);
109     vTaskDelete(NULL);
110 }
111 
tskRunSHA256Test(void * pvParameters)112 static void tskRunSHA256Test(void *pvParameters)
113 {
114     mbedtls_sha256_context sha256_ctx;
115     unsigned char sha256[32];
116 
117     for (int i = 0; i < 1000; i++) {
118         mbedtls_sha256_init(&sha256_ctx);
119         TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&sha256_ctx, false));
120         for (int j = 0; j < 10; j++) {
121             TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&sha256_ctx, (unsigned char *)one_hundred_bs, 100));
122         }
123         TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&sha256_ctx, sha256));
124         mbedtls_sha256_free(&sha256_ctx);
125         TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_bs, sha256, 32, "SHA256 calculation");
126     }
127     xSemaphoreGive(done_sem);
128     vTaskDelete(NULL);
129 }
130 
131 #define SHA_TASK_STACK_SIZE (10*1024)
132 
133 TEST_CASE("mbedtls SHA multithreading", "[mbedtls]")
134 {
135     done_sem = xSemaphoreCreateCounting(4, 0);
136     xTaskCreate(tskRunSHA1Test, "SHA1Task1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
137     xTaskCreate(tskRunSHA1Test, "SHA1Task2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
138     xTaskCreate(tskRunSHA256Test, "SHA256Task1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
139     xTaskCreate(tskRunSHA256Test, "SHA256Task2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
140 
141     for (int i = 0; i < 4; i++) {
142         if (!xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS)) {
143             TEST_FAIL_MESSAGE("done_sem not released by test task");
144         }
145     }
146     vSemaphoreDelete(done_sem);
147 }
148 
tskRunSHASelftests(void * param)149 void tskRunSHASelftests(void *param)
150 {
151     for (int i = 0; i < 5; i++) {
152         if (mbedtls_sha1_self_test(1)) {
153             printf("SHA1 self-tests failed.\n");
154             while (1) {}
155         }
156 
157         if (mbedtls_sha256_self_test(1)) {
158             printf("SHA256 self-tests failed.\n");
159             while (1) {}
160         }
161 
162 #if SOC_SHA_SUPPORT_SHA512
163         if (mbedtls_sha512_self_test(1)) {
164             printf("SHA512 self-tests failed.\n");
165             while (1) {}
166         }
167 
168         if (mbedtls_sha512_self_test(1)) {
169             printf("SHA512 self-tests failed.\n");
170             while (1) {}
171         }
172 #endif //SOC_SHA_SUPPORT_SHA512
173     }
174     xSemaphoreGive(done_sem);
175     vTaskDelete(NULL);
176 }
177 
178 TEST_CASE("mbedtls SHA self-tests multithreaded", "[mbedtls]")
179 {
180     done_sem = xSemaphoreCreateCounting(2, 0);
181     xTaskCreate(tskRunSHASelftests, "SHASelftests1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
182     xTaskCreate(tskRunSHASelftests, "SHASelftests2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
183 
184     const int TIMEOUT_MS = 40000;
185 
186     for (int i = 0; i < 2; i++) {
187         if (!xSemaphoreTake(done_sem, TIMEOUT_MS / portTICK_PERIOD_MS)) {
188             TEST_FAIL_MESSAGE("done_sem not released by test task");
189         }
190     }
191     vSemaphoreDelete(done_sem);
192 }
193 
194 TEST_CASE("mbedtls SHA512 clone", "[mbedtls]")
195 {
196     mbedtls_sha512_context ctx;
197     mbedtls_sha512_context clone;
198     unsigned char sha512[64];
199 
200     mbedtls_sha512_init(&ctx);
201     TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts_ret(&ctx, false));
202     for (int i = 0; i < 5; i++) {
203         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
204     }
205 
206     mbedtls_sha512_init(&clone);
207     mbedtls_sha512_clone(&clone, &ctx);
208     for (int i = 0; i < 5; i++) {
209         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
210         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&clone, one_hundred_bs, 100));
211     }
212     TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&ctx, sha512));
213     mbedtls_sha512_free(&ctx);
214 
215     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 original calculation");
216 
217     TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&clone, sha512));
218     mbedtls_sha512_free(&clone);
219 
220     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 cloned calculation");
221 }
222 
223 TEST_CASE("mbedtls SHA384 clone", "[mbedtls][")
224 {
225     mbedtls_sha512_context ctx;
226     mbedtls_sha512_context clone;
227 
228     unsigned char sha384[48];
229 
230     mbedtls_sha512_init(&ctx);
231     TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts_ret(&ctx, true));
232     for (int i = 0; i < 5; i++) {
233         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
234     }
235 
236     mbedtls_sha512_init(&clone);
237     mbedtls_sha512_clone(&clone, &ctx);
238 
239     for (int i = 0; i < 5; i++) {
240         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
241         TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&clone, one_hundred_bs, 100));
242     }
243     TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&ctx, sha384));
244     mbedtls_sha512_free(&ctx);
245 
246     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 original calculation");
247 
248     TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&clone, sha384));
249     mbedtls_sha512_free(&clone);
250 
251     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 cloned calculation");
252 }
253 
254 
255 TEST_CASE("mbedtls SHA256 clone", "[mbedtls]")
256 {
257     mbedtls_sha256_context ctx;
258     mbedtls_sha256_context clone;
259     unsigned char sha256[64];
260 
261     mbedtls_sha256_init(&ctx);
262     TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&ctx, false));
263     for (int i = 0; i < 5; i++) {
264         TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&ctx, one_hundred_as, 100));
265     }
266 
267     mbedtls_sha256_init(&clone);
268     mbedtls_sha256_clone(&clone, &ctx);
269     for (int i = 0; i < 5; i++) {
270         TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&ctx, one_hundred_as, 100));
271         TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&clone, one_hundred_as, 100));
272     }
273     TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&ctx, sha256));
274     mbedtls_sha256_free(&ctx);
275 
276     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 original calculation");
277 
278     TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&clone, sha256));
279     mbedtls_sha256_free(&clone);
280 
281     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 cloned calculation");
282 }
283 
284 typedef struct {
285     mbedtls_sha256_context ctx;
286     uint8_t result[32];
287     int ret;
288     bool done;
289 } finalise_sha_param_t;
290 
tskFinaliseSha(void * v_param)291 static void tskFinaliseSha(void *v_param)
292 {
293     finalise_sha_param_t *param = (finalise_sha_param_t *)v_param;
294 
295     for (int i = 0; i < 5; i++) {
296         TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&param->ctx, one_hundred_as, 100));
297     }
298 
299     param->ret = mbedtls_sha256_finish_ret(&param->ctx, param->result);
300     mbedtls_sha256_free(&param->ctx);
301 
302     param->done = true;
303     vTaskDelete(NULL);
304 }
305 
306 
307 TEST_CASE("mbedtls SHA session passed between tasks", "[mbedtls]")
308 {
309     finalise_sha_param_t param = { 0 };
310 
311     mbedtls_sha256_init(&param.ctx);
312     TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&param.ctx, false));
313     for (int i = 0; i < 5; i++) {
314         TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&param.ctx, one_hundred_as, 100));
315     }
316 
317     // pass the SHA context off to a different task
318     //
319     // note: at the moment this doesn't crash even if a mutex semaphore is used as the
320     // engine lock, but it can crash...
321     xTaskCreate(tskFinaliseSha, "SHAFinalise", SHA_TASK_STACK_SIZE, &param, 3, NULL);
322 
323     while (!param.done) {
324         vTaskDelay(1);
325     }
326 
327     TEST_ASSERT_EQUAL(0, param.ret);
328     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, param.result, 32, "SHA256 result from other task");
329 }
330 
331 
332 
333 
334 /* Random input generated and hashed using python:
335 
336     import hashlib
337     import os, binascii
338 
339     input = bytearray(os.urandom(150))
340     arr = ''
341     for idx, b in enumerate(input):
342         if idx % 8 == 0:
343             arr += '\n'
344         arr += "{}, ".format(hex(b))
345     digest = hashlib.sha256(input).hexdigest()
346 
347 */
348 const uint8_t test_vector[] = {
349     0xe4, 0x1a, 0x1a, 0x30, 0x71, 0xd3, 0x94, 0xb0,
350     0xc3, 0x7e, 0x99, 0x9f, 0x1a, 0xde, 0x4a, 0x36,
351     0xb1, 0x1, 0x81, 0x2b, 0x41, 0x91, 0x11, 0x7f,
352     0xd8, 0xe1, 0xd5, 0xe5, 0x52, 0x6d, 0x92, 0xee,
353     0x6c, 0xf7, 0x70, 0xea, 0x3a, 0xb, 0xc9, 0x97,
354     0xc0, 0x12, 0x6f, 0x10, 0x5b, 0x90, 0xd8, 0x52,
355     0x91, 0x69, 0xea, 0xc4, 0x1f, 0xc, 0xcf, 0xc6,
356     0xf0, 0x43, 0xc6, 0xa3, 0x1f, 0x46, 0x3c, 0x3d,
357     0x25, 0xe5, 0xa8, 0x27, 0x86, 0x85, 0x32, 0x3f,
358     0x33, 0xd8, 0x40, 0xc4, 0x41, 0xf6, 0x4b, 0x12,
359     0xd8, 0x5e, 0x4, 0x27, 0x42, 0x90, 0x73, 0x4,
360     0x8, 0x42, 0xd1, 0x64, 0xd, 0x84, 0x3, 0x1,
361     0x76, 0x88, 0xe4, 0x95, 0xdf, 0xe7, 0x62, 0xb4,
362     0xb3, 0xb2, 0x7e, 0x6d, 0x78, 0xca, 0x79, 0x82,
363     0xcc, 0xba, 0x22, 0xd2, 0x90, 0x2e, 0xe3, 0xa8,
364     0x2a, 0x53, 0x3a, 0xb1, 0x9a, 0x7f, 0xb7, 0x8b,
365     0xfa, 0x32, 0x47, 0xc1, 0x5c, 0x6, 0x4f, 0x7b,
366     0xcd, 0xb3, 0xf4, 0xf1, 0xd0, 0xb5, 0xbf, 0xfb,
367     0x7c, 0xc3, 0xa5, 0xb2, 0xc4, 0xd4,
368 };
369 
370 const uint8_t test_vector_digest[] = {
371     0xff, 0x1c, 0x60, 0xcb, 0x21, 0xf0, 0x63, 0x68,
372     0xb9, 0xfc, 0xfe, 0xad, 0x3e, 0xb0, 0x2e, 0xd1,
373     0xf9, 0x08, 0x82, 0x82, 0x83, 0x06, 0xc1, 0x8a,
374     0x98, 0x5d, 0x36, 0xc0, 0xb7, 0xeb, 0x35, 0xe0,
375 };
376 
377 TEST_CASE("mbedtls SHA, input in flash", "[mbedtls]")
378 {
379     mbedtls_sha256_context sha256_ctx;
380     unsigned char sha256[32];
381 
382     mbedtls_sha256_init(&sha256_ctx);
383 
384     TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&sha256_ctx, false));
385     TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&sha256_ctx, test_vector, sizeof(test_vector)));
386     TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&sha256_ctx, sha256));
387     mbedtls_sha256_free(&sha256_ctx);
388 
389     TEST_ASSERT_EQUAL_MEMORY_MESSAGE(test_vector_digest, sha256, 32, "SHA256 calculation");
390 }
391 
392 /* Function are not implemented in SW */
393 #if CONFIG_MBEDTLS_HARDWARE_SHA && SOC_SHA_SUPPORT_SHA512_T
394 
395 /*
396  * FIPS-180-2 test vectors
397  */
398 static unsigned char sha512T_test_buf[2][113] = {
399     { "abc" },
400     {
401         "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
402         "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
403     }
404 };
405 
406 static const size_t sha512T_test_buflen[2] = {
407     3, 112
408 };
409 
410 static const esp_sha_type sha512T_algo[4] = {
411     SHA2_512224, SHA2_512256, SHA2_512T, SHA2_512T
412 };
413 
414 static const size_t sha512T_t_len[4] = { 224, 256, 224, 256 };
415 
416 static const unsigned char sha512_test_sum[4][32] = {
417     /* SHA512-224 */
418     {
419         0x46, 0x34, 0x27, 0x0f, 0x70, 0x7b, 0x6a, 0x54,
420         0xda, 0xae, 0x75, 0x30, 0x46, 0x08, 0x42, 0xe2,
421         0x0e, 0x37, 0xed, 0x26, 0x5c, 0xee, 0xe9, 0xa4,
422         0x3e, 0x89, 0x24, 0xaa
423     },
424     {
425         0x23, 0xfe, 0xc5, 0xbb, 0x94, 0xd6, 0x0b, 0x23,
426         0x30, 0x81, 0x92, 0x64, 0x0b, 0x0c, 0x45, 0x33,
427         0x35, 0xd6, 0x64, 0x73, 0x4f, 0xe4, 0x0e, 0x72,
428         0x68, 0x67, 0x4a, 0xf9
429     },
430 
431     /* SHA512-256 */
432     {
433         0x53, 0x04, 0x8e, 0x26, 0x81, 0x94, 0x1e, 0xf9,
434         0x9b, 0x2e, 0x29, 0xb7, 0x6b, 0x4c, 0x7d, 0xab,
435         0xe4, 0xc2, 0xd0, 0xc6, 0x34, 0xfc, 0x6d, 0x46,
436         0xe0, 0xe2, 0xf1, 0x31, 0x07, 0xe7, 0xaf, 0x23
437     },
438     {
439         0x39, 0x28, 0xe1, 0x84, 0xfb, 0x86, 0x90, 0xf8,
440         0x40, 0xda, 0x39, 0x88, 0x12, 0x1d, 0x31, 0xbe,
441         0x65, 0xcb, 0x9d, 0x3e, 0xf8, 0x3e, 0xe6, 0x14,
442         0x6f, 0xea, 0xc8, 0x61, 0xe1, 0x9b, 0x56, 0x3a
443     }
444 
445     /* For SHA512_T testing we use t=224 & t=256
446      * so the hash digest should be same as above
447      */
448 };
449 
450 /* This will run total of 8 test cases, 2 for each of the below MODE
451  * SHA512/224, SHA512/256, SHA512/t with t=224 & SHA512/t with t=256
452  *
453  * Test is disabled for ESP32 as there is no hardware for SHA512/t
454  */
455 TEST_CASE("mbedtls SHA512/t", "[mbedtls]")
456 {
457     mbedtls_sha512_context sha512_ctx;
458     unsigned char sha512[64], k;
459 
460     for (int i = 0; i < 4; i++) {
461         for (int j = 0; j < 2; j++) {
462             k = i * 2 + j;
463             mbedtls_sha512_init(&sha512_ctx);
464             TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts_ret(&sha512_ctx, false));
465             esp_sha512_set_mode(&sha512_ctx, sha512T_algo[i]);
466             if (i > 1) {
467                 k = (i - 2) * 2 + j;
468                 esp_sha512_set_t(&sha512_ctx, sha512T_t_len[i]);
469             }
470             TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&sha512_ctx, sha512T_test_buf[j], sha512T_test_buflen[j]));
471             TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&sha512_ctx, sha512));
472             mbedtls_sha512_free(&sha512_ctx);
473 
474             TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_test_sum[k], sha512, sha512T_t_len[i] / 8, "SHA512t calculation");
475         }
476     }
477 }
478 #endif //CONFIG_MBEDTLS_HARDWARE_SHA
479 
480 #ifdef CONFIG_SPIRAM_USE_MALLOC
481 TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]")
482 {
483     const unsigned CALLS = 256;
484     const unsigned CALL_SZ = 16 * 1024;
485     mbedtls_sha256_context sha256_ctx;
486     unsigned char sha256[32];
487 
488     // allocate external memory
489     uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
490     TEST_ASSERT(esp_ptr_external_ram(buf));
491     memset(buf, 0x54, CALL_SZ);
492 
493     mbedtls_sha256_init(&sha256_ctx);
494     TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&sha256_ctx, false));
495     for (int c = 0; c < CALLS; c++) {
496         TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&sha256_ctx, buf, CALL_SZ));
497     }
498     TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&sha256_ctx, sha256));
499 
500     free(buf);
501     mbedtls_sha256_free(&sha256_ctx);
502 
503     /* Check the result. Reference value can be calculated using:
504      * dd if=/dev/zero bs=$((16*1024)) count=256 | tr '\000' '\124' | sha256sum
505      */
506     const char *expected_hash = "8d031167bd706ac337e07aa9129c34ae4ae792d0a79a2c70e7f012102e8adc3d";
507     char hash_str[sizeof(sha256) * 2 + 1];
508     sodium_bin2hex(hash_str, sizeof(hash_str), sha256, sizeof(sha256));
509 
510     TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str);
511 
512 }
513 #endif //CONFIG_SPIRAM_USE_MALLOC
514 
515 #if CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK
516 
517 extern RTC_FAST_ATTR uint8_t rtc_stack[4096];
518 
519 static xSemaphoreHandle done_sem;
520 
521 TEST_CASE("mbedtls SHA stack in RTC RAM", "[mbedtls]")
522 {
523     done_sem = xSemaphoreCreateBinary();
524     static StaticTask_t rtc_task;
525     memset(rtc_stack, 0, sizeof(rtc_stack));
526 
527     TEST_ASSERT(esp_ptr_in_rtc_dram_fast(rtc_stack));
528 
529     TEST_ASSERT_NOT_NULL(xTaskCreateStatic(tskRunSHA256Test, "tskRunSHA256Test_task", sizeof(rtc_stack), NULL,
530                                             3, rtc_stack, &rtc_task));
531     TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS));
532     vSemaphoreDelete(done_sem);
533 }
534 
535 #endif //CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK
536