]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/utils/utils_module_tests.c
Use a shared helper function for RSN supplicant capabilities
[thirdparty/hostap.git] / src / utils / utils_module_tests.c
CommitLineData
0d7773b6 1/*
8860e0f4 2 * utils module tests
38ff2193 3 * Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi>
0d7773b6
JM
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9#include "utils/includes.h"
8860e0f4 10
0d7773b6 11#include "utils/common.h"
72056f69 12#include "utils/const_time.h"
6ca8a74c 13#include "common/ieee802_11_defs.h"
8b0980af 14#include "utils/bitfield.h"
a3fe74bd 15#include "utils/ext_password.h"
f347935f 16#include "utils/trace.h"
38ff2193 17#include "utils/base64.h"
3c48c9c0 18#include "utils/ip_addr.h"
569f8f9b 19#include "utils/eloop.h"
4e19eb88 20#include "utils/json.h"
50a17a76 21#include "utils/module_tests.h"
0d7773b6
JM
22
23
8860e0f4 24struct printf_test_data {
0d7773b6
JM
25 u8 *data;
26 size_t len;
27 char *encoded;
28};
29
8860e0f4 30static const struct printf_test_data printf_tests[] = {
0d7773b6 31 { (u8 *) "abcde", 5, "abcde" },
8860e0f4 32 { (u8 *) "a\0b\nc\ed\re\tf\"\\", 13, "a\\0b\\nc\\ed\\re\\tf\\\"\\\\" },
0d7773b6
JM
33 { (u8 *) "\x00\x31\x00\x32\x00\x39", 6, "\\x001\\0002\\09" },
34 { (u8 *) "\n\n\n", 3, "\n\12\x0a" },
35 { (u8 *) "\303\245\303\244\303\266\303\205\303\204\303\226", 12,
36 "\\xc3\\xa5\xc3\\xa4\\xc3\\xb6\\xc3\\x85\\xc3\\x84\\xc3\\x96" },
37 { (u8 *) "\303\245\303\244\303\266\303\205\303\204\303\226", 12,
38 "\\303\\245\\303\\244\\303\\266\\303\\205\\303\\204\\303\\226" },
39 { (u8 *) "\xe5\xe4\xf6\xc5\xc4\xd6", 6,
40 "\\xe5\\xe4\\xf6\\xc5\\xc4\\xd6" },
41 { NULL, 0, NULL }
42};
43
44
8860e0f4 45static int printf_encode_decode_tests(void)
0d7773b6
JM
46{
47 int i;
48 size_t binlen;
49 char buf[100];
50 u8 bin[100];
51 int errors = 0;
3c48c9c0 52 int array[10];
0d7773b6 53
8860e0f4
JM
54 wpa_printf(MSG_INFO, "printf encode/decode tests");
55
56 for (i = 0; printf_tests[i].data; i++) {
57 const struct printf_test_data *test = &printf_tests[i];
0d7773b6 58 printf_encode(buf, sizeof(buf), test->data, test->len);
8860e0f4 59 wpa_printf(MSG_INFO, "%d: -> \"%s\"", i, buf);
0d7773b6
JM
60
61 binlen = printf_decode(bin, sizeof(bin), buf);
62 if (binlen != test->len ||
63 os_memcmp(bin, test->data, binlen) != 0) {
8860e0f4
JM
64 wpa_hexdump(MSG_ERROR, "Error in decoding#1",
65 bin, binlen);
0d7773b6
JM
66 errors++;
67 }
68
69 binlen = printf_decode(bin, sizeof(bin), test->encoded);
70 if (binlen != test->len ||
71 os_memcmp(bin, test->data, binlen) != 0) {
8860e0f4
JM
72 wpa_hexdump(MSG_ERROR, "Error in decoding#2",
73 bin, binlen);
0d7773b6
JM
74 errors++;
75 }
76 }
77
ee54e401
JM
78 buf[5] = 'A';
79 printf_encode(buf, 5, (const u8 *) "abcde", 5);
80 if (buf[5] != 'A') {
81 wpa_printf(MSG_ERROR, "Error in bounds checking#1");
82 errors++;
83 }
84
85 for (i = 5; i < 10; i++) {
86 buf[i] = 'A';
87 printf_encode(buf, i, (const u8 *) "\xdd\xdd\xdd\xdd\xdd", 5);
88 if (buf[i] != 'A') {
89 wpa_printf(MSG_ERROR, "Error in bounds checking#2(%d)",
90 i);
91 errors++;
92 }
93 }
94
2eb64ea4
JM
95 if (printf_decode(bin, 3, "abcde") != 2)
96 errors++;
97
98 if (printf_decode(bin, 3, "\\xa") != 1 || bin[0] != 10)
99 errors++;
100
3c48c9c0
JM
101 if (printf_decode(bin, 3, "\\xq") != 1 || bin[0] != 'q')
102 errors++;
103
2eb64ea4
JM
104 if (printf_decode(bin, 3, "\\a") != 1 || bin[0] != 'a')
105 errors++;
106
3c48c9c0
JM
107 array[0] = 10;
108 array[1] = 10;
109 array[2] = 5;
110 array[3] = 10;
111 array[4] = 5;
112 array[5] = 0;
113 if (int_array_len(array) != 5)
114 errors++;
115 int_array_sort_unique(array);
116 if (int_array_len(array) != 2)
117 errors++;
118
0d7773b6 119 if (errors) {
8860e0f4 120 wpa_printf(MSG_ERROR, "%d printf test(s) failed", errors);
0d7773b6
JM
121 return -1;
122 }
123
124 return 0;
125}
8860e0f4
JM
126
127
8b0980af
JM
128static int bitfield_tests(void)
129{
130 struct bitfield *bf;
131 int i;
132 int errors = 0;
133
134 wpa_printf(MSG_INFO, "bitfield tests");
135
136 bf = bitfield_alloc(123);
137 if (bf == NULL)
138 return -1;
139
140 for (i = 0; i < 123; i++) {
141 if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1))
142 errors++;
143 if (i > 0 && bitfield_is_set(bf, i - 1))
144 errors++;
145 bitfield_set(bf, i);
146 if (!bitfield_is_set(bf, i))
147 errors++;
148 bitfield_clear(bf, i);
149 if (bitfield_is_set(bf, i))
150 errors++;
151 }
152
153 for (i = 123; i < 200; i++) {
154 if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1))
155 errors++;
156 if (i > 0 && bitfield_is_set(bf, i - 1))
157 errors++;
158 bitfield_set(bf, i);
159 if (bitfield_is_set(bf, i))
160 errors++;
161 bitfield_clear(bf, i);
162 if (bitfield_is_set(bf, i))
163 errors++;
164 }
165
166 for (i = 0; i < 123; i++) {
167 if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1))
168 errors++;
169 bitfield_set(bf, i);
170 if (!bitfield_is_set(bf, i))
171 errors++;
172 }
173
174 for (i = 0; i < 123; i++) {
175 if (!bitfield_is_set(bf, i))
176 errors++;
177 bitfield_clear(bf, i);
178 if (bitfield_is_set(bf, i))
179 errors++;
180 }
181
182 for (i = 0; i < 123; i++) {
183 if (bitfield_get_first_zero(bf) != i)
184 errors++;
185 bitfield_set(bf, i);
186 }
187 if (bitfield_get_first_zero(bf) != -1)
188 errors++;
189 for (i = 0; i < 123; i++) {
190 if (!bitfield_is_set(bf, i))
191 errors++;
192 bitfield_clear(bf, i);
193 if (bitfield_get_first_zero(bf) != i)
194 errors++;
195 bitfield_set(bf, i);
196 }
197 if (bitfield_get_first_zero(bf) != -1)
198 errors++;
199
200 bitfield_free(bf);
201
56a11801
JM
202 bf = bitfield_alloc(8);
203 if (bf == NULL)
204 return -1;
205 if (bitfield_get_first_zero(bf) != 0)
206 errors++;
207 for (i = 0; i < 8; i++)
208 bitfield_set(bf, i);
209 if (bitfield_get_first_zero(bf) != -1)
210 errors++;
211 bitfield_free(bf);
212
8b0980af
JM
213 if (errors) {
214 wpa_printf(MSG_ERROR, "%d bitfield test(s) failed", errors);
215 return -1;
216 }
217
218 return 0;
219}
220
221
3eb744a3
JM
222static int int_array_tests(void)
223{
224 int test1[] = { 1, 2, 3, 4, 5, 6, 0 };
225 int test2[] = { 1, -1, 0 };
226 int test3[] = { 1, 1, 1, -1, 2, 3, 4, 1, 2, 0 };
227 int test3_res[] = { -1, 1, 2, 3, 4, 0 };
228 int errors = 0;
9f9a148a 229 size_t len;
3eb744a3
JM
230
231 wpa_printf(MSG_INFO, "int_array tests");
232
233 if (int_array_len(test1) != 6 ||
234 int_array_len(test2) != 2)
235 errors++;
236
237 int_array_sort_unique(test3);
238 len = int_array_len(test3_res);
239 if (int_array_len(test3) != len)
240 errors++;
241 else if (os_memcmp(test3, test3_res, len * sizeof(int)) != 0)
242 errors++;
243
244 if (errors) {
245 wpa_printf(MSG_ERROR, "%d int_array test(s) failed", errors);
246 return -1;
247 }
248
249 return 0;
250}
251
252
a3fe74bd
JM
253static int ext_password_tests(void)
254{
255 struct ext_password_data *data;
256 int ret = 0;
257 struct wpabuf *pw;
258
259 wpa_printf(MSG_INFO, "ext_password tests");
260
261 data = ext_password_init("unknown", "foo");
262 if (data != NULL)
263 return -1;
264
265 data = ext_password_init("test", NULL);
266 if (data == NULL)
267 return -1;
268 pw = ext_password_get(data, "foo");
269 if (pw != NULL)
270 ret = -1;
271 ext_password_free(pw);
272
273 ext_password_deinit(data);
274
275 pw = ext_password_get(NULL, "foo");
276 if (pw != NULL)
277 ret = -1;
278 ext_password_free(pw);
279
280 return ret;
281}
282
283
f347935f
JM
284static int trace_tests(void)
285{
286 wpa_printf(MSG_INFO, "trace tests");
287
288 wpa_trace_show("test backtrace");
289 wpa_trace_dump_funcname("test funcname", trace_tests);
290
291 return 0;
292}
293
294
38ff2193
JM
295static int base64_tests(void)
296{
297 int errors = 0;
298 unsigned char *res;
8e5e36a1 299 char *res2;
38ff2193
JM
300 size_t res_len;
301
302 wpa_printf(MSG_INFO, "base64 tests");
303
8e5e36a1
JM
304 res2 = base64_encode("", ~0, &res_len);
305 if (res2) {
38ff2193 306 errors++;
8e5e36a1 307 os_free(res2);
38ff2193
JM
308 }
309
8e5e36a1
JM
310 res2 = base64_encode("=", 1, &res_len);
311 if (!res2 || res_len != 5 || res2[0] != 'P' || res2[1] != 'Q' ||
312 res2[2] != '=' || res2[3] != '=' || res2[4] != '\n')
38ff2193 313 errors++;
8e5e36a1 314 os_free(res2);
38ff2193 315
8e5e36a1
JM
316 res2 = base64_encode("=", 1, NULL);
317 if (!res2 || res2[0] != 'P' || res2[1] != 'Q' ||
318 res2[2] != '=' || res2[3] != '=' || res2[4] != '\n')
38ff2193 319 errors++;
8e5e36a1 320 os_free(res2);
38ff2193 321
8e5e36a1 322 res = base64_decode("", 0, &res_len);
38ff2193
JM
323 if (res) {
324 errors++;
325 os_free(res);
326 }
327
8e5e36a1 328 res = base64_decode("a", 1, &res_len);
38ff2193
JM
329 if (res) {
330 errors++;
331 os_free(res);
332 }
333
8e5e36a1 334 res = base64_decode("====", 4, &res_len);
38ff2193
JM
335 if (res) {
336 errors++;
337 os_free(res);
338 }
339
8e5e36a1 340 res = base64_decode("PQ==", 4, &res_len);
38ff2193
JM
341 if (!res || res_len != 1 || res[0] != '=')
342 errors++;
343 os_free(res);
344
8e5e36a1 345 res = base64_decode("P.Q-=!=*", 8, &res_len);
38ff2193
JM
346 if (!res || res_len != 1 || res[0] != '=')
347 errors++;
348 os_free(res);
349
350 if (errors) {
351 wpa_printf(MSG_ERROR, "%d base64 test(s) failed", errors);
352 return -1;
353 }
354
355 return 0;
356}
357
358
2eb64ea4
JM
359static int common_tests(void)
360{
3c48c9c0 361 char buf[3], longbuf[100];
2eb64ea4
JM
362 u8 addr[ETH_ALEN] = { 1, 2, 3, 4, 5, 6 };
363 u8 bin[3];
364 int errors = 0;
365 struct wpa_freq_range_list ranges;
6ca8a74c
JM
366 size_t len;
367 const char *txt;
368 u8 ssid[255];
2eb64ea4
JM
369
370 wpa_printf(MSG_INFO, "common tests");
371
372 if (hwaddr_mask_txt(buf, 3, addr, addr) != -1)
373 errors++;
374
375 if (wpa_scnprintf(buf, 0, "hello") != 0 ||
376 wpa_scnprintf(buf, 3, "hello") != 2)
377 errors++;
378
379 if (wpa_snprintf_hex(buf, 0, addr, ETH_ALEN) != 0 ||
380 wpa_snprintf_hex(buf, 3, addr, ETH_ALEN) != 2)
381 errors++;
382
383 if (merge_byte_arrays(bin, 3, addr, ETH_ALEN, NULL, 0) != 3 ||
384 merge_byte_arrays(bin, 3, NULL, 0, addr, ETH_ALEN) != 3)
385 errors++;
386
387 if (dup_binstr(NULL, 0) != NULL)
388 errors++;
389
390 if (freq_range_list_includes(NULL, 0) != 0)
391 errors++;
392
393 os_memset(&ranges, 0, sizeof(ranges));
394 if (freq_range_list_parse(&ranges, "") != 0 ||
395 freq_range_list_includes(&ranges, 0) != 0 ||
396 freq_range_list_str(&ranges) != NULL)
397 errors++;
398
399 if (utf8_unescape(NULL, 0, buf, sizeof(buf)) != 0 ||
400 utf8_unescape("a", 1, NULL, 0) != 0 ||
401 utf8_unescape("a\\", 2, buf, sizeof(buf)) != 0 ||
402 utf8_unescape("abcde", 5, buf, sizeof(buf)) != 0 ||
403 utf8_unescape("abc", 3, buf, 3) != 3)
404 errors++;
405
406 if (utf8_unescape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a')
407 errors++;
408
409 if (utf8_unescape("\\b", 2, buf, sizeof(buf)) != 1 || buf[0] != 'b')
410 errors++;
411
412 if (utf8_escape(NULL, 0, buf, sizeof(buf)) != 0 ||
413 utf8_escape("a", 1, NULL, 0) != 0 ||
414 utf8_escape("abcde", 5, buf, sizeof(buf)) != 0 ||
415 utf8_escape("a\\bcde", 6, buf, sizeof(buf)) != 0 ||
416 utf8_escape("ab\\cde", 6, buf, sizeof(buf)) != 0 ||
417 utf8_escape("abc\\de", 6, buf, sizeof(buf)) != 0 ||
418 utf8_escape("abc", 3, buf, 3) != 3)
419 errors++;
420
421 if (utf8_escape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a')
422 errors++;
423
6ca8a74c
JM
424 os_memset(ssid, 0, sizeof(ssid));
425 txt = wpa_ssid_txt(ssid, sizeof(ssid));
426 len = os_strlen(txt);
427 /* Verify that SSID_MAX_LEN * 4 buffer limit is enforced. */
428 if (len != SSID_MAX_LEN * 4) {
429 wpa_printf(MSG_ERROR,
430 "Unexpected wpa_ssid_txt() result with too long SSID");
431 errors++;
432 }
433
3c48c9c0
JM
434 if (wpa_snprintf_hex_sep(longbuf, 0, addr, ETH_ALEN, '-') != 0 ||
435 wpa_snprintf_hex_sep(longbuf, 5, addr, ETH_ALEN, '-') != 3 ||
436 os_strcmp(longbuf, "01-0") != 0)
437 errors++;
438
2eb64ea4
JM
439 if (errors) {
440 wpa_printf(MSG_ERROR, "%d common test(s) failed", errors);
441 return -1;
442 }
443
444 return 0;
445}
446
447
3c48c9c0
JM
448static int os_tests(void)
449{
450 int errors = 0;
451 void *ptr;
452 os_time_t t;
453
454 wpa_printf(MSG_INFO, "os tests");
455
456 ptr = os_calloc((size_t) -1, (size_t) -1);
457 if (ptr) {
458 errors++;
459 os_free(ptr);
460 }
461 ptr = os_calloc((size_t) 2, (size_t) -1);
462 if (ptr) {
463 errors++;
464 os_free(ptr);
465 }
466 ptr = os_calloc((size_t) -1, (size_t) 2);
467 if (ptr) {
468 errors++;
469 os_free(ptr);
470 }
471
472 ptr = os_realloc_array(NULL, (size_t) -1, (size_t) -1);
473 if (ptr) {
474 errors++;
475 os_free(ptr);
476 }
477
478 os_sleep(1, 1);
479
480 if (os_mktime(1969, 1, 1, 1, 1, 1, &t) == 0 ||
481 os_mktime(1971, 0, 1, 1, 1, 1, &t) == 0 ||
482 os_mktime(1971, 13, 1, 1, 1, 1, &t) == 0 ||
483 os_mktime(1971, 1, 0, 1, 1, 1, &t) == 0 ||
484 os_mktime(1971, 1, 32, 1, 1, 1, &t) == 0 ||
485 os_mktime(1971, 1, 1, -1, 1, 1, &t) == 0 ||
486 os_mktime(1971, 1, 1, 24, 1, 1, &t) == 0 ||
487 os_mktime(1971, 1, 1, 1, -1, 1, &t) == 0 ||
488 os_mktime(1971, 1, 1, 1, 60, 1, &t) == 0 ||
489 os_mktime(1971, 1, 1, 1, 1, -1, &t) == 0 ||
490 os_mktime(1971, 1, 1, 1, 1, 61, &t) == 0 ||
491 os_mktime(1971, 1, 1, 1, 1, 1, &t) != 0 ||
492 os_mktime(2020, 1, 2, 3, 4, 5, &t) != 0 ||
493 os_mktime(2015, 12, 31, 23, 59, 59, &t) != 0)
494 errors++;
495
496 if (os_setenv("hwsim_test_env", "test value", 0) != 0 ||
497 os_setenv("hwsim_test_env", "test value 2", 1) != 0 ||
498 os_unsetenv("hwsim_test_env") != 0)
499 errors++;
500
501 if (os_file_exists("/this-file-does-not-exists-hwsim") != 0)
502 errors++;
503
504 if (errors) {
505 wpa_printf(MSG_ERROR, "%d os test(s) failed", errors);
506 return -1;
507 }
508
509 return 0;
510}
511
512
513static int wpabuf_tests(void)
514{
515 int errors = 0;
516 void *ptr;
517 struct wpabuf *buf;
518
519 wpa_printf(MSG_INFO, "wpabuf tests");
520
521 ptr = os_malloc(100);
522 if (ptr) {
523 buf = wpabuf_alloc_ext_data(ptr, 100);
524 if (buf) {
525 if (wpabuf_resize(&buf, 100) < 0)
526 errors++;
527 else
528 wpabuf_put(buf, 100);
529 wpabuf_free(buf);
530 } else {
531 errors++;
532 os_free(ptr);
533 }
534 } else {
535 errors++;
536 }
537
538 buf = wpabuf_alloc(100);
539 if (buf) {
540 struct wpabuf *buf2;
541
542 wpabuf_put(buf, 100);
543 if (wpabuf_resize(&buf, 100) < 0)
544 errors++;
545 else
546 wpabuf_put(buf, 100);
547 buf2 = wpabuf_concat(buf, NULL);
548 if (buf2 != buf)
549 errors++;
550 wpabuf_free(buf2);
551 } else {
552 errors++;
553 }
554
555 buf = NULL;
556 buf = wpabuf_zeropad(buf, 10);
557 if (buf != NULL)
558 errors++;
559
560 if (errors) {
561 wpa_printf(MSG_ERROR, "%d wpabuf test(s) failed", errors);
562 return -1;
563 }
564
565 return 0;
566}
567
568
569static int ip_addr_tests(void)
570{
571 int errors = 0;
572 struct hostapd_ip_addr addr;
573 char buf[100];
574
575 wpa_printf(MSG_INFO, "ip_addr tests");
576
577 if (hostapd_parse_ip_addr("1.2.3.4", &addr) != 0 ||
578 addr.af != AF_INET ||
579 hostapd_ip_txt(NULL, buf, sizeof(buf)) != NULL ||
580 hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' ||
581 hostapd_ip_txt(&addr, buf, 0) != NULL ||
582 hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf)
583 errors++;
584
585 if (hostapd_parse_ip_addr("::", &addr) != 0 ||
586 addr.af != AF_INET6 ||
587 hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' ||
588 hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf)
589 errors++;
590
591 if (errors) {
592 wpa_printf(MSG_ERROR, "%d ip_addr test(s) failed", errors);
593 return -1;
594 }
595
596 return 0;
597}
598
599
569f8f9b
JM
600struct test_eloop {
601 unsigned int magic;
602 int close_in_timeout;
603 int pipefd1[2];
604 int pipefd2[2];
605};
606
607
608static void eloop_tests_start(int close_in_timeout);
609
610
611static void eloop_test_read_2(int sock, void *eloop_ctx, void *sock_ctx)
612{
613 struct test_eloop *t = eloop_ctx;
614 ssize_t res;
615 char buf[10];
616
617 wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
618
619 if (t->magic != 0x12345678) {
620 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
621 __func__, t->magic);
622 }
623
624 if (t->pipefd2[0] != sock) {
625 wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
626 __func__, sock, t->pipefd2[0]);
627 }
628
629 res = read(sock, buf, sizeof(buf));
630 wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d",
631 __func__, sock, (int) res);
632}
633
634
635static void eloop_test_read_2_wrong(int sock, void *eloop_ctx, void *sock_ctx)
636{
637 struct test_eloop *t = eloop_ctx;
638
639 wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
640
641 if (t->magic != 0x12345678) {
642 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
643 __func__, t->magic);
644 }
645
646 if (t->pipefd2[0] != sock) {
647 wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
648 __func__, sock, t->pipefd2[0]);
649 }
650
651 /*
652 * This is expected to block due to the original socket with data having
653 * been closed and no new data having been written to the new socket
654 * with the same fd. To avoid blocking the process during test, skip the
655 * read here.
656 */
657 wpa_printf(MSG_ERROR, "%s: FAIL - should not have called this function",
658 __func__);
659}
660
661
662static void reopen_pipefd2(struct test_eloop *t)
663{
664 if (t->pipefd2[0] < 0) {
665 wpa_printf(MSG_INFO, "pipefd2 had been closed");
666 } else {
667 int res;
668
669 wpa_printf(MSG_INFO, "close pipefd2");
670 eloop_unregister_read_sock(t->pipefd2[0]);
671 close(t->pipefd2[0]);
672 t->pipefd2[0] = -1;
673 close(t->pipefd2[1]);
674 t->pipefd2[1] = -1;
675
676 res = pipe(t->pipefd2);
677 if (res < 0) {
678 wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
679 t->pipefd2[0] = -1;
680 t->pipefd2[1] = -1;
681 return;
682 }
683
684 wpa_printf(MSG_INFO,
685 "re-register pipefd2 with new sockets %d,%d",
686 t->pipefd2[0], t->pipefd2[1]);
687 eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2_wrong,
688 t, NULL);
689 }
690}
691
692
693static void eloop_test_read_1(int sock, void *eloop_ctx, void *sock_ctx)
694{
695 struct test_eloop *t = eloop_ctx;
696 ssize_t res;
697 char buf[10];
698
699 wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
700
701 if (t->magic != 0x12345678) {
702 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
703 __func__, t->magic);
704 }
705
706 if (t->pipefd1[0] != sock) {
707 wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
708 __func__, sock, t->pipefd1[0]);
709 }
710
711 res = read(sock, buf, sizeof(buf));
712 wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d",
713 __func__, sock, (int) res);
714
715 if (!t->close_in_timeout)
716 reopen_pipefd2(t);
717}
718
719
720static void eloop_test_cb(void *eloop_data, void *user_ctx)
721{
722 struct test_eloop *t = eloop_data;
723
724 wpa_printf(MSG_INFO, "%s", __func__);
725
726 if (t->magic != 0x12345678) {
727 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
728 __func__, t->magic);
729 }
730
731 if (t->close_in_timeout)
732 reopen_pipefd2(t);
733}
734
735
736static void eloop_test_timeout(void *eloop_data, void *user_ctx)
737{
738 struct test_eloop *t = eloop_data;
739 int next_run = 0;
740
741 wpa_printf(MSG_INFO, "%s", __func__);
742
743 if (t->magic != 0x12345678) {
744 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
745 __func__, t->magic);
746 }
747
748 if (t->pipefd1[0] >= 0) {
749 wpa_printf(MSG_INFO, "pipefd1 had not been closed");
750 eloop_unregister_read_sock(t->pipefd1[0]);
751 close(t->pipefd1[0]);
752 t->pipefd1[0] = -1;
753 close(t->pipefd1[1]);
754 t->pipefd1[1] = -1;
755 }
756
757 if (t->pipefd2[0] >= 0) {
758 wpa_printf(MSG_INFO, "pipefd2 had not been closed");
759 eloop_unregister_read_sock(t->pipefd2[0]);
760 close(t->pipefd2[0]);
761 t->pipefd2[0] = -1;
762 close(t->pipefd2[1]);
763 t->pipefd2[1] = -1;
764 }
765
766 next_run = t->close_in_timeout;
767 t->magic = 0;
768 wpa_printf(MSG_INFO, "%s - free(%p)", __func__, t);
769 os_free(t);
770
771 if (next_run)
772 eloop_tests_start(0);
773}
774
775
776static void eloop_tests_start(int close_in_timeout)
777{
778 struct test_eloop *t;
779 int res;
780
781 t = os_zalloc(sizeof(*t));
782 if (!t)
783 return;
784 t->magic = 0x12345678;
785 t->close_in_timeout = close_in_timeout;
786
787 wpa_printf(MSG_INFO, "starting eloop tests (%p) (close_in_timeout=%d)",
788 t, close_in_timeout);
789
790 res = pipe(t->pipefd1);
791 if (res < 0) {
792 wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
793 os_free(t);
794 return;
795 }
796
797 res = pipe(t->pipefd2);
798 if (res < 0) {
799 wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
800 close(t->pipefd1[0]);
801 close(t->pipefd1[1]);
802 os_free(t);
803 return;
804 }
805
806 wpa_printf(MSG_INFO, "pipe fds: %d,%d %d,%d",
807 t->pipefd1[0], t->pipefd1[1],
808 t->pipefd2[0], t->pipefd2[1]);
809
810 eloop_register_read_sock(t->pipefd1[0], eloop_test_read_1, t, NULL);
811 eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2, t, NULL);
812 eloop_register_timeout(0, 0, eloop_test_cb, t, NULL);
813 eloop_register_timeout(0, 200000, eloop_test_timeout, t, NULL);
814
815 if (write(t->pipefd1[1], "HELLO", 5) < 0)
816 wpa_printf(MSG_INFO, "write: %s", strerror(errno));
817 if (write(t->pipefd2[1], "TEST", 4) < 0)
818 wpa_printf(MSG_INFO, "write: %s", strerror(errno));
819 os_sleep(0, 50000);
820 wpa_printf(MSG_INFO, "waiting for eloop callbacks");
821}
822
823
824static void eloop_tests_run(void *eloop_data, void *user_ctx)
825{
826 eloop_tests_start(1);
827}
828
829
830static int eloop_tests(void)
831{
832 wpa_printf(MSG_INFO, "schedule eloop tests to be run");
833
834 /*
835 * Cannot return error from these without a significant design change,
836 * so for now, run the tests from a scheduled timeout and require
837 * separate verification of the results from the debug log.
838 */
839 eloop_register_timeout(0, 0, eloop_tests_run, NULL, NULL);
840
841 return 0;
842}
843
844
4e19eb88
JM
845#ifdef CONFIG_JSON
846struct json_test_data {
847 const char *json;
848 const char *tree;
849};
850
851static const struct json_test_data json_test_cases[] = {
852 { "{}", "[1:OBJECT:]" },
853 { "[]", "[1:ARRAY:]" },
854 { "{", NULL },
855 { "[", NULL },
856 { "}", NULL },
857 { "]", NULL },
858 { "[[]]", "[1:ARRAY:][2:ARRAY:]" },
859 { "{\"t\":\"test\"}", "[1:OBJECT:][2:STRING:t]" },
860 { "{\"t\":123}", "[1:OBJECT:][2:NUMBER:t]" },
861 { "{\"t\":true}", "[1:OBJECT:][2:BOOLEAN:t]" },
862 { "{\"t\":false}", "[1:OBJECT:][2:BOOLEAN:t]" },
863 { "{\"t\":null}", "[1:OBJECT:][2:NULL:t]" },
864 { "{\"t\":truetrue}", NULL },
865 { "\"test\"", "[1:STRING:]" },
866 { "123", "[1:NUMBER:]" },
867 { "true", "[1:BOOLEAN:]" },
868 { "false", "[1:BOOLEAN:]" },
869 { "null", "[1:NULL:]" },
870 { "truetrue", NULL },
871 { " {\t\n\r\"a\"\n:\r1\n,\n\"b\":3\n}\n",
872 "[1:OBJECT:][2:NUMBER:a][2:NUMBER:b]" },
873 { ",", NULL },
874 { "{,}", NULL },
875 { "[,]", NULL },
876 { ":", NULL },
877 { "{:}", NULL },
878 { "[:]", NULL },
879 { "{ \"\\u005c\" : \"\\u005c\" }", "[1:OBJECT:][2:STRING:\\]" },
17385fba
JM
880 { "[{},{}]", "[1:ARRAY:][2:OBJECT:][2:OBJECT:]" },
881 { "[1,2]", "[1:ARRAY:][2:NUMBER:][2:NUMBER:]" },
882 { "[\"1\",\"2\"]", "[1:ARRAY:][2:STRING:][2:STRING:]" },
883 { "[true,false]", "[1:ARRAY:][2:BOOLEAN:][2:BOOLEAN:]" },
4e19eb88
JM
884};
885#endif /* CONFIG_JSON */
886
887
888static int json_tests(void)
889{
890#ifdef CONFIG_JSON
891 unsigned int i;
892 struct json_token *root;
893 char buf[1000];
894
895 wpa_printf(MSG_INFO, "JSON tests");
896
897 for (i = 0; i < ARRAY_SIZE(json_test_cases); i++) {
898 const struct json_test_data *test = &json_test_cases[i];
899 int res = 0;
900
901 root = json_parse(test->json, os_strlen(test->json));
902 if ((root && !test->tree) || (!root && test->tree)) {
903 wpa_printf(MSG_INFO, "JSON test %u failed", i);
904 res = -1;
905 } else if (root) {
906 json_print_tree(root, buf, sizeof(buf));
907 if (os_strcmp(buf, test->tree) != 0) {
908 wpa_printf(MSG_INFO,
909 "JSON test %u tree mismatch: %s %s",
910 i, buf, test->tree);
911 res = -1;
912 }
913 }
914 json_free(root);
915 if (res < 0)
916 return -1;
917
918 }
919#endif /* CONFIG_JSON */
920 return 0;
921}
922
923
72056f69
JM
924static int const_time_tests(void)
925{
926 struct const_time_fill_msb_test {
927 unsigned int val;
928 unsigned int expected;
929 } const_time_fill_msb_tests[] = {
930 { 0, 0 },
931 { 1, 0 },
932 { 2, 0 },
f7b2fe99 933 { 1U << (sizeof(unsigned int) * 8 - 1), ~0 },
72056f69
JM
934 { ~0 - 1, ~0 },
935 { ~0, ~0 }
936 };
937 struct const_time_is_zero_test {
938 unsigned int val;
939 unsigned int expected;
940 } const_time_is_zero_tests[] = {
941 { 0, ~0 },
942 { 1, 0 },
943 { 2, 0 },
f7b2fe99 944 { 1U << (sizeof(unsigned int) * 8 - 1), 0 },
72056f69
JM
945 { ~0 - 1, 0 },
946 { ~0, 0 }
947 };
948 struct const_time_eq_test {
949 unsigned int a;
950 unsigned int b;
951 unsigned int expected;
952 unsigned int expected_u8;
953 } const_time_eq_tests[] = {
954 { 0, 1, 0, 0 },
955 { 1, 2, 0, 0 },
956 { 1, 1, ~0, 0xff },
957 { ~0, ~0, ~0, 0xff },
958 { ~0, ~0 - 1, 0, 0 },
959 { 0, 0, ~0, 0xff }
960 };
961 struct const_time_eq_bin_test {
962 u8 *a;
963 u8 *b;
964 size_t len;
965 unsigned int expected;
966 } const_time_eq_bin_tests[] = {
967 { (u8 *) "", (u8 *) "", 0, ~0 },
968 { (u8 *) "abcde", (u8 *) "abcde", 5, ~0 },
969 { (u8 *) "abcde", (u8 *) "Abcde", 5, 0 },
970 { (u8 *) "abcde", (u8 *) "aBcde", 5, 0 },
971 { (u8 *) "abcde", (u8 *) "abCde", 5, 0 },
972 { (u8 *) "abcde", (u8 *) "abcDe", 5, 0 },
973 { (u8 *) "abcde", (u8 *) "abcdE", 5, 0 },
974 { (u8 *) "\x00", (u8 *) "\x01", 1, 0 },
975 { (u8 *) "\x00", (u8 *) "\x80", 1, 0 },
976 { (u8 *) "\x00", (u8 *) "\x00", 1, ~0 }
977 };
978 struct const_time_select_test {
979 unsigned int mask;
980 unsigned int true_val;
981 unsigned int false_val;
982 unsigned int expected;
983 } const_time_select_tests[] = {
984 { ~0, ~0, ~0, ~0 },
985 { 0, ~0, ~0, ~0 },
986 { ~0, ~0, 0, ~0 },
987 { 0, ~0, 0, 0 },
988 { ~0, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa },
989 { 0, 0xaaaaaaaa, 0x55555555, 0x55555555 },
990 { ~0, 3, 3, 3 },
991 { 0, 3, 3, 3 },
992 { ~0, 1, 2, 1 },
993 { 0, 1, 2, 2 }
994 };
995 struct const_time_select_int_test {
996 unsigned int mask;
997 int true_val;
998 int false_val;
999 int expected;
1000 } const_time_select_int_tests[] = {
1001 { ~0, -128, 127, -128 },
1002 { 0, -128, 127, 127 },
1003 { ~0, -2147483648, 2147483647, -2147483648 },
1004 { 0, -2147483648, 2147483647, 2147483647 },
1005 { ~0, 0, 0, 0 },
1006 { 0, 0, 0, 0 },
1007 { ~0, -1, 1, -1 },
1008 { 0, -1, 1, 1 }
1009 };
1010 struct const_time_select_u8_test {
1011 u8 mask;
1012 u8 true_val;
1013 u8 false_val;
1014 u8 expected;
1015 } const_time_select_u8_tests[] = {
1016 { ~0, ~0, ~0, ~0 },
1017 { 0, ~0, ~0, ~0 },
1018 { ~0, ~0, 0, ~0 },
1019 { 0, ~0, 0, 0 },
1020 { ~0, 0xaa, 0x55, 0xaa },
1021 { 0, 0xaa, 0x55, 0x55 },
1022 { ~0, 1, 2, 1 },
1023 { 0, 1, 2, 2 }
1024 };
1025 struct const_time_select_s8_test {
1026 u8 mask;
1027 s8 true_val;
1028 s8 false_val;
1029 s8 expected;
1030 } const_time_select_s8_tests[] = {
1031 { ~0, -128, 127, -128 },
1032 { 0, -128, 127, 127 },
1033 { ~0, 0, 0, 0 },
1034 { 0, 0, 0, 0 },
1035 { ~0, -1, 1, -1 },
1036 { 0, -1, 1, 1 }
1037 };
1038 struct const_time_select_bin_test {
1039 u8 mask;
1040 u8 *true_val;
1041 u8 *false_val;
1042 size_t len;
1043 u8 *expected;
1044 } const_time_select_bin_tests[] = {
1045 { ~0, (u8 *) "abcde", (u8 *) "ABCDE", 5, (u8 *) "abcde" },
1046 { 0, (u8 *) "abcde", (u8 *) "ABCDE", 5, (u8 *) "ABCDE" },
1047 { ~0, (u8 *) "", (u8 *) "", 0, (u8 *) "" },
1048 { 0, (u8 *) "", (u8 *) "", 0, (u8 *) "" }
1049 };
1050 struct const_time_memcmp_test {
1051 char *a;
1052 char *b;
1053 size_t len;
1054 int expected;
1055 } const_time_memcmp_tests[] = {
1056 { "abcde", "abcde", 5, 0 },
1057 { "abcde", "bbcde", 5, -1 },
1058 { "bbcde", "abcde", 5, 1 },
1059 { "accde", "abcde", 5, 1 },
1060 { "abcee", "abcde", 5, 1 },
1061 { "abcdf", "abcde", 5, 1 },
1062 { "cbcde", "aXXXX", 5, 2 },
1063 { "a", "d", 1, -3 },
1064 { "", "", 0, 0 }
1065 };
1066 unsigned int i;
1067 int ret = 0;
1068
1069 wpa_printf(MSG_INFO, "constant time tests");
1070
1071 for (i = 0; i < ARRAY_SIZE(const_time_fill_msb_tests); i++) {
1072 struct const_time_fill_msb_test *test;
1073
1074 test = &const_time_fill_msb_tests[i];
1075 if (const_time_fill_msb(test->val) != test->expected) {
1076 wpa_printf(MSG_ERROR,
1077 "const_time_fill_msb(0x%x) test failed",
1078 test->val);
1079 ret = -1;
1080 }
1081 }
1082
1083 for (i = 0; i < ARRAY_SIZE(const_time_is_zero_tests); i++) {
1084 struct const_time_is_zero_test *test;
1085
1086 test = &const_time_is_zero_tests[i];
1087 if (const_time_is_zero(test->val) != test->expected) {
1088 wpa_printf(MSG_ERROR,
1089 "const_time_is_zero(0x%x) test failed",
1090 test->val);
1091 ret = -1;
1092 }
1093 }
1094
1095 for (i = 0; i < ARRAY_SIZE(const_time_eq_tests); i++) {
1096 struct const_time_eq_test *test;
1097
1098 test = &const_time_eq_tests[i];
1099 if (const_time_eq(test->a, test->b) != test->expected) {
1100 wpa_printf(MSG_ERROR,
1101 "const_time_eq(0x%x,0x%x) test failed",
1102 test->a, test->b);
1103 ret = -1;
1104 }
1105 if (const_time_eq_u8(test->a, test->b) != test->expected_u8) {
1106 wpa_printf(MSG_ERROR,
1107 "const_time_eq_u8(0x%x,0x%x) test failed",
1108 test->a, test->b);
1109 ret = -1;
1110 }
1111 }
1112
1113 for (i = 0; i < ARRAY_SIZE(const_time_eq_bin_tests); i++) {
1114 struct const_time_eq_bin_test *test;
1115
1116 test = &const_time_eq_bin_tests[i];
1117 if (const_time_eq_bin(test->a, test->b, test->len) !=
1118 test->expected) {
1119 wpa_printf(MSG_ERROR,
1120 "const_time_eq_bin(len=%u) test failed",
1121 (unsigned int) test->len);
1122 ret = -1;
1123 }
1124 }
1125
1126 for (i = 0; i < ARRAY_SIZE(const_time_select_tests); i++) {
1127 struct const_time_select_test *test;
1128
1129 test = &const_time_select_tests[i];
1130 if (const_time_select(test->mask, test->true_val,
1131 test->false_val) != test->expected) {
1132 wpa_printf(MSG_ERROR,
1133 "const_time_select(0x%x,0x%x,0x%x) test failed",
1134 test->mask, test->true_val, test->false_val);
1135 ret = -1;
1136 }
1137 }
1138
1139 for (i = 0; i < ARRAY_SIZE(const_time_select_int_tests); i++) {
1140 struct const_time_select_int_test *test;
1141
1142 test = &const_time_select_int_tests[i];
1143 if (const_time_select_int(test->mask, test->true_val,
1144 test->false_val) != test->expected) {
1145 wpa_printf(MSG_ERROR,
1146 "const_time_select_int(0x%x,%d,%d) test failed",
1147 test->mask, test->true_val, test->false_val);
1148 ret = -1;
1149 }
1150 }
1151
1152 for (i = 0; i < ARRAY_SIZE(const_time_select_u8_tests); i++) {
1153 struct const_time_select_u8_test *test;
1154
1155 test = &const_time_select_u8_tests[i];
1156 if (const_time_select_u8(test->mask, test->true_val,
1157 test->false_val) != test->expected) {
1158 wpa_printf(MSG_ERROR,
1159 "const_time_select_u8(0x%x,0x%x,0x%x) test failed",
1160 test->mask, test->true_val, test->false_val);
1161 ret = -1;
1162 }
1163 }
1164
1165 for (i = 0; i < ARRAY_SIZE(const_time_select_s8_tests); i++) {
1166 struct const_time_select_s8_test *test;
1167
1168 test = &const_time_select_s8_tests[i];
1169 if (const_time_select_s8(test->mask, test->true_val,
1170 test->false_val) != test->expected) {
1171 wpa_printf(MSG_ERROR,
1172 "const_time_select_s8(0x%x,0x%x,0x%x) test failed",
1173 test->mask, test->true_val, test->false_val);
1174 ret = -1;
1175 }
1176 }
1177
1178 for (i = 0; i < ARRAY_SIZE(const_time_select_bin_tests); i++) {
1179 struct const_time_select_bin_test *test;
1180 u8 dst[100];
1181
1182 test = &const_time_select_bin_tests[i];
1183 const_time_select_bin(test->mask, test->true_val,
1184 test->false_val, test->len, dst);
1185 if (os_memcmp(dst, test->expected, test->len) != 0) {
1186 wpa_printf(MSG_ERROR,
1187 "const_time_select_bin(0x%x,%u) test failed",
1188 test->mask, (unsigned int) test->len);
1189 ret = -1;
1190 }
1191 }
1192
1193 for (i = 0; i < ARRAY_SIZE(const_time_memcmp_tests); i++) {
1194 struct const_time_memcmp_test *test;
1195 int res;
1196
1197 test = &const_time_memcmp_tests[i];
1198 res = const_time_memcmp(test->a, test->b, test->len);
1199 if (res != test->expected) {
1200 wpa_printf(MSG_ERROR,
1201 "const_time_memcmp(%s,%s,%d) test failed (%d != %d)",
1202 test->a, test->b, (int) test->len,
1203 res, test->expected);
1204 ret = -1;
1205 }
1206 }
1207
1208 return ret;
1209}
1210
1211
8860e0f4
JM
1212int utils_module_tests(void)
1213{
1214 int ret = 0;
1215
1216 wpa_printf(MSG_INFO, "utils module tests");
1217
3eb744a3 1218 if (printf_encode_decode_tests() < 0 ||
a3fe74bd 1219 ext_password_tests() < 0 ||
f347935f 1220 trace_tests() < 0 ||
3eb744a3 1221 bitfield_tests() < 0 ||
38ff2193 1222 base64_tests() < 0 ||
2eb64ea4 1223 common_tests() < 0 ||
3c48c9c0
JM
1224 os_tests() < 0 ||
1225 wpabuf_tests() < 0 ||
1226 ip_addr_tests() < 0 ||
569f8f9b 1227 eloop_tests() < 0 ||
4e19eb88 1228 json_tests() < 0 ||
72056f69 1229 const_time_tests() < 0 ||
3eb744a3 1230 int_array_tests() < 0)
8b0980af 1231 ret = -1;
8860e0f4
JM
1232
1233 return ret;
1234}