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