• Home
  • History
  • Annotate
  • 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 P802.11-REVmd/D2.1, Annex J.10 */
260 	const u8 addr1[ETH_ALEN] = { 0x82, 0x7b, 0x91, 0x9d, 0xd4, 0xb9 };
261 	const u8 addr2[ETH_ALEN] = { 0x1e, 0xec, 0x49, 0xea, 0x64, 0x88 };
262 	const char *ssid = "byteme";
263 	const char *pw = "mekmitasdigoat";
264 	const char *pwid = "psk4internet";
265 	const u8 local_rand[] = {
266 		0xa9, 0x06, 0xf6, 0x1e, 0x4d, 0x3a, 0x5d, 0x4e,
267 		0xb2, 0x96, 0x5f, 0xf3, 0x4c, 0xf9, 0x17, 0xdd,
268 		0x04, 0x44, 0x45, 0xc8, 0x78, 0xc1, 0x7c, 0xa5,
269 		0xd5, 0xb9, 0x37, 0x86, 0xda, 0x9f, 0x83, 0xcf
270 	};
271 	const u8 local_mask[] = {
272 		0x42, 0x34, 0xb4, 0xfb, 0x17, 0xaa, 0x43, 0x5c,
273 		0x52, 0xfb, 0xfd, 0xeb, 0xe6, 0x40, 0x39, 0xb4,
274 		0x34, 0x78, 0x20, 0x0e, 0x54, 0xff, 0x7b, 0x6e,
275 		0x07, 0xb6, 0x9c, 0xad, 0x74, 0x15, 0x3c, 0x15
276 	};
277 	const u8 local_commit[] = {
278 		0x13, 0x00, 0xeb, 0x3b, 0xab, 0x19, 0x64, 0xe4,
279 		0xa0, 0xab, 0x05, 0x92, 0x5d, 0xdf, 0x33, 0x39,
280 		0x51, 0x91, 0x38, 0xbc, 0x65, 0xd6, 0xcd, 0xc0,
281 		0xf8, 0x13, 0xdd, 0x6f, 0xd4, 0x34, 0x4e, 0xb4,
282 		0xbf, 0xe4, 0x4b, 0x5c, 0x21, 0x59, 0x76, 0x58,
283 		0xf4, 0xe3, 0xed, 0xdf, 0xb4, 0xb9, 0x9f, 0x25,
284 		0xb4, 0xd6, 0x54, 0x0f, 0x32, 0xff, 0x1f, 0xd5,
285 		0xc5, 0x30, 0xc6, 0x0a, 0x79, 0x44, 0x48, 0x61,
286 		0x0b, 0xc6, 0xde, 0x3d, 0x92, 0xbd, 0xbb, 0xd4,
287 		0x7d, 0x93, 0x59, 0x80, 0xca, 0x6c, 0xf8, 0x98,
288 		0x8a, 0xb6, 0x63, 0x0b, 0xe6, 0x76, 0x4c, 0x88,
289 		0x5c, 0xeb, 0x97, 0x93, 0x97, 0x0f, 0x69, 0x52,
290 		0x17, 0xee, 0xff, 0x0d, 0x21, 0x70, 0x73, 0x6b,
291 		0x34, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
292 		0x74
293 	};
294 	const u8 peer_commit[] = {
295 		0x13, 0x00, 0x55, 0x64, 0xf0, 0x45, 0xb2, 0xea,
296 		0x1e, 0x56, 0x6c, 0xf1, 0xdd, 0x74, 0x1f, 0x70,
297 		0xd9, 0xbe, 0x35, 0xd2, 0xdf, 0x5b, 0x9a, 0x55,
298 		0x02, 0x94, 0x6e, 0xe0, 0x3c, 0xf8, 0xda, 0xe2,
299 		0x7e, 0x1e, 0x05, 0xb8, 0x43, 0x0e, 0xb7, 0xa9,
300 		0x9e, 0x24, 0x87, 0x7c, 0xe6, 0x9b, 0xaf, 0x3d,
301 		0xc5, 0x80, 0xe3, 0x09, 0x63, 0x3d, 0x6b, 0x38,
302 		0x5f, 0x83, 0xee, 0x1c, 0x3e, 0xc3, 0x59, 0x1f,
303 		0x1a, 0x53, 0x93, 0xc0, 0x6e, 0x80, 0x5d, 0xdc,
304 		0xeb, 0x2f, 0xde, 0x50, 0x93, 0x0d, 0xd7, 0xcf,
305 		0xeb, 0xb9, 0x87, 0xc6, 0xff, 0x96, 0x66, 0xaf,
306 		0x16, 0x4e, 0xb5, 0x18, 0x4d, 0x8e, 0x66, 0x62,
307 		0xed, 0x6a, 0xff, 0x0d, 0x21, 0x70, 0x73, 0x6b,
308 		0x34, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
309 		0x74
310 	};
311 	const u8 kck[] = {
312 		0x59, 0x9d, 0x6f, 0x1e, 0x27, 0x54, 0x8b, 0xe8,
313 		0x49, 0x9d, 0xce, 0xed, 0x2f, 0xec, 0xcf, 0x94,
314 		0x81, 0x8c, 0xe1, 0xc7, 0x9f, 0x1b, 0x4e, 0xb3,
315 		0xd6, 0xa5, 0x32, 0x28, 0xa0, 0x9b, 0xf3, 0xed
316 	};
317 	const u8 pmk[] = {
318 		0x7a, 0xea, 0xd8, 0x6f, 0xba, 0x4c, 0x32, 0x21,
319 		0xfc, 0x43, 0x7f, 0x5f, 0x14, 0xd7, 0x0d, 0x85,
320 		0x4e, 0xa5, 0xd5, 0xaa, 0xc1, 0x69, 0x01, 0x16,
321 		0x79, 0x30, 0x81, 0xed, 0xa4, 0xd5, 0x57, 0xc5
322 	};
323 	const u8 pmkid[] = {
324 		0x40, 0xa0, 0x9b, 0x60, 0x17, 0xce, 0xbf, 0x00,
325 		0x72, 0x84, 0x3b, 0x53, 0x52, 0xaa, 0x2b, 0x4f
326 	};
327 	const u8 local_confirm[] = {
328 		0x01, 0x00, 0x12, 0xd9, 0xd5, 0xc7, 0x8c, 0x50,
329 		0x05, 0x26, 0xd3, 0x6c, 0x41, 0xdb, 0xc5, 0x6a,
330 		0xed, 0xf2, 0x91, 0x4c, 0xed, 0xdd, 0xd7, 0xca,
331 		0xd4, 0xa5, 0x8c, 0x48, 0xf8, 0x3d, 0xbd, 0xe9,
332 		0xfc, 0x77
333 	};
334 	const u8 peer_confirm[] = {
335 		0x01, 0x00, 0x02, 0x87, 0x1c, 0xf9, 0x06, 0x89,
336 		0x8b, 0x80, 0x60, 0xec, 0x18, 0x41, 0x43, 0xbe,
337 		0x77, 0xb8, 0xc0, 0x8a, 0x80, 0x19, 0xb1, 0x3e,
338 		0xb6, 0xd0, 0xae, 0xf0, 0xd8, 0x38, 0x3d, 0xfa,
339 		0xc2, 0xfd
340 	};
341 	struct wpabuf *buf = NULL;
342 	struct crypto_bignum *mask = NULL;
343 	const u8 pwe_19_x[32] = {
344 		0xc9, 0x30, 0x49, 0xb9, 0xe6, 0x40, 0x00, 0xf8,
345 		0x48, 0x20, 0x16, 0x49, 0xe9, 0x99, 0xf2, 0xb5,
346 		0xc2, 0x2d, 0xea, 0x69, 0xb5, 0x63, 0x2c, 0x9d,
347 		0xf4, 0xd6, 0x33, 0xb8, 0xaa, 0x1f, 0x6c, 0x1e
348 	};
349 	const u8 pwe_19_y[32] = {
350 		0x73, 0x63, 0x4e, 0x94, 0xb5, 0x3d, 0x82, 0xe7,
351 		0x38, 0x3a, 0x8d, 0x25, 0x81, 0x99, 0xd9, 0xdc,
352 		0x1a, 0x5e, 0xe8, 0x26, 0x9d, 0x06, 0x03, 0x82,
353 		0xcc, 0xbf, 0x33, 0xe6, 0x14, 0xff, 0x59, 0xa0
354 	};
355 	const u8 pwe_15[384] = {
356 		0x69, 0x68, 0x73, 0x65, 0x8f, 0x65, 0x31, 0x42,
357 		0x9f, 0x97, 0x39, 0x6f, 0xb8, 0x5f, 0x89, 0xe1,
358 		0xfc, 0xd2, 0xf6, 0x92, 0x19, 0xa9, 0x0e, 0x82,
359 		0x2f, 0xf7, 0xf4, 0xbc, 0x0b, 0xd8, 0xa7, 0x9f,
360 		0xf0, 0x80, 0x35, 0x31, 0x6f, 0xca, 0xe1, 0xa5,
361 		0x39, 0x77, 0xdc, 0x11, 0x2b, 0x0b, 0xfe, 0x2e,
362 		0x6f, 0x65, 0x6d, 0xc7, 0xd4, 0xa4, 0x5b, 0x08,
363 		0x1f, 0xd9, 0xbb, 0xe2, 0x22, 0x85, 0x31, 0x81,
364 		0x79, 0x70, 0xbe, 0xa1, 0x66, 0x58, 0x4a, 0x09,
365 		0x3c, 0x57, 0x34, 0x3c, 0x9d, 0x57, 0x8f, 0x42,
366 		0x58, 0xd0, 0x39, 0x81, 0xdb, 0x8f, 0x79, 0xa2,
367 		0x1b, 0x01, 0xcd, 0x27, 0xc9, 0xae, 0xcf, 0xcb,
368 		0x9c, 0xdb, 0x1f, 0x84, 0xb8, 0x88, 0x4e, 0x8f,
369 		0x50, 0x66, 0xb4, 0x29, 0x83, 0x1e, 0xb9, 0x89,
370 		0x0c, 0xa5, 0x47, 0x21, 0xba, 0x10, 0xd5, 0xaa,
371 		0x1a, 0x80, 0xce, 0xf1, 0x4c, 0xad, 0x16, 0xda,
372 		0x57, 0xb2, 0x41, 0x8a, 0xbe, 0x4b, 0x8c, 0xb0,
373 		0xb2, 0xeb, 0xf7, 0xa8, 0x0e, 0x3e, 0xcf, 0x22,
374 		0x8f, 0xd8, 0xb6, 0xdb, 0x79, 0x9c, 0x9b, 0x80,
375 		0xaf, 0xd7, 0x14, 0xad, 0x51, 0x82, 0xf4, 0x64,
376 		0xb6, 0x3f, 0x4c, 0x6c, 0xe5, 0x3f, 0xaa, 0x6f,
377 		0xbf, 0x3d, 0xc2, 0x3f, 0x77, 0xfd, 0xcb, 0xe1,
378 		0x9c, 0xe3, 0x1e, 0x8a, 0x0e, 0x97, 0xe2, 0x2b,
379 		0xe2, 0xdd, 0x37, 0x39, 0x88, 0xc2, 0x8e, 0xbe,
380 		0xfa, 0xac, 0x3d, 0x5b, 0x62, 0x2e, 0x1e, 0x74,
381 		0xa0, 0x9a, 0xf8, 0xed, 0xfa, 0xe1, 0xce, 0x9c,
382 		0xab, 0xbb, 0xdc, 0x36, 0xb1, 0x28, 0x46, 0x3c,
383 		0x7e, 0xa8, 0xbd, 0xb9, 0x36, 0x4c, 0x26, 0x75,
384 		0xe0, 0x17, 0x73, 0x1f, 0xe0, 0xfe, 0xf6, 0x49,
385 		0xfa, 0xa0, 0x45, 0xf4, 0x44, 0x05, 0x20, 0x27,
386 		0x25, 0xc2, 0x99, 0xde, 0x27, 0x8b, 0x70, 0xdc,
387 		0x54, 0x60, 0x90, 0x02, 0x1e, 0x29, 0x97, 0x9a,
388 		0xc4, 0xe7, 0xb6, 0xf5, 0x8b, 0xae, 0x7c, 0x34,
389 		0xaa, 0xef, 0x9b, 0xc6, 0x30, 0xf2, 0x80, 0x8d,
390 		0x80, 0x78, 0xc2, 0x55, 0x63, 0xa0, 0xa1, 0x38,
391 		0x70, 0xfb, 0xf4, 0x74, 0x8d, 0xcd, 0x87, 0x90,
392 		0xb4, 0x54, 0xc3, 0x75, 0xdf, 0x10, 0xc5, 0xb6,
393 		0xb2, 0x08, 0x59, 0x61, 0xe6, 0x68, 0xa5, 0x82,
394 		0xf8, 0x8f, 0x47, 0x30, 0x43, 0xb4, 0xdc, 0x31,
395 		0xfc, 0xbc, 0x69, 0xe7, 0xb4, 0x94, 0xb0, 0x6a,
396 		0x60, 0x59, 0x80, 0x2e, 0xd3, 0xa4, 0xe8, 0x97,
397 		0xa2, 0xa3, 0xc9, 0x08, 0x4b, 0x27, 0x6c, 0xc1,
398 		0x37, 0xe8, 0xfc, 0x5c, 0xe2, 0x54, 0x30, 0x3e,
399 		0xf8, 0xfe, 0xa2, 0xfc, 0xbb, 0xbd, 0x88, 0x6c,
400 		0x92, 0xa3, 0x2a, 0x40, 0x7a, 0x2c, 0x22, 0x38,
401 		0x8c, 0x86, 0x86, 0xfe, 0xb9, 0xd4, 0x6b, 0xd6,
402 		0x47, 0x88, 0xa7, 0xf6, 0x8e, 0x0f, 0x14, 0xad,
403 		0x1e, 0xac, 0xcf, 0x33, 0x01, 0x99, 0xc1, 0x62
404 	};
405 	int pt_groups[] = { 19, 20, 21, 25, 26, 28, 29, 30, 15, 0 };
406 	struct sae_pt *pt_info, *pt;
407 	const u8 addr1b[ETH_ALEN] = { 0x00, 0x09, 0x5b, 0x66, 0xec, 0x1e };
408 	const u8 addr2b[ETH_ALEN] = { 0x00, 0x0b, 0x6b, 0xd9, 0x02, 0x46 };
409 
410 	os_memset(&sae, 0, sizeof(sae));
411 	buf = wpabuf_alloc(1000);
412 	if (!buf ||
413 	    sae_set_group(&sae, 19) < 0 ||
414 	    sae_prepare_commit(addr1, addr2, (const u8 *) pw, os_strlen(pw),
415 			       pwid, &sae) < 0)
416 		goto fail;
417 
418 	/* Override local values based on SAE test vector */
419 	crypto_bignum_deinit(sae.tmp->sae_rand, 1);
420 	sae.tmp->sae_rand = crypto_bignum_init_set(local_rand,
421 						   sizeof(local_rand));
422 	mask = crypto_bignum_init_set(local_mask, sizeof(local_mask));
423 	if (!sae.tmp->sae_rand || !mask)
424 		goto fail;
425 
426 	if (crypto_bignum_add(sae.tmp->sae_rand, mask,
427 			      sae.tmp->own_commit_scalar) < 0 ||
428 	    crypto_bignum_mod(sae.tmp->own_commit_scalar, sae.tmp->order,
429 			      sae.tmp->own_commit_scalar) < 0 ||
430 	    crypto_ec_point_mul(sae.tmp->ec, sae.tmp->pwe_ecc, mask,
431 				sae.tmp->own_commit_element_ecc) < 0 ||
432 	    crypto_ec_point_invert(sae.tmp->ec,
433 				   sae.tmp->own_commit_element_ecc) < 0)
434 		goto fail;
435 
436 	/* Check that output matches the test vector */
437 	if (sae_write_commit(&sae, buf, NULL, pwid) < 0)
438 		goto fail;
439 	wpa_hexdump_buf(MSG_DEBUG, "SAE: Commit message", buf);
440 
441 	if (wpabuf_len(buf) != sizeof(local_commit) ||
442 	    os_memcmp(wpabuf_head(buf), local_commit,
443 		      sizeof(local_commit)) != 0) {
444 		wpa_printf(MSG_ERROR, "SAE: Mismatch in local commit");
445 		goto fail;
446 	}
447 
448 	if (sae_parse_commit(&sae, peer_commit, sizeof(peer_commit), NULL, NULL,
449 			     NULL, 0) != 0 ||
450 	    sae_process_commit(&sae) < 0)
451 		goto fail;
452 
453 	if (os_memcmp(kck, sae.tmp->kck, SAE_KCK_LEN) != 0) {
454 		wpa_printf(MSG_ERROR, "SAE: Mismatch in KCK");
455 		goto fail;
456 	}
457 
458 	if (os_memcmp(pmk, sae.pmk, SAE_PMK_LEN) != 0) {
459 		wpa_printf(MSG_ERROR, "SAE: Mismatch in PMK");
460 		goto fail;
461 	}
462 
463 	if (os_memcmp(pmkid, sae.pmkid, SAE_PMKID_LEN) != 0) {
464 		wpa_printf(MSG_ERROR, "SAE: Mismatch in PMKID");
465 		goto fail;
466 	}
467 
468 	buf->used = 0;
469 	sae.send_confirm = 1;
470 	sae_write_confirm(&sae, buf);
471 	wpa_hexdump_buf(MSG_DEBUG, "SAE: Confirm message", buf);
472 
473 	if (wpabuf_len(buf) != sizeof(local_confirm) ||
474 	    os_memcmp(wpabuf_head(buf), local_confirm,
475 		      sizeof(local_confirm)) != 0) {
476 		wpa_printf(MSG_ERROR, "SAE: Mismatch in local confirm");
477 		goto fail;
478 	}
479 
480 	if (sae_check_confirm(&sae, peer_confirm, sizeof(peer_confirm)) < 0)
481 		goto fail;
482 
483 	pt_info = sae_derive_pt(pt_groups,
484 				(const u8 *) ssid, os_strlen(ssid),
485 				(const u8 *) pw, os_strlen(pw), pwid);
486 	if (!pt_info)
487 		goto fail;
488 
489 	for (pt = pt_info; pt; pt = pt->next) {
490 		if (pt->group == 19) {
491 			struct crypto_ec_point *pwe;
492 			u8 bin[SAE_MAX_ECC_PRIME_LEN * 2];
493 			size_t prime_len = sizeof(pwe_19_x);
494 
495 			pwe = sae_derive_pwe_from_pt_ecc(pt, addr1b, addr2b);
496 			if (!pwe) {
497 				sae_deinit_pt(pt);
498 				goto fail;
499 			}
500 			if (crypto_ec_point_to_bin(pt->ec, pwe, bin,
501 						   bin + prime_len) < 0 ||
502 			    os_memcmp(pwe_19_x, bin, prime_len) != 0 ||
503 			    os_memcmp(pwe_19_y, bin + prime_len,
504 				      prime_len) != 0) {
505 				wpa_printf(MSG_ERROR,
506 					   "SAE: PT/PWE test vector mismatch");
507 				crypto_ec_point_deinit(pwe, 1);
508 				sae_deinit_pt(pt);
509 				goto fail;
510 			}
511 			crypto_ec_point_deinit(pwe, 1);
512 		}
513 
514 		if (pt->group == 15) {
515 			struct crypto_bignum *pwe;
516 			u8 bin[SAE_MAX_PRIME_LEN];
517 			size_t prime_len = sizeof(pwe_15);
518 
519 			pwe = sae_derive_pwe_from_pt_ffc(pt, addr1b, addr2b);
520 			if (!pwe) {
521 				sae_deinit_pt(pt);
522 				goto fail;
523 			}
524 			if (crypto_bignum_to_bin(pwe, bin, sizeof(bin),
525 						 prime_len) < 0 ||
526 			    os_memcmp(pwe_15, bin, prime_len) != 0) {
527 				wpa_printf(MSG_ERROR,
528 					   "SAE: PT/PWE test vector mismatch");
529 				crypto_bignum_deinit(pwe, 1);
530 				sae_deinit_pt(pt);
531 				goto fail;
532 			}
533 			crypto_bignum_deinit(pwe, 1);
534 		}
535 	}
536 
537 	sae_deinit_pt(pt_info);
538 
539 	ret = 0;
540 fail:
541 	sae_clear_data(&sae);
542 	wpabuf_free(buf);
543 	crypto_bignum_deinit(mask, 1);
544 	return ret;
545 #else /* CONFIG_SAE */
546 	return 0;
547 #endif /* CONFIG_SAE */
548 }
549 
550 
sae_pk_tests(void)551 static int sae_pk_tests(void)
552 {
553 #ifdef CONFIG_SAE_PK
554 	const char *invalid[] = { "a2bc-de3f-ghim-", "a2bcde3fghim", "", NULL };
555 	struct {
556 		const char *pw;
557 		const u8 *val;
558 	} valid[] = {
559 		{ "a2bc-de3f-ghim", (u8 *) "\x06\x82\x21\x93\x65\x31\xd0\xc0" },
560 		{ "aaaa-aaaa-aaaj", (u8 *) "\x00\x00\x00\x00\x00\x00\x00\x90" },
561 		{ "7777-7777-777f", (u8 *) "\xff\xff\xff\xff\xff\xff\xfe\x50" },
562 		{ NULL, NULL }
563 	};
564 	int i;
565 	bool failed;
566 
567 	for (i = 0; invalid[i]; i++) {
568 		if (sae_pk_valid_password(invalid[i])) {
569 			wpa_printf(MSG_ERROR,
570 				   "SAE-PK: Invalid password '%s' not recognized",
571 				   invalid[i]);
572 			return -1;
573 		}
574 	}
575 
576 	failed = false;
577 	for (i = 0; valid[i].pw; i++) {
578 		u8 *res;
579 		size_t res_len;
580 		char *b32;
581 		const char *pw = valid[i].pw;
582 		const u8 *val = valid[i].val;
583 		size_t pw_len = os_strlen(pw);
584 		size_t bits = (pw_len - pw_len / 5) * 5;
585 		size_t bytes = (bits + 7) / 8;
586 
587 		if (!sae_pk_valid_password(pw)) {
588 			wpa_printf(MSG_ERROR,
589 				   "SAE-PK: Valid password '%s' not recognized",
590 				   pw);
591 			failed = true;
592 			continue;
593 		}
594 
595 		res = sae_pk_base32_decode(pw, pw_len, &res_len);
596 		if (!res) {
597 			wpa_printf(MSG_ERROR,
598 				   "SAE-PK: Failed to decode password '%s'",
599 				   valid[i].pw);
600 			failed = true;
601 			continue;
602 		}
603 		if (res_len != bytes || os_memcmp(val, res, res_len) != 0) {
604 			wpa_printf(MSG_ERROR,
605 				   "SAE-PK: Mismatch for decoded password '%s'",
606 				   valid[i].pw);
607 			wpa_hexdump(MSG_INFO, "SAE-PK: Decoded value",
608 				    res, res_len);
609 			wpa_hexdump(MSG_INFO, "SAE-PK: Expected value",
610 				    val, bytes);
611 			failed = true;
612 		}
613 		os_free(res);
614 
615 		b32 = sae_pk_base32_encode(val, bits - 5);
616 		if (!b32) {
617 			wpa_printf(MSG_ERROR,
618 				   "SAE-PK: Failed to encode password '%s'",
619 				   pw);
620 			failed = true;
621 			continue;
622 		}
623 		if (os_strcmp(b32, pw) != 0) {
624 			wpa_printf(MSG_ERROR,
625 				   "SAE-PK: Mismatch for password '%s'", pw);
626 			wpa_printf(MSG_INFO, "SAE-PK: Encoded value: '%s'",
627 				   b32);
628 			failed = true;
629 		}
630 		os_free(b32);
631 	}
632 
633 	return failed ? -1 : 0;
634 #else /* CONFIG_SAE_PK */
635 	return 0;
636 #endif /* CONFIG_SAE_PK */
637 }
638 
639 
640 #ifdef CONFIG_PASN
641 
pasn_test_pasn_auth(void)642 static int pasn_test_pasn_auth(void)
643 {
644 	/* Test vector taken from IEEE P802.11az/D2.6, J.12 */
645 	const u8 pmk[] = {
646 		0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
647 		0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
648 		0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
649 		0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
650 	};
651 
652 	const u8 spa_addr[] = {
653 		0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
654 	};
655 	const u8 bssid[] = {
656 		0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
657 	};
658 	const u8 dhss[] = {
659 		0xf8, 0x7b, 0x20, 0x8e, 0x7e, 0xd2, 0xb7, 0x37,
660 		0xaf, 0xdb, 0xc2, 0xe1, 0x3e, 0xae, 0x78, 0xda,
661 		0x30, 0x01, 0x23, 0xd4, 0xd8, 0x4b, 0xa8, 0xb0,
662 		0xea, 0xfe, 0x90, 0xc4, 0x8c, 0xdf, 0x1f, 0x93
663 	};
664 	const u8 kck[] = {
665 		0x7b, 0xb8, 0x21, 0xac, 0x0a, 0xa5, 0x90, 0x9d,
666 		0xd6, 0x54, 0xa5, 0x60, 0x65, 0xad, 0x7c, 0x77,
667 		0xeb, 0x88, 0x9c, 0xbe, 0x29, 0x05, 0xbb, 0xf0,
668 		0x5a, 0xbb, 0x1e, 0xea, 0xc8, 0x8b, 0xa3, 0x06
669 	};
670 	const u8 tk[] = {
671 		0x67, 0x3e, 0xab, 0x46, 0xb8, 0x32, 0xd5, 0xa8,
672 		0x0c, 0xbc, 0x02, 0x43, 0x01, 0x6e, 0x20, 0x7e
673 	};
674 	const u8 kdk[] = {
675 		0x2d, 0x0f, 0x0e, 0x82, 0xc7, 0x0d, 0xd2, 0x6b,
676 		0x79, 0x06, 0x1a, 0x46, 0x81, 0xe8, 0xdb, 0xb2,
677 		0xea, 0x83, 0xbe, 0xa3, 0x99, 0x84, 0x4b, 0xd5,
678 		0x89, 0x4e, 0xb3, 0x20, 0xf6, 0x9d, 0x7d, 0xd6
679 	};
680 	struct wpa_ptk ptk;
681 	int ret;
682 
683 	ret = pasn_pmk_to_ptk(pmk, sizeof(pmk),
684 			      spa_addr, bssid,
685 			      dhss, sizeof(dhss),
686 			      &ptk, WPA_KEY_MGMT_PASN, WPA_CIPHER_CCMP,
687 			      WPA_KDK_MAX_LEN);
688 
689 	if (ret)
690 		return ret;
691 
692 	if (ptk.kck_len != sizeof(kck) ||
693 	    os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
694 		wpa_printf(MSG_ERROR, "PASN: Mismatched KCK");
695 		return -1;
696 	}
697 
698 	if (ptk.tk_len != sizeof(tk) ||
699 	    os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
700 		wpa_printf(MSG_ERROR, "PASN: Mismatched TK");
701 		return -1;
702 	}
703 
704 	if (ptk.kdk_len != sizeof(kdk) ||
705 	    os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
706 		wpa_printf(MSG_ERROR, "PASN: Mismatched KDK");
707 		return -1;
708 	}
709 
710 	return 0;
711 }
712 
713 
pasn_test_no_pasn_auth(void)714 static int pasn_test_no_pasn_auth(void)
715 {
716 	/* Test vector taken from IEEE P802.11az/D2.6, J.13 */
717 	const u8 pmk[] = {
718 		0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
719 		0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
720 		0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
721 		0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
722 	};
723 	const u8 aa[] = {
724 		0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
725 	};
726 	const u8 spa[] = {
727 		0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
728 	};
729 	const u8 anonce[] = {
730 		0xbe, 0x7a, 0x1c, 0xa2, 0x84, 0x34, 0x7b, 0x5b,
731 		0xd6, 0x7d, 0xbd, 0x2d, 0xfd, 0xb4, 0xd9, 0x9f,
732 		0x1a, 0xfa, 0xe0, 0xb8, 0x8b, 0xa1, 0x8e, 0x00,
733 		0x87, 0x18, 0x41, 0x7e, 0x4b, 0x27, 0xef, 0x5f
734 	};
735 	const u8 snonce[] = {
736 		0x40, 0x4b, 0x01, 0x2f, 0xfb, 0x43, 0xed, 0x0f,
737 		0xb4, 0x3e, 0xa1, 0xf2, 0x87, 0xc9, 0x1f, 0x25,
738 		0x06, 0xd2, 0x1b, 0x4a, 0x92, 0xd7, 0x4b, 0x5e,
739 		0xa5, 0x0c, 0x94, 0x33, 0x50, 0xce, 0x86, 0x71
740 	};
741 	const u8 kck[] = {
742 		0xcd, 0x7b, 0x9e, 0x75, 0x55, 0x36, 0x2d, 0xf0,
743 		0xb6, 0x35, 0x68, 0x48, 0x4a, 0x81, 0x12, 0xf5
744 	};
745 	const u8 kek[] = {
746 		0x99, 0xca, 0xd3, 0x58, 0x8d, 0xa0, 0xf1, 0xe6,
747 		0x3f, 0xd1, 0x90, 0x19, 0x10, 0x39, 0xbb, 0x4b
748 	};
749 	const u8 tk[] = {
750 		0x9e, 0x2e, 0x93, 0x77, 0xe7, 0x53, 0x2e, 0x73,
751 		0x7a, 0x1b, 0xc2, 0x50, 0xfe, 0x19, 0x4a, 0x03
752 	};
753 	const u8 kdk[] = {
754 		0x6c, 0x7f, 0xb9, 0x7c, 0xeb, 0x55, 0xb0, 0x1a,
755 		0xcf, 0xf0, 0x0f, 0x07, 0x09, 0x42, 0xbd, 0xf5,
756 		0x29, 0x1f, 0xeb, 0x4b, 0xee, 0x38, 0xe0, 0x36,
757 		0x5b, 0x25, 0xa2, 0x50, 0xbb, 0x2a, 0xc9, 0xff
758 	};
759 	struct wpa_ptk ptk;
760 	int ret;
761 
762 	ret = wpa_pmk_to_ptk(pmk, sizeof(pmk),
763 			     "Pairwise key expansion",
764 			     spa, aa, snonce, anonce,
765 			     &ptk, WPA_KEY_MGMT_SAE, WPA_CIPHER_CCMP,
766 			     NULL, 0, WPA_KDK_MAX_LEN);
767 
768 	if (ret)
769 		return ret;
770 
771 	if (ptk.kck_len != sizeof(kck) ||
772 	    os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
773 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KCK");
774 		return -1;
775 	}
776 
777 	if (ptk.kek_len != sizeof(kek) ||
778 	    os_memcmp(kek, ptk.kek, sizeof(kek)) != 0) {
779 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KEK");
780 		return -1;
781 	}
782 
783 	if (ptk.tk_len != sizeof(tk) ||
784 	    os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
785 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched TK");
786 		return -1;
787 	}
788 
789 	if (ptk.kdk_len != sizeof(kdk) ||
790 	    os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
791 		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KDK");
792 		return -1;
793 	}
794 
795 	return 0;
796 }
797 
798 #endif /* CONFIG_PASN */
799 
800 
pasn_tests(void)801 static int pasn_tests(void)
802 {
803 #ifdef CONFIG_PASN
804 	if (pasn_test_pasn_auth() ||
805 	    pasn_test_no_pasn_auth())
806 		return -1;
807 #endif /* CONFIG_PASN */
808 	return 0;
809 }
810 
811 
common_module_tests(void)812 int common_module_tests(void)
813 {
814 	int ret = 0;
815 
816 	wpa_printf(MSG_INFO, "common module tests");
817 
818 	if (ieee802_11_parse_tests() < 0 ||
819 	    gas_tests() < 0 ||
820 	    sae_tests() < 0 ||
821 	    sae_pk_tests() < 0 ||
822 	    pasn_tests() < 0 ||
823 	    rsn_ie_parse_tests() < 0)
824 		ret = -1;
825 
826 	return ret;
827 }
828