Branch data Line data Source code
1 : : /*
2 : : * hostapd - WPA/RSN IE and KDE definitions
3 : : * Copyright (c) 2004-2008, 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 "common/ieee802_11_defs.h"
13 : : #include "eapol_auth/eapol_auth_sm.h"
14 : : #include "ap_config.h"
15 : : #include "ieee802_11.h"
16 : : #include "wpa_auth.h"
17 : : #include "pmksa_cache_auth.h"
18 : : #include "wpa_auth_ie.h"
19 : : #include "wpa_auth_i.h"
20 : :
21 : :
22 : : #ifdef CONFIG_RSN_TESTING
23 : : int rsn_testing = 0;
24 : : #endif /* CONFIG_RSN_TESTING */
25 : :
26 : :
27 : 18 : static int wpa_write_wpa_ie(struct wpa_auth_config *conf, u8 *buf, size_t len)
28 : : {
29 : : struct wpa_ie_hdr *hdr;
30 : : int num_suites;
31 : : u8 *pos, *count;
32 : : u32 suite;
33 : :
34 : 18 : hdr = (struct wpa_ie_hdr *) buf;
35 : 18 : hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC;
36 : 18 : RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE);
37 : 18 : WPA_PUT_LE16(hdr->version, WPA_VERSION);
38 : 18 : pos = (u8 *) (hdr + 1);
39 : :
40 : 18 : suite = wpa_cipher_to_suite(WPA_PROTO_WPA, conf->wpa_group);
41 [ - + ]: 18 : if (suite == 0) {
42 : 0 : wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",
43 : : conf->wpa_group);
44 : 0 : return -1;
45 : : }
46 : 18 : RSN_SELECTOR_PUT(pos, suite);
47 : 18 : pos += WPA_SELECTOR_LEN;
48 : :
49 : 18 : count = pos;
50 : 18 : pos += 2;
51 : :
52 : 18 : num_suites = wpa_cipher_put_suites(pos, conf->wpa_pairwise);
53 [ - + ]: 18 : if (num_suites == 0) {
54 : 0 : wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",
55 : : conf->wpa_pairwise);
56 : 0 : return -1;
57 : : }
58 : 18 : pos += num_suites * WPA_SELECTOR_LEN;
59 : 18 : WPA_PUT_LE16(count, num_suites);
60 : :
61 : 18 : num_suites = 0;
62 : 18 : count = pos;
63 : 18 : pos += 2;
64 : :
65 [ + + ]: 18 : if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
66 : 2 : RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
67 : 2 : pos += WPA_SELECTOR_LEN;
68 : 2 : num_suites++;
69 : : }
70 [ + + ]: 18 : if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
71 : 17 : RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
72 : 17 : pos += WPA_SELECTOR_LEN;
73 : 17 : num_suites++;
74 : : }
75 : :
76 [ - + ]: 18 : if (num_suites == 0) {
77 : 0 : wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
78 : : conf->wpa_key_mgmt);
79 : 0 : return -1;
80 : : }
81 : 18 : WPA_PUT_LE16(count, num_suites);
82 : :
83 : : /* WPA Capabilities; use defaults, so no need to include it */
84 : :
85 : 18 : hdr->len = (pos - buf) - 2;
86 : :
87 : 18 : return pos - buf;
88 : : }
89 : :
90 : :
91 : 380 : int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
92 : : const u8 *pmkid)
93 : : {
94 : : struct rsn_ie_hdr *hdr;
95 : : int num_suites, res;
96 : : u8 *pos, *count;
97 : : u16 capab;
98 : : u32 suite;
99 : :
100 : 380 : hdr = (struct rsn_ie_hdr *) buf;
101 : 380 : hdr->elem_id = WLAN_EID_RSN;
102 : 380 : WPA_PUT_LE16(hdr->version, RSN_VERSION);
103 : 380 : pos = (u8 *) (hdr + 1);
104 : :
105 : 380 : suite = wpa_cipher_to_suite(WPA_PROTO_RSN, conf->wpa_group);
106 [ - + ]: 380 : if (suite == 0) {
107 : 0 : wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",
108 : : conf->wpa_group);
109 : 0 : return -1;
110 : : }
111 : 380 : RSN_SELECTOR_PUT(pos, suite);
112 : 380 : pos += RSN_SELECTOR_LEN;
113 : :
114 : 380 : num_suites = 0;
115 : 380 : count = pos;
116 : 380 : pos += 2;
117 : :
118 : : #ifdef CONFIG_RSN_TESTING
119 : : if (rsn_testing) {
120 : : RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1));
121 : : pos += RSN_SELECTOR_LEN;
122 : : num_suites++;
123 : : }
124 : : #endif /* CONFIG_RSN_TESTING */
125 : :
126 : 380 : res = rsn_cipher_put_suites(pos, conf->rsn_pairwise);
127 : 380 : num_suites += res;
128 : 380 : pos += res * RSN_SELECTOR_LEN;
129 : :
130 : : #ifdef CONFIG_RSN_TESTING
131 : : if (rsn_testing) {
132 : : RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2));
133 : : pos += RSN_SELECTOR_LEN;
134 : : num_suites++;
135 : : }
136 : : #endif /* CONFIG_RSN_TESTING */
137 : :
138 [ - + ]: 380 : if (num_suites == 0) {
139 : 0 : wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",
140 : : conf->rsn_pairwise);
141 : 0 : return -1;
142 : : }
143 : 380 : WPA_PUT_LE16(count, num_suites);
144 : :
145 : 380 : num_suites = 0;
146 : 380 : count = pos;
147 : 380 : pos += 2;
148 : :
149 : : #ifdef CONFIG_RSN_TESTING
150 : : if (rsn_testing) {
151 : : RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1));
152 : : pos += RSN_SELECTOR_LEN;
153 : : num_suites++;
154 : : }
155 : : #endif /* CONFIG_RSN_TESTING */
156 : :
157 [ + + ]: 380 : if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
158 : 153 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X);
159 : 153 : pos += RSN_SELECTOR_LEN;
160 : 153 : num_suites++;
161 : : }
162 [ + + ]: 380 : if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
163 : 178 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X);
164 : 178 : pos += RSN_SELECTOR_LEN;
165 : 178 : num_suites++;
166 : : }
167 : : #ifdef CONFIG_IEEE80211R
168 [ + + ]: 380 : if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
169 : 6 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
170 : 6 : pos += RSN_SELECTOR_LEN;
171 : 6 : num_suites++;
172 : : }
173 [ + + ]: 380 : if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_PSK) {
174 : 30 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
175 : 30 : pos += RSN_SELECTOR_LEN;
176 : 30 : num_suites++;
177 : : }
178 : : #endif /* CONFIG_IEEE80211R */
179 : : #ifdef CONFIG_IEEE80211W
180 [ + + ]: 380 : if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
181 : 1 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
182 : 1 : pos += RSN_SELECTOR_LEN;
183 : 1 : num_suites++;
184 : : }
185 [ + + ]: 380 : if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
186 : 4 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
187 : 4 : pos += RSN_SELECTOR_LEN;
188 : 4 : num_suites++;
189 : : }
190 : : #endif /* CONFIG_IEEE80211W */
191 : : #ifdef CONFIG_SAE
192 [ + + ]: 380 : if (conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE) {
193 : 4 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
194 : 4 : pos += RSN_SELECTOR_LEN;
195 : 4 : num_suites++;
196 : : }
197 [ + + ]: 380 : if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) {
198 : 12 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
199 : 12 : pos += RSN_SELECTOR_LEN;
200 : 12 : num_suites++;
201 : : }
202 : : #endif /* CONFIG_SAE */
203 : :
204 : : #ifdef CONFIG_RSN_TESTING
205 : : if (rsn_testing) {
206 : : RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2));
207 : : pos += RSN_SELECTOR_LEN;
208 : : num_suites++;
209 : : }
210 : : #endif /* CONFIG_RSN_TESTING */
211 : :
212 [ - + ]: 380 : if (num_suites == 0) {
213 : 0 : wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
214 : : conf->wpa_key_mgmt);
215 : 0 : return -1;
216 : : }
217 : 380 : WPA_PUT_LE16(count, num_suites);
218 : :
219 : : /* RSN Capabilities */
220 : 380 : capab = 0;
221 [ - + ]: 380 : if (conf->rsn_preauth)
222 : 0 : capab |= WPA_CAPABILITY_PREAUTH;
223 [ + + ]: 380 : if (conf->peerkey)
224 : 1 : capab |= WPA_CAPABILITY_PEERKEY_ENABLED;
225 [ + + ]: 380 : if (conf->wmm_enabled) {
226 : : /* 4 PTKSA replay counters when using WMM */
227 : 378 : capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
228 : : }
229 : : #ifdef CONFIG_IEEE80211W
230 [ + + ]: 380 : if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
231 : 111 : capab |= WPA_CAPABILITY_MFPC;
232 [ + + ]: 111 : if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
233 : 16 : capab |= WPA_CAPABILITY_MFPR;
234 : : }
235 : : #endif /* CONFIG_IEEE80211W */
236 : : #ifdef CONFIG_RSN_TESTING
237 : : if (rsn_testing)
238 : : capab |= BIT(8) | BIT(14) | BIT(15);
239 : : #endif /* CONFIG_RSN_TESTING */
240 : 380 : WPA_PUT_LE16(pos, capab);
241 : 380 : pos += 2;
242 : :
243 [ + + ]: 380 : if (pmkid) {
244 [ - + ]: 32 : if (pos + 2 + PMKID_LEN > buf + len)
245 : 0 : return -1;
246 : : /* PMKID Count */
247 : 32 : WPA_PUT_LE16(pos, 1);
248 : 32 : pos += 2;
249 : 32 : os_memcpy(pos, pmkid, PMKID_LEN);
250 : 32 : pos += PMKID_LEN;
251 : : }
252 : :
253 : : #ifdef CONFIG_IEEE80211W
254 [ + + ]: 380 : if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
255 [ - + ]: 111 : if (pos + 2 + 4 > buf + len)
256 : 0 : return -1;
257 [ + + ]: 111 : if (pmkid == NULL) {
258 : : /* PMKID Count */
259 : 103 : WPA_PUT_LE16(pos, 0);
260 : 103 : pos += 2;
261 : : }
262 : :
263 : : /* Management Group Cipher Suite */
264 : 111 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
265 : 111 : pos += RSN_SELECTOR_LEN;
266 : : }
267 : : #endif /* CONFIG_IEEE80211W */
268 : :
269 : : #ifdef CONFIG_RSN_TESTING
270 : : if (rsn_testing) {
271 : : /*
272 : : * Fill in any defined fields and add extra data to the end of
273 : : * the element.
274 : : */
275 : : int pmkid_count_set = pmkid != NULL;
276 : : if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION)
277 : : pmkid_count_set = 1;
278 : : /* PMKID Count */
279 : : WPA_PUT_LE16(pos, 0);
280 : : pos += 2;
281 : : if (conf->ieee80211w == NO_MGMT_FRAME_PROTECTION) {
282 : : /* Management Group Cipher Suite */
283 : : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
284 : : pos += RSN_SELECTOR_LEN;
285 : : }
286 : :
287 : : os_memset(pos, 0x12, 17);
288 : : pos += 17;
289 : : }
290 : : #endif /* CONFIG_RSN_TESTING */
291 : :
292 : 380 : hdr->len = (pos - buf) - 2;
293 : :
294 : 380 : return pos - buf;
295 : : }
296 : :
297 : :
298 : 1 : static u8 * wpa_write_osen(struct wpa_auth_config *conf, u8 *eid)
299 : : {
300 : : u8 *len;
301 : : u16 capab;
302 : :
303 : 1 : *eid++ = WLAN_EID_VENDOR_SPECIFIC;
304 : 1 : len = eid++; /* to be filled */
305 : 1 : WPA_PUT_BE24(eid, OUI_WFA);
306 : 1 : eid += 3;
307 : 1 : *eid++ = HS20_OSEN_OUI_TYPE;
308 : :
309 : : /* Group Data Cipher Suite */
310 : 1 : RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
311 : 1 : eid += RSN_SELECTOR_LEN;
312 : :
313 : : /* Pairwise Cipher Suite Count and List */
314 : 1 : WPA_PUT_LE16(eid, 1);
315 : 1 : eid += 2;
316 : 1 : RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_CCMP);
317 : 1 : eid += RSN_SELECTOR_LEN;
318 : :
319 : : /* AKM Suite Count and List */
320 : 1 : WPA_PUT_LE16(eid, 1);
321 : 1 : eid += 2;
322 : 1 : RSN_SELECTOR_PUT(eid, RSN_AUTH_KEY_MGMT_OSEN);
323 : 1 : eid += RSN_SELECTOR_LEN;
324 : :
325 : : /* RSN Capabilities */
326 : 1 : capab = 0;
327 [ + - ]: 1 : if (conf->wmm_enabled) {
328 : : /* 4 PTKSA replay counters when using WMM */
329 : 1 : capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
330 : : }
331 : : #ifdef CONFIG_IEEE80211W
332 [ + - ]: 1 : if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
333 : 1 : capab |= WPA_CAPABILITY_MFPC;
334 [ - + ]: 1 : if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
335 : 0 : capab |= WPA_CAPABILITY_MFPR;
336 : : }
337 : : #endif /* CONFIG_IEEE80211W */
338 : 1 : WPA_PUT_LE16(eid, capab);
339 : 1 : eid += 2;
340 : :
341 : 1 : *len = eid - len - 1;
342 : :
343 : 1 : return eid;
344 : : }
345 : :
346 : :
347 : 352 : int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
348 : : {
349 : : u8 *pos, buf[128];
350 : : int res;
351 : :
352 : 352 : pos = buf;
353 : :
354 [ + + ]: 352 : if (wpa_auth->conf.wpa == WPA_PROTO_OSEN) {
355 : 1 : pos = wpa_write_osen(&wpa_auth->conf, pos);
356 : : }
357 [ + + ]: 352 : if (wpa_auth->conf.wpa & WPA_PROTO_RSN) {
358 : 348 : res = wpa_write_rsn_ie(&wpa_auth->conf,
359 : 348 : pos, buf + sizeof(buf) - pos, NULL);
360 [ - + ]: 348 : if (res < 0)
361 : 0 : return res;
362 : 348 : pos += res;
363 : : }
364 : : #ifdef CONFIG_IEEE80211R
365 [ + + ]: 352 : if (wpa_key_mgmt_ft(wpa_auth->conf.wpa_key_mgmt)) {
366 : 16 : res = wpa_write_mdie(&wpa_auth->conf, pos,
367 : 16 : buf + sizeof(buf) - pos);
368 [ - + ]: 16 : if (res < 0)
369 : 0 : return res;
370 : 16 : pos += res;
371 : : }
372 : : #endif /* CONFIG_IEEE80211R */
373 [ + + ]: 352 : if (wpa_auth->conf.wpa & WPA_PROTO_WPA) {
374 : 18 : res = wpa_write_wpa_ie(&wpa_auth->conf,
375 : 18 : pos, buf + sizeof(buf) - pos);
376 [ - + ]: 18 : if (res < 0)
377 : 0 : return res;
378 : 18 : pos += res;
379 : : }
380 : :
381 : 352 : os_free(wpa_auth->wpa_ie);
382 : 352 : wpa_auth->wpa_ie = os_malloc(pos - buf);
383 [ - + ]: 352 : if (wpa_auth->wpa_ie == NULL)
384 : 0 : return -1;
385 : 352 : os_memcpy(wpa_auth->wpa_ie, buf, pos - buf);
386 : 352 : wpa_auth->wpa_ie_len = pos - buf;
387 : :
388 : 352 : return 0;
389 : : }
390 : :
391 : :
392 : 472 : u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len,
393 : : const u8 *data2, size_t data2_len)
394 : : {
395 : 472 : *pos++ = WLAN_EID_VENDOR_SPECIFIC;
396 : 472 : *pos++ = RSN_SELECTOR_LEN + data_len + data2_len;
397 : 472 : RSN_SELECTOR_PUT(pos, kde);
398 : 472 : pos += RSN_SELECTOR_LEN;
399 : 472 : os_memcpy(pos, data, data_len);
400 : 472 : pos += data_len;
401 [ + + ]: 472 : if (data2) {
402 : 399 : os_memcpy(pos, data2, data2_len);
403 : 399 : pos += data2_len;
404 : : }
405 : 472 : return pos;
406 : : }
407 : :
408 : :
409 : : struct wpa_auth_okc_iter_data {
410 : : struct rsn_pmksa_cache_entry *pmksa;
411 : : const u8 *aa;
412 : : const u8 *spa;
413 : : const u8 *pmkid;
414 : : };
415 : :
416 : :
417 : 1 : static int wpa_auth_okc_iter(struct wpa_authenticator *a, void *ctx)
418 : : {
419 : 1 : struct wpa_auth_okc_iter_data *data = ctx;
420 : 1 : data->pmksa = pmksa_cache_get_okc(a->pmksa, data->aa, data->spa,
421 : : data->pmkid);
422 [ + - ]: 1 : if (data->pmksa)
423 : 1 : return 1;
424 : 1 : return 0;
425 : : }
426 : :
427 : :
428 : 428 : int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
429 : : struct wpa_state_machine *sm,
430 : : const u8 *wpa_ie, size_t wpa_ie_len,
431 : : const u8 *mdie, size_t mdie_len)
432 : : {
433 : : struct wpa_ie_data data;
434 : : int ciphers, key_mgmt, res, version;
435 : : u32 selector;
436 : : size_t i;
437 : 428 : const u8 *pmkid = NULL;
438 : :
439 [ + - ][ - + ]: 428 : if (wpa_auth == NULL || sm == NULL)
440 : 0 : return WPA_NOT_ENABLED;
441 : :
442 [ + - ][ - + ]: 428 : if (wpa_ie == NULL || wpa_ie_len < 1)
443 : 0 : return WPA_INVALID_IE;
444 : :
445 [ + + ]: 428 : if (wpa_ie[0] == WLAN_EID_RSN)
446 : 421 : version = WPA_PROTO_RSN;
447 : : else
448 : 7 : version = WPA_PROTO_WPA;
449 : :
450 [ - + ]: 428 : if (!(wpa_auth->conf.wpa & version)) {
451 : 0 : wpa_printf(MSG_DEBUG, "Invalid WPA proto (%d) from " MACSTR,
452 : 0 : version, MAC2STR(sm->addr));
453 : 0 : return WPA_INVALID_PROTO;
454 : : }
455 : :
456 [ + + ]: 428 : if (version == WPA_PROTO_RSN) {
457 : 421 : res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data);
458 : :
459 : 421 : selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
460 : : if (0) {
461 : : }
462 : : #ifdef CONFIG_IEEE80211R
463 [ + + ]: 421 : else if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
464 : 3 : selector = RSN_AUTH_KEY_MGMT_FT_802_1X;
465 [ + + ]: 418 : else if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK)
466 : 15 : selector = RSN_AUTH_KEY_MGMT_FT_PSK;
467 : : #endif /* CONFIG_IEEE80211R */
468 : : #ifdef CONFIG_IEEE80211W
469 [ + + ]: 403 : else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
470 : 2 : selector = RSN_AUTH_KEY_MGMT_802_1X_SHA256;
471 [ + + ]: 401 : else if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
472 : 6 : selector = RSN_AUTH_KEY_MGMT_PSK_SHA256;
473 : : #endif /* CONFIG_IEEE80211W */
474 : : #ifdef CONFIG_SAE
475 [ + + ]: 395 : else if (data.key_mgmt & WPA_KEY_MGMT_SAE)
476 : 14 : selector = RSN_AUTH_KEY_MGMT_SAE;
477 [ + + ]: 381 : else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE)
478 : 6 : selector = RSN_AUTH_KEY_MGMT_FT_SAE;
479 : : #endif /* CONFIG_SAE */
480 [ + + ]: 375 : else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
481 : 177 : selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
482 [ + - ]: 198 : else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
483 : 198 : selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
484 : 421 : wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector;
485 : :
486 : 421 : selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
487 : : data.pairwise_cipher);
488 [ - + ]: 421 : if (!selector)
489 : 0 : selector = RSN_CIPHER_SUITE_CCMP;
490 : 421 : wpa_auth->dot11RSNAPairwiseCipherSelected = selector;
491 : :
492 : 421 : selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
493 : : data.group_cipher);
494 [ - + ]: 421 : if (!selector)
495 : 0 : selector = RSN_CIPHER_SUITE_CCMP;
496 : 421 : wpa_auth->dot11RSNAGroupCipherSelected = selector;
497 : : } else {
498 : 7 : res = wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, &data);
499 : :
500 : 7 : selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
501 [ + + ]: 7 : if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
502 : 1 : selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
503 [ + - ]: 6 : else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
504 : 6 : selector = WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X;
505 : 7 : wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector;
506 : :
507 : 7 : selector = wpa_cipher_to_suite(WPA_PROTO_WPA,
508 : : data.pairwise_cipher);
509 [ - + ]: 7 : if (!selector)
510 : 0 : selector = RSN_CIPHER_SUITE_TKIP;
511 : 7 : wpa_auth->dot11RSNAPairwiseCipherSelected = selector;
512 : :
513 : 7 : selector = wpa_cipher_to_suite(WPA_PROTO_WPA,
514 : : data.group_cipher);
515 [ - + ]: 7 : if (!selector)
516 : 0 : selector = WPA_CIPHER_SUITE_TKIP;
517 : 7 : wpa_auth->dot11RSNAGroupCipherSelected = selector;
518 : : }
519 [ - + ]: 428 : if (res) {
520 : 0 : wpa_printf(MSG_DEBUG, "Failed to parse WPA/RSN IE from "
521 : 0 : MACSTR " (res=%d)", MAC2STR(sm->addr), res);
522 : 0 : wpa_hexdump(MSG_DEBUG, "WPA/RSN IE", wpa_ie, wpa_ie_len);
523 : 0 : return WPA_INVALID_IE;
524 : : }
525 : :
526 [ - + ]: 428 : if (data.group_cipher != wpa_auth->conf.wpa_group) {
527 : 0 : wpa_printf(MSG_DEBUG, "Invalid WPA group cipher (0x%x) from "
528 : 0 : MACSTR, data.group_cipher, MAC2STR(sm->addr));
529 : 0 : return WPA_INVALID_GROUP;
530 : : }
531 : :
532 : 428 : key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt;
533 [ - + ]: 428 : if (!key_mgmt) {
534 : 0 : wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from "
535 : 0 : MACSTR, data.key_mgmt, MAC2STR(sm->addr));
536 : 0 : return WPA_INVALID_AKMP;
537 : : }
538 : : if (0) {
539 : : }
540 : : #ifdef CONFIG_IEEE80211R
541 [ + + ]: 428 : else if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
542 : 3 : sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
543 [ + + ]: 425 : else if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
544 : 15 : sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_PSK;
545 : : #endif /* CONFIG_IEEE80211R */
546 : : #ifdef CONFIG_IEEE80211W
547 [ + + ]: 410 : else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
548 : 2 : sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
549 [ + + ]: 408 : else if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
550 : 6 : sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
551 : : #endif /* CONFIG_IEEE80211W */
552 : : #ifdef CONFIG_SAE
553 [ + + ]: 402 : else if (key_mgmt & WPA_KEY_MGMT_SAE)
554 : 14 : sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE;
555 [ + + ]: 388 : else if (key_mgmt & WPA_KEY_MGMT_FT_SAE)
556 : 6 : sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE;
557 : : #endif /* CONFIG_SAE */
558 [ + + ]: 382 : else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
559 : 178 : sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
560 : : else
561 : 204 : sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
562 : :
563 [ + + ]: 428 : if (version == WPA_PROTO_RSN)
564 : 421 : ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise;
565 : : else
566 : 7 : ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise;
567 [ - + ]: 428 : if (!ciphers) {
568 [ # # ]: 0 : wpa_printf(MSG_DEBUG, "Invalid %s pairwise cipher (0x%x) "
569 : : "from " MACSTR,
570 : : version == WPA_PROTO_RSN ? "RSN" : "WPA",
571 : 0 : data.pairwise_cipher, MAC2STR(sm->addr));
572 : 0 : return WPA_INVALID_PAIRWISE;
573 : : }
574 : :
575 : : #ifdef CONFIG_IEEE80211W
576 [ + + ]: 428 : if (wpa_auth->conf.ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) {
577 [ - + ]: 12 : if (!(data.capabilities & WPA_CAPABILITY_MFPC)) {
578 : 0 : wpa_printf(MSG_DEBUG, "Management frame protection "
579 : : "required, but client did not enable it");
580 : 0 : return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
581 : : }
582 : :
583 [ - + ]: 12 : if (ciphers & WPA_CIPHER_TKIP) {
584 : 0 : wpa_printf(MSG_DEBUG, "Management frame protection "
585 : : "cannot use TKIP");
586 : 0 : return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
587 : : }
588 : :
589 [ - + ]: 12 : if (data.mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC) {
590 : 0 : wpa_printf(MSG_DEBUG, "Unsupported management group "
591 : : "cipher %d", data.mgmt_group_cipher);
592 : 0 : return WPA_INVALID_MGMT_GROUP_CIPHER;
593 : : }
594 : : }
595 : :
596 [ + + ][ + + ]: 428 : if (wpa_auth->conf.ieee80211w == NO_MGMT_FRAME_PROTECTION ||
597 : 90 : !(data.capabilities & WPA_CAPABILITY_MFPC))
598 : 409 : sm->mgmt_frame_prot = 0;
599 : : else
600 : 19 : sm->mgmt_frame_prot = 1;
601 : : #endif /* CONFIG_IEEE80211W */
602 : :
603 : : #ifdef CONFIG_IEEE80211R
604 [ + + ]: 428 : if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
605 [ + - ][ - + ]: 24 : if (mdie == NULL || mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) {
606 : 0 : wpa_printf(MSG_DEBUG, "RSN: Trying to use FT, but "
607 : : "MDIE not included");
608 : 0 : return WPA_INVALID_MDIE;
609 : : }
610 [ - + ]: 24 : if (os_memcmp(mdie, wpa_auth->conf.mobility_domain,
611 : : MOBILITY_DOMAIN_ID_LEN) != 0) {
612 : 0 : wpa_hexdump(MSG_DEBUG, "RSN: Attempted to use unknown "
613 : : "MDIE", mdie, MOBILITY_DOMAIN_ID_LEN);
614 : 0 : return WPA_INVALID_MDIE;
615 : : }
616 : : }
617 : : #endif /* CONFIG_IEEE80211R */
618 : :
619 : 428 : sm->pairwise = wpa_pick_pairwise_cipher(ciphers, 0);
620 [ - + ]: 428 : if (sm->pairwise < 0)
621 : 0 : return WPA_INVALID_PAIRWISE;
622 : :
623 : : /* TODO: clear WPA/WPA2 state if STA changes from one to another */
624 [ + + ]: 428 : if (wpa_ie[0] == WLAN_EID_RSN)
625 : 421 : sm->wpa = WPA_VERSION_WPA2;
626 : : else
627 : 7 : sm->wpa = WPA_VERSION_WPA;
628 : :
629 : 428 : sm->pmksa = NULL;
630 [ + + ]: 450 : for (i = 0; i < data.num_pmkid; i++) {
631 : 26 : wpa_hexdump(MSG_DEBUG, "RSN IE: STA PMKID",
632 : 26 : &data.pmkid[i * PMKID_LEN], PMKID_LEN);
633 : 26 : sm->pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sm->addr,
634 : 26 : &data.pmkid[i * PMKID_LEN]);
635 [ + + ]: 26 : if (sm->pmksa) {
636 : 4 : pmkid = sm->pmksa->pmkid;
637 : 4 : break;
638 : : }
639 : : }
640 [ + + ][ + + ]: 428 : for (i = 0; sm->pmksa == NULL && wpa_auth->conf.okc &&
[ + + ]
641 : 0 : i < data.num_pmkid; i++) {
642 : : struct wpa_auth_okc_iter_data idata;
643 : 1 : idata.pmksa = NULL;
644 : 1 : idata.aa = wpa_auth->addr;
645 : 1 : idata.spa = sm->addr;
646 : 1 : idata.pmkid = &data.pmkid[i * PMKID_LEN];
647 : 1 : wpa_auth_for_each_auth(wpa_auth, wpa_auth_okc_iter, &idata);
648 [ + - ]: 1 : if (idata.pmksa) {
649 : 1 : wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
650 : : "OKC match for PMKID");
651 : 1 : sm->pmksa = pmksa_cache_add_okc(wpa_auth->pmksa,
652 : 1 : idata.pmksa,
653 : 1 : wpa_auth->addr,
654 : : idata.pmkid);
655 : 1 : pmkid = idata.pmkid;
656 : 1 : break;
657 : : }
658 : : }
659 [ + + ]: 428 : if (sm->pmksa) {
660 : 5 : wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
661 : : "PMKID found from PMKSA cache "
662 : : "eap_type=%d vlan_id=%d",
663 : 5 : sm->pmksa->eap_type_authsrv,
664 : 5 : sm->pmksa->vlan_id);
665 : 5 : os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN);
666 : : }
667 : :
668 [ + + ][ + + ]: 428 : if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) {
669 : 417 : os_free(sm->wpa_ie);
670 : 417 : sm->wpa_ie = os_malloc(wpa_ie_len);
671 [ - + ]: 417 : if (sm->wpa_ie == NULL)
672 : 0 : return WPA_ALLOC_FAIL;
673 : : }
674 : 428 : os_memcpy(sm->wpa_ie, wpa_ie, wpa_ie_len);
675 : 428 : sm->wpa_ie_len = wpa_ie_len;
676 : :
677 : 428 : return WPA_IE_OK;
678 : : }
679 : :
680 : :
681 : : #ifdef CONFIG_HS20
682 : 1 : int wpa_validate_osen(struct wpa_authenticator *wpa_auth,
683 : : struct wpa_state_machine *sm,
684 : : const u8 *osen_ie, size_t osen_ie_len)
685 : : {
686 [ + - ][ - + ]: 1 : if (wpa_auth == NULL || sm == NULL)
687 : 0 : return -1;
688 : :
689 : : /* TODO: parse OSEN element */
690 : 1 : sm->wpa_key_mgmt = WPA_KEY_MGMT_OSEN;
691 : 1 : sm->mgmt_frame_prot = 1;
692 : 1 : sm->pairwise = WPA_CIPHER_CCMP;
693 : 1 : sm->wpa = WPA_VERSION_WPA2;
694 : :
695 [ - + ][ # # ]: 1 : if (sm->wpa_ie == NULL || sm->wpa_ie_len < osen_ie_len) {
696 : 1 : os_free(sm->wpa_ie);
697 : 1 : sm->wpa_ie = os_malloc(osen_ie_len);
698 [ - + ]: 1 : if (sm->wpa_ie == NULL)
699 : 0 : return -1;
700 : : }
701 : :
702 : 1 : os_memcpy(sm->wpa_ie, osen_ie, osen_ie_len);
703 : 1 : sm->wpa_ie_len = osen_ie_len;
704 : :
705 : 1 : return 0;
706 : : }
707 : :
708 : : #endif /* CONFIG_HS20 */
709 : :
710 : :
711 : : /**
712 : : * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
713 : : * @pos: Pointer to the IE header
714 : : * @end: Pointer to the end of the Key Data buffer
715 : : * @ie: Pointer to parsed IE data
716 : : * Returns: 0 on success, 1 if end mark is found, -1 on failure
717 : : */
718 : 116 : static int wpa_parse_generic(const u8 *pos, const u8 *end,
719 : : struct wpa_eapol_ie_parse *ie)
720 : : {
721 [ - + ]: 116 : if (pos[1] == 0)
722 : 0 : return 1;
723 : :
724 [ + + + + ]: 128 : if (pos[1] >= 6 &&
725 [ + - ]: 20 : RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
726 [ + - ]: 8 : pos[2 + WPA_SELECTOR_LEN] == 1 &&
727 : 8 : pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
728 : 8 : ie->wpa_ie = pos;
729 : 8 : ie->wpa_ie_len = pos[1] + 2;
730 : 8 : return 0;
731 : : }
732 : :
733 [ + - ][ + + ]: 108 : if (pos[1] >= 4 && WPA_GET_BE32(pos + 2) == OSEN_IE_VENDOR_TYPE) {
734 : 1 : ie->osen = pos;
735 : 1 : ie->osen_len = pos[1] + 2;
736 : 1 : return 0;
737 : : }
738 : :
739 [ + - ][ + + ]: 107 : if (pos + 1 + RSN_SELECTOR_LEN < end &&
740 [ - + ]: 1 : pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
741 : 1 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
742 : 0 : ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
743 : 0 : return 0;
744 : : }
745 : :
746 [ + + - + ]: 110 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
747 : 3 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
748 : 0 : ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
749 : 0 : ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
750 : 0 : return 0;
751 : : }
752 : :
753 [ + + + + ]: 110 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
754 : 3 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
755 : 2 : ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
756 : 2 : ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
757 : 2 : return 0;
758 : : }
759 : :
760 : : #ifdef CONFIG_PEERKEY
761 [ + + - + ]: 106 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
762 : 1 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) {
763 : 0 : ie->smk = pos + 2 + RSN_SELECTOR_LEN;
764 : 0 : ie->smk_len = pos[1] - RSN_SELECTOR_LEN;
765 : 0 : return 0;
766 : : }
767 : :
768 [ + + + - ]: 106 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
769 : 1 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) {
770 : 1 : ie->nonce = pos + 2 + RSN_SELECTOR_LEN;
771 : 1 : ie->nonce_len = pos[1] - RSN_SELECTOR_LEN;
772 : 1 : return 0;
773 : : }
774 : :
775 [ - + # # ]: 104 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
776 : 0 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) {
777 : 0 : ie->lifetime = pos + 2 + RSN_SELECTOR_LEN;
778 : 0 : ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN;
779 : 0 : return 0;
780 : : }
781 : :
782 [ - + # # ]: 104 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
783 : 0 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) {
784 : 0 : ie->error = pos + 2 + RSN_SELECTOR_LEN;
785 : 0 : ie->error_len = pos[1] - RSN_SELECTOR_LEN;
786 : 0 : return 0;
787 : : }
788 : : #endif /* CONFIG_PEERKEY */
789 : :
790 : : #ifdef CONFIG_IEEE80211W
791 [ - + # # ]: 104 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
792 : 0 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
793 : 0 : ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
794 : 0 : ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
795 : 0 : return 0;
796 : : }
797 : : #endif /* CONFIG_IEEE80211W */
798 : :
799 : : #ifdef CONFIG_P2P
800 [ + - + - ]: 208 : if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
801 : 104 : RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_REQ) {
802 : 104 : ie->ip_addr_req = pos + 2 + RSN_SELECTOR_LEN;
803 : 104 : wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
804 : 208 : ie->ip_addr_req, pos[1] - RSN_SELECTOR_LEN);
805 : 104 : return 0;
806 : : }
807 : :
808 [ # # # # ]: 0 : if (pos[1] >= RSN_SELECTOR_LEN + 3 * 4 &&
809 : 0 : RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_ALLOC) {
810 : 0 : ie->ip_addr_alloc = pos + 2 + RSN_SELECTOR_LEN;
811 : 0 : wpa_hexdump(MSG_DEBUG,
812 : : "WPA: IP Address Allocation in EAPOL-Key",
813 : 0 : ie->ip_addr_alloc, pos[1] - RSN_SELECTOR_LEN);
814 : 0 : return 0;
815 : : }
816 : : #endif /* CONFIG_P2P */
817 : :
818 : 116 : return 0;
819 : : }
820 : :
821 : :
822 : : /**
823 : : * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
824 : : * @buf: Pointer to the Key Data buffer
825 : : * @len: Key Data Length
826 : : * @ie: Pointer to parsed IE data
827 : : * Returns: 0 on success, -1 on failure
828 : : */
829 : 434 : int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
830 : : {
831 : : const u8 *pos, *end;
832 : 434 : int ret = 0;
833 : :
834 : 434 : os_memset(ie, 0, sizeof(*ie));
835 [ + + ]: 991 : for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) {
836 [ + + ][ + - ]: 557 : if (pos[0] == 0xdd &&
837 [ + - ]: 116 : ((pos == buf + len - 1) || pos[1] == 0)) {
838 : : /* Ignore padding */
839 : : break;
840 : : }
841 [ - + ]: 557 : if (pos + 2 + pos[1] > end) {
842 : 0 : wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
843 : : "underflow (ie=%d len=%d pos=%d)",
844 : 0 : pos[0], pos[1], (int) (pos - buf));
845 : 0 : wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
846 : : buf, len);
847 : 0 : ret = -1;
848 : 0 : break;
849 : : }
850 [ + + ]: 557 : if (*pos == WLAN_EID_RSN) {
851 : 425 : ie->rsn_ie = pos;
852 : 425 : ie->rsn_ie_len = pos[1] + 2;
853 : : #ifdef CONFIG_IEEE80211R
854 [ + + ]: 132 : } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
855 : 8 : ie->mdie = pos;
856 : 8 : ie->mdie_len = pos[1] + 2;
857 [ + + ]: 124 : } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
858 : 8 : ie->ftie = pos;
859 : 8 : ie->ftie_len = pos[1] + 2;
860 : : #endif /* CONFIG_IEEE80211R */
861 [ + - ]: 116 : } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
862 : 116 : ret = wpa_parse_generic(pos, end, ie);
863 [ - + ]: 116 : if (ret < 0)
864 : 0 : break;
865 [ - + ]: 116 : if (ret > 0) {
866 : 0 : ret = 0;
867 : 0 : break;
868 : : }
869 : : } else {
870 : 0 : wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
871 : 0 : "Key Data IE", pos, 2 + pos[1]);
872 : : }
873 : : }
874 : :
875 : 434 : return ret;
876 : : }
877 : :
878 : :
879 : 435 : int wpa_auth_uses_mfp(struct wpa_state_machine *sm)
880 : : {
881 [ + + ]: 435 : return sm ? sm->mgmt_frame_prot : 0;
882 : : }
|