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	int 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	size_t res_len;
300
301	wpa_printf(MSG_INFO, "base64 tests");
302
303	res = base64_encode((const unsigned char *) "", ~0, &res_len);
304	if (res) {
305		errors++;
306		os_free(res);
307	}
308
309	res = base64_encode((const unsigned char *) "=", 1, &res_len);
310	if (!res || res_len != 5 || res[0] != 'P' || res[1] != 'Q' ||
311	    res[2] != '=' || res[3] != '=' || res[4] != '\n')
312		errors++;
313	os_free(res);
314
315	res = base64_encode((const unsigned char *) "=", 1, NULL);
316	if (!res || res[0] != 'P' || res[1] != 'Q' ||
317	    res[2] != '=' || res[3] != '=' || res[4] != '\n')
318		errors++;
319	os_free(res);
320
321	res = base64_decode((const unsigned char *) "", 0, &res_len);
322	if (res) {
323		errors++;
324		os_free(res);
325	}
326
327	res = base64_decode((const unsigned char *) "a", 1, &res_len);
328	if (res) {
329		errors++;
330		os_free(res);
331	}
332
333	res = base64_decode((const unsigned char *) "====", 4, &res_len);
334	if (res) {
335		errors++;
336		os_free(res);
337	}
338
339	res = base64_decode((const unsigned char *) "PQ==", 4, &res_len);
340	if (!res || res_len != 1 || res[0] != '=')
341		errors++;
342	os_free(res);
343
344	res = base64_decode((const unsigned char *) "P.Q-=!=*", 8, &res_len);
345	if (!res || res_len != 1 || res[0] != '=')
346		errors++;
347	os_free(res);
348
349	if (errors) {
350		wpa_printf(MSG_ERROR, "%d base64 test(s) failed", errors);
351		return -1;
352	}
353
354	return 0;
355}
356
357
358static int common_tests(void)
359{
360	char buf[3], longbuf[100];
361	u8 addr[ETH_ALEN] = { 1, 2, 3, 4, 5, 6 };
362	u8 bin[3];
363	int errors = 0;
364	struct wpa_freq_range_list ranges;
365	size_t len;
366	const char *txt;
367	u8 ssid[255];
368
369	wpa_printf(MSG_INFO, "common tests");
370
371	if (hwaddr_mask_txt(buf, 3, addr, addr) != -1)
372		errors++;
373
374	if (wpa_scnprintf(buf, 0, "hello") != 0 ||
375	    wpa_scnprintf(buf, 3, "hello") != 2)
376		errors++;
377
378	if (wpa_snprintf_hex(buf, 0, addr, ETH_ALEN) != 0 ||
379	    wpa_snprintf_hex(buf, 3, addr, ETH_ALEN) != 2)
380		errors++;
381
382	if (merge_byte_arrays(bin, 3, addr, ETH_ALEN, NULL, 0) != 3 ||
383	    merge_byte_arrays(bin, 3, NULL, 0, addr, ETH_ALEN) != 3)
384		errors++;
385
386	if (dup_binstr(NULL, 0) != NULL)
387		errors++;
388
389	if (freq_range_list_includes(NULL, 0) != 0)
390		errors++;
391
392	os_memset(&ranges, 0, sizeof(ranges));
393	if (freq_range_list_parse(&ranges, "") != 0 ||
394	    freq_range_list_includes(&ranges, 0) != 0 ||
395	    freq_range_list_str(&ranges) != NULL)
396		errors++;
397
398	if (utf8_unescape(NULL, 0, buf, sizeof(buf)) != 0 ||
399	    utf8_unescape("a", 1, NULL, 0) != 0 ||
400	    utf8_unescape("a\\", 2, buf, sizeof(buf)) != 0 ||
401	    utf8_unescape("abcde", 5, buf, sizeof(buf)) != 0 ||
402	    utf8_unescape("abc", 3, buf, 3) != 3)
403		errors++;
404
405	if (utf8_unescape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a')
406		errors++;
407
408	if (utf8_unescape("\\b", 2, buf, sizeof(buf)) != 1 || buf[0] != 'b')
409		errors++;
410
411	if (utf8_escape(NULL, 0, buf, sizeof(buf)) != 0 ||
412	    utf8_escape("a", 1, NULL, 0) != 0 ||
413	    utf8_escape("abcde", 5, buf, sizeof(buf)) != 0 ||
414	    utf8_escape("a\\bcde", 6, buf, sizeof(buf)) != 0 ||
415	    utf8_escape("ab\\cde", 6, buf, sizeof(buf)) != 0 ||
416	    utf8_escape("abc\\de", 6, buf, sizeof(buf)) != 0 ||
417	    utf8_escape("abc", 3, buf, 3) != 3)
418		errors++;
419
420	if (utf8_escape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a')
421		errors++;
422
423	os_memset(ssid, 0, sizeof(ssid));
424	txt = wpa_ssid_txt(ssid, sizeof(ssid));
425	len = os_strlen(txt);
426	/* Verify that SSID_MAX_LEN * 4 buffer limit is enforced. */
427	if (len != SSID_MAX_LEN * 4) {
428		wpa_printf(MSG_ERROR,
429			   "Unexpected wpa_ssid_txt() result with too long SSID");
430		errors++;
431	}
432
433	if (wpa_snprintf_hex_sep(longbuf, 0, addr, ETH_ALEN, '-') != 0 ||
434	    wpa_snprintf_hex_sep(longbuf, 5, addr, ETH_ALEN, '-') != 3 ||
435	    os_strcmp(longbuf, "01-0") != 0)
436		errors++;
437
438	if (errors) {
439		wpa_printf(MSG_ERROR, "%d common test(s) failed", errors);
440		return -1;
441	}
442
443	return 0;
444}
445
446
447static int os_tests(void)
448{
449	int errors = 0;
450	void *ptr;
451	os_time_t t;
452
453	wpa_printf(MSG_INFO, "os tests");
454
455	ptr = os_calloc((size_t) -1, (size_t) -1);
456	if (ptr) {
457		errors++;
458		os_free(ptr);
459	}
460	ptr = os_calloc((size_t) 2, (size_t) -1);
461	if (ptr) {
462		errors++;
463		os_free(ptr);
464	}
465	ptr = os_calloc((size_t) -1, (size_t) 2);
466	if (ptr) {
467		errors++;
468		os_free(ptr);
469	}
470
471	ptr = os_realloc_array(NULL, (size_t) -1, (size_t) -1);
472	if (ptr) {
473		errors++;
474		os_free(ptr);
475	}
476
477	os_sleep(1, 1);
478
479	if (os_mktime(1969, 1, 1, 1, 1, 1, &t) == 0 ||
480	    os_mktime(1971, 0, 1, 1, 1, 1, &t) == 0 ||
481	    os_mktime(1971, 13, 1, 1, 1, 1, &t) == 0 ||
482	    os_mktime(1971, 1, 0, 1, 1, 1, &t) == 0 ||
483	    os_mktime(1971, 1, 32, 1, 1, 1, &t) == 0 ||
484	    os_mktime(1971, 1, 1, -1, 1, 1, &t) == 0 ||
485	    os_mktime(1971, 1, 1, 24, 1, 1, &t) == 0 ||
486	    os_mktime(1971, 1, 1, 1, -1, 1, &t) == 0 ||
487	    os_mktime(1971, 1, 1, 1, 60, 1, &t) == 0 ||
488	    os_mktime(1971, 1, 1, 1, 1, -1, &t) == 0 ||
489	    os_mktime(1971, 1, 1, 1, 1, 61, &t) == 0 ||
490	    os_mktime(1971, 1, 1, 1, 1, 1, &t) != 0 ||
491	    os_mktime(2020, 1, 2, 3, 4, 5, &t) != 0 ||
492	    os_mktime(2015, 12, 31, 23, 59, 59, &t) != 0)
493		errors++;
494
495	if (os_setenv("hwsim_test_env", "test value", 0) != 0 ||
496	    os_setenv("hwsim_test_env", "test value 2", 1) != 0 ||
497	    os_unsetenv("hwsim_test_env") != 0)
498		errors++;
499
500	if (os_file_exists("/this-file-does-not-exists-hwsim") != 0)
501		errors++;
502
503	if (errors) {
504		wpa_printf(MSG_ERROR, "%d os test(s) failed", errors);
505		return -1;
506	}
507
508	return 0;
509}
510
511
512static int wpabuf_tests(void)
513{
514	int errors = 0;
515	void *ptr;
516	struct wpabuf *buf;
517
518	wpa_printf(MSG_INFO, "wpabuf tests");
519
520	ptr = os_malloc(100);
521	if (ptr) {
522		buf = wpabuf_alloc_ext_data(ptr, 100);
523		if (buf) {
524			if (wpabuf_resize(&buf, 100) < 0)
525				errors++;
526			else
527				wpabuf_put(buf, 100);
528			wpabuf_free(buf);
529		} else {
530			errors++;
531			os_free(ptr);
532		}
533	} else {
534		errors++;
535	}
536
537	buf = wpabuf_alloc(100);
538	if (buf) {
539		struct wpabuf *buf2;
540
541		wpabuf_put(buf, 100);
542		if (wpabuf_resize(&buf, 100) < 0)
543			errors++;
544		else
545			wpabuf_put(buf, 100);
546		buf2 = wpabuf_concat(buf, NULL);
547		if (buf2 != buf)
548			errors++;
549		wpabuf_free(buf2);
550	} else {
551		errors++;
552	}
553
554	buf = NULL;
555	buf = wpabuf_zeropad(buf, 10);
556	if (buf != NULL)
557		errors++;
558
559	if (errors) {
560		wpa_printf(MSG_ERROR, "%d wpabuf test(s) failed", errors);
561		return -1;
562	}
563
564	return 0;
565}
566
567
568static int ip_addr_tests(void)
569{
570	int errors = 0;
571	struct hostapd_ip_addr addr;
572	char buf[100];
573
574	wpa_printf(MSG_INFO, "ip_addr tests");
575
576	if (hostapd_parse_ip_addr("1.2.3.4", &addr) != 0 ||
577	    addr.af != AF_INET ||
578	    hostapd_ip_txt(NULL, buf, sizeof(buf)) != NULL ||
579	    hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' ||
580	    hostapd_ip_txt(&addr, buf, 0) != NULL ||
581	    hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf)
582		errors++;
583
584	if (hostapd_parse_ip_addr("::", &addr) != 0 ||
585	    addr.af != AF_INET6 ||
586	    hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' ||
587	    hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf)
588		errors++;
589
590	if (errors) {
591		wpa_printf(MSG_ERROR, "%d ip_addr test(s) failed", errors);
592		return -1;
593	}
594
595	return 0;
596}
597
598
599struct test_eloop {
600	unsigned int magic;
601	int close_in_timeout;
602	int pipefd1[2];
603	int pipefd2[2];
604};
605
606
607static void eloop_tests_start(int close_in_timeout);
608
609
610static void eloop_test_read_2(int sock, void *eloop_ctx, void *sock_ctx)
611{
612	struct test_eloop *t = eloop_ctx;
613	ssize_t res;
614	char buf[10];
615
616	wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
617
618	if (t->magic != 0x12345678) {
619		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
620			   __func__, t->magic);
621	}
622
623	if (t->pipefd2[0] != sock) {
624		wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
625			   __func__, sock, t->pipefd2[0]);
626	}
627
628	res = read(sock, buf, sizeof(buf));
629	wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d",
630		   __func__, sock, (int) res);
631}
632
633
634static void eloop_test_read_2_wrong(int sock, void *eloop_ctx, void *sock_ctx)
635{
636	struct test_eloop *t = eloop_ctx;
637
638	wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
639
640	if (t->magic != 0x12345678) {
641		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
642			   __func__, t->magic);
643	}
644
645	if (t->pipefd2[0] != sock) {
646		wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
647			   __func__, sock, t->pipefd2[0]);
648	}
649
650	/*
651	 * This is expected to block due to the original socket with data having
652	 * been closed and no new data having been written to the new socket
653	 * with the same fd. To avoid blocking the process during test, skip the
654	 * read here.
655	 */
656	wpa_printf(MSG_ERROR, "%s: FAIL - should not have called this function",
657		   __func__);
658}
659
660
661static void reopen_pipefd2(struct test_eloop *t)
662{
663	if (t->pipefd2[0] < 0) {
664		wpa_printf(MSG_INFO, "pipefd2 had been closed");
665	} else {
666		int res;
667
668		wpa_printf(MSG_INFO, "close pipefd2");
669		eloop_unregister_read_sock(t->pipefd2[0]);
670		close(t->pipefd2[0]);
671		t->pipefd2[0] = -1;
672		close(t->pipefd2[1]);
673		t->pipefd2[1] = -1;
674
675		res = pipe(t->pipefd2);
676		if (res < 0) {
677			wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
678			t->pipefd2[0] = -1;
679			t->pipefd2[1] = -1;
680			return;
681		}
682
683		wpa_printf(MSG_INFO,
684			   "re-register pipefd2 with new sockets %d,%d",
685			   t->pipefd2[0], t->pipefd2[1]);
686		eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2_wrong,
687					 t, NULL);
688	}
689}
690
691
692static void eloop_test_read_1(int sock, void *eloop_ctx, void *sock_ctx)
693{
694	struct test_eloop *t = eloop_ctx;
695	ssize_t res;
696	char buf[10];
697
698	wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
699
700	if (t->magic != 0x12345678) {
701		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
702			   __func__, t->magic);
703	}
704
705	if (t->pipefd1[0] != sock) {
706		wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
707			   __func__, sock, t->pipefd1[0]);
708	}
709
710	res = read(sock, buf, sizeof(buf));
711	wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d",
712		   __func__, sock, (int) res);
713
714	if (!t->close_in_timeout)
715		reopen_pipefd2(t);
716}
717
718
719static void eloop_test_cb(void *eloop_data, void *user_ctx)
720{
721	struct test_eloop *t = eloop_data;
722
723	wpa_printf(MSG_INFO, "%s", __func__);
724
725	if (t->magic != 0x12345678) {
726		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
727			   __func__, t->magic);
728	}
729
730	if (t->close_in_timeout)
731		reopen_pipefd2(t);
732}
733
734
735static void eloop_test_timeout(void *eloop_data, void *user_ctx)
736{
737	struct test_eloop *t = eloop_data;
738	int next_run = 0;
739
740	wpa_printf(MSG_INFO, "%s", __func__);
741
742	if (t->magic != 0x12345678) {
743		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
744			   __func__, t->magic);
745	}
746
747	if (t->pipefd1[0] >= 0) {
748		wpa_printf(MSG_INFO, "pipefd1 had not been closed");
749		eloop_unregister_read_sock(t->pipefd1[0]);
750		close(t->pipefd1[0]);
751		t->pipefd1[0] = -1;
752		close(t->pipefd1[1]);
753		t->pipefd1[1] = -1;
754	}
755
756	if (t->pipefd2[0] >= 0) {
757		wpa_printf(MSG_INFO, "pipefd2 had not been closed");
758		eloop_unregister_read_sock(t->pipefd2[0]);
759		close(t->pipefd2[0]);
760		t->pipefd2[0] = -1;
761		close(t->pipefd2[1]);
762		t->pipefd2[1] = -1;
763	}
764
765	next_run = t->close_in_timeout;
766	t->magic = 0;
767	wpa_printf(MSG_INFO, "%s - free(%p)", __func__, t);
768	os_free(t);
769
770	if (next_run)
771		eloop_tests_start(0);
772}
773
774
775static void eloop_tests_start(int close_in_timeout)
776{
777	struct test_eloop *t;
778	int res;
779
780	t = os_zalloc(sizeof(*t));
781	if (!t)
782		return;
783	t->magic = 0x12345678;
784	t->close_in_timeout = close_in_timeout;
785
786	wpa_printf(MSG_INFO, "starting eloop tests (%p) (close_in_timeout=%d)",
787		   t, close_in_timeout);
788
789	res = pipe(t->pipefd1);
790	if (res < 0) {
791		wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
792		os_free(t);
793		return;
794	}
795
796	res = pipe(t->pipefd2);
797	if (res < 0) {
798		wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
799		close(t->pipefd1[0]);
800		close(t->pipefd1[1]);
801		os_free(t);
802		return;
803	}
804
805	wpa_printf(MSG_INFO, "pipe fds: %d,%d %d,%d",
806		   t->pipefd1[0], t->pipefd1[1],
807		   t->pipefd2[0], t->pipefd2[1]);
808
809	eloop_register_read_sock(t->pipefd1[0], eloop_test_read_1, t, NULL);
810	eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2, t, NULL);
811	eloop_register_timeout(0, 0, eloop_test_cb, t, NULL);
812	eloop_register_timeout(0, 200000, eloop_test_timeout, t, NULL);
813
814	if (write(t->pipefd1[1], "HELLO", 5) < 0)
815		wpa_printf(MSG_INFO, "write: %s", strerror(errno));
816	if (write(t->pipefd2[1], "TEST", 4) < 0)
817		wpa_printf(MSG_INFO, "write: %s", strerror(errno));
818	os_sleep(0, 50000);
819	wpa_printf(MSG_INFO, "waiting for eloop callbacks");
820}
821
822
823static void eloop_tests_run(void *eloop_data, void *user_ctx)
824{
825	eloop_tests_start(1);
826}
827
828
829static int eloop_tests(void)
830{
831	wpa_printf(MSG_INFO, "schedule eloop tests to be run");
832
833	/*
834	 * Cannot return error from these without a significant design change,
835	 * so for now, run the tests from a scheduled timeout and require
836	 * separate verification of the results from the debug log.
837	 */
838	eloop_register_timeout(0, 0, eloop_tests_run, NULL, NULL);
839
840	return 0;
841}
842
843
844#ifdef CONFIG_JSON
845struct json_test_data {
846	const char *json;
847	const char *tree;
848};
849
850static const struct json_test_data json_test_cases[] = {
851	{ "{}", "[1:OBJECT:]" },
852	{ "[]", "[1:ARRAY:]" },
853	{ "{", NULL },
854	{ "[", NULL },
855	{ "}", NULL },
856	{ "]", NULL },
857	{ "[[]]", "[1:ARRAY:][2:ARRAY:]" },
858	{ "{\"t\":\"test\"}", "[1:OBJECT:][2:STRING:t]" },
859	{ "{\"t\":123}", "[1:OBJECT:][2:NUMBER:t]" },
860	{ "{\"t\":true}", "[1:OBJECT:][2:BOOLEAN:t]" },
861	{ "{\"t\":false}", "[1:OBJECT:][2:BOOLEAN:t]" },
862	{ "{\"t\":null}", "[1:OBJECT:][2:NULL:t]" },
863	{ "{\"t\":truetrue}", NULL },
864	{ "\"test\"", "[1:STRING:]" },
865	{ "123", "[1:NUMBER:]" },
866	{ "true", "[1:BOOLEAN:]" },
867	{ "false", "[1:BOOLEAN:]" },
868	{ "null", "[1:NULL:]" },
869	{ "truetrue", NULL },
870	{ " {\t\n\r\"a\"\n:\r1\n,\n\"b\":3\n}\n",
871	  "[1:OBJECT:][2:NUMBER:a][2:NUMBER:b]" },
872	{ ",", NULL },
873	{ "{,}", NULL },
874	{ "[,]", NULL },
875	{ ":", NULL },
876	{ "{:}", NULL },
877	{ "[:]", NULL },
878	{ "{ \"\\u005c\" : \"\\u005c\" }", "[1:OBJECT:][2:STRING:\\]" },
879	{ "[{},{}]", "[1:ARRAY:][2:OBJECT:][2:OBJECT:]" },
880	{ "[1,2]", "[1:ARRAY:][2:NUMBER:][2:NUMBER:]" },
881	{ "[\"1\",\"2\"]", "[1:ARRAY:][2:STRING:][2:STRING:]" },
882	{ "[true,false]", "[1:ARRAY:][2:BOOLEAN:][2:BOOLEAN:]" },
883};
884#endif /* CONFIG_JSON */
885
886
887static int json_tests(void)
888{
889#ifdef CONFIG_JSON
890	unsigned int i;
891	struct json_token *root;
892	char buf[1000];
893
894	wpa_printf(MSG_INFO, "JSON tests");
895
896	for (i = 0; i < ARRAY_SIZE(json_test_cases); i++) {
897		const struct json_test_data *test = &json_test_cases[i];
898		int res = 0;
899
900		root = json_parse(test->json, os_strlen(test->json));
901		if ((root && !test->tree) || (!root && test->tree)) {
902			wpa_printf(MSG_INFO, "JSON test %u failed", i);
903			res = -1;
904		} else if (root) {
905			json_print_tree(root, buf, sizeof(buf));
906			if (os_strcmp(buf, test->tree) != 0) {
907				wpa_printf(MSG_INFO,
908					   "JSON test %u tree mismatch: %s %s",
909					   i, buf, test->tree);
910				res = -1;
911			}
912		}
913		json_free(root);
914		if (res < 0)
915			return -1;
916
917	}
918#endif /* CONFIG_JSON */
919	return 0;
920}
921
922
923static int const_time_tests(void)
924{
925	struct const_time_fill_msb_test {
926		unsigned int val;
927		unsigned int expected;
928	} const_time_fill_msb_tests[] = {
929		{ 0, 0 },
930		{ 1, 0 },
931		{ 2, 0 },
932		{ 1 << (sizeof(unsigned int) * 8 - 1), ~0 },
933		{ ~0 - 1, ~0 },
934		{ ~0, ~0 }
935	};
936	struct const_time_is_zero_test {
937		unsigned int val;
938		unsigned int expected;
939	} const_time_is_zero_tests[] = {
940		{ 0, ~0 },
941		{ 1, 0 },
942		{ 2, 0 },
943		{ 1 << (sizeof(unsigned int) * 8 - 1), 0 },
944		{ ~0 - 1, 0 },
945		{ ~0, 0 }
946	};
947	struct const_time_eq_test {
948		unsigned int a;
949		unsigned int b;
950		unsigned int expected;
951		unsigned int expected_u8;
952	} const_time_eq_tests[] = {
953		{ 0, 1, 0, 0 },
954		{ 1, 2, 0, 0 },
955		{ 1, 1, ~0, 0xff },
956		{ ~0, ~0, ~0, 0xff },
957		{ ~0, ~0 - 1, 0, 0 },
958		{ 0, 0, ~0, 0xff }
959	};
960	struct const_time_eq_bin_test {
961		u8 *a;
962		u8 *b;
963		size_t len;
964		unsigned int expected;
965	} const_time_eq_bin_tests[] = {
966		{ (u8 *) "", (u8 *) "", 0, ~0 },
967		{ (u8 *) "abcde", (u8 *) "abcde", 5, ~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 *) "\x00", (u8 *) "\x01", 1, 0 },
974		{ (u8 *) "\x00", (u8 *) "\x80", 1, 0 },
975		{ (u8 *) "\x00", (u8 *) "\x00", 1, ~0 }
976	};
977	struct const_time_select_test {
978		unsigned int mask;
979		unsigned int true_val;
980		unsigned int false_val;
981		unsigned int expected;
982	} const_time_select_tests[] = {
983		{ ~0, ~0, ~0, ~0 },
984		{ 0, ~0, ~0, ~0 },
985		{ ~0, ~0, 0, ~0 },
986		{ 0, ~0, 0, 0 },
987		{ ~0, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa },
988		{ 0, 0xaaaaaaaa, 0x55555555, 0x55555555 },
989		{ ~0, 3, 3, 3 },
990		{ 0, 3, 3, 3 },
991		{ ~0, 1, 2, 1 },
992		{ 0, 1, 2, 2 }
993	};
994	struct const_time_select_int_test {
995		unsigned int mask;
996		int true_val;
997		int false_val;
998		int expected;
999	} const_time_select_int_tests[] = {
1000		{ ~0, -128, 127, -128 },
1001		{ 0, -128, 127, 127 },
1002		{ ~0, -2147483648, 2147483647, -2147483648 },
1003		{ 0, -2147483648, 2147483647, 2147483647 },
1004		{ ~0, 0, 0, 0 },
1005		{ 0, 0, 0, 0 },
1006		{ ~0, -1, 1, -1 },
1007		{ 0, -1, 1, 1 }
1008	};
1009	struct const_time_select_u8_test {
1010		u8 mask;
1011		u8 true_val;
1012		u8 false_val;
1013		u8 expected;
1014	} const_time_select_u8_tests[] = {
1015		{ ~0, ~0, ~0, ~0 },
1016		{ 0, ~0, ~0, ~0 },
1017		{ ~0, ~0, 0, ~0 },
1018		{ 0, ~0, 0, 0 },
1019		{ ~0, 0xaa, 0x55, 0xaa },
1020		{ 0, 0xaa, 0x55, 0x55 },
1021		{ ~0, 1, 2, 1 },
1022		{ 0, 1, 2, 2 }
1023	};
1024	struct const_time_select_s8_test {
1025		u8 mask;
1026		s8 true_val;
1027		s8 false_val;
1028		s8 expected;
1029	} const_time_select_s8_tests[] = {
1030		{ ~0, -128, 127, -128 },
1031		{ 0, -128, 127, 127 },
1032		{ ~0, 0, 0, 0 },
1033		{ 0, 0, 0, 0 },
1034		{ ~0, -1, 1, -1 },
1035		{ 0, -1, 1, 1 }
1036	};
1037	struct const_time_select_bin_test {
1038		u8 mask;
1039		u8 *true_val;
1040		u8 *false_val;
1041		size_t len;
1042		u8 *expected;
1043	} const_time_select_bin_tests[] = {
1044		{ ~0, (u8 *) "abcde", (u8 *) "ABCDE", 5, (u8 *) "abcde" },
1045		{ 0, (u8 *) "abcde", (u8 *) "ABCDE", 5, (u8 *) "ABCDE" },
1046		{ ~0, (u8 *) "", (u8 *) "", 0, (u8 *) "" },
1047		{ 0, (u8 *) "", (u8 *) "", 0, (u8 *) "" }
1048	};
1049	struct const_time_memcmp_test {
1050		char *a;
1051		char *b;
1052		size_t len;
1053		int expected;
1054	} const_time_memcmp_tests[] = {
1055		{ "abcde", "abcde", 5, 0 },
1056		{ "abcde", "bbcde", 5, -1 },
1057		{ "bbcde", "abcde", 5, 1 },
1058		{ "accde", "abcde", 5, 1 },
1059		{ "abcee", "abcde", 5, 1 },
1060		{ "abcdf", "abcde", 5, 1 },
1061		{ "cbcde", "aXXXX", 5, 2 },
1062		{ "a", "d", 1, -3 },
1063		{ "", "", 0, 0 }
1064	};
1065	unsigned int i;
1066	int ret = 0;
1067
1068	wpa_printf(MSG_INFO, "constant time tests");
1069
1070	for (i = 0; i < ARRAY_SIZE(const_time_fill_msb_tests); i++) {
1071		struct const_time_fill_msb_test *test;
1072
1073		test = &const_time_fill_msb_tests[i];
1074		if (const_time_fill_msb(test->val) != test->expected) {
1075			wpa_printf(MSG_ERROR,
1076				   "const_time_fill_msb(0x%x) test failed",
1077				   test->val);
1078			ret = -1;
1079		}
1080	}
1081
1082	for (i = 0; i < ARRAY_SIZE(const_time_is_zero_tests); i++) {
1083		struct const_time_is_zero_test *test;
1084
1085		test = &const_time_is_zero_tests[i];
1086		if (const_time_is_zero(test->val) != test->expected) {
1087			wpa_printf(MSG_ERROR,
1088				   "const_time_is_zero(0x%x) test failed",
1089				   test->val);
1090			ret = -1;
1091		}
1092	}
1093
1094	for (i = 0; i < ARRAY_SIZE(const_time_eq_tests); i++) {
1095		struct const_time_eq_test *test;
1096
1097		test = &const_time_eq_tests[i];
1098		if (const_time_eq(test->a, test->b) != test->expected) {
1099			wpa_printf(MSG_ERROR,
1100				   "const_time_eq(0x%x,0x%x) test failed",
1101				   test->a, test->b);
1102			ret = -1;
1103		}
1104		if (const_time_eq_u8(test->a, test->b) != test->expected_u8) {
1105			wpa_printf(MSG_ERROR,
1106				   "const_time_eq_u8(0x%x,0x%x) test failed",
1107				   test->a, test->b);
1108			ret = -1;
1109		}
1110	}
1111
1112	for (i = 0; i < ARRAY_SIZE(const_time_eq_bin_tests); i++) {
1113		struct const_time_eq_bin_test *test;
1114
1115		test = &const_time_eq_bin_tests[i];
1116		if (const_time_eq_bin(test->a, test->b, test->len) !=
1117		    test->expected) {
1118			wpa_printf(MSG_ERROR,
1119				   "const_time_eq_bin(len=%u) test failed",
1120				   (unsigned int) test->len);
1121			ret = -1;
1122		}
1123	}
1124
1125	for (i = 0; i < ARRAY_SIZE(const_time_select_tests); i++) {
1126		struct const_time_select_test *test;
1127
1128		test = &const_time_select_tests[i];
1129		if (const_time_select(test->mask, test->true_val,
1130				      test->false_val) != test->expected) {
1131			wpa_printf(MSG_ERROR,
1132				   "const_time_select(0x%x,0x%x,0x%x) test failed",
1133				   test->mask, test->true_val, test->false_val);
1134			ret = -1;
1135		}
1136	}
1137
1138	for (i = 0; i < ARRAY_SIZE(const_time_select_int_tests); i++) {
1139		struct const_time_select_int_test *test;
1140
1141		test = &const_time_select_int_tests[i];
1142		if (const_time_select_int(test->mask, test->true_val,
1143					  test->false_val) != test->expected) {
1144			wpa_printf(MSG_ERROR,
1145				   "const_time_select_int(0x%x,%d,%d) test failed",
1146				   test->mask, test->true_val, test->false_val);
1147			ret = -1;
1148		}
1149	}
1150
1151	for (i = 0; i < ARRAY_SIZE(const_time_select_u8_tests); i++) {
1152		struct const_time_select_u8_test *test;
1153
1154		test = &const_time_select_u8_tests[i];
1155		if (const_time_select_u8(test->mask, test->true_val,
1156					 test->false_val) != test->expected) {
1157			wpa_printf(MSG_ERROR,
1158				   "const_time_select_u8(0x%x,0x%x,0x%x) test failed",
1159				   test->mask, test->true_val, test->false_val);
1160			ret = -1;
1161		}
1162	}
1163
1164	for (i = 0; i < ARRAY_SIZE(const_time_select_s8_tests); i++) {
1165		struct const_time_select_s8_test *test;
1166
1167		test = &const_time_select_s8_tests[i];
1168		if (const_time_select_s8(test->mask, test->true_val,
1169					 test->false_val) != test->expected) {
1170			wpa_printf(MSG_ERROR,
1171				   "const_time_select_s8(0x%x,0x%x,0x%x) test failed",
1172				   test->mask, test->true_val, test->false_val);
1173			ret = -1;
1174		}
1175	}
1176
1177	for (i = 0; i < ARRAY_SIZE(const_time_select_bin_tests); i++) {
1178		struct const_time_select_bin_test *test;
1179		u8 dst[100];
1180
1181		test = &const_time_select_bin_tests[i];
1182		const_time_select_bin(test->mask, test->true_val,
1183				      test->false_val, test->len, dst);
1184		if (os_memcmp(dst, test->expected, test->len) != 0) {
1185			wpa_printf(MSG_ERROR,
1186				   "const_time_select_bin(0x%x,%u) test failed",
1187				   test->mask, (unsigned int) test->len);
1188			ret = -1;
1189		}
1190	}
1191
1192	for (i = 0; i < ARRAY_SIZE(const_time_memcmp_tests); i++) {
1193		struct const_time_memcmp_test *test;
1194		int res;
1195
1196		test = &const_time_memcmp_tests[i];
1197		res = const_time_memcmp(test->a, test->b, test->len);
1198		if (res != test->expected) {
1199			wpa_printf(MSG_ERROR,
1200				   "const_time_memcmp(%s,%s,%d) test failed (%d != %d)",
1201				   test->a, test->b, (int) test->len,
1202				   res, test->expected);
1203			ret = -1;
1204		}
1205	}
1206
1207	return ret;
1208}
1209
1210
1211int utils_module_tests(void)
1212{
1213	int ret = 0;
1214
1215	wpa_printf(MSG_INFO, "utils module tests");
1216
1217	if (printf_encode_decode_tests() < 0 ||
1218	    ext_password_tests() < 0 ||
1219	    trace_tests() < 0 ||
1220	    bitfield_tests() < 0 ||
1221	    base64_tests() < 0 ||
1222	    common_tests() < 0 ||
1223	    os_tests() < 0 ||
1224	    wpabuf_tests() < 0 ||
1225	    ip_addr_tests() < 0 ||
1226	    eloop_tests() < 0 ||
1227	    json_tests() < 0 ||
1228	    const_time_tests() < 0 ||
1229	    int_array_tests() < 0)
1230		ret = -1;
1231
1232	return ret;
1233}
1234