1 /*
2  *  Copyright The Mbed TLS Contributors
3  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
4  */
5 
6 #include <test/constant_flow.h>
7 #include <test/helpers.h>
8 #include <test/macros.h>
9 #include <string.h>
10 
11 #if defined(MBEDTLS_PSA_INJECT_ENTROPY)
12 #include <psa/crypto.h>
13 #include <test/psa_crypto_helpers.h>
14 #endif
15 
16 #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C)
17 #include <test/psa_memory_poisoning_wrappers.h>
18 #endif
19 #if defined(MBEDTLS_THREADING_C)
20 #include "mbedtls/threading.h"
21 #endif
22 
23 /*----------------------------------------------------------------------------*/
24 /* Static global variables */
25 
26 #if defined(MBEDTLS_PLATFORM_C)
27 static mbedtls_platform_context platform_ctx;
28 #endif
29 
30 static mbedtls_test_info_t mbedtls_test_info;
31 
32 #ifdef MBEDTLS_THREADING_C
33 mbedtls_threading_mutex_t mbedtls_test_info_mutex;
34 #endif /* MBEDTLS_THREADING_C */
35 
36 /*----------------------------------------------------------------------------*/
37 /* Mbedtls Test Info accessors
38  *
39  * NOTE - there are two types of accessors here: public accessors and internal
40  * accessors. The public accessors have prototypes in helpers.h and lock
41  * mbedtls_test_info_mutex (if mutexes are enabled). The _internal accessors,
42  * which are expected to be used from this module *only*, do not lock the mutex.
43  * These are designed to be called from within public functions which already
44  * hold the mutex. The main reason for this difference is the need to set
45  * multiple test data values atomically (without releasing the mutex) to prevent
46  * race conditions. */
47 
mbedtls_test_get_result(void)48 mbedtls_test_result_t mbedtls_test_get_result(void)
49 {
50     mbedtls_test_result_t result;
51 
52 #ifdef MBEDTLS_THREADING_C
53     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
54 #endif /* MBEDTLS_THREADING_C */
55 
56     result =  mbedtls_test_info.result;
57 
58 #ifdef MBEDTLS_THREADING_C
59     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
60 #endif /* MBEDTLS_THREADING_C */
61 
62     return result;
63 }
64 
mbedtls_test_set_result_internal(mbedtls_test_result_t result,const char * test,int line_no,const char * filename)65 static void mbedtls_test_set_result_internal(mbedtls_test_result_t result, const char *test,
66                                              int line_no, const char *filename)
67 {
68     /* Internal function only - mbedtls_test_info_mutex should be held prior
69      * to calling this function. */
70 
71     mbedtls_test_info.result = result;
72     mbedtls_test_info.test = test;
73     mbedtls_test_info.line_no = line_no;
74     mbedtls_test_info.filename = filename;
75 }
76 
mbedtls_test_get_test(void)77 const char *mbedtls_test_get_test(void)
78 {
79     const char *test;
80 
81 #ifdef MBEDTLS_THREADING_C
82     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
83 #endif /* MBEDTLS_THREADING_C */
84 
85     test = mbedtls_test_info.test;
86 
87 #ifdef MBEDTLS_THREADING_C
88     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
89 #endif /* MBEDTLS_THREADING_C */
90 
91     return test;
92 }
mbedtls_get_test_filename(void)93 const char *mbedtls_get_test_filename(void)
94 {
95     const char *filename;
96 
97 #ifdef MBEDTLS_THREADING_C
98     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
99 #endif /* MBEDTLS_THREADING_C */
100 
101     /* It should be ok just to pass back the pointer here, as it is going to
102      * be a pointer into non changing data. */
103     filename = mbedtls_test_info.filename;
104 
105 #ifdef MBEDTLS_THREADING_C
106     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
107 #endif /* MBEDTLS_THREADING_C */
108 
109     return filename;
110 }
111 
mbedtls_test_get_line_no(void)112 int mbedtls_test_get_line_no(void)
113 {
114     int line_no;
115 
116 #ifdef MBEDTLS_THREADING_C
117     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
118 #endif /* MBEDTLS_THREADING_C */
119 
120     line_no = mbedtls_test_info.line_no;
121 
122 #ifdef MBEDTLS_THREADING_C
123     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
124 #endif /* MBEDTLS_THREADING_C */
125 
126     return line_no;
127 }
128 
mbedtls_test_increment_step(void)129 void mbedtls_test_increment_step(void)
130 {
131 #ifdef MBEDTLS_THREADING_C
132     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
133 #endif /* MBEDTLS_THREADING_C */
134 
135     ++mbedtls_test_info.step;
136 
137 #ifdef MBEDTLS_THREADING_C
138     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
139 #endif /* MBEDTLS_THREADING_C */
140 }
141 
mbedtls_test_get_step(void)142 unsigned long mbedtls_test_get_step(void)
143 {
144     unsigned long step;
145 
146 #ifdef MBEDTLS_THREADING_C
147     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
148 #endif /* MBEDTLS_THREADING_C */
149 
150     step = mbedtls_test_info.step;
151 
152 #ifdef MBEDTLS_THREADING_C
153     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
154 #endif /* MBEDTLS_THREADING_C */
155 
156     return step;
157 }
158 
mbedtls_test_reset_step_internal(void)159 static void mbedtls_test_reset_step_internal(void)
160 {
161     /* Internal function only - mbedtls_test_info_mutex should be held prior
162      * to calling this function. */
163 
164     mbedtls_test_info.step = (unsigned long) (-1);
165 }
166 
mbedtls_test_set_step(unsigned long step)167 void mbedtls_test_set_step(unsigned long step)
168 {
169 #ifdef MBEDTLS_THREADING_C
170     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
171 #endif /* MBEDTLS_THREADING_C */
172 
173     mbedtls_test_info.step = step;
174 
175 #ifdef MBEDTLS_THREADING_C
176     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
177 #endif /* MBEDTLS_THREADING_C */
178 }
179 
mbedtls_test_get_line1(char * line)180 void mbedtls_test_get_line1(char *line)
181 {
182 #ifdef MBEDTLS_THREADING_C
183     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
184 #endif /* MBEDTLS_THREADING_C */
185 
186     memcpy(line, mbedtls_test_info.line1, MBEDTLS_TEST_LINE_LENGTH);
187 
188 #ifdef MBEDTLS_THREADING_C
189     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
190 #endif /* MBEDTLS_THREADING_C */
191 }
192 
mbedtls_test_set_line1_internal(const char * line)193 static void mbedtls_test_set_line1_internal(const char *line)
194 {
195     /* Internal function only - mbedtls_test_info_mutex should be held prior
196      * to calling this function. */
197 
198     if (line == NULL) {
199         memset(mbedtls_test_info.line1, 0, MBEDTLS_TEST_LINE_LENGTH);
200     } else {
201         memcpy(mbedtls_test_info.line1, line, MBEDTLS_TEST_LINE_LENGTH);
202     }
203 }
204 
mbedtls_test_get_line2(char * line)205 void mbedtls_test_get_line2(char *line)
206 {
207 #ifdef MBEDTLS_THREADING_C
208     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
209 #endif /* MBEDTLS_THREADING_C */
210 
211     memcpy(line, mbedtls_test_info.line2, MBEDTLS_TEST_LINE_LENGTH);
212 
213 #ifdef MBEDTLS_THREADING_C
214     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
215 #endif /* MBEDTLS_THREADING_C */
216 }
217 
mbedtls_test_set_line2_internal(const char * line)218 static void mbedtls_test_set_line2_internal(const char *line)
219 {
220     /* Internal function only - mbedtls_test_info_mutex should be held prior
221      * to calling this function. */
222 
223     if (line == NULL) {
224         memset(mbedtls_test_info.line2, 0, MBEDTLS_TEST_LINE_LENGTH);
225     } else {
226         memcpy(mbedtls_test_info.line2, line, MBEDTLS_TEST_LINE_LENGTH);
227     }
228 }
229 
230 
231 #if defined(MBEDTLS_TEST_MUTEX_USAGE)
mbedtls_test_get_mutex_usage_error(void)232 const char *mbedtls_test_get_mutex_usage_error(void)
233 {
234     const char *usage_error;
235 
236 #ifdef MBEDTLS_THREADING_C
237     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
238 #endif /* MBEDTLS_THREADING_C */
239 
240     usage_error = mbedtls_test_info.mutex_usage_error;
241 
242 #ifdef MBEDTLS_THREADING_C
243     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
244 #endif /* MBEDTLS_THREADING_C */
245 
246     return usage_error;
247 }
248 
mbedtls_test_set_mutex_usage_error(const char * msg)249 void mbedtls_test_set_mutex_usage_error(const char *msg)
250 {
251 #ifdef MBEDTLS_THREADING_C
252     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
253 #endif /* MBEDTLS_THREADING_C */
254 
255     if (mbedtls_test_info.mutex_usage_error == NULL || msg == NULL) {
256         mbedtls_test_info.mutex_usage_error = msg;
257     }
258 
259 #ifdef MBEDTLS_THREADING_C
260     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
261 #endif /* MBEDTLS_THREADING_C */
262 }
263 #endif // #if defined(MBEDTLS_TEST_MUTEX_USAGE)
264 
265 #if defined(MBEDTLS_BIGNUM_C)
266 
mbedtls_test_get_case_uses_negative_0(void)267 unsigned mbedtls_test_get_case_uses_negative_0(void)
268 {
269     unsigned test_case_uses_negative_0 = 0;
270 #ifdef MBEDTLS_THREADING_C
271     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
272 #endif /* MBEDTLS_THREADING_C */
273     test_case_uses_negative_0 = mbedtls_test_info.case_uses_negative_0;
274 
275 #ifdef MBEDTLS_THREADING_C
276     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
277 #endif /* MBEDTLS_THREADING_C */
278 
279     return test_case_uses_negative_0;
280 }
281 
mbedtls_test_set_case_uses_negative_0_internal(unsigned uses)282 static void mbedtls_test_set_case_uses_negative_0_internal(unsigned uses)
283 {
284     /* Internal function only - mbedtls_test_info_mutex should be held prior
285      * to calling this function. */
286 
287     mbedtls_test_info.case_uses_negative_0 = uses;
288 }
289 
mbedtls_test_increment_case_uses_negative_0(void)290 void mbedtls_test_increment_case_uses_negative_0(void)
291 {
292 #ifdef MBEDTLS_THREADING_C
293     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
294 #endif /* MBEDTLS_THREADING_C */
295 
296     ++mbedtls_test_info.case_uses_negative_0;
297 
298 #ifdef MBEDTLS_THREADING_C
299     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
300 #endif /* MBEDTLS_THREADING_C */
301 }
302 
303 #endif /* MBEDTLS_BIGNUM_C */
304 
305 #ifdef MBEDTLS_TEST_MUTEX_USAGE
mbedtls_test_get_info_mutex(void)306 mbedtls_threading_mutex_t *mbedtls_test_get_info_mutex(void)
307 {
308     return &mbedtls_test_info_mutex;
309 }
310 
311 #endif /* MBEDTLS_TEST_MUTEX_USAGE */
312 
313 /*----------------------------------------------------------------------------*/
314 /* Helper Functions */
315 
mbedtls_test_platform_setup(void)316 int mbedtls_test_platform_setup(void)
317 {
318     int ret = 0;
319 
320 #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \
321     && !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) \
322     && defined(MBEDTLS_TEST_MEMORY_CAN_POISON)
323     mbedtls_poison_test_hooks_setup();
324 #endif
325 
326 #if defined(MBEDTLS_PSA_INJECT_ENTROPY)
327     /* Make sure that injected entropy is present. Otherwise
328      * psa_crypto_init() will fail. This is not necessary for test suites
329      * that don't use PSA, but it's harmless (except for leaving a file
330      * behind). */
331     ret = mbedtls_test_inject_entropy_restore();
332     if (ret != 0) {
333         return ret;
334     }
335 #endif
336 
337 #if defined(MBEDTLS_PLATFORM_C)
338     ret = mbedtls_platform_setup(&platform_ctx);
339 #endif /* MBEDTLS_PLATFORM_C */
340 
341 #ifdef MBEDTLS_THREADING_C
342     mbedtls_mutex_init(&mbedtls_test_info_mutex);
343 #endif /* MBEDTLS_THREADING_C */
344 
345     return ret;
346 }
347 
mbedtls_test_platform_teardown(void)348 void mbedtls_test_platform_teardown(void)
349 {
350 #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \
351     && !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) \
352     &&  defined(MBEDTLS_TEST_MEMORY_CAN_POISON)
353     mbedtls_poison_test_hooks_teardown();
354 #endif
355 #ifdef MBEDTLS_THREADING_C
356     mbedtls_mutex_free(&mbedtls_test_info_mutex);
357 #endif /* MBEDTLS_THREADING_C */
358 
359 #if defined(MBEDTLS_PLATFORM_C)
360     mbedtls_platform_teardown(&platform_ctx);
361 #endif /* MBEDTLS_PLATFORM_C */
362 }
363 
mbedtls_test_ascii2uc(const char c,unsigned char * uc)364 int mbedtls_test_ascii2uc(const char c, unsigned char *uc)
365 {
366     if ((c >= '0') && (c <= '9')) {
367         *uc = c - '0';
368     } else if ((c >= 'a') && (c <= 'f')) {
369         *uc = c - 'a' + 10;
370     } else if ((c >= 'A') && (c <= 'F')) {
371         *uc = c - 'A' + 10;
372     } else {
373         return -1;
374     }
375 
376     return 0;
377 }
378 
mbedtls_test_fail_internal(const char * test,int line_no,const char * filename)379 static void mbedtls_test_fail_internal(const char *test, int line_no, const char *filename)
380 {
381     /* Internal function only - mbedtls_test_info_mutex should be held prior
382      * to calling this function. */
383 
384     /* Don't use accessor, we already hold mutex. */
385     if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
386         /* If we have already recorded the test as having failed then don't
387          * overwrite any previous information about the failure. */
388         mbedtls_test_set_result_internal(MBEDTLS_TEST_RESULT_FAILED, test, line_no, filename);
389     }
390 }
391 
mbedtls_test_fail(const char * test,int line_no,const char * filename)392 void mbedtls_test_fail(const char *test, int line_no, const char *filename)
393 {
394 #ifdef MBEDTLS_THREADING_C
395     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
396 #endif /* MBEDTLS_THREADING_C */
397 
398     mbedtls_test_fail_internal(test, line_no, filename);
399 
400 #ifdef MBEDTLS_THREADING_C
401     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
402 #endif /* MBEDTLS_THREADING_C */
403 }
404 
mbedtls_test_skip(const char * test,int line_no,const char * filename)405 void mbedtls_test_skip(const char *test, int line_no, const char *filename)
406 {
407 #ifdef MBEDTLS_THREADING_C
408     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
409 #endif /* MBEDTLS_THREADING_C */
410 
411     mbedtls_test_set_result_internal(MBEDTLS_TEST_RESULT_SKIPPED, test, line_no, filename);
412 
413 #ifdef MBEDTLS_THREADING_C
414     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
415 #endif /* MBEDTLS_THREADING_C */
416 }
417 
mbedtls_test_info_reset(void)418 void mbedtls_test_info_reset(void)
419 {
420 #ifdef MBEDTLS_THREADING_C
421     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
422 #endif /* MBEDTLS_THREADING_C */
423 
424     mbedtls_test_set_result_internal(MBEDTLS_TEST_RESULT_SUCCESS, 0, 0, 0);
425     mbedtls_test_reset_step_internal();
426     mbedtls_test_set_line1_internal(NULL);
427     mbedtls_test_set_line2_internal(NULL);
428 
429 #if defined(MBEDTLS_BIGNUM_C)
430     mbedtls_test_set_case_uses_negative_0_internal(0);
431 #endif
432 
433 #ifdef MBEDTLS_THREADING_C
434     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
435 #endif /* MBEDTLS_THREADING_C */
436 }
437 
mbedtls_test_equal(const char * test,int line_no,const char * filename,unsigned long long value1,unsigned long long value2)438 int mbedtls_test_equal(const char *test, int line_no, const char *filename,
439                        unsigned long long value1, unsigned long long value2)
440 {
441     TEST_CF_PUBLIC(&value1, sizeof(value1));
442     TEST_CF_PUBLIC(&value2, sizeof(value2));
443 
444     if (value1 == value2) {
445         return 1;
446     }
447 
448 #ifdef MBEDTLS_THREADING_C
449     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
450 #endif /* MBEDTLS_THREADING_C */
451 
452     /* Don't use accessor, as we already hold mutex. */
453     if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
454         /* If we've already recorded the test as having failed then don't
455          * overwrite any previous information about the failure. */
456 
457         char buf[MBEDTLS_TEST_LINE_LENGTH];
458         mbedtls_test_fail_internal(test, line_no, filename);
459         (void) mbedtls_snprintf(buf, sizeof(buf),
460                                 "lhs = 0x%016llx = %lld",
461                                 value1, (long long) value1);
462         mbedtls_test_set_line1_internal(buf);
463         (void) mbedtls_snprintf(buf, sizeof(buf),
464                                 "rhs = 0x%016llx = %lld",
465                                 value2, (long long) value2);
466         mbedtls_test_set_line2_internal(buf);
467     }
468 
469 #ifdef MBEDTLS_THREADING_C
470     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
471 #endif /* MBEDTLS_THREADING_C */
472 
473     return 0;
474 }
475 
mbedtls_test_le_u(const char * test,int line_no,const char * filename,unsigned long long value1,unsigned long long value2)476 int mbedtls_test_le_u(const char *test, int line_no, const char *filename,
477                       unsigned long long value1, unsigned long long value2)
478 {
479     TEST_CF_PUBLIC(&value1, sizeof(value1));
480     TEST_CF_PUBLIC(&value2, sizeof(value2));
481 
482     if (value1 <= value2) {
483         return 1;
484     }
485 
486 #ifdef MBEDTLS_THREADING_C
487     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
488 #endif /* MBEDTLS_THREADING_C */
489 
490     /* Don't use accessor, we already hold mutex. */
491     if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
492         /* If we've already recorded the test as having failed then don't
493          * overwrite any previous information about the failure. */
494 
495         char buf[MBEDTLS_TEST_LINE_LENGTH];
496         mbedtls_test_fail_internal(test, line_no, filename);
497         (void) mbedtls_snprintf(buf, sizeof(buf),
498                                 "lhs = 0x%016llx = %llu",
499                                 value1, value1);
500         mbedtls_test_set_line1_internal(buf);
501         (void) mbedtls_snprintf(buf, sizeof(buf),
502                                 "rhs = 0x%016llx = %llu",
503                                 value2, value2);
504         mbedtls_test_set_line2_internal(buf);
505     }
506 
507 #ifdef MBEDTLS_THREADING_C
508     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
509 #endif /* MBEDTLS_THREADING_C */
510 
511     return 0;
512 }
513 
mbedtls_test_le_s(const char * test,int line_no,const char * filename,long long value1,long long value2)514 int mbedtls_test_le_s(const char *test, int line_no, const char *filename,
515                       long long value1, long long value2)
516 {
517     TEST_CF_PUBLIC(&value1, sizeof(value1));
518     TEST_CF_PUBLIC(&value2, sizeof(value2));
519 
520     if (value1 <= value2) {
521         return 1;
522     }
523 
524 #ifdef MBEDTLS_THREADING_C
525     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
526 #endif /* MBEDTLS_THREADING_C */
527 
528     /* Don't use accessor, we already hold mutex. */
529     if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
530         /* If we've already recorded the test as having failed then don't
531          * overwrite any previous information about the failure. */
532 
533         char buf[MBEDTLS_TEST_LINE_LENGTH];
534         mbedtls_test_fail_internal(test, line_no, filename);
535         (void) mbedtls_snprintf(buf, sizeof(buf),
536                                 "lhs = 0x%016llx = %lld",
537                                 (unsigned long long) value1, value1);
538         mbedtls_test_set_line1_internal(buf);
539         (void) mbedtls_snprintf(buf, sizeof(buf),
540                                 "rhs = 0x%016llx = %lld",
541                                 (unsigned long long) value2, value2);
542         mbedtls_test_set_line2_internal(buf);
543     }
544 
545 #ifdef MBEDTLS_THREADING_C
546     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
547 #endif /* MBEDTLS_THREADING_C */
548 
549     return 0;
550 }
551 
mbedtls_test_unhexify(unsigned char * obuf,size_t obufmax,const char * ibuf,size_t * len)552 int mbedtls_test_unhexify(unsigned char *obuf,
553                           size_t obufmax,
554                           const char *ibuf,
555                           size_t *len)
556 {
557     unsigned char uc, uc2;
558 
559     *len = strlen(ibuf);
560 
561     /* Must be even number of bytes. */
562     if ((*len) & 1) {
563         return -1;
564     }
565     *len /= 2;
566 
567     if ((*len) > obufmax) {
568         return -1;
569     }
570 
571     while (*ibuf != 0) {
572         if (mbedtls_test_ascii2uc(*(ibuf++), &uc) != 0) {
573             return -1;
574         }
575 
576         if (mbedtls_test_ascii2uc(*(ibuf++), &uc2) != 0) {
577             return -1;
578         }
579 
580         *(obuf++) = (uc << 4) | uc2;
581     }
582 
583     return 0;
584 }
585 
mbedtls_test_hexify(unsigned char * obuf,const unsigned char * ibuf,int len)586 void mbedtls_test_hexify(unsigned char *obuf,
587                          const unsigned char *ibuf,
588                          int len)
589 {
590     unsigned char l, h;
591 
592     while (len != 0) {
593         h = *ibuf / 16;
594         l = *ibuf % 16;
595 
596         if (h < 10) {
597             *obuf++ = '0' + h;
598         } else {
599             *obuf++ = 'a' + h - 10;
600         }
601 
602         if (l < 10) {
603             *obuf++ = '0' + l;
604         } else {
605             *obuf++ = 'a' + l - 10;
606         }
607 
608         ++ibuf;
609         len--;
610     }
611 }
612 
mbedtls_test_zero_alloc(size_t len)613 unsigned char *mbedtls_test_zero_alloc(size_t len)
614 {
615     void *p;
616     size_t actual_len = (len != 0) ? len : 1;
617 
618     p = mbedtls_calloc(1, actual_len);
619     TEST_HELPER_ASSERT(p != NULL);
620 
621     memset(p, 0x00, actual_len);
622 
623     return p;
624 }
625 
mbedtls_test_unhexify_alloc(const char * ibuf,size_t * olen)626 unsigned char *mbedtls_test_unhexify_alloc(const char *ibuf, size_t *olen)
627 {
628     unsigned char *obuf;
629     size_t len;
630 
631     *olen = strlen(ibuf) / 2;
632 
633     if (*olen == 0) {
634         return mbedtls_test_zero_alloc(*olen);
635     }
636 
637     obuf = mbedtls_calloc(1, *olen);
638     TEST_HELPER_ASSERT(obuf != NULL);
639     TEST_HELPER_ASSERT(mbedtls_test_unhexify(obuf, *olen, ibuf, &len) == 0);
640 
641     return obuf;
642 }
643 
mbedtls_test_hexcmp(uint8_t * a,uint8_t * b,uint32_t a_len,uint32_t b_len)644 int mbedtls_test_hexcmp(uint8_t *a, uint8_t *b,
645                         uint32_t a_len, uint32_t b_len)
646 {
647     int ret = 0;
648     uint32_t i = 0;
649 
650     if (a_len != b_len) {
651         return -1;
652     }
653 
654     for (i = 0; i < a_len; i++) {
655         if (a[i] != b[i]) {
656             ret = -1;
657             break;
658         }
659     }
660     return ret;
661 }
662 
663 #if defined(MBEDTLS_TEST_HOOKS)
mbedtls_test_err_add_check(int high,int low,const char * file,int line)664 void mbedtls_test_err_add_check(int high, int low,
665                                 const char *file, int line)
666 {
667     /* Error codes are always negative (a value of zero is a success) however
668      * their positive opposites can be easier to understand. The following
669      * examples given in comments have been made positive for ease of
670      * understanding. The structure of an error code is such:
671      *
672      *                                                shhhhhhhhlllllll
673      *
674      * s = sign bit.
675      * h = high level error code (includes high level module ID (bits 12..14)
676      *     and module-dependent error code (bits 7..11)).
677      * l = low level error code.
678      */
679     if (high > -0x1000 && high != 0) {
680         /* high < 0001000000000000
681          * No high level module ID bits are set.
682          */
683         mbedtls_test_fail("'high' is not a high-level error code",
684                           line, file);
685     } else if (high < -0x7F80) {
686         /* high > 0111111110000000
687          * Error code is greater than the largest allowed high level module ID.
688          */
689         mbedtls_test_fail("'high' error code is greater than 15 bits",
690                           line, file);
691     } else if ((high & 0x7F) != 0) {
692         /* high & 0000000001111111
693          * Error code contains low level error code bits.
694          */
695         mbedtls_test_fail("'high' contains a low-level error code",
696                           line, file);
697     } else if (low < -0x007F) {
698         /* low >  0000000001111111
699          * Error code contains high or module level error code bits.
700          */
701         mbedtls_test_fail("'low' error code is greater than 7 bits",
702                           line, file);
703     } else if (low > 0) {
704         mbedtls_test_fail("'low' error code is greater than zero",
705                           line, file);
706     }
707 }
708 #endif /* MBEDTLS_TEST_HOOKS */
709