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