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, NULL) != 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  
sae_pk_tests(void)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  
pasn_test_pasn_auth(void)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, 0);
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  
pasn_test_no_pasn_auth(void)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  
pasn_tests(void)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  
common_module_tests(void)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