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