quickjs-tart

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

test_suite_constant_time.function (14693B)


      1 /* BEGIN_HEADER */
      2 /** \file test_suite_constant_time.function
      3  *
      4  * Functional testing of functions in the constant_time module.
      5  *
      6  * The tests are instrumented with #TEST_CF_SECRET and #TEST_CF_PUBLIC
      7  * (see framework/tests/include/test/constant_flow.h) so that running the tests
      8  * under MSan or Valgrind will detect a non-constant-time implementation.
      9  */
     10 
     11 #include <stdio.h>
     12 
     13 #include <limits.h>
     14 #include <stdlib.h>
     15 #include <errno.h>
     16 
     17 #include <mbedtls/bignum.h>
     18 #include <mbedtls/constant_time.h>
     19 #include <constant_time_internal.h>
     20 
     21 #include <test/constant_flow.h>
     22 /* END_HEADER */
     23 
     24 /* BEGIN_CASE */
     25 void mbedtls_ct_memcmp_null()
     26 {
     27     uint32_t x = 0;
     28     TEST_ASSERT(mbedtls_ct_memcmp(&x, NULL, 0) == 0);
     29     TEST_ASSERT(mbedtls_ct_memcmp(NULL, &x, 0) == 0);
     30     TEST_ASSERT(mbedtls_ct_memcmp(NULL, NULL, 0) == 0);
     31 }
     32 /* END_CASE */
     33 
     34 /* BEGIN_CASE */
     35 void mbedtls_ct_bool(char *input)
     36 {
     37     mbedtls_ct_uint_t v = (mbedtls_ct_uint_t) strtoull(input, NULL, 16);
     38     TEST_ASSERT(errno == 0);
     39 
     40     mbedtls_ct_condition_t expected = (v != 0) ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     41     TEST_CF_SECRET(&v, sizeof(v));
     42     TEST_EQUAL(mbedtls_ct_bool(v), expected);
     43     TEST_CF_PUBLIC(&v, sizeof(v));
     44 }
     45 /* END_CASE */
     46 
     47 /* BEGIN_CASE */
     48 void mbedtls_ct_bool_xxx(char *x_str, char *y_str)
     49 {
     50     mbedtls_ct_uint_t x = strtoull(x_str, NULL, 0);
     51     mbedtls_ct_uint_t y = strtoull(y_str, NULL, 0);
     52 
     53     mbedtls_ct_uint_t x1 = x;
     54     mbedtls_ct_uint_t y1 = y;
     55 
     56     TEST_CF_SECRET(&x, sizeof(x));
     57     TEST_CF_SECRET(&y, sizeof(y));
     58 
     59     mbedtls_ct_condition_t expected = x1 ? MBEDTLS_CT_FALSE : MBEDTLS_CT_TRUE;
     60     TEST_EQUAL(mbedtls_ct_bool_not(mbedtls_ct_bool(x)), expected);
     61 
     62     expected = x1 != y1 ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     63     TEST_EQUAL(mbedtls_ct_uint_ne(x, y), expected);
     64 
     65     expected = x1 == y1 ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     66     TEST_EQUAL(mbedtls_ct_uint_eq(x, y), expected);
     67 
     68     expected = x1 > y1 ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     69     TEST_EQUAL(mbedtls_ct_uint_gt(x, y), expected);
     70 
     71     expected = x1 < y1 ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     72     TEST_EQUAL(mbedtls_ct_uint_lt(x, y), expected);
     73 
     74     expected = x1 >= y1 ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     75     TEST_EQUAL(mbedtls_ct_uint_ge(x, y), expected);
     76 
     77     expected = x1 <= y1 ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     78     TEST_EQUAL(mbedtls_ct_uint_le(x, y), expected);
     79 
     80     expected = (!!x1) != (!!y1) ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     81     TEST_EQUAL(mbedtls_ct_bool_ne(mbedtls_ct_bool(x), mbedtls_ct_bool(y)), expected);
     82 
     83     expected = (!!x1) && (!!y1) ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     84     TEST_EQUAL(mbedtls_ct_bool_and(mbedtls_ct_bool(x), mbedtls_ct_bool(y)), expected);
     85 
     86     expected = (!!x1) || (!!y1) ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     87     TEST_EQUAL(mbedtls_ct_bool_or(mbedtls_ct_bool(x), mbedtls_ct_bool(y)), expected);
     88 
     89     TEST_CF_PUBLIC(&x, sizeof(x));
     90     TEST_CF_PUBLIC(&y, sizeof(y));
     91 }
     92 /* END_CASE */
     93 
     94 /* BEGIN_CASE depends_on:MBEDTLS_BASE64_C */
     95 void mbedtls_ct_uchar_in_range_if(int li, int hi, int ti)
     96 {
     97     unsigned char l = li, h = hi, t = ti;
     98 
     99     for (unsigned x = 0; x <= 255; x++) {
    100         unsigned char expected = (x >= l) && (x <= h) ? t : 0;
    101 
    102         TEST_CF_SECRET(&x, sizeof(x));
    103         TEST_CF_SECRET(&l, sizeof(l));
    104         TEST_CF_SECRET(&h, sizeof(h));
    105         TEST_CF_SECRET(&t, sizeof(t));
    106 
    107         TEST_EQUAL(mbedtls_ct_uchar_in_range_if(l, h, (unsigned char) x, t), expected);
    108 
    109         TEST_CF_PUBLIC(&x, sizeof(x));
    110         TEST_CF_PUBLIC(&l, sizeof(l));
    111         TEST_CF_PUBLIC(&h, sizeof(h));
    112         TEST_CF_PUBLIC(&t, sizeof(t));
    113     }
    114 }
    115 /* END_CASE */
    116 
    117 /* BEGIN_CASE */
    118 void mbedtls_ct_error_if(int cond, int t, int f)
    119 {
    120     mbedtls_ct_condition_t c = mbedtls_ct_bool(cond);
    121 
    122     int expected = c ? t : f;
    123     int expected0 = c ? t : 0;
    124 
    125     TEST_CF_SECRET(&c, sizeof(c));
    126     TEST_CF_SECRET(&t, sizeof(t));
    127     TEST_CF_SECRET(&f, sizeof(f));
    128 
    129     TEST_EQUAL(mbedtls_ct_error_if(c, t, f), expected);
    130     TEST_EQUAL(mbedtls_ct_error_if_else_0(c, t), expected0);
    131 
    132     TEST_CF_PUBLIC(&c, sizeof(c));
    133     TEST_CF_PUBLIC(&t, sizeof(t));
    134     TEST_CF_PUBLIC(&f, sizeof(f));
    135 }
    136 /* END_CASE */
    137 
    138 /* BEGIN_CASE */
    139 void mbedtls_ct_if(char *c_str, char *t_str, char *f_str)
    140 {
    141     mbedtls_ct_condition_t c = mbedtls_ct_bool(strtoull(c_str, NULL, 16));
    142     mbedtls_ct_uint_t t = (mbedtls_ct_uint_t) strtoull(t_str, NULL, 16);
    143     mbedtls_ct_uint_t f = (mbedtls_ct_uint_t) strtoull(f_str, NULL, 16);
    144 
    145     mbedtls_ct_uint_t expected = c ? t : f;
    146     mbedtls_ct_uint_t expected0 = c ? t : 0;
    147 
    148     TEST_CF_SECRET(&c, sizeof(c));
    149     TEST_CF_SECRET(&t, sizeof(t));
    150     TEST_CF_SECRET(&f, sizeof(f));
    151 
    152     TEST_EQUAL(mbedtls_ct_if(c, t, f), expected);
    153     TEST_EQUAL(mbedtls_ct_size_if(c, t, f), (size_t) expected);
    154     TEST_EQUAL(mbedtls_ct_uint_if(c, t, f), (unsigned) expected);
    155     TEST_EQUAL(mbedtls_ct_bool_if(c, mbedtls_ct_bool(t), mbedtls_ct_bool(f)),
    156                mbedtls_ct_bool(expected));
    157 #if defined(MBEDTLS_BIGNUM_C)
    158     TEST_EQUAL(mbedtls_ct_mpi_uint_if(c, t, f), (mbedtls_mpi_uint) expected);
    159 #endif
    160 
    161     TEST_EQUAL(mbedtls_ct_uint_if_else_0(c, t), (unsigned) expected0);
    162     TEST_EQUAL(mbedtls_ct_size_if_else_0(c, (size_t) t), (size_t) expected0);
    163     TEST_EQUAL(mbedtls_ct_bool_if_else_0(c, mbedtls_ct_bool(t)), mbedtls_ct_bool(expected0));
    164 #if defined(MBEDTLS_BIGNUM_C)
    165     TEST_EQUAL(mbedtls_ct_mpi_uint_if_else_0(c, t), (mbedtls_mpi_uint) expected0);
    166 #endif
    167 
    168     TEST_CF_PUBLIC(&c, sizeof(c));
    169     TEST_CF_PUBLIC(&t, sizeof(t));
    170     TEST_CF_PUBLIC(&f, sizeof(f));
    171 }
    172 /* END_CASE */
    173 
    174 /* BEGIN_CASE depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:!MBEDTLS_RSA_ALT */
    175 void mbedtls_ct_zeroize_if(char *c_str, int len)
    176 {
    177     uint8_t *buf = NULL;
    178     mbedtls_ct_condition_t c = mbedtls_ct_bool(strtoull(c_str, NULL, 16));
    179 
    180     TEST_CALLOC(buf, len);
    181     for (size_t i = 0; i < (size_t) len; i++) {
    182         buf[i] = 1;
    183     }
    184 
    185     TEST_CF_SECRET(&c, sizeof(c));
    186     TEST_CF_SECRET(buf, len);
    187     mbedtls_ct_zeroize_if(c, buf, len);
    188     TEST_CF_PUBLIC(&c, sizeof(c));
    189     TEST_CF_PUBLIC(buf, len);
    190 
    191     for (size_t i = 0; i < (size_t) len; i++) {
    192         TEST_EQUAL(buf[i], c != 0 ? 0 : 1);
    193     }
    194 exit:
    195     mbedtls_free(buf);
    196 }
    197 /* END_CASE */
    198 
    199 /* BEGIN_CASE */
    200 void mbedtls_ct_memcmp_single_bit_diff()
    201 {
    202     uint8_t *a = NULL, *b = NULL;
    203     size_t size = 32;
    204     TEST_CALLOC(a, size);
    205     TEST_CALLOC(b, size);
    206 
    207     TEST_CF_SECRET(a, size);
    208     TEST_CF_SECRET(b, size);
    209     int result = mbedtls_ct_memcmp(a, b, size);
    210     TEST_CF_PUBLIC(a, size);
    211     TEST_CF_PUBLIC(b, size);
    212     TEST_CF_PUBLIC(&result, sizeof(result));
    213 
    214     TEST_EQUAL(result, 0);
    215 
    216     for (size_t offset = 0; offset < size; offset++) {
    217         for (size_t bit_offset = 0; bit_offset < 8; bit_offset++) {
    218             /* Set a single bit to be different at given offset, to test that we
    219                detect single-bit differences */
    220             a[offset] = 1 << bit_offset;
    221 
    222             TEST_CF_SECRET(a, size);
    223             TEST_CF_SECRET(b, size);
    224             result = mbedtls_ct_memcmp(a, b, size);
    225             TEST_CF_PUBLIC(a, size);
    226             TEST_CF_PUBLIC(b, size);
    227             TEST_CF_PUBLIC(&result, sizeof(result));
    228 
    229             TEST_ASSERT(result != 0);
    230 
    231             a[offset] = 0;
    232         }
    233     }
    234 
    235 
    236 exit:
    237     mbedtls_free(a);
    238     mbedtls_free(b);
    239 }
    240 /* END_CASE */
    241 
    242 /* BEGIN_CASE */
    243 void mbedtls_ct_memcmp(int same, int size, int offset)
    244 {
    245     uint8_t *a = NULL, *b = NULL;
    246     TEST_CALLOC(a, size + offset);
    247     TEST_CALLOC(b, size + offset);
    248 
    249     /* Construct data that matches, if same == -1, otherwise
    250      * same gives the number of bytes (after the initial offset)
    251      * that will match; after that it will differ.
    252      */
    253     for (int i = 0; i < size + offset; i++) {
    254         a[i] = i & 0xff;
    255         if (same == -1 || (i - offset) < same) {
    256             b[i] = a[i];
    257         } else {
    258             b[i] = (i + 1) & 0xff;
    259         }
    260     }
    261 
    262     int reference = memcmp(a + offset, b + offset, size);
    263 
    264     TEST_CF_SECRET(a, size + offset);
    265     TEST_CF_SECRET(b, size + offset);
    266 
    267     int actual = mbedtls_ct_memcmp(a + offset, b + offset, size);
    268 
    269     TEST_CF_PUBLIC(a, size + offset);
    270     TEST_CF_PUBLIC(b, size + offset);
    271     TEST_CF_PUBLIC(&actual, sizeof(actual));
    272 
    273     if (same == -1 || same >= size) {
    274         TEST_ASSERT(reference == 0);
    275         TEST_ASSERT(actual == 0);
    276     } else {
    277         TEST_ASSERT(reference != 0);
    278         TEST_ASSERT(actual != 0);
    279     }
    280 exit:
    281     mbedtls_free(a);
    282     mbedtls_free(b);
    283 }
    284 /* END_CASE */
    285 
    286 /* BEGIN_CASE depends_on:MBEDTLS_NIST_KW_C */
    287 
    288 /**
    289  * Generate two arrays of the given size, and test mbedtls_ct_memcmp_partial
    290  * over them. The arrays will be identical, except that one byte may be specified
    291  * to be different.
    292  *
    293  * \p diff      Index of byte that differs (if out of range, the arrays will match).
    294  * \p size      Size of arrays to compare
    295  * \p skip_head Leading bytes to skip, as per mbedtls_ct_memcmp_partial
    296  * \p skip_tail Trailing bytes to skip, as per mbedtls_ct_memcmp_partial
    297  */
    298 void mbedtls_ct_memcmp_partial(int diff, int size, int skip_head, int skip_tail)
    299 {
    300     uint8_t *a = NULL, *b = NULL;
    301 
    302     TEST_CALLOC_NONNULL(a, size);
    303     TEST_CALLOC_NONNULL(b, size);
    304 
    305     TEST_ASSERT((skip_head + skip_tail) <= size);
    306 
    307     /* Construct data that matches, except for specified byte (if in range). */
    308     for (int i = 0; i < size; i++) {
    309         a[i] = i & 0xff;
    310         b[i] = a[i];
    311         if (i == diff) {
    312             // modify the specified byte
    313             b[i] ^= 1;
    314         }
    315     }
    316 
    317     int reference = memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail);
    318 
    319     TEST_CF_SECRET(a, size);
    320     TEST_CF_SECRET(b, size);
    321 
    322     int actual = mbedtls_ct_memcmp_partial(a, b, size, skip_head, skip_tail);
    323 
    324     TEST_CF_PUBLIC(a, size);
    325     TEST_CF_PUBLIC(b, size);
    326     TEST_CF_PUBLIC(&actual, sizeof(actual));
    327 
    328     TEST_EQUAL(!!reference, !!actual);
    329 exit:
    330     mbedtls_free(a);
    331     mbedtls_free(b);
    332 }
    333 /* END_CASE */
    334 
    335 /* BEGIN_CASE */
    336 void mbedtls_ct_memcpy_if(int eq, int size, int offset)
    337 {
    338     uint8_t *src = NULL, *src2 = NULL, *result = NULL, *expected = NULL;
    339     TEST_CALLOC(src, size + offset);
    340     TEST_CALLOC(src2, size + offset);
    341     TEST_CALLOC(result, size + offset);
    342     TEST_CALLOC(expected, size + offset);
    343 
    344     /* Apply offset to result only */
    345     for (int i = 0; i < size + offset; i++) {
    346         src[i]      = 1;
    347         result[i]   = 0xff;
    348         expected[i] = eq ? 1 : 0xff;
    349     }
    350 
    351     int secret_eq = eq;
    352     TEST_CF_SECRET(&secret_eq, sizeof(secret_eq));
    353     TEST_CF_SECRET(src, size + offset);
    354     TEST_CF_SECRET(result, size + offset);
    355 
    356     mbedtls_ct_memcpy_if(mbedtls_ct_bool(secret_eq), result + offset, src, NULL, size);
    357 
    358     TEST_CF_PUBLIC(&secret_eq, sizeof(secret_eq));
    359     TEST_CF_PUBLIC(src, size + offset);
    360     TEST_CF_PUBLIC(result, size + offset);
    361 
    362     TEST_MEMORY_COMPARE(expected, size, result + offset, size);
    363 
    364 
    365     /* Apply offset to src only */
    366     for (int i = 0; i < size + offset; i++) {
    367         src[i]    = 1;
    368         result[i] = 0xff;
    369         expected[i] = eq ? 1 : 0xff;
    370     }
    371 
    372     TEST_CF_SECRET(&secret_eq, sizeof(secret_eq));
    373     TEST_CF_SECRET(src, size + offset);
    374     TEST_CF_SECRET(result, size + offset);
    375 
    376     mbedtls_ct_memcpy_if(mbedtls_ct_bool(secret_eq), result, src + offset, NULL, size);
    377 
    378     TEST_CF_PUBLIC(&secret_eq, sizeof(secret_eq));
    379     TEST_CF_PUBLIC(src, size + offset);
    380     TEST_CF_PUBLIC(result, size + offset);
    381 
    382     TEST_MEMORY_COMPARE(expected, size, result, size);
    383 
    384 
    385     /* Apply offset to src and src2 */
    386     for (int i = 0; i < size + offset; i++) {
    387         src[i]      = 1;
    388         src2[i]     = 2;
    389         result[i]   = 0xff;
    390         expected[i] = eq ? 1 : 2;
    391     }
    392 
    393     TEST_CF_SECRET(&secret_eq, sizeof(secret_eq));
    394     TEST_CF_SECRET(src, size + offset);
    395     TEST_CF_SECRET(src2, size + offset);
    396     TEST_CF_SECRET(result, size + offset);
    397 
    398     mbedtls_ct_memcpy_if(mbedtls_ct_bool(secret_eq), result, src + offset, src2 + offset, size);
    399 
    400     TEST_CF_PUBLIC(&secret_eq, sizeof(secret_eq));
    401     TEST_CF_PUBLIC(src, size + offset);
    402     TEST_CF_SECRET(src2, size + offset);
    403     TEST_CF_PUBLIC(result, size + offset);
    404 
    405     TEST_MEMORY_COMPARE(expected, size, result, size);
    406 
    407 
    408     /* result == src == dest */
    409     for (int i = 0; i < size + offset; i++) {
    410         src[i]      = 2;
    411         expected[i] = 2;
    412     }
    413 
    414     TEST_CF_SECRET(&secret_eq, sizeof(secret_eq));
    415     TEST_CF_SECRET(src, size + offset);
    416     TEST_CF_SECRET(result, size + offset);
    417 
    418     mbedtls_ct_memcpy_if(mbedtls_ct_bool(secret_eq), src + offset, src + offset, src + offset,
    419                          size);
    420 
    421     TEST_CF_PUBLIC(&secret_eq, sizeof(secret_eq));
    422     TEST_CF_PUBLIC(src, size + offset);
    423     TEST_CF_PUBLIC(result, size + offset);
    424 
    425     TEST_MEMORY_COMPARE(expected, size, src + offset, size);
    426 exit:
    427     mbedtls_free(src);
    428     mbedtls_free(src2);
    429     mbedtls_free(result);
    430     mbedtls_free(expected);
    431 }
    432 /* END_CASE */
    433 
    434 /* BEGIN_CASE depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:!MBEDTLS_RSA_ALT */
    435 void mbedtls_ct_memmove_left(int len, int offset)
    436 {
    437     size_t l = (size_t) len;
    438     size_t o = (size_t) offset;
    439 
    440     uint8_t *buf = NULL, *buf_expected = NULL;
    441     TEST_CALLOC(buf, l);
    442     TEST_CALLOC(buf_expected, l);
    443 
    444     for (size_t i = 0; i < l; i++) {
    445         buf[i] = (uint8_t) i;
    446         buf_expected[i] = buf[i];
    447     }
    448 
    449     TEST_CF_SECRET(&o, sizeof(o));
    450     TEST_CF_SECRET(buf, l);
    451     mbedtls_ct_memmove_left(buf, l, o);
    452     TEST_CF_PUBLIC(&o, sizeof(o));
    453     TEST_CF_PUBLIC(buf, l);
    454 
    455     if (l > 0) {
    456         memmove(buf_expected, buf_expected + o, l - o);
    457         memset(buf_expected + (l - o), 0, o);
    458         TEST_ASSERT(memcmp(buf, buf_expected, l) == 0);
    459     }
    460 exit:
    461     mbedtls_free(buf);
    462     mbedtls_free(buf_expected);
    463 }
    464 /* END_CASE */
    465 
    466 /* BEGIN_CASE */
    467 void mbedtls_ct_memcpy_offset(int offset_min, int offset_max, int len)
    468 {
    469     unsigned char *dst = NULL;
    470     unsigned char *src = NULL;
    471     size_t src_len = offset_max + len;
    472     size_t secret;
    473 
    474     TEST_CALLOC(dst, len);
    475     TEST_CALLOC(src, src_len);
    476 
    477     /* Fill src in a way that we can detect if we copied the right bytes */
    478     mbedtls_test_rnd_std_rand(NULL, src, src_len);
    479 
    480     for (secret = offset_min; secret <= (size_t) offset_max; secret++) {
    481         mbedtls_test_set_step((int) secret);
    482 
    483         TEST_CF_SECRET(&secret, sizeof(secret));
    484         TEST_CF_SECRET(src, len);
    485         TEST_CF_SECRET(dst, len);
    486         mbedtls_ct_memcpy_offset(dst, src, secret,
    487                                  offset_min, offset_max, len);
    488         TEST_CF_PUBLIC(&secret, sizeof(secret));
    489         TEST_CF_PUBLIC(src, len);
    490         TEST_CF_PUBLIC(dst, len);
    491 
    492         TEST_MEMORY_COMPARE(dst, len, src + secret, len);
    493     }
    494 
    495 exit:
    496     mbedtls_free(dst);
    497     mbedtls_free(src);
    498 }
    499 /* END_CASE */