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