• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ieee802_11_parse_tests(void)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 
rsn_ie_parse_tests(void)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 
gas_tests(void)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 
sae_tests(void)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
432 #ifdef CONFIG_MLD_PATCH
433                  , NULL
434 #endif
435 		) != 0 ||
436 	    sae_process_commit(&sae) < 0)
437 		goto fail;
438 
439 	if (os_memcmp(kck, sae.tmp->kck, SAE_KCK_LEN) != 0) {
440 		wpa_printf(MSG_ERROR, "SAE: Mismatch in KCK");
441 		goto fail;
442 	}
443 
444 	if (os_memcmp(pmk, sae.pmk, SAE_PMK_LEN) != 0) {
445 		wpa_printf(MSG_ERROR, "SAE: Mismatch in PMK");
446 		goto fail;
447 	}
448 
449 	if (os_memcmp(pmkid, sae.pmkid, SAE_PMKID_LEN) != 0) {
450 		wpa_printf(MSG_ERROR, "SAE: Mismatch in PMKID");
451 		goto fail;
452 	}
453 
454 	pt_info = sae_derive_pt(pt_groups,
455 				(const u8 *) ssid, os_strlen(ssid),
456 				(const u8 *) pw, os_strlen(pw), pwid);
457 	if (!pt_info)
458 		goto fail;
459 
460 	for (pt = pt_info; pt; pt = pt->next) {
461 		if (pt->group == 19) {
462 			struct crypto_ec_point *pwe;
463 			u8 bin[SAE_MAX_ECC_PRIME_LEN * 2];
464 			size_t prime_len = sizeof(pwe_19_x);
465 
466 			pwe = sae_derive_pwe_from_pt_ecc(pt, addr1b, addr2b);
467 			if (!pwe) {
468 				sae_deinit_pt(pt);
469 				goto fail;
470 			}
471 			if (crypto_ec_point_to_bin(pt->ec, pwe, bin,
472 						   bin + prime_len) < 0 ||
473 			    os_memcmp(pwe_19_x, bin, prime_len) != 0 ||
474 			    os_memcmp(pwe_19_y, bin + prime_len,
475 				      prime_len) != 0) {
476 				wpa_printf(MSG_ERROR,
477 					   "SAE: PT/PWE test vector mismatch");
478 				crypto_ec_point_deinit(pwe, 1);
479 				sae_deinit_pt(pt);
480 				goto fail;
481 			}
482 			crypto_ec_point_deinit(pwe, 1);
483 		}
484 
485 		if (pt->group == 15) {
486 			struct crypto_bignum *pwe;
487 			u8 bin[SAE_MAX_PRIME_LEN];
488 			size_t prime_len = sizeof(pwe_15);
489 
490 			pwe = sae_derive_pwe_from_pt_ffc(pt, addr1b, addr2b);
491 			if (!pwe) {
492 				sae_deinit_pt(pt);
493 				goto fail;
494 			}
495 			if (crypto_bignum_to_bin(pwe, bin, sizeof(bin),
496 						 prime_len) < 0 ||
497 			    os_memcmp(pwe_15, bin, prime_len) != 0) {
498 				wpa_printf(MSG_ERROR,
499 					   "SAE: PT/PWE test vector mismatch");
500 				crypto_bignum_deinit(pwe, 1);
501 				sae_deinit_pt(pt);
502 				goto fail;
503 			}
504 			crypto_bignum_deinit(pwe, 1);
505 		}
506 	}
507 
508 	sae_deinit_pt(pt_info);
509 
510 	ret = 0;
511 fail:
512 	sae_clear_data(&sae);
513 	wpabuf_free(buf);
514 	crypto_bignum_deinit(mask, 1);
515 	return ret;
516 #else /* CONFIG_SAE */
517 	return 0;
518 #endif /* CONFIG_SAE */
519 }
520 
521 
sae_pk_tests(void)522 static int sae_pk_tests(void)
523 {
524 #ifdef CONFIG_SAE_PK
525 	const char *invalid[] = { "a2bc-de3f-ghim-", "a2bcde3fghim", "", NULL };
526 	struct {
527 		const char *pw;
528 		const u8 *val;
529 	} valid[] = {
530 		{ "a2bc-de3f-ghim", (u8 *) "\x06\x82\x21\x93\x65\x31\xd0\xc0" },
531 		{ "aaaa-aaaa-aaaj", (u8 *) "\x00\x00\x00\x00\x00\x00\x00\x90" },
532 		{ "7777-7777-777f", (u8 *) "\xff\xff\xff\xff\xff\xff\xfe\x50" },
533 		{ NULL, NULL }
534 	};
535 	int i;
536 	bool failed;
537 
538 	for (i = 0; invalid[i]; i++) {
539 		if (sae_pk_valid_password(invalid[i])) {
540 			wpa_printf(MSG_ERROR,
541 				   "SAE-PK: Invalid password '%s' not recognized",
542 				   invalid[i]);
543 			return -1;
544 		}
545 	}
546 
547 	failed = false;
548 	for (i = 0; valid[i].pw; i++) {
549 		u8 *res;
550 		size_t res_len;
551 		char *b32;
552 		const char *pw = valid[i].pw;
553 		const u8 *val = valid[i].val;
554 		size_t pw_len = os_strlen(pw);
555 		size_t bits = (pw_len - pw_len / 5) * 5;
556 		size_t bytes = (bits + 7) / 8;
557 
558 		if (!sae_pk_valid_password(pw)) {
559 			wpa_printf(MSG_ERROR,
560 				   "SAE-PK: Valid password '%s' not recognized",
561 				   pw);
562 			failed = true;
563 			continue;
564 		}
565 
566 		res = sae_pk_base32_decode(pw, pw_len, &res_len);
567 		if (!res) {
568 			wpa_printf(MSG_ERROR,
569 				   "SAE-PK: Failed to decode password '%s'",
570 				   valid[i].pw);
571 			failed = true;
572 			continue;
573 		}
574 		if (res_len != bytes || os_memcmp(val, res, res_len) != 0) {
575 			wpa_printf(MSG_ERROR,
576 				   "SAE-PK: Mismatch for decoded password '%s'",
577 				   valid[i].pw);
578 			wpa_hexdump(MSG_INFO, "SAE-PK: Decoded value",
579 				    res, res_len);
580 			wpa_hexdump(MSG_INFO, "SAE-PK: Expected value",
581 				    val, bytes);
582 			failed = true;
583 		}
584 		os_free(res);
585 
586 		b32 = sae_pk_base32_encode(val, bits - 5);
587 		if (!b32) {
588 			wpa_printf(MSG_ERROR,
589 				   "SAE-PK: Failed to encode password '%s'",
590 				   pw);
591 			failed = true;
592 			continue;
593 		}
594 		if (os_strcmp(b32, pw) != 0) {
595 			wpa_printf(MSG_ERROR,
596 				   "SAE-PK: Mismatch for password '%s'", pw);
597 			wpa_printf(MSG_INFO, "SAE-PK: Encoded value: '%s'",
598 				   b32);
599 			failed = true;
600 		}
601 		os_free(b32);
602 	}
603 
604 	return failed ? -1 : 0;
605 #else /* CONFIG_SAE_PK */
606 	return 0;
607 #endif /* CONFIG_SAE_PK */
608 }
609 
610 
611 #ifdef CONFIG_PASN
612 
pasn_test_pasn_auth(void)613 static int pasn_test_pasn_auth(void)
614 {
615 	/* Test vector taken from IEEE P802.11az/D2.6, J.12 */
616 	const u8 pmk[] = {
617 		0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
618 		0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
619 		0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
620 		0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
621 	};
622 
623 	const u8 spa_addr[] = {
624 		0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
625 	};
626 	const u8 bssid[] = {
627 		0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
628 	};
629 	const u8 dhss[] = {
630 		0xf8, 0x7b, 0x20, 0x8e, 0x7e, 0xd2, 0xb7, 0x37,
631 		0xaf, 0xdb, 0xc2, 0xe1, 0x3e, 0xae, 0x78, 0xda,
632 		0x30, 0x01, 0x23, 0xd4, 0xd8, 0x4b, 0xa8, 0xb0,
633 		0xea, 0xfe, 0x90, 0xc4, 0x8c, 0xdf, 0x1f, 0x93
634 	};
635 	const u8 kck[] = {
636 		0x7b, 0xb8, 0x21, 0xac, 0x0a, 0xa5, 0x90, 0x9d,
637 		0xd6, 0x54, 0xa5, 0x60, 0x65, 0xad, 0x7c, 0x77,
638 		0xeb, 0x88, 0x9c, 0xbe, 0x29, 0x05, 0xbb, 0xf0,
639 		0x5a, 0xbb, 0x1e, 0xea, 0xc8, 0x8b, 0xa3, 0x06
640 	};
641 	const u8 tk[] = {
642 		0x67, 0x3e, 0xab, 0x46, 0xb8, 0x32, 0xd5, 0xa8,
643 		0x0c, 0xbc, 0x02, 0x43, 0x01, 0x6e, 0x20, 0x7e
644 	};
645 	const u8 kdk[] = {
646 		0x2d, 0x0f, 0x0e, 0x82, 0xc7, 0x0d, 0xd2, 0x6b,
647 		0x79, 0x06, 0x1a, 0x46, 0x81, 0xe8, 0xdb, 0xb2,
648 		0xea, 0x83, 0xbe, 0xa3, 0x99, 0x84, 0x4b, 0xd5,
649 		0x89, 0x4e, 0xb3, 0x20, 0xf6, 0x9d, 0x7d, 0xd6
650 	};
651 	struct wpa_ptk ptk;
652 	int ret;
653 
654 	ret = pasn_pmk_to_ptk(pmk, sizeof(pmk),
655 			      spa_addr, bssid,
656 			      dhss, sizeof(dhss),
657 			      &ptk, WPA_KEY_MGMT_PASN, WPA_CIPHER_CCMP,
658 			      WPA_KDK_MAX_LEN);
659 
660 	if (ret)
661 		return ret;
662 
663 	if (ptk.kck_len != sizeof(kck) ||
664 	    os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
665 		wpa_printf(MSG_ERROR, "PASN: Mismatched KCK");
666 		return -1;
667 	}
668 
669 	if (ptk.tk_len != sizeof(tk) ||
670 	    os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
671 		wpa_printf(MSG_ERROR, "PASN: Mismatched TK");
672 		return -1;
673 	}
674 
675 	if (ptk.kdk_len != sizeof(kdk) ||
676 	    os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
677 		wpa_printf(MSG_ERROR, "PASN: Mismatched KDK");
678 		return -1;
679 	}
680 
681 	return 0;
682 }
683 
684 
pasn_test_no_pasn_auth(void)685 static int pasn_test_no_pasn_auth(void)
686 {
687 	/* Test vector taken from IEEE P802.11az/D2.6, J.13 */
688 	const u8 pmk[] = {
689 		0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
690 		0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
691 		0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
692 		0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
693 	};
694 	const u8 aa[] = {
695 		0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
696 	};
697 	const u8 spa[] = {
698 		0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
699 	};
700 	const u8 anonce[] = {
701 		0xbe, 0x7a, 0x1c, 0xa2, 0x84, 0x34, 0x7b, 0x5b,
702 		0xd6, 0x7d, 0xbd, 0x2d, 0xfd, 0xb4, 0xd9, 0x9f,
703 		0x1a, 0xfa, 0xe0, 0xb8, 0x8b, 0xa1, 0x8e, 0x00,
704 		0x87, 0x18, 0x41, 0x7e, 0x4b, 0x27, 0xef, 0x5f
705 	};
706 	const u8 snonce[] = {
707 		0x40, 0x4b, 0x01, 0x2f, 0xfb, 0x43, 0xed, 0x0f,
708 		0xb4, 0x3e, 0xa1, 0xf2, 0x87, 0xc9, 0x1f, 0x25,
709 		0x06, 0xd2, 0x1b, 0x4a, 0x92, 0xd7, 0x4b, 0x5e,
710 		0xa5, 0x0c, 0x94, 0x33, 0x50, 0xce, 0x86, 0x71
711 	};
712 	const u8 kck[] = {
713 		0xcd, 0x7b, 0x9e, 0x75, 0x55, 0x36, 0x2d, 0xf0,
714 		0xb6, 0x35, 0x68, 0x48, 0x4a, 0x81, 0x12, 0xf5
715 	};
716 	const u8 kek[] = {
717 		0x99, 0xca, 0xd3, 0x58, 0x8d, 0xa0, 0xf1, 0xe6,
718 		0x3f, 0xd1, 0x90, 0x19, 0x10, 0x39, 0xbb, 0x4b
719 	};
720 	const u8 tk[] = {
721 		0x9e, 0x2e, 0x93, 0x77, 0xe7, 0x53, 0x2e, 0x73,
722 		0x7a, 0x1b, 0xc2, 0x50, 0xfe, 0x19, 0x4a, 0x03
723 	};
724 	const u8 kdk[] = {
725 		0x6c, 0x7f, 0xb9, 0x7c, 0xeb, 0x55, 0xb0, 0x1a,
726 		0xcf, 0xf0, 0x0f, 0x07, 0x09, 0x42, 0xbd, 0xf5,
727 		0x29, 0x1f, 0xeb, 0x4b, 0xee, 0x38, 0xe0, 0x36,
728 		0x5b, 0x25, 0xa2, 0x50, 0xbb, 0x2a, 0xc9, 0xff
729 	};
730 	struct wpa_ptk ptk;
731 	int ret;
732 
733 	ret = wpa_pmk_to_ptk(pmk, sizeof(pmk),
734 			     "Pairwise key expansion",
735 			     spa, aa, snonce, anonce,
736 			     &ptk, WPA_KEY_MGMT_SAE, WPA_CIPHER_CCMP,
737 			     NULL, 0, WPA_KDK_MAX_LEN);
738 
739 	if (ret)
740 		return ret;
741 
742 	if (ptk.kck_len != sizeof(kck) ||
743 	    os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
744 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KCK");
745 		return -1;
746 	}
747 
748 	if (ptk.kek_len != sizeof(kek) ||
749 	    os_memcmp(kek, ptk.kek, sizeof(kek)) != 0) {
750 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KEK");
751 		return -1;
752 	}
753 
754 	if (ptk.tk_len != sizeof(tk) ||
755 	    os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
756 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched TK");
757 		return -1;
758 	}
759 
760 	if (ptk.kdk_len != sizeof(kdk) ||
761 	    os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
762 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KDK");
763 		return -1;
764 	}
765 
766 	return 0;
767 }
768 
769 #endif /* CONFIG_PASN */
770 
771 
pasn_tests(void)772 static int pasn_tests(void)
773 {
774 #ifdef CONFIG_PASN
775 	if (pasn_test_pasn_auth() ||
776 	    pasn_test_no_pasn_auth())
777 		return -1;
778 #endif /* CONFIG_PASN */
779 	return 0;
780 }
781 
782 
common_module_tests(void)783 int common_module_tests(void)
784 {
785 	int ret = 0;
786 
787 	wpa_printf(MSG_INFO, "common module tests");
788 
789 	if (ieee802_11_parse_tests() < 0 ||
790 	    gas_tests() < 0 ||
791 	    sae_tests() < 0 ||
792 	    sae_pk_tests() < 0 ||
793 	    pasn_tests() < 0 ||
794 	    rsn_ie_parse_tests() < 0)
795 		ret = -1;
796 
797 	return ret;
798 }
799