xref: /freebsd/contrib/wpa/src/common/common_module_tests.c (revision 5956d97f4b3204318ceb6aa9c77bd0bc6ea87a41)
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 "crypto/dh_groups.h"
15 #include "ieee802_11_common.h"
16 #include "ieee802_11_defs.h"
17 #include "gas.h"
18 #include "wpa_common.h"
19 #include "sae.h"
20 
21 
22 struct ieee802_11_parse_test_data {
23 	u8 *data;
24 	size_t len;
25 	ParseRes result;
26 	int count;
27 };
28 
29 static const struct ieee802_11_parse_test_data parse_tests[] = {
30 	{ (u8 *) "", 0, ParseOK, 0 },
31 	{ (u8 *) " ", 1, ParseFailed, 0 },
32 	{ (u8 *) "\xff\x00", 2, ParseUnknown, 1 },
33 	{ (u8 *) "\xff\x01", 2, ParseFailed, 0 },
34 	{ (u8 *) "\xdd\x03\x01\x02\x03", 5, ParseUnknown, 1 },
35 	{ (u8 *) "\xdd\x04\x01\x02\x03\x04", 6, ParseUnknown, 1 },
36 	{ (u8 *) "\xdd\x04\x00\x50\xf2\x02", 6, ParseUnknown, 1 },
37 	{ (u8 *) "\xdd\x05\x00\x50\xf2\x02\x02", 7, ParseOK, 1 },
38 	{ (u8 *) "\xdd\x05\x00\x50\xf2\x02\xff", 7, ParseUnknown, 1 },
39 	{ (u8 *) "\xdd\x04\x00\x50\xf2\xff", 6, ParseUnknown, 1 },
40 	{ (u8 *) "\xdd\x04\x50\x6f\x9a\xff", 6, ParseUnknown, 1 },
41 	{ (u8 *) "\xdd\x04\x00\x90\x4c\x33", 6, ParseOK, 1 },
42 	{ (u8 *) "\xdd\x04\x00\x90\x4c\xff\xdd\x04\x00\x90\x4c\x33", 12,
43 	  ParseUnknown, 2 },
44 	{ (u8 *) "\x10\x01\x00\x21\x00", 5, ParseOK, 2 },
45 	{ (u8 *) "\x24\x00", 2, ParseOK, 1 },
46 	{ (u8 *) "\x38\x00", 2, ParseOK, 1 },
47 	{ (u8 *) "\x54\x00", 2, ParseOK, 1 },
48 	{ (u8 *) "\x5a\x00", 2, ParseOK, 1 },
49 	{ (u8 *) "\x65\x00", 2, ParseOK, 1 },
50 	{ (u8 *) "\x65\x12\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11",
51 	  20, ParseOK, 1 },
52 	{ (u8 *) "\x6e\x00", 2, ParseOK, 1 },
53 	{ (u8 *) "\xc7\x00", 2, ParseOK, 1 },
54 	{ (u8 *) "\xc7\x01\x00", 3, ParseOK, 1 },
55 	{ (u8 *) "\x03\x00\x2a\x00\x36\x00\x37\x00\x38\x00\x2d\x00\x3d\x00\xbf\x00\xc0\x00",
56 	  18, ParseOK, 9 },
57 	{ (u8 *) "\x8b\x00", 2, ParseOK, 1 },
58 	{ (u8 *) "\xdd\x04\x00\x90\x4c\x04", 6, ParseUnknown, 1 },
59 	{ (u8 *) "\xed\x00", 2, ParseOK, 1 },
60 	{ (u8 *) "\xef\x00", 2, ParseOK, 1 },
61 	{ (u8 *) "\xef\x01\x11", 3, ParseOK, 1 },
62 	{ (u8 *) "\xf0\x00", 2, ParseOK, 1 },
63 	{ (u8 *) "\xf1\x00", 2, ParseOK, 1 },
64 	{ (u8 *) "\xf1\x02\x11\x22", 4, ParseOK, 1 },
65 	{ (u8 *) "\xf2\x00", 2, ParseOK, 1 },
66 	{ (u8 *) "\xff\x00", 2, ParseUnknown, 1 },
67 	{ (u8 *) "\xff\x01\x00", 3, ParseUnknown, 1 },
68 	{ (u8 *) "\xff\x01\x01", 3, ParseOK, 1 },
69 	{ (u8 *) "\xff\x02\x01\x00", 4, ParseOK, 1 },
70 	{ (u8 *) "\xff\x01\x02", 3, ParseOK, 1 },
71 	{ (u8 *) "\xff\x04\x02\x11\x22\x33", 6, ParseOK, 1 },
72 	{ (u8 *) "\xff\x01\x04", 3, ParseOK, 1 },
73 	{ (u8 *) "\xff\x01\x05", 3, ParseOK, 1 },
74 	{ (u8 *) "\xff\x0d\x05\x11\x22\x33\x44\x55\x55\x11\x22\x33\x44\x55\x55",
75 	  15, ParseOK, 1 },
76 	{ (u8 *) "\xff\x01\x06", 3, ParseOK, 1 },
77 	{ (u8 *) "\xff\x02\x06\x00", 4, ParseOK, 1 },
78 	{ (u8 *) "\xff\x01\x07", 3, ParseOK, 1 },
79 	{ (u8 *) "\xff\x09\x07\x11\x22\x33\x44\x55\x66\x77\x88", 11,
80 	  ParseOK, 1 },
81 	{ (u8 *) "\xff\x01\x0c", 3, ParseOK, 1 },
82 	{ (u8 *) "\xff\x02\x0c\x00", 4, ParseOK, 1 },
83 	{ (u8 *) "\xff\x01\x0d", 3, ParseOK, 1 },
84 	{ NULL, 0, ParseOK, 0 }
85 };
86 
87 static int ieee802_11_parse_tests(void)
88 {
89 	int i, ret = 0;
90 	struct wpabuf *buf;
91 
92 	wpa_printf(MSG_INFO, "ieee802_11_parse tests");
93 
94 	for (i = 0; parse_tests[i].data; i++) {
95 		const struct ieee802_11_parse_test_data *test;
96 		struct ieee802_11_elems elems;
97 		ParseRes res;
98 
99 		test = &parse_tests[i];
100 		res = ieee802_11_parse_elems(test->data, test->len, &elems, 1);
101 		if (res != test->result ||
102 		    ieee802_11_ie_count(test->data, test->len) != test->count) {
103 			wpa_printf(MSG_ERROR, "ieee802_11_parse test %d failed",
104 				   i);
105 			ret = -1;
106 		}
107 	}
108 
109 	if (ieee802_11_vendor_ie_concat((const u8 *) "\x00\x01", 2, 0) != NULL)
110 	{
111 		wpa_printf(MSG_ERROR,
112 			   "ieee802_11_vendor_ie_concat test failed");
113 		ret = -1;
114 	}
115 
116 	buf = ieee802_11_vendor_ie_concat((const u8 *) "\xdd\x05\x11\x22\x33\x44\x01\xdd\x05\x11\x22\x33\x44\x02\x00\x01",
117 					  16, 0x11223344);
118 	do {
119 		const u8 *pos;
120 
121 		if (!buf) {
122 			wpa_printf(MSG_ERROR,
123 				   "ieee802_11_vendor_ie_concat test 2 failed");
124 			ret = -1;
125 			break;
126 		}
127 
128 		if (wpabuf_len(buf) != 2) {
129 			wpa_printf(MSG_ERROR,
130 				   "ieee802_11_vendor_ie_concat test 3 failed");
131 			ret = -1;
132 			break;
133 		}
134 
135 		pos = wpabuf_head(buf);
136 		if (pos[0] != 0x01 || pos[1] != 0x02) {
137 			wpa_printf(MSG_ERROR,
138 				   "ieee802_11_vendor_ie_concat test 3 failed");
139 			ret = -1;
140 			break;
141 		}
142 	} while (0);
143 	wpabuf_free(buf);
144 
145 	return ret;
146 }
147 
148 
149 struct rsn_ie_parse_test_data {
150 	u8 *data;
151 	size_t len;
152 	int result;
153 };
154 
155 static const struct rsn_ie_parse_test_data rsn_parse_tests[] = {
156 	{ (u8 *) "", 0, -1 },
157 	{ (u8 *) "\x30\x00", 2, -1 },
158 	{ (u8 *) "\x30\x02\x01\x00", 4, 0 },
159 	{ (u8 *) "\x30\x02\x00\x00", 4, -2 },
160 	{ (u8 *) "\x30\x02\x02\x00", 4, -2 },
161 	{ (u8 *) "\x30\x02\x00\x01", 4, -2 },
162 	{ (u8 *) "\x30\x02\x00\x00\x00", 5, -2 },
163 	{ (u8 *) "\x30\x03\x01\x00\x00", 5, -3 },
164 	{ (u8 *) "\x30\x06\x01\x00\x00\x00\x00\x00", 8, -1 },
165 	{ (u8 *) "\x30\x06\x01\x00\x00\x0f\xac\x04", 8, 0 },
166 	{ (u8 *) "\x30\x07\x01\x00\x00\x0f\xac\x04\x00", 9, -5 },
167 	{ (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x00", 10, -4 },
168 	{ (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x01", 10, -4 },
169 	{ (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
170 	  14, 0 },
171 	{ (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x00\x01\x00\x0f\xac\x04",
172 	  14, -4 },
173 	{ (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x06",
174 	  14, -1 },
175 	{ (u8 *) "\x30\x10\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x04\x00\x0f\xac\x08",
176 	  18, 0 },
177 	{ (u8 *) "\x30\x0d\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00",
178 	  15, -7 },
179 	{ (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x00",
180 	  16, -6 },
181 	{ (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x01",
182 	  16, -6 },
183 	{ (u8 *) "\x30\x12\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01",
184 	  20, 0 },
185 	{ (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",
186 	  24, 0 },
187 	{ (u8 *) "\x30\x13\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00",
188 	  21, 0 },
189 	{ (u8 *) "\x30\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00",
190 	  22, 0 },
191 	{ (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",
192 	  24, 0 },
193 	{ (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",
194 	  24, -9 },
195 	{ (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",
196 	  28, -10 },
197 	{ (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",
198 	  28, 0 },
199 	{ (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",
200 	  30, 0 },
201 	{ NULL, 0, 0 }
202 };
203 
204 static int rsn_ie_parse_tests(void)
205 {
206 	int i, ret = 0;
207 
208 	wpa_printf(MSG_INFO, "rsn_ie_parse tests");
209 
210 	for (i = 0; rsn_parse_tests[i].data; i++) {
211 		const struct rsn_ie_parse_test_data *test;
212 		struct wpa_ie_data data;
213 
214 		test = &rsn_parse_tests[i];
215 		if (wpa_parse_wpa_ie_rsn(test->data, test->len, &data) !=
216 		    test->result) {
217 			wpa_printf(MSG_ERROR, "rsn_ie_parse test %d failed", i);
218 			ret = -1;
219 		}
220 	}
221 
222 	return ret;
223 }
224 
225 
226 static int gas_tests(void)
227 {
228 	struct wpabuf *buf;
229 
230 	wpa_printf(MSG_INFO, "gas tests");
231 	gas_anqp_set_len(NULL);
232 
233 	buf = wpabuf_alloc(1);
234 	if (buf == NULL)
235 		return -1;
236 	gas_anqp_set_len(buf);
237 	wpabuf_free(buf);
238 
239 	buf = wpabuf_alloc(20);
240 	if (buf == NULL)
241 		return -1;
242 	wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
243 	wpabuf_put_u8(buf, WLAN_PA_GAS_INITIAL_REQ);
244 	wpabuf_put_u8(buf, 0);
245 	wpabuf_put_be32(buf, 0);
246 	wpabuf_put_u8(buf, 0);
247 	gas_anqp_set_len(buf);
248 	wpabuf_free(buf);
249 
250 	return 0;
251 }
252 
253 
254 static int sae_tests(void)
255 {
256 #ifdef CONFIG_SAE
257 	struct sae_data sae;
258 	int ret = -1;
259 	/* IEEE Std 802.11-2020, Annex J.10 */
260 	const u8 addr1[ETH_ALEN] = { 0x4d, 0x3f, 0x2f, 0xff, 0xe3, 0x87 };
261 	const u8 addr2[ETH_ALEN] = { 0xa5, 0xd8, 0xaa, 0x95, 0x8e, 0x3c };
262 	const char *ssid = "byteme";
263 	const char *pw = "mekmitasdigoat";
264 	const char *pwid = "psk4internet";
265 	const u8 local_rand[] = {
266 		0x99, 0x24, 0x65, 0xfd, 0x3d, 0xaa, 0x3c, 0x60,
267 		0xaa, 0x65, 0x65, 0xb7, 0xf6, 0x2a, 0x2a, 0x7f,
268 		0x2e, 0x12, 0xdd, 0x12, 0xf1, 0x98, 0xfa, 0xf4,
269 		0xfb, 0xed, 0x89, 0xd7, 0xff, 0x1a, 0xce, 0x94
270 	};
271 	const u8 local_mask[] = {
272 		0x95, 0x07, 0xa9, 0x0f, 0x77, 0x7a, 0x04, 0x4d,
273 		0x6a, 0x08, 0x30, 0xb9, 0x1e, 0xa3, 0xd5, 0xdd,
274 		0x70, 0xbe, 0xce, 0x44, 0xe1, 0xac, 0xff, 0xb8,
275 		0x69, 0x83, 0xb5, 0xe1, 0xbf, 0x9f, 0xb3, 0x22
276 	};
277 	const u8 local_commit[] = {
278 		0x13, 0x00, 0x2e, 0x2c, 0x0f, 0x0d, 0xb5, 0x24,
279 		0x40, 0xad, 0x14, 0x6d, 0x96, 0x71, 0x14, 0xce,
280 		0x00, 0x5c, 0xe1, 0xea, 0xb0, 0xaa, 0x2c, 0x2e,
281 		0x5c, 0x28, 0x71, 0xb7, 0x74, 0xf6, 0xc2, 0x57,
282 		0x5c, 0x65, 0xd5, 0xad, 0x9e, 0x00, 0x82, 0x97,
283 		0x07, 0xaa, 0x36, 0xba, 0x8b, 0x85, 0x97, 0x38,
284 		0xfc, 0x96, 0x1d, 0x08, 0x24, 0x35, 0x05, 0xf4,
285 		0x7c, 0x03, 0x53, 0x76, 0xd7, 0xac, 0x4b, 0xc8,
286 		0xd7, 0xb9, 0x50, 0x83, 0xbf, 0x43, 0x82, 0x7d,
287 		0x0f, 0xc3, 0x1e, 0xd7, 0x78, 0xdd, 0x36, 0x71,
288 		0xfd, 0x21, 0xa4, 0x6d, 0x10, 0x91, 0xd6, 0x4b,
289 		0x6f, 0x9a, 0x1e, 0x12, 0x72, 0x62, 0x13, 0x25,
290 		0xdb, 0xe1
291 	};
292 	const u8 peer_commit[] = {
293 		0x13, 0x00, 0x59, 0x1b, 0x96, 0xf3, 0x39, 0x7f,
294 		0xb9, 0x45, 0x10, 0x08, 0x48, 0xe7, 0xb5, 0x50,
295 		0x54, 0x3b, 0x67, 0x20, 0xd8, 0x83, 0x37, 0xee,
296 		0x93, 0xfc, 0x49, 0xfd, 0x6d, 0xf7, 0xe0, 0x8b,
297 		0x52, 0x23, 0xe7, 0x1b, 0x9b, 0xb0, 0x48, 0xd3,
298 		0x87, 0x3f, 0x20, 0x55, 0x69, 0x53, 0xa9, 0x6c,
299 		0x91, 0x53, 0x6f, 0xd8, 0xee, 0x6c, 0xa9, 0xb4,
300 		0xa6, 0x8a, 0x14, 0x8b, 0x05, 0x6a, 0x90, 0x9b,
301 		0xe0, 0x3e, 0x83, 0xae, 0x20, 0x8f, 0x60, 0xf8,
302 		0xef, 0x55, 0x37, 0x85, 0x80, 0x74, 0xdb, 0x06,
303 		0x68, 0x70, 0x32, 0x39, 0x98, 0x62, 0x99, 0x9b,
304 		0x51, 0x1e, 0x0a, 0x15, 0x52, 0xa5, 0xfe, 0xa3,
305 		0x17, 0xc2
306 	};
307 	const u8 kck[] = {
308 		0x1e, 0x73, 0x3f, 0x6d, 0x9b, 0xd5, 0x32, 0x56,
309 		0x28, 0x73, 0x04, 0x33, 0x88, 0x31, 0xb0, 0x9a,
310 		0x39, 0x40, 0x6d, 0x12, 0x10, 0x17, 0x07, 0x3a,
311 		0x5c, 0x30, 0xdb, 0x36, 0xf3, 0x6c, 0xb8, 0x1a
312 	};
313 	const u8 pmk[] = {
314 		0x4e, 0x4d, 0xfa, 0xb1, 0xa2, 0xdd, 0x8a, 0xc1,
315 		0xa9, 0x17, 0x90, 0xf9, 0x53, 0xfa, 0xaa, 0x45,
316 		0x2a, 0xe5, 0xc6, 0x87, 0x3a, 0xb7, 0x5b, 0x63,
317 		0x60, 0x5b, 0xa6, 0x63, 0xf8, 0xa7, 0xfe, 0x59
318 	};
319 	const u8 pmkid[] = {
320 		0x87, 0x47, 0xa6, 0x00, 0xee, 0xa3, 0xf9, 0xf2,
321 		0x24, 0x75, 0xdf, 0x58, 0xca, 0x1e, 0x54, 0x98
322 	};
323 	struct wpabuf *buf = NULL;
324 	struct crypto_bignum *mask = NULL;
325 	const u8 pwe_19_x[32] = {
326 		0xc9, 0x30, 0x49, 0xb9, 0xe6, 0x40, 0x00, 0xf8,
327 		0x48, 0x20, 0x16, 0x49, 0xe9, 0x99, 0xf2, 0xb5,
328 		0xc2, 0x2d, 0xea, 0x69, 0xb5, 0x63, 0x2c, 0x9d,
329 		0xf4, 0xd6, 0x33, 0xb8, 0xaa, 0x1f, 0x6c, 0x1e
330 	};
331 	const u8 pwe_19_y[32] = {
332 		0x73, 0x63, 0x4e, 0x94, 0xb5, 0x3d, 0x82, 0xe7,
333 		0x38, 0x3a, 0x8d, 0x25, 0x81, 0x99, 0xd9, 0xdc,
334 		0x1a, 0x5e, 0xe8, 0x26, 0x9d, 0x06, 0x03, 0x82,
335 		0xcc, 0xbf, 0x33, 0xe6, 0x14, 0xff, 0x59, 0xa0
336 	};
337 	const u8 pwe_15[384] = {
338 		0x69, 0x68, 0x73, 0x65, 0x8f, 0x65, 0x31, 0x42,
339 		0x9f, 0x97, 0x39, 0x6f, 0xb8, 0x5f, 0x89, 0xe1,
340 		0xfc, 0xd2, 0xf6, 0x92, 0x19, 0xa9, 0x0e, 0x82,
341 		0x2f, 0xf7, 0xf4, 0xbc, 0x0b, 0xd8, 0xa7, 0x9f,
342 		0xf0, 0x80, 0x35, 0x31, 0x6f, 0xca, 0xe1, 0xa5,
343 		0x39, 0x77, 0xdc, 0x11, 0x2b, 0x0b, 0xfe, 0x2e,
344 		0x6f, 0x65, 0x6d, 0xc7, 0xd4, 0xa4, 0x5b, 0x08,
345 		0x1f, 0xd9, 0xbb, 0xe2, 0x22, 0x85, 0x31, 0x81,
346 		0x79, 0x70, 0xbe, 0xa1, 0x66, 0x58, 0x4a, 0x09,
347 		0x3c, 0x57, 0x34, 0x3c, 0x9d, 0x57, 0x8f, 0x42,
348 		0x58, 0xd0, 0x39, 0x81, 0xdb, 0x8f, 0x79, 0xa2,
349 		0x1b, 0x01, 0xcd, 0x27, 0xc9, 0xae, 0xcf, 0xcb,
350 		0x9c, 0xdb, 0x1f, 0x84, 0xb8, 0x88, 0x4e, 0x8f,
351 		0x50, 0x66, 0xb4, 0x29, 0x83, 0x1e, 0xb9, 0x89,
352 		0x0c, 0xa5, 0x47, 0x21, 0xba, 0x10, 0xd5, 0xaa,
353 		0x1a, 0x80, 0xce, 0xf1, 0x4c, 0xad, 0x16, 0xda,
354 		0x57, 0xb2, 0x41, 0x8a, 0xbe, 0x4b, 0x8c, 0xb0,
355 		0xb2, 0xeb, 0xf7, 0xa8, 0x0e, 0x3e, 0xcf, 0x22,
356 		0x8f, 0xd8, 0xb6, 0xdb, 0x79, 0x9c, 0x9b, 0x80,
357 		0xaf, 0xd7, 0x14, 0xad, 0x51, 0x82, 0xf4, 0x64,
358 		0xb6, 0x3f, 0x4c, 0x6c, 0xe5, 0x3f, 0xaa, 0x6f,
359 		0xbf, 0x3d, 0xc2, 0x3f, 0x77, 0xfd, 0xcb, 0xe1,
360 		0x9c, 0xe3, 0x1e, 0x8a, 0x0e, 0x97, 0xe2, 0x2b,
361 		0xe2, 0xdd, 0x37, 0x39, 0x88, 0xc2, 0x8e, 0xbe,
362 		0xfa, 0xac, 0x3d, 0x5b, 0x62, 0x2e, 0x1e, 0x74,
363 		0xa0, 0x9a, 0xf8, 0xed, 0xfa, 0xe1, 0xce, 0x9c,
364 		0xab, 0xbb, 0xdc, 0x36, 0xb1, 0x28, 0x46, 0x3c,
365 		0x7e, 0xa8, 0xbd, 0xb9, 0x36, 0x4c, 0x26, 0x75,
366 		0xe0, 0x17, 0x73, 0x1f, 0xe0, 0xfe, 0xf6, 0x49,
367 		0xfa, 0xa0, 0x45, 0xf4, 0x44, 0x05, 0x20, 0x27,
368 		0x25, 0xc2, 0x99, 0xde, 0x27, 0x8b, 0x70, 0xdc,
369 		0x54, 0x60, 0x90, 0x02, 0x1e, 0x29, 0x97, 0x9a,
370 		0xc4, 0xe7, 0xb6, 0xf5, 0x8b, 0xae, 0x7c, 0x34,
371 		0xaa, 0xef, 0x9b, 0xc6, 0x30, 0xf2, 0x80, 0x8d,
372 		0x80, 0x78, 0xc2, 0x55, 0x63, 0xa0, 0xa1, 0x38,
373 		0x70, 0xfb, 0xf4, 0x74, 0x8d, 0xcd, 0x87, 0x90,
374 		0xb4, 0x54, 0xc3, 0x75, 0xdf, 0x10, 0xc5, 0xb6,
375 		0xb2, 0x08, 0x59, 0x61, 0xe6, 0x68, 0xa5, 0x82,
376 		0xf8, 0x8f, 0x47, 0x30, 0x43, 0xb4, 0xdc, 0x31,
377 		0xfc, 0xbc, 0x69, 0xe7, 0xb4, 0x94, 0xb0, 0x6a,
378 		0x60, 0x59, 0x80, 0x2e, 0xd3, 0xa4, 0xe8, 0x97,
379 		0xa2, 0xa3, 0xc9, 0x08, 0x4b, 0x27, 0x6c, 0xc1,
380 		0x37, 0xe8, 0xfc, 0x5c, 0xe2, 0x54, 0x30, 0x3e,
381 		0xf8, 0xfe, 0xa2, 0xfc, 0xbb, 0xbd, 0x88, 0x6c,
382 		0x92, 0xa3, 0x2a, 0x40, 0x7a, 0x2c, 0x22, 0x38,
383 		0x8c, 0x86, 0x86, 0xfe, 0xb9, 0xd4, 0x6b, 0xd6,
384 		0x47, 0x88, 0xa7, 0xf6, 0x8e, 0x0f, 0x14, 0xad,
385 		0x1e, 0xac, 0xcf, 0x33, 0x01, 0x99, 0xc1, 0x62
386 	};
387 	int pt_groups[] = { 19, 20, 21, 25, 26, 28, 29, 30, 15, 0 };
388 	struct sae_pt *pt_info, *pt;
389 	const u8 addr1b[ETH_ALEN] = { 0x00, 0x09, 0x5b, 0x66, 0xec, 0x1e };
390 	const u8 addr2b[ETH_ALEN] = { 0x00, 0x0b, 0x6b, 0xd9, 0x02, 0x46 };
391 
392 	os_memset(&sae, 0, sizeof(sae));
393 	buf = wpabuf_alloc(1000);
394 	if (!buf ||
395 	    sae_set_group(&sae, 19) < 0 ||
396 	    sae_prepare_commit(addr1, addr2, (const u8 *) pw, os_strlen(pw),
397 			       &sae) < 0)
398 		goto fail;
399 
400 	/* Override local values based on SAE test vector */
401 	crypto_bignum_deinit(sae.tmp->sae_rand, 1);
402 	sae.tmp->sae_rand = crypto_bignum_init_set(local_rand,
403 						   sizeof(local_rand));
404 	mask = crypto_bignum_init_set(local_mask, sizeof(local_mask));
405 	if (!sae.tmp->sae_rand || !mask)
406 		goto fail;
407 
408 	if (crypto_bignum_add(sae.tmp->sae_rand, mask,
409 			      sae.tmp->own_commit_scalar) < 0 ||
410 	    crypto_bignum_mod(sae.tmp->own_commit_scalar, sae.tmp->order,
411 			      sae.tmp->own_commit_scalar) < 0 ||
412 	    crypto_ec_point_mul(sae.tmp->ec, sae.tmp->pwe_ecc, mask,
413 				sae.tmp->own_commit_element_ecc) < 0 ||
414 	    crypto_ec_point_invert(sae.tmp->ec,
415 				   sae.tmp->own_commit_element_ecc) < 0)
416 		goto fail;
417 
418 	/* Check that output matches the test vector */
419 	if (sae_write_commit(&sae, buf, NULL, NULL) < 0)
420 		goto fail;
421 	wpa_hexdump_buf(MSG_DEBUG, "SAE: Commit message", buf);
422 
423 	if (wpabuf_len(buf) != sizeof(local_commit) ||
424 	    os_memcmp(wpabuf_head(buf), local_commit,
425 		      sizeof(local_commit)) != 0) {
426 		wpa_printf(MSG_ERROR, "SAE: Mismatch in local commit");
427 		goto fail;
428 	}
429 
430 	if (sae_parse_commit(&sae, peer_commit, sizeof(peer_commit), NULL, NULL,
431 			     NULL, 0) != 0 ||
432 	    sae_process_commit(&sae) < 0)
433 		goto fail;
434 
435 	if (os_memcmp(kck, sae.tmp->kck, SAE_KCK_LEN) != 0) {
436 		wpa_printf(MSG_ERROR, "SAE: Mismatch in KCK");
437 		goto fail;
438 	}
439 
440 	if (os_memcmp(pmk, sae.pmk, SAE_PMK_LEN) != 0) {
441 		wpa_printf(MSG_ERROR, "SAE: Mismatch in PMK");
442 		goto fail;
443 	}
444 
445 	if (os_memcmp(pmkid, sae.pmkid, SAE_PMKID_LEN) != 0) {
446 		wpa_printf(MSG_ERROR, "SAE: Mismatch in PMKID");
447 		goto fail;
448 	}
449 
450 	pt_info = sae_derive_pt(pt_groups,
451 				(const u8 *) ssid, os_strlen(ssid),
452 				(const u8 *) pw, os_strlen(pw), pwid);
453 	if (!pt_info)
454 		goto fail;
455 
456 	for (pt = pt_info; pt; pt = pt->next) {
457 		if (pt->group == 19) {
458 			struct crypto_ec_point *pwe;
459 			u8 bin[SAE_MAX_ECC_PRIME_LEN * 2];
460 			size_t prime_len = sizeof(pwe_19_x);
461 
462 			pwe = sae_derive_pwe_from_pt_ecc(pt, addr1b, addr2b);
463 			if (!pwe) {
464 				sae_deinit_pt(pt);
465 				goto fail;
466 			}
467 			if (crypto_ec_point_to_bin(pt->ec, pwe, bin,
468 						   bin + prime_len) < 0 ||
469 			    os_memcmp(pwe_19_x, bin, prime_len) != 0 ||
470 			    os_memcmp(pwe_19_y, bin + prime_len,
471 				      prime_len) != 0) {
472 				wpa_printf(MSG_ERROR,
473 					   "SAE: PT/PWE test vector mismatch");
474 				crypto_ec_point_deinit(pwe, 1);
475 				sae_deinit_pt(pt);
476 				goto fail;
477 			}
478 			crypto_ec_point_deinit(pwe, 1);
479 		}
480 
481 		if (pt->group == 15) {
482 			struct crypto_bignum *pwe;
483 			u8 bin[SAE_MAX_PRIME_LEN];
484 			size_t prime_len = sizeof(pwe_15);
485 
486 			pwe = sae_derive_pwe_from_pt_ffc(pt, addr1b, addr2b);
487 			if (!pwe) {
488 				sae_deinit_pt(pt);
489 				goto fail;
490 			}
491 			if (crypto_bignum_to_bin(pwe, bin, sizeof(bin),
492 						 prime_len) < 0 ||
493 			    os_memcmp(pwe_15, bin, prime_len) != 0) {
494 				wpa_printf(MSG_ERROR,
495 					   "SAE: PT/PWE test vector mismatch");
496 				crypto_bignum_deinit(pwe, 1);
497 				sae_deinit_pt(pt);
498 				goto fail;
499 			}
500 			crypto_bignum_deinit(pwe, 1);
501 		}
502 	}
503 
504 	sae_deinit_pt(pt_info);
505 
506 	ret = 0;
507 fail:
508 	sae_clear_data(&sae);
509 	wpabuf_free(buf);
510 	crypto_bignum_deinit(mask, 1);
511 	return ret;
512 #else /* CONFIG_SAE */
513 	return 0;
514 #endif /* CONFIG_SAE */
515 }
516 
517 
518 static int sae_pk_tests(void)
519 {
520 #ifdef CONFIG_SAE_PK
521 	const char *invalid[] = { "a2bc-de3f-ghim-", "a2bcde3fghim", "", NULL };
522 	struct {
523 		const char *pw;
524 		const u8 *val;
525 	} valid[] = {
526 		{ "a2bc-de3f-ghim", (u8 *) "\x06\x82\x21\x93\x65\x31\xd0\xc0" },
527 		{ "aaaa-aaaa-aaaj", (u8 *) "\x00\x00\x00\x00\x00\x00\x00\x90" },
528 		{ "7777-7777-777f", (u8 *) "\xff\xff\xff\xff\xff\xff\xfe\x50" },
529 		{ NULL, NULL }
530 	};
531 	int i;
532 	bool failed;
533 
534 	for (i = 0; invalid[i]; i++) {
535 		if (sae_pk_valid_password(invalid[i])) {
536 			wpa_printf(MSG_ERROR,
537 				   "SAE-PK: Invalid password '%s' not recognized",
538 				   invalid[i]);
539 			return -1;
540 		}
541 	}
542 
543 	failed = false;
544 	for (i = 0; valid[i].pw; i++) {
545 		u8 *res;
546 		size_t res_len;
547 		char *b32;
548 		const char *pw = valid[i].pw;
549 		const u8 *val = valid[i].val;
550 		size_t pw_len = os_strlen(pw);
551 		size_t bits = (pw_len - pw_len / 5) * 5;
552 		size_t bytes = (bits + 7) / 8;
553 
554 		if (!sae_pk_valid_password(pw)) {
555 			wpa_printf(MSG_ERROR,
556 				   "SAE-PK: Valid password '%s' not recognized",
557 				   pw);
558 			failed = true;
559 			continue;
560 		}
561 
562 		res = sae_pk_base32_decode(pw, pw_len, &res_len);
563 		if (!res) {
564 			wpa_printf(MSG_ERROR,
565 				   "SAE-PK: Failed to decode password '%s'",
566 				   valid[i].pw);
567 			failed = true;
568 			continue;
569 		}
570 		if (res_len != bytes || os_memcmp(val, res, res_len) != 0) {
571 			wpa_printf(MSG_ERROR,
572 				   "SAE-PK: Mismatch for decoded password '%s'",
573 				   valid[i].pw);
574 			wpa_hexdump(MSG_INFO, "SAE-PK: Decoded value",
575 				    res, res_len);
576 			wpa_hexdump(MSG_INFO, "SAE-PK: Expected value",
577 				    val, bytes);
578 			failed = true;
579 		}
580 		os_free(res);
581 
582 		b32 = sae_pk_base32_encode(val, bits - 5);
583 		if (!b32) {
584 			wpa_printf(MSG_ERROR,
585 				   "SAE-PK: Failed to encode password '%s'",
586 				   pw);
587 			failed = true;
588 			continue;
589 		}
590 		if (os_strcmp(b32, pw) != 0) {
591 			wpa_printf(MSG_ERROR,
592 				   "SAE-PK: Mismatch for password '%s'", pw);
593 			wpa_printf(MSG_INFO, "SAE-PK: Encoded value: '%s'",
594 				   b32);
595 			failed = true;
596 		}
597 		os_free(b32);
598 	}
599 
600 	return failed ? -1 : 0;
601 #else /* CONFIG_SAE_PK */
602 	return 0;
603 #endif /* CONFIG_SAE_PK */
604 }
605 
606 
607 #ifdef CONFIG_PASN
608 
609 static int pasn_test_pasn_auth(void)
610 {
611 	/* Test vector taken from IEEE P802.11az/D2.6, J.12 */
612 	const u8 pmk[] = {
613 		0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
614 		0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
615 		0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
616 		0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
617 	};
618 
619 	const u8 spa_addr[] = {
620 		0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
621 	};
622 	const u8 bssid[] = {
623 		0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
624 	};
625 	const u8 dhss[] = {
626 		0xf8, 0x7b, 0x20, 0x8e, 0x7e, 0xd2, 0xb7, 0x37,
627 		0xaf, 0xdb, 0xc2, 0xe1, 0x3e, 0xae, 0x78, 0xda,
628 		0x30, 0x01, 0x23, 0xd4, 0xd8, 0x4b, 0xa8, 0xb0,
629 		0xea, 0xfe, 0x90, 0xc4, 0x8c, 0xdf, 0x1f, 0x93
630 	};
631 	const u8 kck[] = {
632 		0x7b, 0xb8, 0x21, 0xac, 0x0a, 0xa5, 0x90, 0x9d,
633 		0xd6, 0x54, 0xa5, 0x60, 0x65, 0xad, 0x7c, 0x77,
634 		0xeb, 0x88, 0x9c, 0xbe, 0x29, 0x05, 0xbb, 0xf0,
635 		0x5a, 0xbb, 0x1e, 0xea, 0xc8, 0x8b, 0xa3, 0x06
636 	};
637 	const u8 tk[] = {
638 		0x67, 0x3e, 0xab, 0x46, 0xb8, 0x32, 0xd5, 0xa8,
639 		0x0c, 0xbc, 0x02, 0x43, 0x01, 0x6e, 0x20, 0x7e
640 	};
641 	const u8 kdk[] = {
642 		0x2d, 0x0f, 0x0e, 0x82, 0xc7, 0x0d, 0xd2, 0x6b,
643 		0x79, 0x06, 0x1a, 0x46, 0x81, 0xe8, 0xdb, 0xb2,
644 		0xea, 0x83, 0xbe, 0xa3, 0x99, 0x84, 0x4b, 0xd5,
645 		0x89, 0x4e, 0xb3, 0x20, 0xf6, 0x9d, 0x7d, 0xd6
646 	};
647 	struct wpa_ptk ptk;
648 	int ret;
649 
650 	ret = pasn_pmk_to_ptk(pmk, sizeof(pmk),
651 			      spa_addr, bssid,
652 			      dhss, sizeof(dhss),
653 			      &ptk, WPA_KEY_MGMT_PASN, WPA_CIPHER_CCMP,
654 			      WPA_KDK_MAX_LEN);
655 
656 	if (ret)
657 		return ret;
658 
659 	if (ptk.kck_len != sizeof(kck) ||
660 	    os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
661 		wpa_printf(MSG_ERROR, "PASN: Mismatched KCK");
662 		return -1;
663 	}
664 
665 	if (ptk.tk_len != sizeof(tk) ||
666 	    os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
667 		wpa_printf(MSG_ERROR, "PASN: Mismatched TK");
668 		return -1;
669 	}
670 
671 	if (ptk.kdk_len != sizeof(kdk) ||
672 	    os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
673 		wpa_printf(MSG_ERROR, "PASN: Mismatched KDK");
674 		return -1;
675 	}
676 
677 	return 0;
678 }
679 
680 
681 static int pasn_test_no_pasn_auth(void)
682 {
683 	/* Test vector taken from IEEE P802.11az/D2.6, J.13 */
684 	const u8 pmk[] = {
685 		0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
686 		0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
687 		0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
688 		0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
689 	};
690 	const u8 aa[] = {
691 		0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
692 	};
693 	const u8 spa[] = {
694 		0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
695 	};
696 	const u8 anonce[] = {
697 		0xbe, 0x7a, 0x1c, 0xa2, 0x84, 0x34, 0x7b, 0x5b,
698 		0xd6, 0x7d, 0xbd, 0x2d, 0xfd, 0xb4, 0xd9, 0x9f,
699 		0x1a, 0xfa, 0xe0, 0xb8, 0x8b, 0xa1, 0x8e, 0x00,
700 		0x87, 0x18, 0x41, 0x7e, 0x4b, 0x27, 0xef, 0x5f
701 	};
702 	const u8 snonce[] = {
703 		0x40, 0x4b, 0x01, 0x2f, 0xfb, 0x43, 0xed, 0x0f,
704 		0xb4, 0x3e, 0xa1, 0xf2, 0x87, 0xc9, 0x1f, 0x25,
705 		0x06, 0xd2, 0x1b, 0x4a, 0x92, 0xd7, 0x4b, 0x5e,
706 		0xa5, 0x0c, 0x94, 0x33, 0x50, 0xce, 0x86, 0x71
707 	};
708 	const u8 kck[] = {
709 		0xcd, 0x7b, 0x9e, 0x75, 0x55, 0x36, 0x2d, 0xf0,
710 		0xb6, 0x35, 0x68, 0x48, 0x4a, 0x81, 0x12, 0xf5
711 	};
712 	const u8 kek[] = {
713 		0x99, 0xca, 0xd3, 0x58, 0x8d, 0xa0, 0xf1, 0xe6,
714 		0x3f, 0xd1, 0x90, 0x19, 0x10, 0x39, 0xbb, 0x4b
715 	};
716 	const u8 tk[] = {
717 		0x9e, 0x2e, 0x93, 0x77, 0xe7, 0x53, 0x2e, 0x73,
718 		0x7a, 0x1b, 0xc2, 0x50, 0xfe, 0x19, 0x4a, 0x03
719 	};
720 	const u8 kdk[] = {
721 		0x6c, 0x7f, 0xb9, 0x7c, 0xeb, 0x55, 0xb0, 0x1a,
722 		0xcf, 0xf0, 0x0f, 0x07, 0x09, 0x42, 0xbd, 0xf5,
723 		0x29, 0x1f, 0xeb, 0x4b, 0xee, 0x38, 0xe0, 0x36,
724 		0x5b, 0x25, 0xa2, 0x50, 0xbb, 0x2a, 0xc9, 0xff
725 	};
726 	struct wpa_ptk ptk;
727 	int ret;
728 
729 	ret = wpa_pmk_to_ptk(pmk, sizeof(pmk),
730 			     "Pairwise key expansion",
731 			     spa, aa, snonce, anonce,
732 			     &ptk, WPA_KEY_MGMT_SAE, WPA_CIPHER_CCMP,
733 			     NULL, 0, WPA_KDK_MAX_LEN);
734 
735 	if (ret)
736 		return ret;
737 
738 	if (ptk.kck_len != sizeof(kck) ||
739 	    os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
740 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KCK");
741 		return -1;
742 	}
743 
744 	if (ptk.kek_len != sizeof(kek) ||
745 	    os_memcmp(kek, ptk.kek, sizeof(kek)) != 0) {
746 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KEK");
747 		return -1;
748 	}
749 
750 	if (ptk.tk_len != sizeof(tk) ||
751 	    os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
752 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched TK");
753 		return -1;
754 	}
755 
756 	if (ptk.kdk_len != sizeof(kdk) ||
757 	    os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
758 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KDK");
759 		return -1;
760 	}
761 
762 	return 0;
763 }
764 
765 #endif /* CONFIG_PASN */
766 
767 
768 static int pasn_tests(void)
769 {
770 #ifdef CONFIG_PASN
771 	if (pasn_test_pasn_auth() ||
772 	    pasn_test_no_pasn_auth())
773 		return -1;
774 #endif /* CONFIG_PASN */
775 	return 0;
776 }
777 
778 
779 int common_module_tests(void)
780 {
781 	int ret = 0;
782 
783 	wpa_printf(MSG_INFO, "common module tests");
784 
785 	if (ieee802_11_parse_tests() < 0 ||
786 	    gas_tests() < 0 ||
787 	    sae_tests() < 0 ||
788 	    sae_pk_tests() < 0 ||
789 	    pasn_tests() < 0 ||
790 	    rsn_ie_parse_tests() < 0)
791 		ret = -1;
792 
793 	return ret;
794 }
795