13c260e60Schristos /* 23c260e60Schristos * utils module tests 3bb610346Schristos * Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi> 43c260e60Schristos * 53c260e60Schristos * This software may be distributed under the terms of the BSD license. 63c260e60Schristos * See README for more details. 73c260e60Schristos */ 83c260e60Schristos 93c260e60Schristos #include "utils/includes.h" 103c260e60Schristos 113c260e60Schristos #include "utils/common.h" 123d6c0713Schristos #include "utils/const_time.h" 1336ebd06eSchristos #include "common/ieee802_11_defs.h" 143c260e60Schristos #include "utils/bitfield.h" 153c260e60Schristos #include "utils/ext_password.h" 163c260e60Schristos #include "utils/trace.h" 17bb610346Schristos #include "utils/base64.h" 1836ebd06eSchristos #include "utils/ip_addr.h" 1936ebd06eSchristos #include "utils/eloop.h" 200a73ee0aSchristos #include "utils/json.h" 2136ebd06eSchristos #include "utils/module_tests.h" 223c260e60Schristos 233c260e60Schristos 243c260e60Schristos struct printf_test_data { 253c260e60Schristos u8 *data; 263c260e60Schristos size_t len; 273c260e60Schristos char *encoded; 283c260e60Schristos }; 293c260e60Schristos 303c260e60Schristos static const struct printf_test_data printf_tests[] = { 313c260e60Schristos { (u8 *) "abcde", 5, "abcde" }, 323c260e60Schristos { (u8 *) "a\0b\nc\ed\re\tf\"\\", 13, "a\\0b\\nc\\ed\\re\\tf\\\"\\\\" }, 333c260e60Schristos { (u8 *) "\x00\x31\x00\x32\x00\x39", 6, "\\x001\\0002\\09" }, 343c260e60Schristos { (u8 *) "\n\n\n", 3, "\n\12\x0a" }, 353c260e60Schristos { (u8 *) "\303\245\303\244\303\266\303\205\303\204\303\226", 12, 363c260e60Schristos "\\xc3\\xa5\xc3\\xa4\\xc3\\xb6\\xc3\\x85\\xc3\\x84\\xc3\\x96" }, 373c260e60Schristos { (u8 *) "\303\245\303\244\303\266\303\205\303\204\303\226", 12, 383c260e60Schristos "\\303\\245\\303\\244\\303\\266\\303\\205\\303\\204\\303\\226" }, 393c260e60Schristos { (u8 *) "\xe5\xe4\xf6\xc5\xc4\xd6", 6, 403c260e60Schristos "\\xe5\\xe4\\xf6\\xc5\\xc4\\xd6" }, 413c260e60Schristos { NULL, 0, NULL } 423c260e60Schristos }; 433c260e60Schristos 443c260e60Schristos 453c260e60Schristos static int printf_encode_decode_tests(void) 463c260e60Schristos { 473c260e60Schristos int i; 483c260e60Schristos size_t binlen; 493c260e60Schristos char buf[100]; 503c260e60Schristos u8 bin[100]; 513c260e60Schristos int errors = 0; 5236ebd06eSchristos int array[10]; 533c260e60Schristos 543c260e60Schristos wpa_printf(MSG_INFO, "printf encode/decode tests"); 553c260e60Schristos 563c260e60Schristos for (i = 0; printf_tests[i].data; i++) { 573c260e60Schristos const struct printf_test_data *test = &printf_tests[i]; 583c260e60Schristos printf_encode(buf, sizeof(buf), test->data, test->len); 593c260e60Schristos wpa_printf(MSG_INFO, "%d: -> \"%s\"", i, buf); 603c260e60Schristos 613c260e60Schristos binlen = printf_decode(bin, sizeof(bin), buf); 623c260e60Schristos if (binlen != test->len || 633c260e60Schristos os_memcmp(bin, test->data, binlen) != 0) { 643c260e60Schristos wpa_hexdump(MSG_ERROR, "Error in decoding#1", 653c260e60Schristos bin, binlen); 663c260e60Schristos errors++; 673c260e60Schristos } 683c260e60Schristos 693c260e60Schristos binlen = printf_decode(bin, sizeof(bin), test->encoded); 703c260e60Schristos if (binlen != test->len || 713c260e60Schristos os_memcmp(bin, test->data, binlen) != 0) { 723c260e60Schristos wpa_hexdump(MSG_ERROR, "Error in decoding#2", 733c260e60Schristos bin, binlen); 743c260e60Schristos errors++; 753c260e60Schristos } 763c260e60Schristos } 773c260e60Schristos 783c260e60Schristos buf[5] = 'A'; 793c260e60Schristos printf_encode(buf, 5, (const u8 *) "abcde", 5); 803c260e60Schristos if (buf[5] != 'A') { 813c260e60Schristos wpa_printf(MSG_ERROR, "Error in bounds checking#1"); 823c260e60Schristos errors++; 833c260e60Schristos } 843c260e60Schristos 853c260e60Schristos for (i = 5; i < 10; i++) { 863c260e60Schristos buf[i] = 'A'; 873c260e60Schristos printf_encode(buf, i, (const u8 *) "\xdd\xdd\xdd\xdd\xdd", 5); 883c260e60Schristos if (buf[i] != 'A') { 893c260e60Schristos wpa_printf(MSG_ERROR, "Error in bounds checking#2(%d)", 903c260e60Schristos i); 913c260e60Schristos errors++; 923c260e60Schristos } 933c260e60Schristos } 943c260e60Schristos 95bb610346Schristos if (printf_decode(bin, 3, "abcde") != 2) 96bb610346Schristos errors++; 97bb610346Schristos 98bb610346Schristos if (printf_decode(bin, 3, "\\xa") != 1 || bin[0] != 10) 99bb610346Schristos errors++; 100bb610346Schristos 10136ebd06eSchristos if (printf_decode(bin, 3, "\\xq") != 1 || bin[0] != 'q') 10236ebd06eSchristos errors++; 10336ebd06eSchristos 104bb610346Schristos if (printf_decode(bin, 3, "\\a") != 1 || bin[0] != 'a') 105bb610346Schristos errors++; 106bb610346Schristos 10736ebd06eSchristos array[0] = 10; 10836ebd06eSchristos array[1] = 10; 10936ebd06eSchristos array[2] = 5; 11036ebd06eSchristos array[3] = 10; 11136ebd06eSchristos array[4] = 5; 11236ebd06eSchristos array[5] = 0; 11336ebd06eSchristos if (int_array_len(array) != 5) 11436ebd06eSchristos errors++; 11536ebd06eSchristos int_array_sort_unique(array); 11636ebd06eSchristos if (int_array_len(array) != 2) 11736ebd06eSchristos errors++; 11836ebd06eSchristos 1193c260e60Schristos if (errors) { 1203c260e60Schristos wpa_printf(MSG_ERROR, "%d printf test(s) failed", errors); 1213c260e60Schristos return -1; 1223c260e60Schristos } 1233c260e60Schristos 1243c260e60Schristos return 0; 1253c260e60Schristos } 1263c260e60Schristos 1273c260e60Schristos 1283c260e60Schristos static int bitfield_tests(void) 1293c260e60Schristos { 1303c260e60Schristos struct bitfield *bf; 1313c260e60Schristos int i; 1323c260e60Schristos int errors = 0; 1333c260e60Schristos 1343c260e60Schristos wpa_printf(MSG_INFO, "bitfield tests"); 1353c260e60Schristos 1363c260e60Schristos bf = bitfield_alloc(123); 1373c260e60Schristos if (bf == NULL) 1383c260e60Schristos return -1; 1393c260e60Schristos 1403c260e60Schristos for (i = 0; i < 123; i++) { 1413c260e60Schristos if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1)) 1423c260e60Schristos errors++; 1433c260e60Schristos if (i > 0 && bitfield_is_set(bf, i - 1)) 1443c260e60Schristos errors++; 1453c260e60Schristos bitfield_set(bf, i); 1463c260e60Schristos if (!bitfield_is_set(bf, i)) 1473c260e60Schristos errors++; 1483c260e60Schristos bitfield_clear(bf, i); 1493c260e60Schristos if (bitfield_is_set(bf, i)) 1503c260e60Schristos errors++; 1513c260e60Schristos } 1523c260e60Schristos 1533c260e60Schristos for (i = 123; i < 200; i++) { 1543c260e60Schristos if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1)) 1553c260e60Schristos errors++; 1563c260e60Schristos if (i > 0 && bitfield_is_set(bf, i - 1)) 1573c260e60Schristos errors++; 1583c260e60Schristos bitfield_set(bf, i); 1593c260e60Schristos if (bitfield_is_set(bf, i)) 1603c260e60Schristos errors++; 1613c260e60Schristos bitfield_clear(bf, i); 1623c260e60Schristos if (bitfield_is_set(bf, i)) 1633c260e60Schristos errors++; 1643c260e60Schristos } 1653c260e60Schristos 1663c260e60Schristos for (i = 0; i < 123; i++) { 1673c260e60Schristos if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1)) 1683c260e60Schristos errors++; 1693c260e60Schristos bitfield_set(bf, i); 1703c260e60Schristos if (!bitfield_is_set(bf, i)) 1713c260e60Schristos errors++; 1723c260e60Schristos } 1733c260e60Schristos 1743c260e60Schristos for (i = 0; i < 123; i++) { 1753c260e60Schristos if (!bitfield_is_set(bf, i)) 1763c260e60Schristos errors++; 1773c260e60Schristos bitfield_clear(bf, i); 1783c260e60Schristos if (bitfield_is_set(bf, i)) 1793c260e60Schristos errors++; 1803c260e60Schristos } 1813c260e60Schristos 1823c260e60Schristos for (i = 0; i < 123; i++) { 1833c260e60Schristos if (bitfield_get_first_zero(bf) != i) 1843c260e60Schristos errors++; 1853c260e60Schristos bitfield_set(bf, i); 1863c260e60Schristos } 1873c260e60Schristos if (bitfield_get_first_zero(bf) != -1) 1883c260e60Schristos errors++; 1893c260e60Schristos for (i = 0; i < 123; i++) { 1903c260e60Schristos if (!bitfield_is_set(bf, i)) 1913c260e60Schristos errors++; 1923c260e60Schristos bitfield_clear(bf, i); 1933c260e60Schristos if (bitfield_get_first_zero(bf) != i) 1943c260e60Schristos errors++; 1953c260e60Schristos bitfield_set(bf, i); 1963c260e60Schristos } 1973c260e60Schristos if (bitfield_get_first_zero(bf) != -1) 1983c260e60Schristos errors++; 1993c260e60Schristos 2003c260e60Schristos bitfield_free(bf); 2013c260e60Schristos 202bb610346Schristos bf = bitfield_alloc(8); 203bb610346Schristos if (bf == NULL) 204bb610346Schristos return -1; 205bb610346Schristos if (bitfield_get_first_zero(bf) != 0) 206bb610346Schristos errors++; 207bb610346Schristos for (i = 0; i < 8; i++) 208bb610346Schristos bitfield_set(bf, i); 209bb610346Schristos if (bitfield_get_first_zero(bf) != -1) 210bb610346Schristos errors++; 211bb610346Schristos bitfield_free(bf); 212bb610346Schristos 2133c260e60Schristos if (errors) { 2143c260e60Schristos wpa_printf(MSG_ERROR, "%d bitfield test(s) failed", errors); 2153c260e60Schristos return -1; 2163c260e60Schristos } 2173c260e60Schristos 2183c260e60Schristos return 0; 2193c260e60Schristos } 2203c260e60Schristos 2213c260e60Schristos 2223c260e60Schristos static int int_array_tests(void) 2233c260e60Schristos { 2243c260e60Schristos int test1[] = { 1, 2, 3, 4, 5, 6, 0 }; 2253c260e60Schristos int test2[] = { 1, -1, 0 }; 2263c260e60Schristos int test3[] = { 1, 1, 1, -1, 2, 3, 4, 1, 2, 0 }; 2273c260e60Schristos int test3_res[] = { -1, 1, 2, 3, 4, 0 }; 2283c260e60Schristos int errors = 0; 229*bb618362Schristos size_t len; 2303c260e60Schristos 2313c260e60Schristos wpa_printf(MSG_INFO, "int_array tests"); 2323c260e60Schristos 2333c260e60Schristos if (int_array_len(test1) != 6 || 2343c260e60Schristos int_array_len(test2) != 2) 2353c260e60Schristos errors++; 2363c260e60Schristos 2373c260e60Schristos int_array_sort_unique(test3); 2383c260e60Schristos len = int_array_len(test3_res); 2393c260e60Schristos if (int_array_len(test3) != len) 2403c260e60Schristos errors++; 2413c260e60Schristos else if (os_memcmp(test3, test3_res, len * sizeof(int)) != 0) 2423c260e60Schristos errors++; 2433c260e60Schristos 2443c260e60Schristos if (errors) { 2453c260e60Schristos wpa_printf(MSG_ERROR, "%d int_array test(s) failed", errors); 2463c260e60Schristos return -1; 2473c260e60Schristos } 2483c260e60Schristos 2493c260e60Schristos return 0; 2503c260e60Schristos } 2513c260e60Schristos 2523c260e60Schristos 2533c260e60Schristos static int ext_password_tests(void) 2543c260e60Schristos { 2553c260e60Schristos struct ext_password_data *data; 2563c260e60Schristos int ret = 0; 2573c260e60Schristos struct wpabuf *pw; 2583c260e60Schristos 2593c260e60Schristos wpa_printf(MSG_INFO, "ext_password tests"); 2603c260e60Schristos 2613c260e60Schristos data = ext_password_init("unknown", "foo"); 2623c260e60Schristos if (data != NULL) 2633c260e60Schristos return -1; 2643c260e60Schristos 2653c260e60Schristos data = ext_password_init("test", NULL); 2663c260e60Schristos if (data == NULL) 2673c260e60Schristos return -1; 2683c260e60Schristos pw = ext_password_get(data, "foo"); 2693c260e60Schristos if (pw != NULL) 2703c260e60Schristos ret = -1; 2713c260e60Schristos ext_password_free(pw); 2723c260e60Schristos 2733c260e60Schristos ext_password_deinit(data); 2743c260e60Schristos 2753c260e60Schristos pw = ext_password_get(NULL, "foo"); 2763c260e60Schristos if (pw != NULL) 2773c260e60Schristos ret = -1; 2783c260e60Schristos ext_password_free(pw); 2793c260e60Schristos 2803c260e60Schristos return ret; 2813c260e60Schristos } 2823c260e60Schristos 2833c260e60Schristos 2843c260e60Schristos static int trace_tests(void) 2853c260e60Schristos { 2863c260e60Schristos wpa_printf(MSG_INFO, "trace tests"); 2873c260e60Schristos 2883c260e60Schristos wpa_trace_show("test backtrace"); 2893c260e60Schristos wpa_trace_dump_funcname("test funcname", trace_tests); 2903c260e60Schristos 2913c260e60Schristos return 0; 2923c260e60Schristos } 2933c260e60Schristos 2943c260e60Schristos 295bb610346Schristos static int base64_tests(void) 296bb610346Schristos { 297bb610346Schristos int errors = 0; 298bb610346Schristos unsigned char *res; 299*bb618362Schristos char *res2; 300bb610346Schristos size_t res_len; 301bb610346Schristos 302bb610346Schristos wpa_printf(MSG_INFO, "base64 tests"); 303bb610346Schristos 304*bb618362Schristos res2 = base64_encode("", ~0, &res_len); 305*bb618362Schristos if (res2) { 306*bb618362Schristos errors++; 307*bb618362Schristos os_free(res2); 308*bb618362Schristos } 309*bb618362Schristos 310*bb618362Schristos res2 = base64_encode("=", 1, &res_len); 311*bb618362Schristos if (!res2 || res_len != 5 || res2[0] != 'P' || res2[1] != 'Q' || 312*bb618362Schristos res2[2] != '=' || res2[3] != '=' || res2[4] != '\n') 313*bb618362Schristos errors++; 314*bb618362Schristos os_free(res2); 315*bb618362Schristos 316*bb618362Schristos res2 = base64_encode("=", 1, NULL); 317*bb618362Schristos if (!res2 || res2[0] != 'P' || res2[1] != 'Q' || 318*bb618362Schristos res2[2] != '=' || res2[3] != '=' || res2[4] != '\n') 319*bb618362Schristos errors++; 320*bb618362Schristos os_free(res2); 321*bb618362Schristos 322*bb618362Schristos res = base64_decode("", 0, &res_len); 323bb610346Schristos if (res) { 324bb610346Schristos errors++; 325bb610346Schristos os_free(res); 326bb610346Schristos } 327bb610346Schristos 328*bb618362Schristos res = base64_decode("a", 1, &res_len); 329bb610346Schristos if (res) { 330bb610346Schristos errors++; 331bb610346Schristos os_free(res); 332bb610346Schristos } 333bb610346Schristos 334*bb618362Schristos res = base64_decode("====", 4, &res_len); 335bb610346Schristos if (res) { 336bb610346Schristos errors++; 337bb610346Schristos os_free(res); 338bb610346Schristos } 339bb610346Schristos 340*bb618362Schristos res = base64_decode("PQ==", 4, &res_len); 341bb610346Schristos if (!res || res_len != 1 || res[0] != '=') 342bb610346Schristos errors++; 343bb610346Schristos os_free(res); 344bb610346Schristos 345*bb618362Schristos res = base64_decode("P.Q-=!=*", 8, &res_len); 346bb610346Schristos if (!res || res_len != 1 || res[0] != '=') 347bb610346Schristos errors++; 348bb610346Schristos os_free(res); 349bb610346Schristos 350bb610346Schristos if (errors) { 351bb610346Schristos wpa_printf(MSG_ERROR, "%d base64 test(s) failed", errors); 352bb610346Schristos return -1; 353bb610346Schristos } 354bb610346Schristos 355bb610346Schristos return 0; 356bb610346Schristos } 357bb610346Schristos 358bb610346Schristos 359bb610346Schristos static int common_tests(void) 360bb610346Schristos { 36136ebd06eSchristos char buf[3], longbuf[100]; 362bb610346Schristos u8 addr[ETH_ALEN] = { 1, 2, 3, 4, 5, 6 }; 363bb610346Schristos u8 bin[3]; 364bb610346Schristos int errors = 0; 365bb610346Schristos struct wpa_freq_range_list ranges; 36636ebd06eSchristos size_t len; 36736ebd06eSchristos const char *txt; 36836ebd06eSchristos u8 ssid[255]; 369bb610346Schristos 370bb610346Schristos wpa_printf(MSG_INFO, "common tests"); 371bb610346Schristos 372bb610346Schristos if (hwaddr_mask_txt(buf, 3, addr, addr) != -1) 373bb610346Schristos errors++; 374bb610346Schristos 375bb610346Schristos if (wpa_scnprintf(buf, 0, "hello") != 0 || 376bb610346Schristos wpa_scnprintf(buf, 3, "hello") != 2) 377bb610346Schristos errors++; 378bb610346Schristos 379bb610346Schristos if (wpa_snprintf_hex(buf, 0, addr, ETH_ALEN) != 0 || 380bb610346Schristos wpa_snprintf_hex(buf, 3, addr, ETH_ALEN) != 2) 381bb610346Schristos errors++; 382bb610346Schristos 383bb610346Schristos if (merge_byte_arrays(bin, 3, addr, ETH_ALEN, NULL, 0) != 3 || 384bb610346Schristos merge_byte_arrays(bin, 3, NULL, 0, addr, ETH_ALEN) != 3) 385bb610346Schristos errors++; 386bb610346Schristos 387bb610346Schristos if (dup_binstr(NULL, 0) != NULL) 388bb610346Schristos errors++; 389bb610346Schristos 390bb610346Schristos if (freq_range_list_includes(NULL, 0) != 0) 391bb610346Schristos errors++; 392bb610346Schristos 393bb610346Schristos os_memset(&ranges, 0, sizeof(ranges)); 394bb610346Schristos if (freq_range_list_parse(&ranges, "") != 0 || 395bb610346Schristos freq_range_list_includes(&ranges, 0) != 0 || 396bb610346Schristos freq_range_list_str(&ranges) != NULL) 397bb610346Schristos errors++; 398bb610346Schristos 399bb610346Schristos if (utf8_unescape(NULL, 0, buf, sizeof(buf)) != 0 || 400bb610346Schristos utf8_unescape("a", 1, NULL, 0) != 0 || 401bb610346Schristos utf8_unescape("a\\", 2, buf, sizeof(buf)) != 0 || 402bb610346Schristos utf8_unescape("abcde", 5, buf, sizeof(buf)) != 0 || 403bb610346Schristos utf8_unescape("abc", 3, buf, 3) != 3) 404bb610346Schristos errors++; 405bb610346Schristos 406bb610346Schristos if (utf8_unescape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a') 407bb610346Schristos errors++; 408bb610346Schristos 409bb610346Schristos if (utf8_unescape("\\b", 2, buf, sizeof(buf)) != 1 || buf[0] != 'b') 410bb610346Schristos errors++; 411bb610346Schristos 412bb610346Schristos if (utf8_escape(NULL, 0, buf, sizeof(buf)) != 0 || 413bb610346Schristos utf8_escape("a", 1, NULL, 0) != 0 || 414bb610346Schristos utf8_escape("abcde", 5, buf, sizeof(buf)) != 0 || 415bb610346Schristos utf8_escape("a\\bcde", 6, buf, sizeof(buf)) != 0 || 416bb610346Schristos utf8_escape("ab\\cde", 6, buf, sizeof(buf)) != 0 || 417bb610346Schristos utf8_escape("abc\\de", 6, buf, sizeof(buf)) != 0 || 418bb610346Schristos utf8_escape("abc", 3, buf, 3) != 3) 419bb610346Schristos errors++; 420bb610346Schristos 421bb610346Schristos if (utf8_escape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a') 422bb610346Schristos errors++; 423bb610346Schristos 42436ebd06eSchristos os_memset(ssid, 0, sizeof(ssid)); 42536ebd06eSchristos txt = wpa_ssid_txt(ssid, sizeof(ssid)); 42636ebd06eSchristos len = os_strlen(txt); 42736ebd06eSchristos /* Verify that SSID_MAX_LEN * 4 buffer limit is enforced. */ 42836ebd06eSchristos if (len != SSID_MAX_LEN * 4) { 42936ebd06eSchristos wpa_printf(MSG_ERROR, 43036ebd06eSchristos "Unexpected wpa_ssid_txt() result with too long SSID"); 43136ebd06eSchristos errors++; 43236ebd06eSchristos } 43336ebd06eSchristos 43436ebd06eSchristos if (wpa_snprintf_hex_sep(longbuf, 0, addr, ETH_ALEN, '-') != 0 || 43536ebd06eSchristos wpa_snprintf_hex_sep(longbuf, 5, addr, ETH_ALEN, '-') != 3 || 43636ebd06eSchristos os_strcmp(longbuf, "01-0") != 0) 43736ebd06eSchristos errors++; 43836ebd06eSchristos 439bb610346Schristos if (errors) { 440bb610346Schristos wpa_printf(MSG_ERROR, "%d common test(s) failed", errors); 441bb610346Schristos return -1; 442bb610346Schristos } 443bb610346Schristos 444bb610346Schristos return 0; 445bb610346Schristos } 446bb610346Schristos 447bb610346Schristos 44836ebd06eSchristos static int os_tests(void) 44936ebd06eSchristos { 45036ebd06eSchristos int errors = 0; 45136ebd06eSchristos void *ptr; 45236ebd06eSchristos os_time_t t; 45336ebd06eSchristos 45436ebd06eSchristos wpa_printf(MSG_INFO, "os tests"); 45536ebd06eSchristos 45636ebd06eSchristos ptr = os_calloc((size_t) -1, (size_t) -1); 45736ebd06eSchristos if (ptr) { 45836ebd06eSchristos errors++; 45936ebd06eSchristos os_free(ptr); 46036ebd06eSchristos } 46136ebd06eSchristos ptr = os_calloc((size_t) 2, (size_t) -1); 46236ebd06eSchristos if (ptr) { 46336ebd06eSchristos errors++; 46436ebd06eSchristos os_free(ptr); 46536ebd06eSchristos } 46636ebd06eSchristos ptr = os_calloc((size_t) -1, (size_t) 2); 46736ebd06eSchristos if (ptr) { 46836ebd06eSchristos errors++; 46936ebd06eSchristos os_free(ptr); 47036ebd06eSchristos } 47136ebd06eSchristos 47236ebd06eSchristos ptr = os_realloc_array(NULL, (size_t) -1, (size_t) -1); 47336ebd06eSchristos if (ptr) { 47436ebd06eSchristos errors++; 47536ebd06eSchristos os_free(ptr); 47636ebd06eSchristos } 47736ebd06eSchristos 47836ebd06eSchristos os_sleep(1, 1); 47936ebd06eSchristos 48036ebd06eSchristos if (os_mktime(1969, 1, 1, 1, 1, 1, &t) == 0 || 48136ebd06eSchristos os_mktime(1971, 0, 1, 1, 1, 1, &t) == 0 || 48236ebd06eSchristos os_mktime(1971, 13, 1, 1, 1, 1, &t) == 0 || 48336ebd06eSchristos os_mktime(1971, 1, 0, 1, 1, 1, &t) == 0 || 48436ebd06eSchristos os_mktime(1971, 1, 32, 1, 1, 1, &t) == 0 || 48536ebd06eSchristos os_mktime(1971, 1, 1, -1, 1, 1, &t) == 0 || 48636ebd06eSchristos os_mktime(1971, 1, 1, 24, 1, 1, &t) == 0 || 48736ebd06eSchristos os_mktime(1971, 1, 1, 1, -1, 1, &t) == 0 || 48836ebd06eSchristos os_mktime(1971, 1, 1, 1, 60, 1, &t) == 0 || 48936ebd06eSchristos os_mktime(1971, 1, 1, 1, 1, -1, &t) == 0 || 49036ebd06eSchristos os_mktime(1971, 1, 1, 1, 1, 61, &t) == 0 || 49136ebd06eSchristos os_mktime(1971, 1, 1, 1, 1, 1, &t) != 0 || 49236ebd06eSchristos os_mktime(2020, 1, 2, 3, 4, 5, &t) != 0 || 49336ebd06eSchristos os_mktime(2015, 12, 31, 23, 59, 59, &t) != 0) 49436ebd06eSchristos errors++; 49536ebd06eSchristos 49636ebd06eSchristos if (os_setenv("hwsim_test_env", "test value", 0) != 0 || 49736ebd06eSchristos os_setenv("hwsim_test_env", "test value 2", 1) != 0 || 49836ebd06eSchristos os_unsetenv("hwsim_test_env") != 0) 49936ebd06eSchristos errors++; 50036ebd06eSchristos 50136ebd06eSchristos if (os_file_exists("/this-file-does-not-exists-hwsim") != 0) 50236ebd06eSchristos errors++; 50336ebd06eSchristos 50436ebd06eSchristos if (errors) { 50536ebd06eSchristos wpa_printf(MSG_ERROR, "%d os test(s) failed", errors); 50636ebd06eSchristos return -1; 50736ebd06eSchristos } 50836ebd06eSchristos 50936ebd06eSchristos return 0; 51036ebd06eSchristos } 51136ebd06eSchristos 51236ebd06eSchristos 51336ebd06eSchristos static int wpabuf_tests(void) 51436ebd06eSchristos { 51536ebd06eSchristos int errors = 0; 51636ebd06eSchristos void *ptr; 51736ebd06eSchristos struct wpabuf *buf; 51836ebd06eSchristos 51936ebd06eSchristos wpa_printf(MSG_INFO, "wpabuf tests"); 52036ebd06eSchristos 52136ebd06eSchristos ptr = os_malloc(100); 52236ebd06eSchristos if (ptr) { 52336ebd06eSchristos buf = wpabuf_alloc_ext_data(ptr, 100); 52436ebd06eSchristos if (buf) { 52536ebd06eSchristos if (wpabuf_resize(&buf, 100) < 0) 52636ebd06eSchristos errors++; 52736ebd06eSchristos else 52836ebd06eSchristos wpabuf_put(buf, 100); 52936ebd06eSchristos wpabuf_free(buf); 53036ebd06eSchristos } else { 53136ebd06eSchristos errors++; 53236ebd06eSchristos os_free(ptr); 53336ebd06eSchristos } 53436ebd06eSchristos } else { 53536ebd06eSchristos errors++; 53636ebd06eSchristos } 53736ebd06eSchristos 53836ebd06eSchristos buf = wpabuf_alloc(100); 53936ebd06eSchristos if (buf) { 54036ebd06eSchristos struct wpabuf *buf2; 54136ebd06eSchristos 54236ebd06eSchristos wpabuf_put(buf, 100); 54336ebd06eSchristos if (wpabuf_resize(&buf, 100) < 0) 54436ebd06eSchristos errors++; 54536ebd06eSchristos else 54636ebd06eSchristos wpabuf_put(buf, 100); 54736ebd06eSchristos buf2 = wpabuf_concat(buf, NULL); 54836ebd06eSchristos if (buf2 != buf) 54936ebd06eSchristos errors++; 55036ebd06eSchristos wpabuf_free(buf2); 55136ebd06eSchristos } else { 55236ebd06eSchristos errors++; 55336ebd06eSchristos } 55436ebd06eSchristos 55536ebd06eSchristos buf = NULL; 55636ebd06eSchristos buf = wpabuf_zeropad(buf, 10); 55736ebd06eSchristos if (buf != NULL) 55836ebd06eSchristos errors++; 55936ebd06eSchristos 56036ebd06eSchristos if (errors) { 56136ebd06eSchristos wpa_printf(MSG_ERROR, "%d wpabuf test(s) failed", errors); 56236ebd06eSchristos return -1; 56336ebd06eSchristos } 56436ebd06eSchristos 56536ebd06eSchristos return 0; 56636ebd06eSchristos } 56736ebd06eSchristos 56836ebd06eSchristos 56936ebd06eSchristos static int ip_addr_tests(void) 57036ebd06eSchristos { 57136ebd06eSchristos int errors = 0; 57236ebd06eSchristos struct hostapd_ip_addr addr; 57336ebd06eSchristos char buf[100]; 57436ebd06eSchristos 57536ebd06eSchristos wpa_printf(MSG_INFO, "ip_addr tests"); 57636ebd06eSchristos 57736ebd06eSchristos if (hostapd_parse_ip_addr("1.2.3.4", &addr) != 0 || 57836ebd06eSchristos addr.af != AF_INET || 57936ebd06eSchristos hostapd_ip_txt(NULL, buf, sizeof(buf)) != NULL || 58036ebd06eSchristos hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' || 58136ebd06eSchristos hostapd_ip_txt(&addr, buf, 0) != NULL || 58236ebd06eSchristos hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf) 58336ebd06eSchristos errors++; 58436ebd06eSchristos 58536ebd06eSchristos if (hostapd_parse_ip_addr("::", &addr) != 0 || 58636ebd06eSchristos addr.af != AF_INET6 || 58736ebd06eSchristos hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' || 58836ebd06eSchristos hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf) 58936ebd06eSchristos errors++; 59036ebd06eSchristos 59136ebd06eSchristos if (errors) { 59236ebd06eSchristos wpa_printf(MSG_ERROR, "%d ip_addr test(s) failed", errors); 59336ebd06eSchristos return -1; 59436ebd06eSchristos } 59536ebd06eSchristos 59636ebd06eSchristos return 0; 59736ebd06eSchristos } 59836ebd06eSchristos 59936ebd06eSchristos 60036ebd06eSchristos struct test_eloop { 60136ebd06eSchristos unsigned int magic; 60236ebd06eSchristos int close_in_timeout; 60336ebd06eSchristos int pipefd1[2]; 60436ebd06eSchristos int pipefd2[2]; 60536ebd06eSchristos }; 60636ebd06eSchristos 60736ebd06eSchristos 60836ebd06eSchristos static void eloop_tests_start(int close_in_timeout); 60936ebd06eSchristos 61036ebd06eSchristos 61136ebd06eSchristos static void eloop_test_read_2(int sock, void *eloop_ctx, void *sock_ctx) 61236ebd06eSchristos { 61336ebd06eSchristos struct test_eloop *t = eloop_ctx; 61436ebd06eSchristos ssize_t res; 61536ebd06eSchristos char buf[10]; 61636ebd06eSchristos 61736ebd06eSchristos wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock); 61836ebd06eSchristos 61936ebd06eSchristos if (t->magic != 0x12345678) { 62036ebd06eSchristos wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 62136ebd06eSchristos __func__, t->magic); 62236ebd06eSchristos } 62336ebd06eSchristos 62436ebd06eSchristos if (t->pipefd2[0] != sock) { 62536ebd06eSchristos wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d", 62636ebd06eSchristos __func__, sock, t->pipefd2[0]); 62736ebd06eSchristos } 62836ebd06eSchristos 62936ebd06eSchristos res = read(sock, buf, sizeof(buf)); 63036ebd06eSchristos wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d", 63136ebd06eSchristos __func__, sock, (int) res); 63236ebd06eSchristos } 63336ebd06eSchristos 63436ebd06eSchristos 63536ebd06eSchristos static void eloop_test_read_2_wrong(int sock, void *eloop_ctx, void *sock_ctx) 63636ebd06eSchristos { 63736ebd06eSchristos struct test_eloop *t = eloop_ctx; 63836ebd06eSchristos 63936ebd06eSchristos wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock); 64036ebd06eSchristos 64136ebd06eSchristos if (t->magic != 0x12345678) { 64236ebd06eSchristos wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 64336ebd06eSchristos __func__, t->magic); 64436ebd06eSchristos } 64536ebd06eSchristos 64636ebd06eSchristos if (t->pipefd2[0] != sock) { 64736ebd06eSchristos wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d", 64836ebd06eSchristos __func__, sock, t->pipefd2[0]); 64936ebd06eSchristos } 65036ebd06eSchristos 65136ebd06eSchristos /* 65236ebd06eSchristos * This is expected to block due to the original socket with data having 65336ebd06eSchristos * been closed and no new data having been written to the new socket 65436ebd06eSchristos * with the same fd. To avoid blocking the process during test, skip the 65536ebd06eSchristos * read here. 65636ebd06eSchristos */ 65736ebd06eSchristos wpa_printf(MSG_ERROR, "%s: FAIL - should not have called this function", 65836ebd06eSchristos __func__); 65936ebd06eSchristos } 66036ebd06eSchristos 66136ebd06eSchristos 66236ebd06eSchristos static void reopen_pipefd2(struct test_eloop *t) 66336ebd06eSchristos { 66436ebd06eSchristos if (t->pipefd2[0] < 0) { 66536ebd06eSchristos wpa_printf(MSG_INFO, "pipefd2 had been closed"); 66636ebd06eSchristos } else { 66736ebd06eSchristos int res; 66836ebd06eSchristos 66936ebd06eSchristos wpa_printf(MSG_INFO, "close pipefd2"); 67036ebd06eSchristos eloop_unregister_read_sock(t->pipefd2[0]); 67136ebd06eSchristos close(t->pipefd2[0]); 67236ebd06eSchristos t->pipefd2[0] = -1; 67336ebd06eSchristos close(t->pipefd2[1]); 67436ebd06eSchristos t->pipefd2[1] = -1; 67536ebd06eSchristos 67636ebd06eSchristos res = pipe(t->pipefd2); 67736ebd06eSchristos if (res < 0) { 67836ebd06eSchristos wpa_printf(MSG_INFO, "pipe: %s", strerror(errno)); 67936ebd06eSchristos t->pipefd2[0] = -1; 68036ebd06eSchristos t->pipefd2[1] = -1; 68136ebd06eSchristos return; 68236ebd06eSchristos } 68336ebd06eSchristos 68436ebd06eSchristos wpa_printf(MSG_INFO, 68536ebd06eSchristos "re-register pipefd2 with new sockets %d,%d", 68636ebd06eSchristos t->pipefd2[0], t->pipefd2[1]); 68736ebd06eSchristos eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2_wrong, 68836ebd06eSchristos t, NULL); 68936ebd06eSchristos } 69036ebd06eSchristos } 69136ebd06eSchristos 69236ebd06eSchristos 69336ebd06eSchristos static void eloop_test_read_1(int sock, void *eloop_ctx, void *sock_ctx) 69436ebd06eSchristos { 69536ebd06eSchristos struct test_eloop *t = eloop_ctx; 69636ebd06eSchristos ssize_t res; 69736ebd06eSchristos char buf[10]; 69836ebd06eSchristos 69936ebd06eSchristos wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock); 70036ebd06eSchristos 70136ebd06eSchristos if (t->magic != 0x12345678) { 70236ebd06eSchristos wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 70336ebd06eSchristos __func__, t->magic); 70436ebd06eSchristos } 70536ebd06eSchristos 70636ebd06eSchristos if (t->pipefd1[0] != sock) { 70736ebd06eSchristos wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d", 70836ebd06eSchristos __func__, sock, t->pipefd1[0]); 70936ebd06eSchristos } 71036ebd06eSchristos 71136ebd06eSchristos res = read(sock, buf, sizeof(buf)); 71236ebd06eSchristos wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d", 71336ebd06eSchristos __func__, sock, (int) res); 71436ebd06eSchristos 71536ebd06eSchristos if (!t->close_in_timeout) 71636ebd06eSchristos reopen_pipefd2(t); 71736ebd06eSchristos } 71836ebd06eSchristos 71936ebd06eSchristos 72036ebd06eSchristos static void eloop_test_cb(void *eloop_data, void *user_ctx) 72136ebd06eSchristos { 72236ebd06eSchristos struct test_eloop *t = eloop_data; 72336ebd06eSchristos 72436ebd06eSchristos wpa_printf(MSG_INFO, "%s", __func__); 72536ebd06eSchristos 72636ebd06eSchristos if (t->magic != 0x12345678) { 72736ebd06eSchristos wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 72836ebd06eSchristos __func__, t->magic); 72936ebd06eSchristos } 73036ebd06eSchristos 73136ebd06eSchristos if (t->close_in_timeout) 73236ebd06eSchristos reopen_pipefd2(t); 73336ebd06eSchristos } 73436ebd06eSchristos 73536ebd06eSchristos 73636ebd06eSchristos static void eloop_test_timeout(void *eloop_data, void *user_ctx) 73736ebd06eSchristos { 73836ebd06eSchristos struct test_eloop *t = eloop_data; 73936ebd06eSchristos int next_run = 0; 74036ebd06eSchristos 74136ebd06eSchristos wpa_printf(MSG_INFO, "%s", __func__); 74236ebd06eSchristos 74336ebd06eSchristos if (t->magic != 0x12345678) { 74436ebd06eSchristos wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 74536ebd06eSchristos __func__, t->magic); 74636ebd06eSchristos } 74736ebd06eSchristos 74836ebd06eSchristos if (t->pipefd1[0] >= 0) { 74936ebd06eSchristos wpa_printf(MSG_INFO, "pipefd1 had not been closed"); 75036ebd06eSchristos eloop_unregister_read_sock(t->pipefd1[0]); 75136ebd06eSchristos close(t->pipefd1[0]); 75236ebd06eSchristos t->pipefd1[0] = -1; 75336ebd06eSchristos close(t->pipefd1[1]); 75436ebd06eSchristos t->pipefd1[1] = -1; 75536ebd06eSchristos } 75636ebd06eSchristos 75736ebd06eSchristos if (t->pipefd2[0] >= 0) { 75836ebd06eSchristos wpa_printf(MSG_INFO, "pipefd2 had not been closed"); 75936ebd06eSchristos eloop_unregister_read_sock(t->pipefd2[0]); 76036ebd06eSchristos close(t->pipefd2[0]); 76136ebd06eSchristos t->pipefd2[0] = -1; 76236ebd06eSchristos close(t->pipefd2[1]); 76336ebd06eSchristos t->pipefd2[1] = -1; 76436ebd06eSchristos } 76536ebd06eSchristos 76636ebd06eSchristos next_run = t->close_in_timeout; 76736ebd06eSchristos t->magic = 0; 76836ebd06eSchristos wpa_printf(MSG_INFO, "%s - free(%p)", __func__, t); 76936ebd06eSchristos os_free(t); 77036ebd06eSchristos 77136ebd06eSchristos if (next_run) 77236ebd06eSchristos eloop_tests_start(0); 77336ebd06eSchristos } 77436ebd06eSchristos 77536ebd06eSchristos 77636ebd06eSchristos static void eloop_tests_start(int close_in_timeout) 77736ebd06eSchristos { 77836ebd06eSchristos struct test_eloop *t; 77936ebd06eSchristos int res; 78036ebd06eSchristos 78136ebd06eSchristos t = os_zalloc(sizeof(*t)); 78236ebd06eSchristos if (!t) 78336ebd06eSchristos return; 78436ebd06eSchristos t->magic = 0x12345678; 78536ebd06eSchristos t->close_in_timeout = close_in_timeout; 78636ebd06eSchristos 78736ebd06eSchristos wpa_printf(MSG_INFO, "starting eloop tests (%p) (close_in_timeout=%d)", 78836ebd06eSchristos t, close_in_timeout); 78936ebd06eSchristos 79036ebd06eSchristos res = pipe(t->pipefd1); 79136ebd06eSchristos if (res < 0) { 79236ebd06eSchristos wpa_printf(MSG_INFO, "pipe: %s", strerror(errno)); 79336ebd06eSchristos os_free(t); 79436ebd06eSchristos return; 79536ebd06eSchristos } 79636ebd06eSchristos 79736ebd06eSchristos res = pipe(t->pipefd2); 79836ebd06eSchristos if (res < 0) { 79936ebd06eSchristos wpa_printf(MSG_INFO, "pipe: %s", strerror(errno)); 80036ebd06eSchristos close(t->pipefd1[0]); 80136ebd06eSchristos close(t->pipefd1[1]); 80236ebd06eSchristos os_free(t); 80336ebd06eSchristos return; 80436ebd06eSchristos } 80536ebd06eSchristos 80636ebd06eSchristos wpa_printf(MSG_INFO, "pipe fds: %d,%d %d,%d", 80736ebd06eSchristos t->pipefd1[0], t->pipefd1[1], 80836ebd06eSchristos t->pipefd2[0], t->pipefd2[1]); 80936ebd06eSchristos 81036ebd06eSchristos eloop_register_read_sock(t->pipefd1[0], eloop_test_read_1, t, NULL); 81136ebd06eSchristos eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2, t, NULL); 81236ebd06eSchristos eloop_register_timeout(0, 0, eloop_test_cb, t, NULL); 81336ebd06eSchristos eloop_register_timeout(0, 200000, eloop_test_timeout, t, NULL); 81436ebd06eSchristos 81536ebd06eSchristos if (write(t->pipefd1[1], "HELLO", 5) < 0) 81636ebd06eSchristos wpa_printf(MSG_INFO, "write: %s", strerror(errno)); 81736ebd06eSchristos if (write(t->pipefd2[1], "TEST", 4) < 0) 81836ebd06eSchristos wpa_printf(MSG_INFO, "write: %s", strerror(errno)); 81936ebd06eSchristos os_sleep(0, 50000); 82036ebd06eSchristos wpa_printf(MSG_INFO, "waiting for eloop callbacks"); 82136ebd06eSchristos } 82236ebd06eSchristos 82336ebd06eSchristos 82436ebd06eSchristos static void eloop_tests_run(void *eloop_data, void *user_ctx) 82536ebd06eSchristos { 82636ebd06eSchristos eloop_tests_start(1); 82736ebd06eSchristos } 82836ebd06eSchristos 82936ebd06eSchristos 83036ebd06eSchristos static int eloop_tests(void) 83136ebd06eSchristos { 83236ebd06eSchristos wpa_printf(MSG_INFO, "schedule eloop tests to be run"); 83336ebd06eSchristos 83436ebd06eSchristos /* 83536ebd06eSchristos * Cannot return error from these without a significant design change, 83636ebd06eSchristos * so for now, run the tests from a scheduled timeout and require 83736ebd06eSchristos * separate verification of the results from the debug log. 83836ebd06eSchristos */ 83936ebd06eSchristos eloop_register_timeout(0, 0, eloop_tests_run, NULL, NULL); 84036ebd06eSchristos 84136ebd06eSchristos return 0; 84236ebd06eSchristos } 84336ebd06eSchristos 84436ebd06eSchristos 8450a73ee0aSchristos #ifdef CONFIG_JSON 8460a73ee0aSchristos struct json_test_data { 8470a73ee0aSchristos const char *json; 8480a73ee0aSchristos const char *tree; 8490a73ee0aSchristos }; 8500a73ee0aSchristos 8510a73ee0aSchristos static const struct json_test_data json_test_cases[] = { 8520a73ee0aSchristos { "{}", "[1:OBJECT:]" }, 8530a73ee0aSchristos { "[]", "[1:ARRAY:]" }, 8540a73ee0aSchristos { "{", NULL }, 8550a73ee0aSchristos { "[", NULL }, 8560a73ee0aSchristos { "}", NULL }, 8570a73ee0aSchristos { "]", NULL }, 8580a73ee0aSchristos { "[[]]", "[1:ARRAY:][2:ARRAY:]" }, 8590a73ee0aSchristos { "{\"t\":\"test\"}", "[1:OBJECT:][2:STRING:t]" }, 8600a73ee0aSchristos { "{\"t\":123}", "[1:OBJECT:][2:NUMBER:t]" }, 8610a73ee0aSchristos { "{\"t\":true}", "[1:OBJECT:][2:BOOLEAN:t]" }, 8620a73ee0aSchristos { "{\"t\":false}", "[1:OBJECT:][2:BOOLEAN:t]" }, 8630a73ee0aSchristos { "{\"t\":null}", "[1:OBJECT:][2:NULL:t]" }, 8640a73ee0aSchristos { "{\"t\":truetrue}", NULL }, 8650a73ee0aSchristos { "\"test\"", "[1:STRING:]" }, 8660a73ee0aSchristos { "123", "[1:NUMBER:]" }, 8670a73ee0aSchristos { "true", "[1:BOOLEAN:]" }, 8680a73ee0aSchristos { "false", "[1:BOOLEAN:]" }, 8690a73ee0aSchristos { "null", "[1:NULL:]" }, 8700a73ee0aSchristos { "truetrue", NULL }, 8710a73ee0aSchristos { " {\t\n\r\"a\"\n:\r1\n,\n\"b\":3\n}\n", 8720a73ee0aSchristos "[1:OBJECT:][2:NUMBER:a][2:NUMBER:b]" }, 8730a73ee0aSchristos { ",", NULL }, 8740a73ee0aSchristos { "{,}", NULL }, 8750a73ee0aSchristos { "[,]", NULL }, 8760a73ee0aSchristos { ":", NULL }, 8770a73ee0aSchristos { "{:}", NULL }, 8780a73ee0aSchristos { "[:]", NULL }, 8790a73ee0aSchristos { "{ \"\\u005c\" : \"\\u005c\" }", "[1:OBJECT:][2:STRING:\\]" }, 8800a73ee0aSchristos { "[{},{}]", "[1:ARRAY:][2:OBJECT:][2:OBJECT:]" }, 8810a73ee0aSchristos { "[1,2]", "[1:ARRAY:][2:NUMBER:][2:NUMBER:]" }, 8820a73ee0aSchristos { "[\"1\",\"2\"]", "[1:ARRAY:][2:STRING:][2:STRING:]" }, 8830a73ee0aSchristos { "[true,false]", "[1:ARRAY:][2:BOOLEAN:][2:BOOLEAN:]" }, 8840a73ee0aSchristos }; 8850a73ee0aSchristos #endif /* CONFIG_JSON */ 8860a73ee0aSchristos 8870a73ee0aSchristos 8880a73ee0aSchristos static int json_tests(void) 8890a73ee0aSchristos { 8900a73ee0aSchristos #ifdef CONFIG_JSON 8910a73ee0aSchristos unsigned int i; 8920a73ee0aSchristos struct json_token *root; 8930a73ee0aSchristos char buf[1000]; 8940a73ee0aSchristos 8950a73ee0aSchristos wpa_printf(MSG_INFO, "JSON tests"); 8960a73ee0aSchristos 8970a73ee0aSchristos for (i = 0; i < ARRAY_SIZE(json_test_cases); i++) { 8980a73ee0aSchristos const struct json_test_data *test = &json_test_cases[i]; 8990a73ee0aSchristos int res = 0; 9000a73ee0aSchristos 9010a73ee0aSchristos root = json_parse(test->json, os_strlen(test->json)); 9020a73ee0aSchristos if ((root && !test->tree) || (!root && test->tree)) { 9030a73ee0aSchristos wpa_printf(MSG_INFO, "JSON test %u failed", i); 9040a73ee0aSchristos res = -1; 9050a73ee0aSchristos } else if (root) { 9060a73ee0aSchristos json_print_tree(root, buf, sizeof(buf)); 9070a73ee0aSchristos if (os_strcmp(buf, test->tree) != 0) { 9080a73ee0aSchristos wpa_printf(MSG_INFO, 9090a73ee0aSchristos "JSON test %u tree mismatch: %s %s", 9100a73ee0aSchristos i, buf, test->tree); 9110a73ee0aSchristos res = -1; 9120a73ee0aSchristos } 9130a73ee0aSchristos } 9140a73ee0aSchristos json_free(root); 9150a73ee0aSchristos if (res < 0) 9160a73ee0aSchristos return -1; 9170a73ee0aSchristos 9180a73ee0aSchristos } 9190a73ee0aSchristos #endif /* CONFIG_JSON */ 9200a73ee0aSchristos return 0; 9210a73ee0aSchristos } 9220a73ee0aSchristos 9230a73ee0aSchristos 9243d6c0713Schristos static int const_time_tests(void) 9253d6c0713Schristos { 9263d6c0713Schristos struct const_time_fill_msb_test { 9273d6c0713Schristos unsigned int val; 9283d6c0713Schristos unsigned int expected; 9293d6c0713Schristos } const_time_fill_msb_tests[] = { 9303d6c0713Schristos { 0, 0 }, 9313d6c0713Schristos { 1, 0 }, 9323d6c0713Schristos { 2, 0 }, 933*bb618362Schristos { 1U << (sizeof(unsigned int) * 8 - 1), ~0 }, 9343d6c0713Schristos { ~0 - 1, ~0 }, 9353d6c0713Schristos { ~0, ~0 } 9363d6c0713Schristos }; 9373d6c0713Schristos struct const_time_is_zero_test { 9383d6c0713Schristos unsigned int val; 9393d6c0713Schristos unsigned int expected; 9403d6c0713Schristos } const_time_is_zero_tests[] = { 9413d6c0713Schristos { 0, ~0 }, 9423d6c0713Schristos { 1, 0 }, 9433d6c0713Schristos { 2, 0 }, 944*bb618362Schristos { 1U << (sizeof(unsigned int) * 8 - 1), 0 }, 9453d6c0713Schristos { ~0 - 1, 0 }, 9463d6c0713Schristos { ~0, 0 } 9473d6c0713Schristos }; 9483d6c0713Schristos struct const_time_eq_test { 9493d6c0713Schristos unsigned int a; 9503d6c0713Schristos unsigned int b; 9513d6c0713Schristos unsigned int expected; 9523d6c0713Schristos unsigned int expected_u8; 9533d6c0713Schristos } const_time_eq_tests[] = { 9543d6c0713Schristos { 0, 1, 0, 0 }, 9553d6c0713Schristos { 1, 2, 0, 0 }, 9563d6c0713Schristos { 1, 1, ~0, 0xff }, 9573d6c0713Schristos { ~0, ~0, ~0, 0xff }, 9583d6c0713Schristos { ~0, ~0 - 1, 0, 0 }, 9593d6c0713Schristos { 0, 0, ~0, 0xff } 9603d6c0713Schristos }; 9613d6c0713Schristos struct const_time_eq_bin_test { 9623d6c0713Schristos u8 *a; 9633d6c0713Schristos u8 *b; 9643d6c0713Schristos size_t len; 9653d6c0713Schristos unsigned int expected; 9663d6c0713Schristos } const_time_eq_bin_tests[] = { 9673d6c0713Schristos { (u8 *) "", (u8 *) "", 0, ~0 }, 9683d6c0713Schristos { (u8 *) "abcde", (u8 *) "abcde", 5, ~0 }, 9693d6c0713Schristos { (u8 *) "abcde", (u8 *) "Abcde", 5, 0 }, 9703d6c0713Schristos { (u8 *) "abcde", (u8 *) "aBcde", 5, 0 }, 9713d6c0713Schristos { (u8 *) "abcde", (u8 *) "abCde", 5, 0 }, 9723d6c0713Schristos { (u8 *) "abcde", (u8 *) "abcDe", 5, 0 }, 9733d6c0713Schristos { (u8 *) "abcde", (u8 *) "abcdE", 5, 0 }, 9743d6c0713Schristos { (u8 *) "\x00", (u8 *) "\x01", 1, 0 }, 9753d6c0713Schristos { (u8 *) "\x00", (u8 *) "\x80", 1, 0 }, 9763d6c0713Schristos { (u8 *) "\x00", (u8 *) "\x00", 1, ~0 } 9773d6c0713Schristos }; 9783d6c0713Schristos struct const_time_select_test { 9793d6c0713Schristos unsigned int mask; 9803d6c0713Schristos unsigned int true_val; 9813d6c0713Schristos unsigned int false_val; 9823d6c0713Schristos unsigned int expected; 9833d6c0713Schristos } const_time_select_tests[] = { 9843d6c0713Schristos { ~0, ~0, ~0, ~0 }, 9853d6c0713Schristos { 0, ~0, ~0, ~0 }, 9863d6c0713Schristos { ~0, ~0, 0, ~0 }, 9873d6c0713Schristos { 0, ~0, 0, 0 }, 9883d6c0713Schristos { ~0, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa }, 9893d6c0713Schristos { 0, 0xaaaaaaaa, 0x55555555, 0x55555555 }, 9903d6c0713Schristos { ~0, 3, 3, 3 }, 9913d6c0713Schristos { 0, 3, 3, 3 }, 9923d6c0713Schristos { ~0, 1, 2, 1 }, 9933d6c0713Schristos { 0, 1, 2, 2 } 9943d6c0713Schristos }; 9953d6c0713Schristos struct const_time_select_int_test { 9963d6c0713Schristos unsigned int mask; 9973d6c0713Schristos int true_val; 9983d6c0713Schristos int false_val; 9993d6c0713Schristos int expected; 10003d6c0713Schristos } const_time_select_int_tests[] = { 10013d6c0713Schristos { ~0, -128, 127, -128 }, 10023d6c0713Schristos { 0, -128, 127, 127 }, 10033d6c0713Schristos { ~0, -2147483648, 2147483647, -2147483648 }, 10043d6c0713Schristos { 0, -2147483648, 2147483647, 2147483647 }, 10053d6c0713Schristos { ~0, 0, 0, 0 }, 10063d6c0713Schristos { 0, 0, 0, 0 }, 10073d6c0713Schristos { ~0, -1, 1, -1 }, 10083d6c0713Schristos { 0, -1, 1, 1 } 10093d6c0713Schristos }; 10103d6c0713Schristos struct const_time_select_u8_test { 10113d6c0713Schristos u8 mask; 10123d6c0713Schristos u8 true_val; 10133d6c0713Schristos u8 false_val; 10143d6c0713Schristos u8 expected; 10153d6c0713Schristos } const_time_select_u8_tests[] = { 10163d6c0713Schristos { ~0, ~0, ~0, ~0 }, 10173d6c0713Schristos { 0, ~0, ~0, ~0 }, 10183d6c0713Schristos { ~0, ~0, 0, ~0 }, 10193d6c0713Schristos { 0, ~0, 0, 0 }, 10203d6c0713Schristos { ~0, 0xaa, 0x55, 0xaa }, 10213d6c0713Schristos { 0, 0xaa, 0x55, 0x55 }, 10223d6c0713Schristos { ~0, 1, 2, 1 }, 10233d6c0713Schristos { 0, 1, 2, 2 } 10243d6c0713Schristos }; 10253d6c0713Schristos struct const_time_select_s8_test { 10263d6c0713Schristos u8 mask; 10273d6c0713Schristos s8 true_val; 10283d6c0713Schristos s8 false_val; 10293d6c0713Schristos s8 expected; 10303d6c0713Schristos } const_time_select_s8_tests[] = { 10313d6c0713Schristos { ~0, -128, 127, -128 }, 10323d6c0713Schristos { 0, -128, 127, 127 }, 10333d6c0713Schristos { ~0, 0, 0, 0 }, 10343d6c0713Schristos { 0, 0, 0, 0 }, 10353d6c0713Schristos { ~0, -1, 1, -1 }, 10363d6c0713Schristos { 0, -1, 1, 1 } 10373d6c0713Schristos }; 10383d6c0713Schristos struct const_time_select_bin_test { 10393d6c0713Schristos u8 mask; 10403d6c0713Schristos u8 *true_val; 10413d6c0713Schristos u8 *false_val; 10423d6c0713Schristos size_t len; 10433d6c0713Schristos u8 *expected; 10443d6c0713Schristos } const_time_select_bin_tests[] = { 10453d6c0713Schristos { ~0, (u8 *) "abcde", (u8 *) "ABCDE", 5, (u8 *) "abcde" }, 10463d6c0713Schristos { 0, (u8 *) "abcde", (u8 *) "ABCDE", 5, (u8 *) "ABCDE" }, 10473d6c0713Schristos { ~0, (u8 *) "", (u8 *) "", 0, (u8 *) "" }, 10483d6c0713Schristos { 0, (u8 *) "", (u8 *) "", 0, (u8 *) "" } 10493d6c0713Schristos }; 10503d6c0713Schristos struct const_time_memcmp_test { 10513d6c0713Schristos char *a; 10523d6c0713Schristos char *b; 10533d6c0713Schristos size_t len; 10543d6c0713Schristos int expected; 10553d6c0713Schristos } const_time_memcmp_tests[] = { 10563d6c0713Schristos { "abcde", "abcde", 5, 0 }, 10573d6c0713Schristos { "abcde", "bbcde", 5, -1 }, 10583d6c0713Schristos { "bbcde", "abcde", 5, 1 }, 10593d6c0713Schristos { "accde", "abcde", 5, 1 }, 10603d6c0713Schristos { "abcee", "abcde", 5, 1 }, 10613d6c0713Schristos { "abcdf", "abcde", 5, 1 }, 10623d6c0713Schristos { "cbcde", "aXXXX", 5, 2 }, 10633d6c0713Schristos { "a", "d", 1, -3 }, 10643d6c0713Schristos { "", "", 0, 0 } 10653d6c0713Schristos }; 10663d6c0713Schristos unsigned int i; 10673d6c0713Schristos int ret = 0; 10683d6c0713Schristos 10693d6c0713Schristos wpa_printf(MSG_INFO, "constant time tests"); 10703d6c0713Schristos 10713d6c0713Schristos for (i = 0; i < ARRAY_SIZE(const_time_fill_msb_tests); i++) { 10723d6c0713Schristos struct const_time_fill_msb_test *test; 10733d6c0713Schristos 10743d6c0713Schristos test = &const_time_fill_msb_tests[i]; 10753d6c0713Schristos if (const_time_fill_msb(test->val) != test->expected) { 10763d6c0713Schristos wpa_printf(MSG_ERROR, 10773d6c0713Schristos "const_time_fill_msb(0x%x) test failed", 10783d6c0713Schristos test->val); 10793d6c0713Schristos ret = -1; 10803d6c0713Schristos } 10813d6c0713Schristos } 10823d6c0713Schristos 10833d6c0713Schristos for (i = 0; i < ARRAY_SIZE(const_time_is_zero_tests); i++) { 10843d6c0713Schristos struct const_time_is_zero_test *test; 10853d6c0713Schristos 10863d6c0713Schristos test = &const_time_is_zero_tests[i]; 10873d6c0713Schristos if (const_time_is_zero(test->val) != test->expected) { 10883d6c0713Schristos wpa_printf(MSG_ERROR, 10893d6c0713Schristos "const_time_is_zero(0x%x) test failed", 10903d6c0713Schristos test->val); 10913d6c0713Schristos ret = -1; 10923d6c0713Schristos } 10933d6c0713Schristos } 10943d6c0713Schristos 10953d6c0713Schristos for (i = 0; i < ARRAY_SIZE(const_time_eq_tests); i++) { 10963d6c0713Schristos struct const_time_eq_test *test; 10973d6c0713Schristos 10983d6c0713Schristos test = &const_time_eq_tests[i]; 10993d6c0713Schristos if (const_time_eq(test->a, test->b) != test->expected) { 11003d6c0713Schristos wpa_printf(MSG_ERROR, 11013d6c0713Schristos "const_time_eq(0x%x,0x%x) test failed", 11023d6c0713Schristos test->a, test->b); 11033d6c0713Schristos ret = -1; 11043d6c0713Schristos } 11053d6c0713Schristos if (const_time_eq_u8(test->a, test->b) != test->expected_u8) { 11063d6c0713Schristos wpa_printf(MSG_ERROR, 11073d6c0713Schristos "const_time_eq_u8(0x%x,0x%x) test failed", 11083d6c0713Schristos test->a, test->b); 11093d6c0713Schristos ret = -1; 11103d6c0713Schristos } 11113d6c0713Schristos } 11123d6c0713Schristos 11133d6c0713Schristos for (i = 0; i < ARRAY_SIZE(const_time_eq_bin_tests); i++) { 11143d6c0713Schristos struct const_time_eq_bin_test *test; 11153d6c0713Schristos 11163d6c0713Schristos test = &const_time_eq_bin_tests[i]; 11173d6c0713Schristos if (const_time_eq_bin(test->a, test->b, test->len) != 11183d6c0713Schristos test->expected) { 11193d6c0713Schristos wpa_printf(MSG_ERROR, 11203d6c0713Schristos "const_time_eq_bin(len=%u) test failed", 11213d6c0713Schristos (unsigned int) test->len); 11223d6c0713Schristos ret = -1; 11233d6c0713Schristos } 11243d6c0713Schristos } 11253d6c0713Schristos 11263d6c0713Schristos for (i = 0; i < ARRAY_SIZE(const_time_select_tests); i++) { 11273d6c0713Schristos struct const_time_select_test *test; 11283d6c0713Schristos 11293d6c0713Schristos test = &const_time_select_tests[i]; 11303d6c0713Schristos if (const_time_select(test->mask, test->true_val, 11313d6c0713Schristos test->false_val) != test->expected) { 11323d6c0713Schristos wpa_printf(MSG_ERROR, 11333d6c0713Schristos "const_time_select(0x%x,0x%x,0x%x) test failed", 11343d6c0713Schristos test->mask, test->true_val, test->false_val); 11353d6c0713Schristos ret = -1; 11363d6c0713Schristos } 11373d6c0713Schristos } 11383d6c0713Schristos 11393d6c0713Schristos for (i = 0; i < ARRAY_SIZE(const_time_select_int_tests); i++) { 11403d6c0713Schristos struct const_time_select_int_test *test; 11413d6c0713Schristos 11423d6c0713Schristos test = &const_time_select_int_tests[i]; 11433d6c0713Schristos if (const_time_select_int(test->mask, test->true_val, 11443d6c0713Schristos test->false_val) != test->expected) { 11453d6c0713Schristos wpa_printf(MSG_ERROR, 11463d6c0713Schristos "const_time_select_int(0x%x,%d,%d) test failed", 11473d6c0713Schristos test->mask, test->true_val, test->false_val); 11483d6c0713Schristos ret = -1; 11493d6c0713Schristos } 11503d6c0713Schristos } 11513d6c0713Schristos 11523d6c0713Schristos for (i = 0; i < ARRAY_SIZE(const_time_select_u8_tests); i++) { 11533d6c0713Schristos struct const_time_select_u8_test *test; 11543d6c0713Schristos 11553d6c0713Schristos test = &const_time_select_u8_tests[i]; 11563d6c0713Schristos if (const_time_select_u8(test->mask, test->true_val, 11573d6c0713Schristos test->false_val) != test->expected) { 11583d6c0713Schristos wpa_printf(MSG_ERROR, 11593d6c0713Schristos "const_time_select_u8(0x%x,0x%x,0x%x) test failed", 11603d6c0713Schristos test->mask, test->true_val, test->false_val); 11613d6c0713Schristos ret = -1; 11623d6c0713Schristos } 11633d6c0713Schristos } 11643d6c0713Schristos 11653d6c0713Schristos for (i = 0; i < ARRAY_SIZE(const_time_select_s8_tests); i++) { 11663d6c0713Schristos struct const_time_select_s8_test *test; 11673d6c0713Schristos 11683d6c0713Schristos test = &const_time_select_s8_tests[i]; 11693d6c0713Schristos if (const_time_select_s8(test->mask, test->true_val, 11703d6c0713Schristos test->false_val) != test->expected) { 11713d6c0713Schristos wpa_printf(MSG_ERROR, 11723d6c0713Schristos "const_time_select_s8(0x%x,0x%x,0x%x) test failed", 11733d6c0713Schristos test->mask, test->true_val, test->false_val); 11743d6c0713Schristos ret = -1; 11753d6c0713Schristos } 11763d6c0713Schristos } 11773d6c0713Schristos 11783d6c0713Schristos for (i = 0; i < ARRAY_SIZE(const_time_select_bin_tests); i++) { 11793d6c0713Schristos struct const_time_select_bin_test *test; 11803d6c0713Schristos u8 dst[100]; 11813d6c0713Schristos 11823d6c0713Schristos test = &const_time_select_bin_tests[i]; 11833d6c0713Schristos const_time_select_bin(test->mask, test->true_val, 11843d6c0713Schristos test->false_val, test->len, dst); 11853d6c0713Schristos if (os_memcmp(dst, test->expected, test->len) != 0) { 11863d6c0713Schristos wpa_printf(MSG_ERROR, 11873d6c0713Schristos "const_time_select_bin(0x%x,%u) test failed", 11883d6c0713Schristos test->mask, (unsigned int) test->len); 11893d6c0713Schristos ret = -1; 11903d6c0713Schristos } 11913d6c0713Schristos } 11923d6c0713Schristos 11933d6c0713Schristos for (i = 0; i < ARRAY_SIZE(const_time_memcmp_tests); i++) { 11943d6c0713Schristos struct const_time_memcmp_test *test; 11953d6c0713Schristos int res; 11963d6c0713Schristos 11973d6c0713Schristos test = &const_time_memcmp_tests[i]; 11983d6c0713Schristos res = const_time_memcmp(test->a, test->b, test->len); 11993d6c0713Schristos if (res != test->expected) { 12003d6c0713Schristos wpa_printf(MSG_ERROR, 12013d6c0713Schristos "const_time_memcmp(%s,%s,%d) test failed (%d != %d)", 12023d6c0713Schristos test->a, test->b, (int) test->len, 12033d6c0713Schristos res, test->expected); 12043d6c0713Schristos ret = -1; 12053d6c0713Schristos } 12063d6c0713Schristos } 12073d6c0713Schristos 12083d6c0713Schristos return ret; 12093d6c0713Schristos } 12103d6c0713Schristos 12113d6c0713Schristos 12123c260e60Schristos int utils_module_tests(void) 12133c260e60Schristos { 12143c260e60Schristos int ret = 0; 12153c260e60Schristos 12163c260e60Schristos wpa_printf(MSG_INFO, "utils module tests"); 12173c260e60Schristos 12183c260e60Schristos if (printf_encode_decode_tests() < 0 || 12193c260e60Schristos ext_password_tests() < 0 || 12203c260e60Schristos trace_tests() < 0 || 12213c260e60Schristos bitfield_tests() < 0 || 1222bb610346Schristos base64_tests() < 0 || 1223bb610346Schristos common_tests() < 0 || 122436ebd06eSchristos os_tests() < 0 || 122536ebd06eSchristos wpabuf_tests() < 0 || 122636ebd06eSchristos ip_addr_tests() < 0 || 122736ebd06eSchristos eloop_tests() < 0 || 12280a73ee0aSchristos json_tests() < 0 || 12293d6c0713Schristos const_time_tests() < 0 || 12303c260e60Schristos int_array_tests() < 0) 12313c260e60Schristos ret = -1; 12323c260e60Schristos 12333c260e60Schristos return ret; 12343c260e60Schristos } 1235