quickjs-tart

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

test_suite_alignment.function (9825B)


      1 /* BEGIN_HEADER */
      2 #include <alignment.h>
      3 
      4 #include <stdint.h>
      5 
      6 #if defined(__clang__)
      7 #pragma clang diagnostic ignored "-Wunreachable-code"
      8 #endif
      9 
     10 /*
     11  * Convert a string of the form "abcd" (case-insensitive) to a uint64_t.
     12  */
     13 static int parse_hex_string(char *hex_string, uint64_t *result)
     14 {
     15     uint8_t raw[8] = { 0 };
     16     size_t olen;
     17     if (mbedtls_test_unhexify(raw, sizeof(raw), hex_string, &olen) != 0) {
     18         return 0;
     19     }
     20 
     21     *result = 0;
     22     for (size_t i = 0; i < olen; i++) {
     23         *result |= ((uint64_t) raw[i]) << ((olen - i - 1) * 8);
     24     }
     25     return 1;
     26 }
     27 
     28 /* END_HEADER */
     29 
     30 /* BEGIN_CASE */
     31 void mbedtls_unaligned_access(int size, int offset)
     32 {
     33     /* Define 64-bit aligned raw byte array */
     34     uint64_t raw[2];
     35 
     36     /* Populate with known data */
     37     uint8_t *x = (uint8_t *) raw;
     38     for (size_t i = 0; i < sizeof(raw); i++) {
     39         x[i] = (uint8_t) i;
     40     }
     41 
     42     TEST_ASSERT(size == 16 || size == 32 || size == 64);
     43 
     44     uint64_t r = 0;
     45     switch (size) {
     46         case 16:
     47             r = mbedtls_get_unaligned_uint16(x + offset);
     48             break;
     49         case 32:
     50             r = mbedtls_get_unaligned_uint32(x + offset);
     51             break;
     52         case 64:
     53             r = mbedtls_get_unaligned_uint64(x + offset);
     54             break;
     55     }
     56 
     57     /* Define expected result by manually aligning the raw bytes, and
     58      * reading back with a normal pointer access. */
     59     uint64_t raw_aligned_64;
     60     uint16_t *raw_aligned_16 = (uint16_t *) &raw_aligned_64;
     61     uint32_t *raw_aligned_32 = (uint32_t *) &raw_aligned_64;
     62     memcpy(&raw_aligned_64, ((uint8_t *) &raw) + offset, size / 8);
     63     /* Make a 16/32/64 byte read from the aligned location, and copy to expected */
     64     uint64_t expected = 0;
     65     switch (size) {
     66         case 16:
     67             expected = *raw_aligned_16;
     68             break;
     69         case 32:
     70             expected = *raw_aligned_32;
     71             break;
     72         case 64:
     73             expected = raw_aligned_64;
     74             break;
     75     }
     76 
     77     TEST_EQUAL(r, expected);
     78 
     79     /* Write sentinel to the part of the array we will test writing to */
     80     for (size_t i = 0; i < (size_t) (size / 8); i++) {
     81         x[i + offset] = 0xff;
     82     }
     83     /*
     84      * Write back to the array with mbedtls_put_unaligned_uint16 and validate
     85      * that the array is unchanged as a result.
     86      */
     87     switch (size) {
     88         case 16:
     89             mbedtls_put_unaligned_uint16(x + offset, r);
     90             break;
     91         case 32:
     92             mbedtls_put_unaligned_uint32(x + offset, r);
     93             break;
     94         case 64:
     95             mbedtls_put_unaligned_uint64(x + offset, r);
     96             break;
     97     }
     98     for (size_t i = 0; i < sizeof(x); i++) {
     99         TEST_EQUAL(x[i], (uint8_t) i);
    100     }
    101 }
    102 /* END_CASE */
    103 
    104 /* BEGIN_CASE */
    105 void mbedtls_byteswap(char *input_str, int size, char *expected_str)
    106 {
    107     uint64_t input = 0, expected = 0;
    108     TEST_ASSERT(parse_hex_string(input_str, &input));
    109     TEST_ASSERT(parse_hex_string(expected_str, &expected));
    110 
    111     /* Check against expected result */
    112     uint64_t r = 0;
    113     switch (size) {
    114         case 16:
    115             r = MBEDTLS_BSWAP16(input);
    116             break;
    117         case 32:
    118             r = MBEDTLS_BSWAP32(input);
    119             break;
    120         case 64:
    121             r = MBEDTLS_BSWAP64(input);
    122             break;
    123         default:
    124             TEST_FAIL("size must be 16, 32 or 64");
    125     }
    126     TEST_EQUAL(r, expected);
    127 
    128     /*
    129      * Check byte by byte by extracting bytes from opposite ends of
    130      * input and r.
    131      */
    132     for (size_t i = 0; i < (size_t) (size / 8); i++) {
    133         size_t s1 = i * 8;
    134         size_t s2 = ((size / 8 - 1) - i) * 8;
    135         uint64_t a = (input & ((uint64_t) 0xff << s1)) >> s1;
    136         uint64_t b = (r & ((uint64_t) 0xff << s2)) >> s2;
    137         TEST_EQUAL(a, b);
    138     }
    139 
    140     /* Check BSWAP(BSWAP(x)) == x */
    141     switch (size) {
    142         case 16:
    143             r = MBEDTLS_BSWAP16(r);
    144             TEST_EQUAL(r, input & 0xffff);
    145             break;
    146         case 32:
    147             r = MBEDTLS_BSWAP32(r);
    148             TEST_EQUAL(r, input & 0xffffffff);
    149             break;
    150         case 64:
    151             r = MBEDTLS_BSWAP64(r);
    152             TEST_EQUAL(r, input);
    153             break;
    154     }
    155 }
    156 /* END_CASE */
    157 
    158 /* BEGIN_CASE */
    159 void get_byte()
    160 {
    161     uint8_t data[16];
    162 
    163     for (size_t i = 0; i < sizeof(data); i++) {
    164         data[i] = (uint8_t) i;
    165     }
    166 
    167     uint64_t u64 = 0x0706050403020100;
    168     for (size_t b = 0; b < 8; b++) {
    169         uint8_t expected = b;
    170         uint8_t actual = b + 1;
    171         switch (b) {
    172             case 0:
    173                 actual = MBEDTLS_BYTE_0(u64);
    174                 break;
    175             case 1:
    176                 actual = MBEDTLS_BYTE_1(u64);
    177                 break;
    178             case 2:
    179                 actual = MBEDTLS_BYTE_2(u64);
    180                 break;
    181             case 3:
    182                 actual = MBEDTLS_BYTE_3(u64);
    183                 break;
    184             case 4:
    185                 actual = MBEDTLS_BYTE_4(u64);
    186                 break;
    187             case 5:
    188                 actual = MBEDTLS_BYTE_5(u64);
    189                 break;
    190             case 6:
    191                 actual = MBEDTLS_BYTE_6(u64);
    192                 break;
    193             case 7:
    194                 actual = MBEDTLS_BYTE_7(u64);
    195                 break;
    196         }
    197         TEST_EQUAL(actual, expected);
    198     }
    199 
    200     uint32_t u32 = 0x03020100;
    201     for (size_t b = 0; b < 4; b++) {
    202         uint8_t expected = b;
    203         uint8_t actual = b + 1;
    204         switch (b) {
    205             case 0:
    206                 actual = MBEDTLS_BYTE_0(u32);
    207                 break;
    208             case 1:
    209                 actual = MBEDTLS_BYTE_1(u32);
    210                 break;
    211             case 2:
    212                 actual = MBEDTLS_BYTE_2(u32);
    213                 break;
    214             case 3:
    215                 actual = MBEDTLS_BYTE_3(u32);
    216                 break;
    217         }
    218         TEST_EQUAL(actual, expected);
    219     }
    220 
    221     uint16_t u16 = 0x0100;
    222     for (size_t b = 0; b < 2; b++) {
    223         uint8_t expected = b;
    224         uint8_t actual = b + 1;
    225         switch (b) {
    226             case 0:
    227                 actual = MBEDTLS_BYTE_0(u16);
    228                 break;
    229             case 1:
    230                 actual = MBEDTLS_BYTE_1(u16);
    231                 break;
    232         }
    233         TEST_EQUAL(actual, expected);
    234     }
    235 
    236     uint8_t u8 = 0x01;
    237     uint8_t actual = MBEDTLS_BYTE_0(u8);
    238     TEST_EQUAL(actual, u8);
    239 }
    240 /* END_CASE */
    241 
    242 /* BEGIN_CASE */
    243 void unaligned_access_endian_aware(int size, int offset, int big_endian)
    244 {
    245     TEST_ASSERT(size == 16 || size == 24 || size == 32 || size == 64);
    246     TEST_ASSERT(offset >= 0 && offset < 8);
    247 
    248     /* Define 64-bit aligned raw byte array */
    249     uint64_t raw[2];
    250     /* Populate with known data: x == { 0, 1, 2, ... } */
    251     uint8_t *x = (uint8_t *) raw;
    252     for (size_t i = 0; i < sizeof(raw); i++) {
    253         x[i] = (uint8_t) i;
    254     }
    255 
    256     uint64_t read = 0;
    257     if (big_endian) {
    258         switch (size) {
    259             case 16:
    260                 read = MBEDTLS_GET_UINT16_BE(x, offset);
    261                 break;
    262             case 24:
    263                 read = MBEDTLS_GET_UINT24_BE(x, offset);
    264                 break;
    265             case 32:
    266                 read = MBEDTLS_GET_UINT32_BE(x, offset);
    267                 break;
    268             case 64:
    269                 read = MBEDTLS_GET_UINT64_BE(x, offset);
    270                 break;
    271         }
    272     } else {
    273         switch (size) {
    274             case 16:
    275                 read = MBEDTLS_GET_UINT16_LE(x, offset);
    276                 break;
    277             case 24:
    278                 read = MBEDTLS_GET_UINT24_LE(x, offset);
    279                 break;
    280             case 32:
    281                 read = MBEDTLS_GET_UINT32_LE(x, offset);
    282                 break;
    283             case 64:
    284                 read = MBEDTLS_GET_UINT64_LE(x, offset);
    285                 break;
    286         }
    287     }
    288 
    289     /* Build up expected value byte by byte, in either big or little endian format */
    290     uint64_t expected = 0;
    291     for (size_t i = 0; i < (size_t) (size / 8); i++) {
    292         uint64_t b = x[i + offset];
    293         uint8_t shift = (big_endian) ? (8 * ((size / 8 - 1) - i)) : (8 * i);
    294         expected |= b << shift;
    295     }
    296 
    297     /* Verify read */
    298     TEST_EQUAL(read, expected);
    299 
    300     /* Test writing back to memory. First write sentinel */
    301     for (size_t i = 0; i < (size_t) (size / 8); i++) {
    302         x[i + offset] = 0xff;
    303     }
    304     /* Overwrite sentinel with endian-aware write macro */
    305     if (big_endian) {
    306         switch (size) {
    307             case 16:
    308                 MBEDTLS_PUT_UINT16_BE(read, x, offset);
    309                 break;
    310             case 24:
    311                 MBEDTLS_PUT_UINT24_BE(read, x, offset);
    312                 break;
    313             case 32:
    314                 MBEDTLS_PUT_UINT32_BE(read, x, offset);
    315                 break;
    316             case 64:
    317                 MBEDTLS_PUT_UINT64_BE(read, x, offset);
    318                 break;
    319         }
    320     } else {
    321         switch (size) {
    322             case 16:
    323                 MBEDTLS_PUT_UINT16_LE(read, x, offset);
    324                 break;
    325             case 24:
    326                 MBEDTLS_PUT_UINT24_LE(read, x, offset);
    327                 break;
    328             case 32:
    329                 MBEDTLS_PUT_UINT32_LE(read, x, offset);
    330                 break;
    331             case 64:
    332                 MBEDTLS_PUT_UINT64_LE(read, x, offset);
    333                 break;
    334         }
    335     }
    336 
    337     /* Verify write - check memory is correct */
    338     for (size_t i = 0; i < sizeof(raw); i++) {
    339         TEST_EQUAL(x[i], (uint8_t) i);
    340     }
    341 }
    342 /* END_CASE */
    343 
    344 /* BEGIN_CASE */
    345 void mbedtls_is_big_endian()
    346 {
    347     uint16_t check = 0x1234;
    348     uint8_t *p = (uint8_t *) &check;
    349 
    350     if (MBEDTLS_IS_BIG_ENDIAN) {
    351         /* Big-endian: data stored MSB first, i.e. p == { 0x12, 0x34 } */
    352         TEST_EQUAL(p[0], 0x12);
    353         TEST_EQUAL(p[1], 0x34);
    354     } else {
    355         /* Little-endian: data stored LSB first, i.e. p == { 0x34, 0x12 } */
    356         TEST_EQUAL(p[0], 0x34);
    357         TEST_EQUAL(p[1], 0x12);
    358     }
    359 }
    360 /* END_CASE */