1/*
2 * common module tests
3 * Copyright (c) 2014-2019, 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/module_tests.h"
13#include "crypto/crypto.h"
14#include "ieee802_11_common.h"
15#include "ieee802_11_defs.h"
16#include "gas.h"
17#include "wpa_common.h"
18#include "sae.h"
19
20
21struct ieee802_11_parse_test_data {
22	u8 *data;
23	size_t len;
24	ParseRes result;
25	int count;
26};
27
28static const struct ieee802_11_parse_test_data parse_tests[] = {
29	{ (u8 *) "", 0, ParseOK, 0 },
30	{ (u8 *) " ", 1, ParseFailed, 0 },
31	{ (u8 *) "\xff\x00", 2, ParseUnknown, 1 },
32	{ (u8 *) "\xff\x01", 2, ParseFailed, 0 },
33	{ (u8 *) "\xdd\x03\x01\x02\x03", 5, ParseUnknown, 1 },
34	{ (u8 *) "\xdd\x04\x01\x02\x03\x04", 6, ParseUnknown, 1 },
35	{ (u8 *) "\xdd\x04\x00\x50\xf2\x02", 6, ParseUnknown, 1 },
36	{ (u8 *) "\xdd\x05\x00\x50\xf2\x02\x02", 7, ParseOK, 1 },
37	{ (u8 *) "\xdd\x05\x00\x50\xf2\x02\xff", 7, ParseUnknown, 1 },
38	{ (u8 *) "\xdd\x04\x00\x50\xf2\xff", 6, ParseUnknown, 1 },
39	{ (u8 *) "\xdd\x04\x50\x6f\x9a\xff", 6, ParseUnknown, 1 },
40	{ (u8 *) "\xdd\x04\x00\x90\x4c\x33", 6, ParseOK, 1 },
41	{ (u8 *) "\xdd\x04\x00\x90\x4c\xff\xdd\x04\x00\x90\x4c\x33", 12,
42	  ParseUnknown, 2 },
43	{ (u8 *) "\x10\x01\x00\x21\x00", 5, ParseOK, 2 },
44	{ (u8 *) "\x24\x00", 2, ParseOK, 1 },
45	{ (u8 *) "\x38\x00", 2, ParseOK, 1 },
46	{ (u8 *) "\x54\x00", 2, ParseOK, 1 },
47	{ (u8 *) "\x5a\x00", 2, ParseOK, 1 },
48	{ (u8 *) "\x65\x00", 2, ParseOK, 1 },
49	{ (u8 *) "\x65\x12\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11",
50	  20, ParseOK, 1 },
51	{ (u8 *) "\x6e\x00", 2, ParseOK, 1 },
52	{ (u8 *) "\xc7\x00", 2, ParseOK, 1 },
53	{ (u8 *) "\xc7\x01\x00", 3, ParseOK, 1 },
54	{ (u8 *) "\x03\x00\x2a\x00\x36\x00\x37\x00\x38\x00\x2d\x00\x3d\x00\xbf\x00\xc0\x00",
55	  18, ParseOK, 9 },
56	{ (u8 *) "\x8b\x00", 2, ParseOK, 1 },
57	{ (u8 *) "\xdd\x04\x00\x90\x4c\x04", 6, ParseUnknown, 1 },
58	{ (u8 *) "\xed\x00", 2, ParseOK, 1 },
59	{ (u8 *) "\xef\x00", 2, ParseOK, 1 },
60	{ (u8 *) "\xef\x01\x11", 3, ParseOK, 1 },
61	{ (u8 *) "\xf0\x00", 2, ParseOK, 1 },
62	{ (u8 *) "\xf1\x00", 2, ParseOK, 1 },
63	{ (u8 *) "\xf1\x02\x11\x22", 4, ParseOK, 1 },
64	{ (u8 *) "\xf2\x00", 2, ParseOK, 1 },
65	{ (u8 *) "\xff\x00", 2, ParseUnknown, 1 },
66	{ (u8 *) "\xff\x01\x00", 3, ParseUnknown, 1 },
67	{ (u8 *) "\xff\x01\x01", 3, ParseOK, 1 },
68	{ (u8 *) "\xff\x02\x01\x00", 4, ParseOK, 1 },
69	{ (u8 *) "\xff\x01\x02", 3, ParseOK, 1 },
70	{ (u8 *) "\xff\x04\x02\x11\x22\x33", 6, ParseOK, 1 },
71	{ (u8 *) "\xff\x01\x04", 3, ParseOK, 1 },
72	{ (u8 *) "\xff\x01\x05", 3, ParseOK, 1 },
73	{ (u8 *) "\xff\x0d\x05\x11\x22\x33\x44\x55\x55\x11\x22\x33\x44\x55\x55",
74	  15, ParseOK, 1 },
75	{ (u8 *) "\xff\x01\x06", 3, ParseOK, 1 },
76	{ (u8 *) "\xff\x02\x06\x00", 4, ParseOK, 1 },
77	{ (u8 *) "\xff\x01\x07", 3, ParseOK, 1 },
78	{ (u8 *) "\xff\x09\x07\x11\x22\x33\x44\x55\x66\x77\x88", 11,
79	  ParseOK, 1 },
80	{ (u8 *) "\xff\x01\x0c", 3, ParseOK, 1 },
81	{ (u8 *) "\xff\x02\x0c\x00", 4, ParseOK, 1 },
82	{ (u8 *) "\xff\x01\x0d", 3, ParseOK, 1 },
83	{ NULL, 0, ParseOK, 0 }
84};
85
86static int ieee802_11_parse_tests(void)
87{
88	int i, ret = 0;
89	struct wpabuf *buf;
90
91	wpa_printf(MSG_INFO, "ieee802_11_parse tests");
92
93	for (i = 0; parse_tests[i].data; i++) {
94		const struct ieee802_11_parse_test_data *test;
95		struct ieee802_11_elems elems;
96		ParseRes res;
97
98		test = &parse_tests[i];
99		res = ieee802_11_parse_elems(test->data, test->len, &elems, 1);
100		if (res != test->result ||
101		    ieee802_11_ie_count(test->data, test->len) != test->count) {
102			wpa_printf(MSG_ERROR, "ieee802_11_parse test %d failed",
103				   i);
104			ret = -1;
105		}
106	}
107
108	if (ieee802_11_vendor_ie_concat((const u8 *) "\x00\x01", 2, 0) != NULL)
109	{
110		wpa_printf(MSG_ERROR,
111			   "ieee802_11_vendor_ie_concat test failed");
112		ret = -1;
113	}
114
115	buf = ieee802_11_vendor_ie_concat((const u8 *) "\xdd\x05\x11\x22\x33\x44\x01\xdd\x05\x11\x22\x33\x44\x02\x00\x01",
116					  16, 0x11223344);
117	do {
118		const u8 *pos;
119
120		if (!buf) {
121			wpa_printf(MSG_ERROR,
122				   "ieee802_11_vendor_ie_concat test 2 failed");
123			ret = -1;
124			break;
125		}
126
127		if (wpabuf_len(buf) != 2) {
128			wpa_printf(MSG_ERROR,
129				   "ieee802_11_vendor_ie_concat test 3 failed");
130			ret = -1;
131			break;
132		}
133
134		pos = wpabuf_head(buf);
135		if (pos[0] != 0x01 || pos[1] != 0x02) {
136			wpa_printf(MSG_ERROR,
137				   "ieee802_11_vendor_ie_concat test 3 failed");
138			ret = -1;
139			break;
140		}
141	} while (0);
142	wpabuf_free(buf);
143
144	return ret;
145}
146
147
148struct rsn_ie_parse_test_data {
149	u8 *data;
150	size_t len;
151	int result;
152};
153
154static const struct rsn_ie_parse_test_data rsn_parse_tests[] = {
155	{ (u8 *) "", 0, -1 },
156	{ (u8 *) "\x30\x00", 2, -1 },
157	{ (u8 *) "\x30\x02\x01\x00", 4, 0 },
158	{ (u8 *) "\x30\x02\x00\x00", 4, -2 },
159	{ (u8 *) "\x30\x02\x02\x00", 4, -2 },
160	{ (u8 *) "\x30\x02\x00\x01", 4, -2 },
161	{ (u8 *) "\x30\x02\x00\x00\x00", 5, -2 },
162	{ (u8 *) "\x30\x03\x01\x00\x00", 5, -3 },
163	{ (u8 *) "\x30\x06\x01\x00\x00\x00\x00\x00", 8, -1 },
164	{ (u8 *) "\x30\x06\x01\x00\x00\x0f\xac\x04", 8, 0 },
165	{ (u8 *) "\x30\x07\x01\x00\x00\x0f\xac\x04\x00", 9, -5 },
166	{ (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x00", 10, -4 },
167	{ (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x01", 10, -4 },
168	{ (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
169	  14, 0 },
170	{ (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x00\x01\x00\x0f\xac\x04",
171	  14, -4 },
172	{ (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x06",
173	  14, -1 },
174	{ (u8 *) "\x30\x10\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x04\x00\x0f\xac\x08",
175	  18, 0 },
176	{ (u8 *) "\x30\x0d\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00",
177	  15, -7 },
178	{ (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x00",
179	  16, -6 },
180	{ (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x01",
181	  16, -6 },
182	{ (u8 *) "\x30\x12\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01",
183	  20, 0 },
184	{ (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x01\x00\x0f\xac\x02",
185	  24, 0 },
186	{ (u8 *) "\x30\x13\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00",
187	  21, 0 },
188	{ (u8 *) "\x30\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00",
189	  22, 0 },
190	{ (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00",
191	  24, 0 },
192	{ (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x01",
193	  24, -9 },
194	{ (u8 *) "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x00\x00\x00",
195	  28, -10 },
196	{ (u8 *) "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x0f\xac\x06",
197	  28, 0 },
198	{ (u8 *) "\x30\x1c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x0f\xac\x06\x01\x02",
199	  30, 0 },
200	{ NULL, 0, 0 }
201};
202
203static int rsn_ie_parse_tests(void)
204{
205	int i, ret = 0;
206
207	wpa_printf(MSG_INFO, "rsn_ie_parse tests");
208
209	for (i = 0; rsn_parse_tests[i].data; i++) {
210		const struct rsn_ie_parse_test_data *test;
211		struct wpa_ie_data data;
212
213		test = &rsn_parse_tests[i];
214		if (wpa_parse_wpa_ie_rsn(test->data, test->len, &data) !=
215		    test->result) {
216			wpa_printf(MSG_ERROR, "rsn_ie_parse test %d failed", i);
217			ret = -1;
218		}
219	}
220
221	return ret;
222}
223
224
225static int gas_tests(void)
226{
227	struct wpabuf *buf;
228
229	wpa_printf(MSG_INFO, "gas tests");
230	gas_anqp_set_len(NULL);
231
232	buf = wpabuf_alloc(1);
233	if (buf == NULL)
234		return -1;
235	gas_anqp_set_len(buf);
236	wpabuf_free(buf);
237
238	buf = wpabuf_alloc(20);
239	if (buf == NULL)
240		return -1;
241	wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
242	wpabuf_put_u8(buf, WLAN_PA_GAS_INITIAL_REQ);
243	wpabuf_put_u8(buf, 0);
244	wpabuf_put_be32(buf, 0);
245	wpabuf_put_u8(buf, 0);
246	gas_anqp_set_len(buf);
247	wpabuf_free(buf);
248
249	return 0;
250}
251
252
253static int sae_tests(void)
254{
255#ifdef CONFIG_SAE
256	struct sae_data sae;
257	int ret = -1;
258	/* IEEE P802.11-REVmd/D2.1, Annex J.10 */
259	const u8 addr1[ETH_ALEN] = { 0x82, 0x7b, 0x91, 0x9d, 0xd4, 0xb9 };
260	const u8 addr2[ETH_ALEN] = { 0x1e, 0xec, 0x49, 0xea, 0x64, 0x88 };
261	const char *pw = "mekmitasdigoat";
262	const char *pwid = "psk4internet";
263	const u8 local_rand[] = {
264		0xa9, 0x06, 0xf6, 0x1e, 0x4d, 0x3a, 0x5d, 0x4e,
265		0xb2, 0x96, 0x5f, 0xf3, 0x4c, 0xf9, 0x17, 0xdd,
266		0x04, 0x44, 0x45, 0xc8, 0x78, 0xc1, 0x7c, 0xa5,
267		0xd5, 0xb9, 0x37, 0x86, 0xda, 0x9f, 0x83, 0xcf
268	};
269	const u8 local_mask[] = {
270		0x42, 0x34, 0xb4, 0xfb, 0x17, 0xaa, 0x43, 0x5c,
271		0x52, 0xfb, 0xfd, 0xeb, 0xe6, 0x40, 0x39, 0xb4,
272		0x34, 0x78, 0x20, 0x0e, 0x54, 0xff, 0x7b, 0x6e,
273		0x07, 0xb6, 0x9c, 0xad, 0x74, 0x15, 0x3c, 0x15
274	};
275	const u8 local_commit[] = {
276		0x13, 0x00, 0xeb, 0x3b, 0xab, 0x19, 0x64, 0xe4,
277		0xa0, 0xab, 0x05, 0x92, 0x5d, 0xdf, 0x33, 0x39,
278		0x51, 0x91, 0x38, 0xbc, 0x65, 0xd6, 0xcd, 0xc0,
279		0xf8, 0x13, 0xdd, 0x6f, 0xd4, 0x34, 0x4e, 0xb4,
280		0xbf, 0xe4, 0x4b, 0x5c, 0x21, 0x59, 0x76, 0x58,
281		0xf4, 0xe3, 0xed, 0xdf, 0xb4, 0xb9, 0x9f, 0x25,
282		0xb4, 0xd6, 0x54, 0x0f, 0x32, 0xff, 0x1f, 0xd5,
283		0xc5, 0x30, 0xc6, 0x0a, 0x79, 0x44, 0x48, 0x61,
284		0x0b, 0xc6, 0xde, 0x3d, 0x92, 0xbd, 0xbb, 0xd4,
285		0x7d, 0x93, 0x59, 0x80, 0xca, 0x6c, 0xf8, 0x98,
286		0x8a, 0xb6, 0x63, 0x0b, 0xe6, 0x76, 0x4c, 0x88,
287		0x5c, 0xeb, 0x97, 0x93, 0x97, 0x0f, 0x69, 0x52,
288		0x17, 0xee, 0xff, 0x0d, 0x21, 0x70, 0x73, 0x6b,
289		0x34, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
290		0x74
291	};
292	const u8 peer_commit[] = {
293		0x13, 0x00, 0x55, 0x64, 0xf0, 0x45, 0xb2, 0xea,
294		0x1e, 0x56, 0x6c, 0xf1, 0xdd, 0x74, 0x1f, 0x70,
295		0xd9, 0xbe, 0x35, 0xd2, 0xdf, 0x5b, 0x9a, 0x55,
296		0x02, 0x94, 0x6e, 0xe0, 0x3c, 0xf8, 0xda, 0xe2,
297		0x7e, 0x1e, 0x05, 0xb8, 0x43, 0x0e, 0xb7, 0xa9,
298		0x9e, 0x24, 0x87, 0x7c, 0xe6, 0x9b, 0xaf, 0x3d,
299		0xc5, 0x80, 0xe3, 0x09, 0x63, 0x3d, 0x6b, 0x38,
300		0x5f, 0x83, 0xee, 0x1c, 0x3e, 0xc3, 0x59, 0x1f,
301		0x1a, 0x53, 0x93, 0xc0, 0x6e, 0x80, 0x5d, 0xdc,
302		0xeb, 0x2f, 0xde, 0x50, 0x93, 0x0d, 0xd7, 0xcf,
303		0xeb, 0xb9, 0x87, 0xc6, 0xff, 0x96, 0x66, 0xaf,
304		0x16, 0x4e, 0xb5, 0x18, 0x4d, 0x8e, 0x66, 0x62,
305		0xed, 0x6a, 0xff, 0x0d, 0x21, 0x70, 0x73, 0x6b,
306		0x34, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
307		0x74
308	};
309	const u8 kck[] = {
310		0x59, 0x9d, 0x6f, 0x1e, 0x27, 0x54, 0x8b, 0xe8,
311		0x49, 0x9d, 0xce, 0xed, 0x2f, 0xec, 0xcf, 0x94,
312		0x81, 0x8c, 0xe1, 0xc7, 0x9f, 0x1b, 0x4e, 0xb3,
313		0xd6, 0xa5, 0x32, 0x28, 0xa0, 0x9b, 0xf3, 0xed
314	};
315	const u8 pmk[] = {
316		0x7a, 0xea, 0xd8, 0x6f, 0xba, 0x4c, 0x32, 0x21,
317		0xfc, 0x43, 0x7f, 0x5f, 0x14, 0xd7, 0x0d, 0x85,
318		0x4e, 0xa5, 0xd5, 0xaa, 0xc1, 0x69, 0x01, 0x16,
319		0x79, 0x30, 0x81, 0xed, 0xa4, 0xd5, 0x57, 0xc5
320	};
321	const u8 pmkid[] = {
322		0x40, 0xa0, 0x9b, 0x60, 0x17, 0xce, 0xbf, 0x00,
323		0x72, 0x84, 0x3b, 0x53, 0x52, 0xaa, 0x2b, 0x4f
324	};
325	const u8 local_confirm[] = {
326		0x01, 0x00, 0x12, 0xd9, 0xd5, 0xc7, 0x8c, 0x50,
327		0x05, 0x26, 0xd3, 0x6c, 0x41, 0xdb, 0xc5, 0x6a,
328		0xed, 0xf2, 0x91, 0x4c, 0xed, 0xdd, 0xd7, 0xca,
329		0xd4, 0xa5, 0x8c, 0x48, 0xf8, 0x3d, 0xbd, 0xe9,
330		0xfc, 0x77
331	};
332	const u8 peer_confirm[] = {
333		0x01, 0x00, 0x02, 0x87, 0x1c, 0xf9, 0x06, 0x89,
334		0x8b, 0x80, 0x60, 0xec, 0x18, 0x41, 0x43, 0xbe,
335		0x77, 0xb8, 0xc0, 0x8a, 0x80, 0x19, 0xb1, 0x3e,
336		0xb6, 0xd0, 0xae, 0xf0, 0xd8, 0x38, 0x3d, 0xfa,
337		0xc2, 0xfd
338	};
339	struct wpabuf *buf = NULL;
340	struct crypto_bignum *mask = NULL;
341
342	os_memset(&sae, 0, sizeof(sae));
343	buf = wpabuf_alloc(1000);
344	if (!buf ||
345	    sae_set_group(&sae, 19) < 0 ||
346	    sae_prepare_commit(addr1, addr2, (const u8 *) pw, os_strlen(pw),
347			       pwid, &sae) < 0)
348		goto fail;
349
350	/* Override local values based on SAE test vector */
351	crypto_bignum_deinit(sae.tmp->sae_rand, 1);
352	sae.tmp->sae_rand = crypto_bignum_init_set(local_rand,
353						   sizeof(local_rand));
354	mask = crypto_bignum_init_set(local_mask, sizeof(local_mask));
355	if (!sae.tmp->sae_rand || !mask)
356		goto fail;
357
358	if (crypto_bignum_add(sae.tmp->sae_rand, mask,
359			      sae.tmp->own_commit_scalar) < 0 ||
360	    crypto_bignum_mod(sae.tmp->own_commit_scalar, sae.tmp->order,
361			      sae.tmp->own_commit_scalar) < 0 ||
362	    crypto_ec_point_mul(sae.tmp->ec, sae.tmp->pwe_ecc, mask,
363				sae.tmp->own_commit_element_ecc) < 0 ||
364	    crypto_ec_point_invert(sae.tmp->ec,
365				   sae.tmp->own_commit_element_ecc) < 0)
366		goto fail;
367
368	/* Check that output matches the test vector */
369	sae_write_commit(&sae, buf, NULL, pwid);
370	wpa_hexdump_buf(MSG_DEBUG, "SAE: Commit message", buf);
371
372	if (wpabuf_len(buf) != sizeof(local_commit) ||
373	    os_memcmp(wpabuf_head(buf), local_commit,
374		      sizeof(local_commit)) != 0) {
375		wpa_printf(MSG_ERROR, "SAE: Mismatch in local commit");
376		goto fail;
377	}
378
379	if (sae_parse_commit(&sae, peer_commit, sizeof(peer_commit), NULL, NULL,
380		    NULL) != 0 ||
381	    sae_process_commit(&sae) < 0)
382		goto fail;
383
384	if (os_memcmp(kck, sae.tmp->kck, SAE_KCK_LEN) != 0) {
385		wpa_printf(MSG_ERROR, "SAE: Mismatch in KCK");
386		goto fail;
387	}
388
389	if (os_memcmp(pmk, sae.pmk, SAE_PMK_LEN) != 0) {
390		wpa_printf(MSG_ERROR, "SAE: Mismatch in PMK");
391		goto fail;
392	}
393
394	if (os_memcmp(pmkid, sae.pmkid, SAE_PMKID_LEN) != 0) {
395		wpa_printf(MSG_ERROR, "SAE: Mismatch in PMKID");
396		goto fail;
397	}
398
399	buf->used = 0;
400	sae.send_confirm = 1;
401	sae_write_confirm(&sae, buf);
402	wpa_hexdump_buf(MSG_DEBUG, "SAE: Confirm message", buf);
403
404	if (wpabuf_len(buf) != sizeof(local_confirm) ||
405	    os_memcmp(wpabuf_head(buf), local_confirm,
406		      sizeof(local_confirm)) != 0) {
407		wpa_printf(MSG_ERROR, "SAE: Mismatch in local confirm");
408		goto fail;
409	}
410
411	if (sae_check_confirm(&sae, peer_confirm, sizeof(peer_confirm)) < 0)
412		goto fail;
413
414	ret = 0;
415fail:
416	sae_clear_data(&sae);
417	wpabuf_free(buf);
418	crypto_bignum_deinit(mask, 1);
419	return ret;
420#else /* CONFIG_SAE */
421	return 0;
422#endif /* CONFIG_SAE */
423}
424
425
426int common_module_tests(void)
427{
428	int ret = 0;
429
430	wpa_printf(MSG_INFO, "common module tests");
431
432	if (ieee802_11_parse_tests() < 0 ||
433	    gas_tests() < 0 ||
434	    sae_tests() < 0 ||
435	    rsn_ie_parse_tests() < 0)
436		ret = -1;
437
438	return ret;
439}
440