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