2 * hostapd - WPA/RSN IE and KDE definitions
3 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
19 #include "ieee802_11.h"
22 #include "pmksa_cache.h"
23 #include "wpa_auth_ie.h"
24 #include "wpa_auth_i.h"
27 static int wpa_write_wpa_ie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
)
29 struct wpa_ie_hdr
*hdr
;
33 hdr
= (struct wpa_ie_hdr
*) buf
;
34 hdr
->elem_id
= WLAN_EID_VENDOR_SPECIFIC
;
35 RSN_SELECTOR_PUT(hdr
->oui
, WPA_OUI_TYPE
);
36 WPA_PUT_LE16(hdr
->version
, WPA_VERSION
);
37 pos
= (u8
*) (hdr
+ 1);
39 if (conf
->wpa_group
== WPA_CIPHER_CCMP
) {
40 RSN_SELECTOR_PUT(pos
, WPA_CIPHER_SUITE_CCMP
);
41 } else if (conf
->wpa_group
== WPA_CIPHER_TKIP
) {
42 RSN_SELECTOR_PUT(pos
, WPA_CIPHER_SUITE_TKIP
);
43 } else if (conf
->wpa_group
== WPA_CIPHER_WEP104
) {
44 RSN_SELECTOR_PUT(pos
, WPA_CIPHER_SUITE_WEP104
);
45 } else if (conf
->wpa_group
== WPA_CIPHER_WEP40
) {
46 RSN_SELECTOR_PUT(pos
, WPA_CIPHER_SUITE_WEP40
);
48 wpa_printf(MSG_DEBUG
, "Invalid group cipher (%d).",
52 pos
+= WPA_SELECTOR_LEN
;
58 if (conf
->wpa_pairwise
& WPA_CIPHER_CCMP
) {
59 RSN_SELECTOR_PUT(pos
, WPA_CIPHER_SUITE_CCMP
);
60 pos
+= WPA_SELECTOR_LEN
;
63 if (conf
->wpa_pairwise
& WPA_CIPHER_TKIP
) {
64 RSN_SELECTOR_PUT(pos
, WPA_CIPHER_SUITE_TKIP
);
65 pos
+= WPA_SELECTOR_LEN
;
68 if (conf
->wpa_pairwise
& WPA_CIPHER_NONE
) {
69 RSN_SELECTOR_PUT(pos
, WPA_CIPHER_SUITE_NONE
);
70 pos
+= WPA_SELECTOR_LEN
;
74 if (num_suites
== 0) {
75 wpa_printf(MSG_DEBUG
, "Invalid pairwise cipher (%d).",
79 WPA_PUT_LE16(count
, num_suites
);
85 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
86 RSN_SELECTOR_PUT(pos
, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
);
87 pos
+= WPA_SELECTOR_LEN
;
90 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
) {
91 RSN_SELECTOR_PUT(pos
, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X
);
92 pos
+= WPA_SELECTOR_LEN
;
96 if (num_suites
== 0) {
97 wpa_printf(MSG_DEBUG
, "Invalid key management type (%d).",
101 WPA_PUT_LE16(count
, num_suites
);
103 /* WPA Capabilities; use defaults, so no need to include it */
105 hdr
->len
= (pos
- buf
) - 2;
111 int wpa_write_rsn_ie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
,
114 struct rsn_ie_hdr
*hdr
;
119 hdr
= (struct rsn_ie_hdr
*) buf
;
120 hdr
->elem_id
= WLAN_EID_RSN
;
121 WPA_PUT_LE16(hdr
->version
, RSN_VERSION
);
122 pos
= (u8
*) (hdr
+ 1);
124 if (conf
->wpa_group
== WPA_CIPHER_CCMP
) {
125 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_CCMP
);
126 } else if (conf
->wpa_group
== WPA_CIPHER_TKIP
) {
127 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_TKIP
);
128 } else if (conf
->wpa_group
== WPA_CIPHER_WEP104
) {
129 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_WEP104
);
130 } else if (conf
->wpa_group
== WPA_CIPHER_WEP40
) {
131 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_WEP40
);
133 wpa_printf(MSG_DEBUG
, "Invalid group cipher (%d).",
137 pos
+= RSN_SELECTOR_LEN
;
143 if (conf
->rsn_pairwise
& WPA_CIPHER_CCMP
) {
144 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_CCMP
);
145 pos
+= RSN_SELECTOR_LEN
;
148 if (conf
->rsn_pairwise
& WPA_CIPHER_TKIP
) {
149 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_TKIP
);
150 pos
+= RSN_SELECTOR_LEN
;
153 if (conf
->rsn_pairwise
& WPA_CIPHER_NONE
) {
154 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_NONE
);
155 pos
+= RSN_SELECTOR_LEN
;
159 if (num_suites
== 0) {
160 wpa_printf(MSG_DEBUG
, "Invalid pairwise cipher (%d).",
164 WPA_PUT_LE16(count
, num_suites
);
170 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
171 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X
);
172 pos
+= RSN_SELECTOR_LEN
;
175 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
) {
176 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X
);
177 pos
+= RSN_SELECTOR_LEN
;
180 #ifdef CONFIG_IEEE80211R
181 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
) {
182 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_FT_802_1X
);
183 pos
+= RSN_SELECTOR_LEN
;
186 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_FT_PSK
) {
187 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_FT_PSK
);
188 pos
+= RSN_SELECTOR_LEN
;
191 #endif /* CONFIG_IEEE80211R */
193 if (num_suites
== 0) {
194 wpa_printf(MSG_DEBUG
, "Invalid key management type (%d).",
198 WPA_PUT_LE16(count
, num_suites
);
200 /* RSN Capabilities */
202 if (conf
->rsn_preauth
)
203 capab
|= WPA_CAPABILITY_PREAUTH
;
205 capab
|= WPA_CAPABILITY_PEERKEY_ENABLED
;
206 if (conf
->wme_enabled
) {
207 /* 4 PTKSA replay counters when using WME */
208 capab
|= (RSN_NUM_REPLAY_COUNTERS_16
<< 2);
210 #ifdef CONFIG_IEEE80211W
211 if (conf
->ieee80211w
!= WPA_NO_IEEE80211W
)
212 capab
|= WPA_CAPABILITY_MGMT_FRAME_PROTECTION
;
213 #endif /* CONFIG_IEEE80211W */
214 WPA_PUT_LE16(pos
, capab
);
218 if (pos
+ 2 + PMKID_LEN
> buf
+ len
)
221 WPA_PUT_LE16(pos
, 1);
223 os_memcpy(pos
, pmkid
, PMKID_LEN
);
227 #ifdef CONFIG_IEEE80211W
228 if (conf
->ieee80211w
!= WPA_NO_IEEE80211W
) {
229 if (pos
+ 2 + 4 > buf
+ len
)
233 WPA_PUT_LE16(pos
, 0);
237 /* Management Group Cipher Suite */
238 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_AES_128_CMAC
);
239 pos
+= RSN_SELECTOR_LEN
;
241 #endif /* CONFIG_IEEE80211W */
243 hdr
->len
= (pos
- buf
) - 2;
249 int wpa_auth_gen_wpa_ie(struct wpa_authenticator
*wpa_auth
)
256 if (wpa_auth
->conf
.wpa
& WPA_PROTO_RSN
) {
257 res
= wpa_write_rsn_ie(&wpa_auth
->conf
,
258 pos
, buf
+ sizeof(buf
) - pos
, NULL
);
263 #ifdef CONFIG_IEEE80211R
264 if (wpa_auth
->conf
.wpa_key_mgmt
&
265 (WPA_KEY_MGMT_FT_IEEE8021X
| WPA_KEY_MGMT_FT_PSK
)) {
266 res
= wpa_write_mdie(&wpa_auth
->conf
, pos
,
267 buf
+ sizeof(buf
) - pos
);
272 #endif /* CONFIG_IEEE80211R */
273 if (wpa_auth
->conf
.wpa
& WPA_PROTO_WPA
) {
274 res
= wpa_write_wpa_ie(&wpa_auth
->conf
,
275 pos
, buf
+ sizeof(buf
) - pos
);
281 os_free(wpa_auth
->wpa_ie
);
282 wpa_auth
->wpa_ie
= os_malloc(pos
- buf
);
283 if (wpa_auth
->wpa_ie
== NULL
)
285 os_memcpy(wpa_auth
->wpa_ie
, buf
, pos
- buf
);
286 wpa_auth
->wpa_ie_len
= pos
- buf
;
292 u8
* wpa_add_kde(u8
*pos
, u32 kde
, const u8
*data
, size_t data_len
,
293 const u8
*data2
, size_t data2_len
)
295 *pos
++ = WLAN_EID_VENDOR_SPECIFIC
;
296 *pos
++ = RSN_SELECTOR_LEN
+ data_len
+ data2_len
;
297 RSN_SELECTOR_PUT(pos
, kde
);
298 pos
+= RSN_SELECTOR_LEN
;
299 os_memcpy(pos
, data
, data_len
);
302 os_memcpy(pos
, data2
, data2_len
);
309 static int wpa_selector_to_bitfield(const u8
*s
)
311 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_NONE
)
312 return WPA_CIPHER_NONE
;
313 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_WEP40
)
314 return WPA_CIPHER_WEP40
;
315 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_TKIP
)
316 return WPA_CIPHER_TKIP
;
317 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_CCMP
)
318 return WPA_CIPHER_CCMP
;
319 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_WEP104
)
320 return WPA_CIPHER_WEP104
;
325 static int wpa_key_mgmt_to_bitfield(const u8
*s
)
327 if (RSN_SELECTOR_GET(s
) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
)
328 return WPA_KEY_MGMT_IEEE8021X
;
329 if (RSN_SELECTOR_GET(s
) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X
)
330 return WPA_KEY_MGMT_PSK
;
331 if (RSN_SELECTOR_GET(s
) == WPA_AUTH_KEY_MGMT_NONE
)
332 return WPA_KEY_MGMT_WPA_NONE
;
337 static int wpa_parse_wpa_ie_wpa(const u8
*wpa_ie
, size_t wpa_ie_len
,
338 struct wpa_ie_data
*data
)
340 const struct wpa_ie_hdr
*hdr
;
345 os_memset(data
, 0, sizeof(*data
));
346 data
->pairwise_cipher
= WPA_CIPHER_TKIP
;
347 data
->group_cipher
= WPA_CIPHER_TKIP
;
348 data
->key_mgmt
= WPA_KEY_MGMT_IEEE8021X
;
349 data
->mgmt_group_cipher
= 0;
351 if (wpa_ie_len
< sizeof(struct wpa_ie_hdr
))
354 hdr
= (const struct wpa_ie_hdr
*) wpa_ie
;
356 if (hdr
->elem_id
!= WLAN_EID_VENDOR_SPECIFIC
||
357 hdr
->len
!= wpa_ie_len
- 2 ||
358 RSN_SELECTOR_GET(hdr
->oui
) != WPA_OUI_TYPE
||
359 WPA_GET_LE16(hdr
->version
) != WPA_VERSION
) {
363 pos
= (const u8
*) (hdr
+ 1);
364 left
= wpa_ie_len
- sizeof(*hdr
);
366 if (left
>= WPA_SELECTOR_LEN
) {
367 data
->group_cipher
= wpa_selector_to_bitfield(pos
);
368 pos
+= WPA_SELECTOR_LEN
;
369 left
-= WPA_SELECTOR_LEN
;
374 data
->pairwise_cipher
= 0;
375 count
= WPA_GET_LE16(pos
);
378 if (count
== 0 || left
< count
* WPA_SELECTOR_LEN
)
380 for (i
= 0; i
< count
; i
++) {
381 data
->pairwise_cipher
|= wpa_selector_to_bitfield(pos
);
382 pos
+= WPA_SELECTOR_LEN
;
383 left
-= WPA_SELECTOR_LEN
;
385 } else if (left
== 1)
390 count
= WPA_GET_LE16(pos
);
393 if (count
== 0 || left
< count
* WPA_SELECTOR_LEN
)
395 for (i
= 0; i
< count
; i
++) {
396 data
->key_mgmt
|= wpa_key_mgmt_to_bitfield(pos
);
397 pos
+= WPA_SELECTOR_LEN
;
398 left
-= WPA_SELECTOR_LEN
;
400 } else if (left
== 1)
404 data
->capabilities
= WPA_GET_LE16(pos
);
417 struct wpa_auth_okc_iter_data
{
418 struct rsn_pmksa_cache_entry
*pmksa
;
425 static int wpa_auth_okc_iter(struct wpa_authenticator
*a
, void *ctx
)
427 struct wpa_auth_okc_iter_data
*data
= ctx
;
428 data
->pmksa
= pmksa_cache_get_okc(a
->pmksa
, data
->aa
, data
->spa
,
436 int wpa_validate_wpa_ie(struct wpa_authenticator
*wpa_auth
,
437 struct wpa_state_machine
*sm
,
438 const u8
*wpa_ie
, size_t wpa_ie_len
,
439 const u8
*mdie
, size_t mdie_len
)
441 struct wpa_ie_data data
;
442 int ciphers
, key_mgmt
, res
, version
;
445 const u8
*pmkid
= NULL
;
447 if (wpa_auth
== NULL
|| sm
== NULL
)
448 return WPA_NOT_ENABLED
;
450 if (wpa_ie
== NULL
|| wpa_ie_len
< 1)
451 return WPA_INVALID_IE
;
453 if (wpa_ie
[0] == WLAN_EID_RSN
)
454 version
= WPA_PROTO_RSN
;
456 version
= WPA_PROTO_WPA
;
458 if (version
== WPA_PROTO_RSN
) {
459 res
= wpa_parse_wpa_ie_rsn(wpa_ie
, wpa_ie_len
, &data
);
461 selector
= RSN_AUTH_KEY_MGMT_UNSPEC_802_1X
;
464 #ifdef CONFIG_IEEE80211R
465 else if (data
.key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
466 selector
= RSN_AUTH_KEY_MGMT_FT_802_1X
;
467 else if (data
.key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
468 selector
= RSN_AUTH_KEY_MGMT_FT_PSK
;
469 #endif /* CONFIG_IEEE80211R */
470 else if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
471 selector
= RSN_AUTH_KEY_MGMT_UNSPEC_802_1X
;
472 else if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
)
473 selector
= RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X
;
474 wpa_auth
->dot11RSNAAuthenticationSuiteSelected
= selector
;
476 selector
= RSN_CIPHER_SUITE_CCMP
;
477 if (data
.pairwise_cipher
& WPA_CIPHER_CCMP
)
478 selector
= RSN_CIPHER_SUITE_CCMP
;
479 else if (data
.pairwise_cipher
& WPA_CIPHER_TKIP
)
480 selector
= RSN_CIPHER_SUITE_TKIP
;
481 else if (data
.pairwise_cipher
& WPA_CIPHER_WEP104
)
482 selector
= RSN_CIPHER_SUITE_WEP104
;
483 else if (data
.pairwise_cipher
& WPA_CIPHER_WEP40
)
484 selector
= RSN_CIPHER_SUITE_WEP40
;
485 else if (data
.pairwise_cipher
& WPA_CIPHER_NONE
)
486 selector
= RSN_CIPHER_SUITE_NONE
;
487 wpa_auth
->dot11RSNAPairwiseCipherSelected
= selector
;
489 selector
= RSN_CIPHER_SUITE_CCMP
;
490 if (data
.group_cipher
& WPA_CIPHER_CCMP
)
491 selector
= RSN_CIPHER_SUITE_CCMP
;
492 else if (data
.group_cipher
& WPA_CIPHER_TKIP
)
493 selector
= RSN_CIPHER_SUITE_TKIP
;
494 else if (data
.group_cipher
& WPA_CIPHER_WEP104
)
495 selector
= RSN_CIPHER_SUITE_WEP104
;
496 else if (data
.group_cipher
& WPA_CIPHER_WEP40
)
497 selector
= RSN_CIPHER_SUITE_WEP40
;
498 else if (data
.group_cipher
& WPA_CIPHER_NONE
)
499 selector
= RSN_CIPHER_SUITE_NONE
;
500 wpa_auth
->dot11RSNAGroupCipherSelected
= selector
;
502 res
= wpa_parse_wpa_ie_wpa(wpa_ie
, wpa_ie_len
, &data
);
504 selector
= WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
;
505 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
506 selector
= WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
;
507 else if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
)
508 selector
= WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X
;
509 wpa_auth
->dot11RSNAAuthenticationSuiteSelected
= selector
;
511 selector
= WPA_CIPHER_SUITE_TKIP
;
512 if (data
.pairwise_cipher
& WPA_CIPHER_CCMP
)
513 selector
= WPA_CIPHER_SUITE_CCMP
;
514 else if (data
.pairwise_cipher
& WPA_CIPHER_TKIP
)
515 selector
= WPA_CIPHER_SUITE_TKIP
;
516 else if (data
.pairwise_cipher
& WPA_CIPHER_WEP104
)
517 selector
= WPA_CIPHER_SUITE_WEP104
;
518 else if (data
.pairwise_cipher
& WPA_CIPHER_WEP40
)
519 selector
= WPA_CIPHER_SUITE_WEP40
;
520 else if (data
.pairwise_cipher
& WPA_CIPHER_NONE
)
521 selector
= WPA_CIPHER_SUITE_NONE
;
522 wpa_auth
->dot11RSNAPairwiseCipherSelected
= selector
;
524 selector
= WPA_CIPHER_SUITE_TKIP
;
525 if (data
.group_cipher
& WPA_CIPHER_CCMP
)
526 selector
= WPA_CIPHER_SUITE_CCMP
;
527 else if (data
.group_cipher
& WPA_CIPHER_TKIP
)
528 selector
= WPA_CIPHER_SUITE_TKIP
;
529 else if (data
.group_cipher
& WPA_CIPHER_WEP104
)
530 selector
= WPA_CIPHER_SUITE_WEP104
;
531 else if (data
.group_cipher
& WPA_CIPHER_WEP40
)
532 selector
= WPA_CIPHER_SUITE_WEP40
;
533 else if (data
.group_cipher
& WPA_CIPHER_NONE
)
534 selector
= WPA_CIPHER_SUITE_NONE
;
535 wpa_auth
->dot11RSNAGroupCipherSelected
= selector
;
538 wpa_printf(MSG_DEBUG
, "Failed to parse WPA/RSN IE from "
539 MACSTR
" (res=%d)", MAC2STR(sm
->addr
), res
);
540 wpa_hexdump(MSG_DEBUG
, "WPA/RSN IE", wpa_ie
, wpa_ie_len
);
541 return WPA_INVALID_IE
;
544 if (data
.group_cipher
!= wpa_auth
->conf
.wpa_group
) {
545 wpa_printf(MSG_DEBUG
, "Invalid WPA group cipher (0x%x) from "
546 MACSTR
, data
.group_cipher
, MAC2STR(sm
->addr
));
547 return WPA_INVALID_GROUP
;
550 key_mgmt
= data
.key_mgmt
& wpa_auth
->conf
.wpa_key_mgmt
;
552 wpa_printf(MSG_DEBUG
, "Invalid WPA key mgmt (0x%x) from "
553 MACSTR
, data
.key_mgmt
, MAC2STR(sm
->addr
));
554 return WPA_INVALID_AKMP
;
558 #ifdef CONFIG_IEEE80211R
559 else if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
560 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X
;
561 else if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
562 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_PSK
;
563 #endif /* CONFIG_IEEE80211R */
564 else if (key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
565 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_IEEE8021X
;
567 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
569 if (version
== WPA_PROTO_RSN
)
570 ciphers
= data
.pairwise_cipher
& wpa_auth
->conf
.rsn_pairwise
;
572 ciphers
= data
.pairwise_cipher
& wpa_auth
->conf
.wpa_pairwise
;
574 wpa_printf(MSG_DEBUG
, "Invalid %s pairwise cipher (0x%x) "
576 version
== WPA_PROTO_RSN
? "RSN" : "WPA",
577 data
.pairwise_cipher
, MAC2STR(sm
->addr
));
578 return WPA_INVALID_PAIRWISE
;
581 #ifdef CONFIG_IEEE80211W
582 if (wpa_auth
->conf
.ieee80211w
== WPA_IEEE80211W_REQUIRED
) {
583 if (!(data
.capabilities
&
584 WPA_CAPABILITY_MGMT_FRAME_PROTECTION
)) {
585 wpa_printf(MSG_DEBUG
, "Management frame protection "
586 "required, but client did not enable it");
587 return WPA_MGMT_FRAME_PROTECTION_VIOLATION
;
590 if (ciphers
& WPA_CIPHER_TKIP
) {
591 wpa_printf(MSG_DEBUG
, "Management frame protection "
593 return WPA_MGMT_FRAME_PROTECTION_VIOLATION
;
596 if (data
.mgmt_group_cipher
!= WPA_CIPHER_AES_128_CMAC
) {
597 wpa_printf(MSG_DEBUG
, "Unsupported management group "
598 "cipher %d", data
.mgmt_group_cipher
);
599 return WPA_INVALID_MGMT_GROUP_CIPHER
;
603 if (wpa_auth
->conf
.ieee80211w
== WPA_NO_IEEE80211W
||
604 !(data
.capabilities
& WPA_CAPABILITY_MGMT_FRAME_PROTECTION
))
605 sm
->mgmt_frame_prot
= 0;
607 sm
->mgmt_frame_prot
= 1;
608 #endif /* CONFIG_IEEE80211W */
610 #ifdef CONFIG_IEEE80211R
611 if (sm
->wpa_key_mgmt
== WPA_KEY_MGMT_FT_IEEE8021X
||
612 sm
->wpa_key_mgmt
== WPA_KEY_MGMT_FT_PSK
) {
613 if (mdie
== NULL
|| mdie_len
< MOBILITY_DOMAIN_ID_LEN
+ 1) {
614 wpa_printf(MSG_DEBUG
, "RSN: Trying to use FT, but "
615 "MDIE not included");
616 return WPA_INVALID_MDIE
;
618 if (os_memcmp(mdie
, wpa_auth
->conf
.mobility_domain
,
619 MOBILITY_DOMAIN_ID_LEN
) != 0) {
620 wpa_hexdump(MSG_DEBUG
, "RSN: Attempted to use unknown "
621 "MDIE", mdie
, MOBILITY_DOMAIN_ID_LEN
);
622 return WPA_INVALID_MDIE
;
625 #endif /* CONFIG_IEEE80211R */
627 if (ciphers
& WPA_CIPHER_CCMP
)
628 sm
->pairwise
= WPA_CIPHER_CCMP
;
630 sm
->pairwise
= WPA_CIPHER_TKIP
;
632 /* TODO: clear WPA/WPA2 state if STA changes from one to another */
633 if (wpa_ie
[0] == WLAN_EID_RSN
)
634 sm
->wpa
= WPA_VERSION_WPA2
;
636 sm
->wpa
= WPA_VERSION_WPA
;
639 for (i
= 0; i
< data
.num_pmkid
; i
++) {
640 wpa_hexdump(MSG_DEBUG
, "RSN IE: STA PMKID",
641 &data
.pmkid
[i
* PMKID_LEN
], PMKID_LEN
);
642 sm
->pmksa
= pmksa_cache_get(wpa_auth
->pmksa
, sm
->addr
,
643 &data
.pmkid
[i
* PMKID_LEN
]);
645 pmkid
= sm
->pmksa
->pmkid
;
649 for (i
= 0; sm
->pmksa
== NULL
&& wpa_auth
->conf
.okc
&&
650 i
< data
.num_pmkid
; i
++) {
651 struct wpa_auth_okc_iter_data idata
;
653 idata
.aa
= wpa_auth
->addr
;
654 idata
.spa
= sm
->addr
;
655 idata
.pmkid
= &data
.pmkid
[i
* PMKID_LEN
];
656 wpa_auth_for_each_auth(wpa_auth
, wpa_auth_okc_iter
, &idata
);
658 wpa_auth_vlogger(wpa_auth
, sm
->addr
, LOGGER_DEBUG
,
659 "OKC match for PMKID");
660 sm
->pmksa
= pmksa_cache_add_okc(wpa_auth
->pmksa
,
669 wpa_auth_vlogger(wpa_auth
, sm
->addr
, LOGGER_DEBUG
,
670 "PMKID found from PMKSA cache "
671 "eap_type=%d vlan_id=%d",
672 sm
->pmksa
->eap_type_authsrv
,
674 os_memcpy(wpa_auth
->dot11RSNAPMKIDUsed
, pmkid
, PMKID_LEN
);
677 if (sm
->wpa_ie
== NULL
|| sm
->wpa_ie_len
< wpa_ie_len
) {
679 sm
->wpa_ie
= os_malloc(wpa_ie_len
);
680 if (sm
->wpa_ie
== NULL
)
681 return WPA_ALLOC_FAIL
;
683 os_memcpy(sm
->wpa_ie
, wpa_ie
, wpa_ie_len
);
684 sm
->wpa_ie_len
= wpa_ie_len
;
691 * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
692 * @pos: Pointer to the IE header
693 * @end: Pointer to the end of the Key Data buffer
694 * @ie: Pointer to parsed IE data
695 * Returns: 0 on success, 1 if end mark is found, -1 on failure
697 static int wpa_parse_generic(const u8
*pos
, const u8
*end
,
698 struct wpa_eapol_ie_parse
*ie
)
704 RSN_SELECTOR_GET(pos
+ 2) == WPA_OUI_TYPE
&&
705 pos
[2 + WPA_SELECTOR_LEN
] == 1 &&
706 pos
[2 + WPA_SELECTOR_LEN
+ 1] == 0) {
708 ie
->wpa_ie_len
= pos
[1] + 2;
712 if (pos
+ 1 + RSN_SELECTOR_LEN
< end
&&
713 pos
[1] >= RSN_SELECTOR_LEN
+ PMKID_LEN
&&
714 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_PMKID
) {
715 ie
->pmkid
= pos
+ 2 + RSN_SELECTOR_LEN
;
719 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
720 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_GROUPKEY
) {
721 ie
->gtk
= pos
+ 2 + RSN_SELECTOR_LEN
;
722 ie
->gtk_len
= pos
[1] - RSN_SELECTOR_LEN
;
726 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
727 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_MAC_ADDR
) {
728 ie
->mac_addr
= pos
+ 2 + RSN_SELECTOR_LEN
;
729 ie
->mac_addr_len
= pos
[1] - RSN_SELECTOR_LEN
;
733 #ifdef CONFIG_PEERKEY
734 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
735 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_SMK
) {
736 ie
->smk
= pos
+ 2 + RSN_SELECTOR_LEN
;
737 ie
->smk_len
= pos
[1] - RSN_SELECTOR_LEN
;
741 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
742 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_NONCE
) {
743 ie
->nonce
= pos
+ 2 + RSN_SELECTOR_LEN
;
744 ie
->nonce_len
= pos
[1] - RSN_SELECTOR_LEN
;
748 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
749 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_LIFETIME
) {
750 ie
->lifetime
= pos
+ 2 + RSN_SELECTOR_LEN
;
751 ie
->lifetime_len
= pos
[1] - RSN_SELECTOR_LEN
;
755 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
756 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_ERROR
) {
757 ie
->error
= pos
+ 2 + RSN_SELECTOR_LEN
;
758 ie
->error_len
= pos
[1] - RSN_SELECTOR_LEN
;
761 #endif /* CONFIG_PEERKEY */
763 #ifdef CONFIG_IEEE80211W
764 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
765 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_IGTK
) {
766 ie
->igtk
= pos
+ 2 + RSN_SELECTOR_LEN
;
767 ie
->igtk_len
= pos
[1] - RSN_SELECTOR_LEN
;
770 #endif /* CONFIG_IEEE80211W */
777 * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
778 * @buf: Pointer to the Key Data buffer
779 * @len: Key Data Length
780 * @ie: Pointer to parsed IE data
781 * Returns: 0 on success, -1 on failure
783 int wpa_parse_kde_ies(const u8
*buf
, size_t len
, struct wpa_eapol_ie_parse
*ie
)
788 os_memset(ie
, 0, sizeof(*ie
));
789 for (pos
= buf
, end
= pos
+ len
; pos
+ 1 < end
; pos
+= 2 + pos
[1]) {
790 if (pos
[0] == 0xdd &&
791 ((pos
== buf
+ len
- 1) || pos
[1] == 0)) {
795 if (pos
+ 2 + pos
[1] > end
) {
796 wpa_printf(MSG_DEBUG
, "WPA: EAPOL-Key Key Data "
797 "underflow (ie=%d len=%d pos=%d)",
798 pos
[0], pos
[1], (int) (pos
- buf
));
799 wpa_hexdump_key(MSG_DEBUG
, "WPA: Key Data",
804 if (*pos
== WLAN_EID_RSN
) {
806 ie
->rsn_ie_len
= pos
[1] + 2;
807 #ifdef CONFIG_IEEE80211R
808 } else if (*pos
== WLAN_EID_MOBILITY_DOMAIN
) {
810 ie
->mdie_len
= pos
[1] + 2;
811 #endif /* CONFIG_IEEE80211R */
812 } else if (*pos
== WLAN_EID_VENDOR_SPECIFIC
) {
813 ret
= wpa_parse_generic(pos
, end
, ie
);
821 wpa_hexdump(MSG_DEBUG
, "WPA: Unrecognized EAPOL-Key "
822 "Key Data IE", pos
, 2 + pos
[1]);
830 int wpa_auth_uses_mfp(struct wpa_state_machine
*sm
)
832 return sm
? sm
->mgmt_frame_prot
: 0;