quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

helpers.c (20719B)


      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_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)
     30 static mbedtls_platform_context platform_ctx;
     31 #endif
     32 
     33 static mbedtls_test_info_t mbedtls_test_info;
     34 
     35 #ifdef MBEDTLS_THREADING_C
     36 mbedtls_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 
     51 mbedtls_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 
     68 static 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 
     80 const 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 }
     96 const 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 
    115 int 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 
    132 void 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 
    145 unsigned 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 
    162 static 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 
    170 void 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 
    183 void 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 
    196 static 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 
    208 void 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 
    221 static 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)
    235 const 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 
    252 void 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 int mbedtls_test_buffer_is_all_zero(const uint8_t *buf, size_t size)
    269 {
    270     for (size_t i = 0; i < size; i++) {
    271         if (buf[i] != 0) {
    272             return 0;
    273         }
    274     }
    275     return 1;
    276 }
    277 
    278 #if defined(MBEDTLS_BIGNUM_C)
    279 
    280 unsigned mbedtls_test_get_case_uses_negative_0(void)
    281 {
    282     unsigned test_case_uses_negative_0 = 0;
    283 #ifdef MBEDTLS_THREADING_C
    284     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
    285 #endif /* MBEDTLS_THREADING_C */
    286     test_case_uses_negative_0 = mbedtls_test_info.case_uses_negative_0;
    287 
    288 #ifdef MBEDTLS_THREADING_C
    289     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
    290 #endif /* MBEDTLS_THREADING_C */
    291 
    292     return test_case_uses_negative_0;
    293 }
    294 
    295 static void mbedtls_test_set_case_uses_negative_0_internal(unsigned uses)
    296 {
    297     /* Internal function only - mbedtls_test_info_mutex should be held prior
    298      * to calling this function. */
    299 
    300     mbedtls_test_info.case_uses_negative_0 = uses;
    301 }
    302 
    303 void mbedtls_test_increment_case_uses_negative_0(void)
    304 {
    305 #ifdef MBEDTLS_THREADING_C
    306     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
    307 #endif /* MBEDTLS_THREADING_C */
    308 
    309     ++mbedtls_test_info.case_uses_negative_0;
    310 
    311 #ifdef MBEDTLS_THREADING_C
    312     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
    313 #endif /* MBEDTLS_THREADING_C */
    314 }
    315 
    316 #endif /* MBEDTLS_BIGNUM_C */
    317 
    318 #ifdef MBEDTLS_TEST_MUTEX_USAGE
    319 mbedtls_threading_mutex_t *mbedtls_test_get_info_mutex(void)
    320 {
    321     return &mbedtls_test_info_mutex;
    322 }
    323 
    324 #endif /* MBEDTLS_TEST_MUTEX_USAGE */
    325 
    326 /*----------------------------------------------------------------------------*/
    327 /* Helper Functions */
    328 
    329 int mbedtls_test_platform_setup(void)
    330 {
    331     int ret = 0;
    332 
    333 #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \
    334     && !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) \
    335     && defined(MBEDTLS_TEST_MEMORY_CAN_POISON)
    336     mbedtls_poison_test_hooks_setup();
    337 #endif
    338 
    339 #if defined(MBEDTLS_PSA_INJECT_ENTROPY)
    340     /* Make sure that injected entropy is present. Otherwise
    341      * psa_crypto_init() will fail. This is not necessary for test suites
    342      * that don't use PSA, but it's harmless (except for leaving a file
    343      * behind). */
    344     ret = mbedtls_test_inject_entropy_restore();
    345     if (ret != 0) {
    346         return ret;
    347     }
    348 #endif
    349 
    350 #if defined(MBEDTLS_PLATFORM_C)
    351     ret = mbedtls_platform_setup(&platform_ctx);
    352 #endif /* MBEDTLS_PLATFORM_C */
    353 
    354 #ifdef MBEDTLS_THREADING_C
    355     mbedtls_mutex_init(&mbedtls_test_info_mutex);
    356 #endif /* MBEDTLS_THREADING_C */
    357 
    358 
    359 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
    360     mbedtls_codepath_test_hooks_setup();
    361 #endif /* MBEDTLS_TEST_HOOKS && !MBEDTLS_THREADING_C */
    362 
    363     return ret;
    364 }
    365 
    366 void mbedtls_test_platform_teardown(void)
    367 {
    368 #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \
    369     && !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) \
    370     &&  defined(MBEDTLS_TEST_MEMORY_CAN_POISON)
    371     mbedtls_poison_test_hooks_teardown();
    372 #endif
    373 #ifdef MBEDTLS_THREADING_C
    374     mbedtls_mutex_free(&mbedtls_test_info_mutex);
    375 #endif /* MBEDTLS_THREADING_C */
    376 
    377 #if defined(MBEDTLS_PLATFORM_C)
    378     mbedtls_platform_teardown(&platform_ctx);
    379 #endif /* MBEDTLS_PLATFORM_C */
    380 
    381 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
    382     mbedtls_codepath_test_hooks_teardown();
    383 #endif /* MBEDTLS_TEST_HOOKS && !MBEDTLS_THREADING_C */
    384 }
    385 
    386 int mbedtls_test_ascii2uc(const char c, unsigned char *uc)
    387 {
    388     if ((c >= '0') && (c <= '9')) {
    389         *uc = c - '0';
    390     } else if ((c >= 'a') && (c <= 'f')) {
    391         *uc = c - 'a' + 10;
    392     } else if ((c >= 'A') && (c <= 'F')) {
    393         *uc = c - 'A' + 10;
    394     } else {
    395         return -1;
    396     }
    397 
    398     return 0;
    399 }
    400 
    401 static void mbedtls_test_fail_internal(const char *test, int line_no, const char *filename)
    402 {
    403     /* Internal function only - mbedtls_test_info_mutex should be held prior
    404      * to calling this function. */
    405 
    406     /* Don't use accessor, we already hold mutex. */
    407     if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
    408         /* If we have already recorded the test as having failed then don't
    409          * overwrite any previous information about the failure. */
    410         mbedtls_test_set_result_internal(MBEDTLS_TEST_RESULT_FAILED, test, line_no, filename);
    411     }
    412 }
    413 
    414 void mbedtls_test_fail(const char *test, int line_no, const char *filename)
    415 {
    416 #ifdef MBEDTLS_THREADING_C
    417     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
    418 #endif /* MBEDTLS_THREADING_C */
    419 
    420     mbedtls_test_fail_internal(test, line_no, filename);
    421 
    422 #ifdef MBEDTLS_THREADING_C
    423     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
    424 #endif /* MBEDTLS_THREADING_C */
    425 }
    426 
    427 void mbedtls_test_skip(const char *test, int line_no, const char *filename)
    428 {
    429 #ifdef MBEDTLS_THREADING_C
    430     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
    431 #endif /* MBEDTLS_THREADING_C */
    432 
    433     mbedtls_test_set_result_internal(MBEDTLS_TEST_RESULT_SKIPPED, test, line_no, filename);
    434 
    435 #ifdef MBEDTLS_THREADING_C
    436     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
    437 #endif /* MBEDTLS_THREADING_C */
    438 }
    439 
    440 void mbedtls_test_info_reset(void)
    441 {
    442 #ifdef MBEDTLS_THREADING_C
    443     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
    444 #endif /* MBEDTLS_THREADING_C */
    445 
    446     mbedtls_test_set_result_internal(MBEDTLS_TEST_RESULT_SUCCESS, 0, 0, 0);
    447     mbedtls_test_reset_step_internal();
    448     mbedtls_test_set_line1_internal(NULL);
    449     mbedtls_test_set_line2_internal(NULL);
    450 
    451 #if defined(MBEDTLS_BIGNUM_C)
    452     mbedtls_test_set_case_uses_negative_0_internal(0);
    453 #endif
    454 
    455 #ifdef MBEDTLS_THREADING_C
    456     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
    457 #endif /* MBEDTLS_THREADING_C */
    458 }
    459 
    460 int mbedtls_test_equal(const char *test, int line_no, const char *filename,
    461                        unsigned long long value1, unsigned long long value2)
    462 {
    463     TEST_CF_PUBLIC(&value1, sizeof(value1));
    464     TEST_CF_PUBLIC(&value2, sizeof(value2));
    465 
    466     if (value1 == value2) {
    467         return 1;
    468     }
    469 
    470 #ifdef MBEDTLS_THREADING_C
    471     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
    472 #endif /* MBEDTLS_THREADING_C */
    473 
    474     /* Don't use accessor, as we already hold mutex. */
    475     if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
    476         /* If we've already recorded the test as having failed then don't
    477          * overwrite any previous information about the failure. */
    478 
    479         char buf[MBEDTLS_TEST_LINE_LENGTH];
    480         mbedtls_test_fail_internal(test, line_no, filename);
    481         (void) mbedtls_snprintf(buf, sizeof(buf),
    482                                 "lhs = 0x%016llx = %lld",
    483                                 value1, (long long) value1);
    484         mbedtls_test_set_line1_internal(buf);
    485         (void) mbedtls_snprintf(buf, sizeof(buf),
    486                                 "rhs = 0x%016llx = %lld",
    487                                 value2, (long long) value2);
    488         mbedtls_test_set_line2_internal(buf);
    489     }
    490 
    491 #ifdef MBEDTLS_THREADING_C
    492     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
    493 #endif /* MBEDTLS_THREADING_C */
    494 
    495     return 0;
    496 }
    497 
    498 int mbedtls_test_le_u(const char *test, int line_no, const char *filename,
    499                       unsigned long long value1, unsigned long long value2)
    500 {
    501     TEST_CF_PUBLIC(&value1, sizeof(value1));
    502     TEST_CF_PUBLIC(&value2, sizeof(value2));
    503 
    504     if (value1 <= value2) {
    505         return 1;
    506     }
    507 
    508 #ifdef MBEDTLS_THREADING_C
    509     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
    510 #endif /* MBEDTLS_THREADING_C */
    511 
    512     /* Don't use accessor, we already hold mutex. */
    513     if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
    514         /* If we've already recorded the test as having failed then don't
    515          * overwrite any previous information about the failure. */
    516 
    517         char buf[MBEDTLS_TEST_LINE_LENGTH];
    518         mbedtls_test_fail_internal(test, line_no, filename);
    519         (void) mbedtls_snprintf(buf, sizeof(buf),
    520                                 "lhs = 0x%016llx = %llu",
    521                                 value1, value1);
    522         mbedtls_test_set_line1_internal(buf);
    523         (void) mbedtls_snprintf(buf, sizeof(buf),
    524                                 "rhs = 0x%016llx = %llu",
    525                                 value2, value2);
    526         mbedtls_test_set_line2_internal(buf);
    527     }
    528 
    529 #ifdef MBEDTLS_THREADING_C
    530     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
    531 #endif /* MBEDTLS_THREADING_C */
    532 
    533     return 0;
    534 }
    535 
    536 int mbedtls_test_le_s(const char *test, int line_no, const char *filename,
    537                       long long value1, long long value2)
    538 {
    539     TEST_CF_PUBLIC(&value1, sizeof(value1));
    540     TEST_CF_PUBLIC(&value2, sizeof(value2));
    541 
    542     if (value1 <= value2) {
    543         return 1;
    544     }
    545 
    546 #ifdef MBEDTLS_THREADING_C
    547     mbedtls_mutex_lock(&mbedtls_test_info_mutex);
    548 #endif /* MBEDTLS_THREADING_C */
    549 
    550     /* Don't use accessor, we already hold mutex. */
    551     if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
    552         /* If we've already recorded the test as having failed then don't
    553          * overwrite any previous information about the failure. */
    554 
    555         char buf[MBEDTLS_TEST_LINE_LENGTH];
    556         mbedtls_test_fail_internal(test, line_no, filename);
    557         (void) mbedtls_snprintf(buf, sizeof(buf),
    558                                 "lhs = 0x%016llx = %lld",
    559                                 (unsigned long long) value1, value1);
    560         mbedtls_test_set_line1_internal(buf);
    561         (void) mbedtls_snprintf(buf, sizeof(buf),
    562                                 "rhs = 0x%016llx = %lld",
    563                                 (unsigned long long) value2, value2);
    564         mbedtls_test_set_line2_internal(buf);
    565     }
    566 
    567 #ifdef MBEDTLS_THREADING_C
    568     mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
    569 #endif /* MBEDTLS_THREADING_C */
    570 
    571     return 0;
    572 }
    573 
    574 int mbedtls_test_unhexify(unsigned char *obuf,
    575                           size_t obufmax,
    576                           const char *ibuf,
    577                           size_t *len)
    578 {
    579     unsigned char uc, uc2;
    580 
    581     *len = strlen(ibuf);
    582 
    583     /* Must be even number of bytes. */
    584     if ((*len) & 1) {
    585         return -1;
    586     }
    587     *len /= 2;
    588 
    589     if ((*len) > obufmax) {
    590         return -1;
    591     }
    592 
    593     while (*ibuf != 0) {
    594         if (mbedtls_test_ascii2uc(*(ibuf++), &uc) != 0) {
    595             return -1;
    596         }
    597 
    598         if (mbedtls_test_ascii2uc(*(ibuf++), &uc2) != 0) {
    599             return -1;
    600         }
    601 
    602         *(obuf++) = (uc << 4) | uc2;
    603     }
    604 
    605     return 0;
    606 }
    607 
    608 void mbedtls_test_hexify(unsigned char *obuf,
    609                          const unsigned char *ibuf,
    610                          int len)
    611 {
    612     unsigned char l, h;
    613 
    614     while (len != 0) {
    615         h = *ibuf / 16;
    616         l = *ibuf % 16;
    617 
    618         if (h < 10) {
    619             *obuf++ = '0' + h;
    620         } else {
    621             *obuf++ = 'a' + h - 10;
    622         }
    623 
    624         if (l < 10) {
    625             *obuf++ = '0' + l;
    626         } else {
    627             *obuf++ = 'a' + l - 10;
    628         }
    629 
    630         ++ibuf;
    631         len--;
    632     }
    633 }
    634 
    635 unsigned char *mbedtls_test_zero_alloc(size_t len)
    636 {
    637     void *p;
    638     size_t actual_len = (len != 0) ? len : 1;
    639 
    640     p = mbedtls_calloc(1, actual_len);
    641     TEST_HELPER_ASSERT(p != NULL);
    642 
    643     memset(p, 0x00, actual_len);
    644 
    645     return p;
    646 }
    647 
    648 unsigned char *mbedtls_test_unhexify_alloc(const char *ibuf, size_t *olen)
    649 {
    650     unsigned char *obuf;
    651     size_t len;
    652 
    653     *olen = strlen(ibuf) / 2;
    654 
    655     if (*olen == 0) {
    656         return mbedtls_test_zero_alloc(*olen);
    657     }
    658 
    659     obuf = mbedtls_calloc(1, *olen);
    660     TEST_HELPER_ASSERT(obuf != NULL);
    661     TEST_HELPER_ASSERT(mbedtls_test_unhexify(obuf, *olen, ibuf, &len) == 0);
    662 
    663     return obuf;
    664 }
    665 
    666 int mbedtls_test_hexcmp(uint8_t *a, uint8_t *b,
    667                         uint32_t a_len, uint32_t b_len)
    668 {
    669     int ret = 0;
    670     uint32_t i = 0;
    671 
    672     if (a_len != b_len) {
    673         return -1;
    674     }
    675 
    676     for (i = 0; i < a_len; i++) {
    677         if (a[i] != b[i]) {
    678             ret = -1;
    679             break;
    680         }
    681     }
    682     return ret;
    683 }
    684 
    685 #if defined(MBEDTLS_TEST_HOOKS)
    686 void mbedtls_test_err_add_check(int high, int low,
    687                                 const char *file, int line)
    688 {
    689     /* Error codes are always negative (a value of zero is a success) however
    690      * their positive opposites can be easier to understand. The following
    691      * examples given in comments have been made positive for ease of
    692      * understanding. The structure of an error code is such:
    693      *
    694      *                                                shhhhhhhhlllllll
    695      *
    696      * s = sign bit.
    697      * h = high level error code (includes high level module ID (bits 12..14)
    698      *     and module-dependent error code (bits 7..11)).
    699      * l = low level error code.
    700      */
    701     if (high > -0x1000 && high != 0) {
    702         /* high < 0001000000000000
    703          * No high level module ID bits are set.
    704          */
    705         mbedtls_test_fail("'high' is not a high-level error code",
    706                           line, file);
    707     } else if (high < -0x7F80) {
    708         /* high > 0111111110000000
    709          * Error code is greater than the largest allowed high level module ID.
    710          */
    711         mbedtls_test_fail("'high' error code is greater than 15 bits",
    712                           line, file);
    713     } else if ((high & 0x7F) != 0) {
    714         /* high & 0000000001111111
    715          * Error code contains low level error code bits.
    716          */
    717         mbedtls_test_fail("'high' contains a low-level error code",
    718                           line, file);
    719     } else if (low < -0x007F) {
    720         /* low >  0000000001111111
    721          * Error code contains high or module level error code bits.
    722          */
    723         mbedtls_test_fail("'low' error code is greater than 7 bits",
    724                           line, file);
    725     } else if (low > 0) {
    726         mbedtls_test_fail("'low' error code is greater than zero",
    727                           line, file);
    728     }
    729 }
    730 
    731 void (*mbedtls_test_hook_error_add)(int, int, const char *, int);
    732 
    733 #endif /* MBEDTLS_TEST_HOOKS */