1/*
2 * utils module tests
3 * Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi>
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"
10
11#include "utils/common.h"
12#include "utils/const_time.h"
13#include "common/ieee802_11_defs.h"
14#include "utils/bitfield.h"
15#include "utils/ext_password.h"
16#include "utils/trace.h"
17#include "utils/base64.h"
18#include "utils/ip_addr.h"
19#include "utils/eloop.h"
20#include "utils/json.h"
21#include "utils/module_tests.h"
22
23
24struct printf_test_data {
25	u8 *data;
26	size_t len;
27	char *encoded;
28};
29
30static const struct printf_test_data printf_tests[] = {
31	{ (u8 *) "abcde", 5, "abcde" },
32	{ (u8 *) "a\0b\nc\ed\re\tf\"\\", 13, "a\\0b\\nc\\ed\\re\\tf\\\"\\\\" },
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
45static int printf_encode_decode_tests(void)
46{
47	int i;
48	size_t binlen;
49	char buf[100];
50	u8 bin[100];
51	int errors = 0;
52	int array[10];
53
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];
58		printf_encode(buf, sizeof(buf), test->data, test->len);
59		wpa_printf(MSG_INFO, "%d: -> \"%s\"", i, buf);
60
61		binlen = printf_decode(bin, sizeof(bin), buf);
62		if (binlen != test->len ||
63		    os_memcmp(bin, test->data, binlen) != 0) {
64			wpa_hexdump(MSG_ERROR, "Error in decoding#1",
65				    bin, binlen);
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) {
72			wpa_hexdump(MSG_ERROR, "Error in decoding#2",
73				    bin, binlen);
74			errors++;
75		}
76	}
77
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
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
101	if (printf_decode(bin, 3, "\\xq") != 1 || bin[0] != 'q')
102		errors++;
103
104	if (printf_decode(bin, 3, "\\a") != 1 || bin[0] != 'a')
105		errors++;
106
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
119	if (errors) {
120		wpa_printf(MSG_ERROR, "%d printf test(s) failed", errors);
121		return -1;
122	}
123
124	return 0;
125}
126
127
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
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
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
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;
229	size_t len;
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
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
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
295static int base64_tests(void)
296{
297	int errors = 0;
298	unsigned char *res;
299	char *res2;
300	size_t res_len;
301
302	wpa_printf(MSG_INFO, "base64 tests");
303
304	res2 = base64_encode("", ~0, &res_len);
305	if (res2) {
306		errors++;
307		os_free(res2);
308	}
309
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')
313		errors++;
314	os_free(res2);
315
316	res2 = base64_encode("=", 1, NULL);
317	if (!res2 || res2[0] != 'P' || res2[1] != 'Q' ||
318	    res2[2] != '=' || res2[3] != '=' || res2[4] != '\n')
319		errors++;
320	os_free(res2);
321
322	res = base64_decode("", 0, &res_len);
323	if (res) {
324		errors++;
325		os_free(res);
326	}
327
328	res = base64_decode("a", 1, &res_len);
329	if (res) {
330		errors++;
331		os_free(res);
332	}
333
334	res = base64_decode("====", 4, &res_len);
335	if (res) {
336		errors++;
337		os_free(res);
338	}
339
340	res = base64_decode("PQ==", 4, &res_len);
341	if (!res || res_len != 1 || res[0] != '=')
342		errors++;
343	os_free(res);
344
345	res = base64_decode("P.Q-=!=*", 8, &res_len);
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
359static int common_tests(void)
360{
361	char buf[3], longbuf[100];
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;
366	size_t len;
367	const char *txt;
368	u8 ssid[255];
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
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
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
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
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
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
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:\\]" },
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:]" },
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
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 },
933		{ 1U << (sizeof(unsigned int) * 8 - 1), ~0 },
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 },
944		{ 1U << (sizeof(unsigned int) * 8 - 1), 0 },
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
1212int utils_module_tests(void)
1213{
1214	int ret = 0;
1215
1216	wpa_printf(MSG_INFO, "utils module tests");
1217
1218	if (printf_encode_decode_tests() < 0 ||
1219	    ext_password_tests() < 0 ||
1220	    trace_tests() < 0 ||
1221	    bitfield_tests() < 0 ||
1222	    base64_tests() < 0 ||
1223	    common_tests() < 0 ||
1224	    os_tests() < 0 ||
1225	    wpabuf_tests() < 0 ||
1226	    ip_addr_tests() < 0 ||
1227	    eloop_tests() < 0 ||
1228	    json_tests() < 0 ||
1229	    const_time_tests() < 0 ||
1230	    int_array_tests() < 0)
1231		ret = -1;
1232
1233	return ret;
1234}
1235