2 * hostapd - WPA/RSN IE and KDE definitions
3 * Copyright (c) 2004-2008, 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"
20 #include "eapol_auth/eapol_auth_sm.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 */
192 #ifdef CONFIG_IEEE80211W
193 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
) {
194 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_802_1X_SHA256
);
195 pos
+= RSN_SELECTOR_LEN
;
198 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
) {
199 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_PSK_SHA256
);
200 pos
+= RSN_SELECTOR_LEN
;
203 #endif /* CONFIG_IEEE80211W */
205 if (num_suites
== 0) {
206 wpa_printf(MSG_DEBUG
, "Invalid key management type (%d).",
210 WPA_PUT_LE16(count
, num_suites
);
212 /* RSN Capabilities */
214 if (conf
->rsn_preauth
)
215 capab
|= WPA_CAPABILITY_PREAUTH
;
217 capab
|= WPA_CAPABILITY_PEERKEY_ENABLED
;
218 if (conf
->wmm_enabled
) {
219 /* 4 PTKSA replay counters when using WMM */
220 capab
|= (RSN_NUM_REPLAY_COUNTERS_16
<< 2);
222 #ifdef CONFIG_IEEE80211W
223 if (conf
->ieee80211w
!= WPA_NO_IEEE80211W
) {
224 capab
|= WPA_CAPABILITY_MFPC
;
225 if (conf
->ieee80211w
== IEEE80211W_REQUIRED
)
226 capab
|= WPA_CAPABILITY_MFPR
;
228 #endif /* CONFIG_IEEE80211W */
229 WPA_PUT_LE16(pos
, capab
);
233 if (pos
+ 2 + PMKID_LEN
> buf
+ len
)
236 WPA_PUT_LE16(pos
, 1);
238 os_memcpy(pos
, pmkid
, PMKID_LEN
);
242 #ifdef CONFIG_IEEE80211W
243 if (conf
->ieee80211w
!= WPA_NO_IEEE80211W
) {
244 if (pos
+ 2 + 4 > buf
+ len
)
248 WPA_PUT_LE16(pos
, 0);
252 /* Management Group Cipher Suite */
253 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_AES_128_CMAC
);
254 pos
+= RSN_SELECTOR_LEN
;
256 #endif /* CONFIG_IEEE80211W */
258 hdr
->len
= (pos
- buf
) - 2;
264 int wpa_auth_gen_wpa_ie(struct wpa_authenticator
*wpa_auth
)
271 if (wpa_auth
->conf
.wpa
& WPA_PROTO_RSN
) {
272 res
= wpa_write_rsn_ie(&wpa_auth
->conf
,
273 pos
, buf
+ sizeof(buf
) - pos
, NULL
);
278 #ifdef CONFIG_IEEE80211R
279 if (wpa_auth
->conf
.wpa_key_mgmt
&
280 (WPA_KEY_MGMT_FT_IEEE8021X
| WPA_KEY_MGMT_FT_PSK
)) {
281 res
= wpa_write_mdie(&wpa_auth
->conf
, pos
,
282 buf
+ sizeof(buf
) - pos
);
287 #endif /* CONFIG_IEEE80211R */
288 if (wpa_auth
->conf
.wpa
& WPA_PROTO_WPA
) {
289 res
= wpa_write_wpa_ie(&wpa_auth
->conf
,
290 pos
, buf
+ sizeof(buf
) - pos
);
296 os_free(wpa_auth
->wpa_ie
);
297 wpa_auth
->wpa_ie
= os_malloc(pos
- buf
);
298 if (wpa_auth
->wpa_ie
== NULL
)
300 os_memcpy(wpa_auth
->wpa_ie
, buf
, pos
- buf
);
301 wpa_auth
->wpa_ie_len
= pos
- buf
;
307 u8
* wpa_add_kde(u8
*pos
, u32 kde
, const u8
*data
, size_t data_len
,
308 const u8
*data2
, size_t data2_len
)
310 *pos
++ = WLAN_EID_VENDOR_SPECIFIC
;
311 *pos
++ = RSN_SELECTOR_LEN
+ data_len
+ data2_len
;
312 RSN_SELECTOR_PUT(pos
, kde
);
313 pos
+= RSN_SELECTOR_LEN
;
314 os_memcpy(pos
, data
, data_len
);
317 os_memcpy(pos
, data2
, data2_len
);
324 static int wpa_selector_to_bitfield(const u8
*s
)
326 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_NONE
)
327 return WPA_CIPHER_NONE
;
328 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_WEP40
)
329 return WPA_CIPHER_WEP40
;
330 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_TKIP
)
331 return WPA_CIPHER_TKIP
;
332 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_CCMP
)
333 return WPA_CIPHER_CCMP
;
334 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_WEP104
)
335 return WPA_CIPHER_WEP104
;
340 static int wpa_key_mgmt_to_bitfield(const u8
*s
)
342 if (RSN_SELECTOR_GET(s
) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
)
343 return WPA_KEY_MGMT_IEEE8021X
;
344 if (RSN_SELECTOR_GET(s
) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X
)
345 return WPA_KEY_MGMT_PSK
;
346 if (RSN_SELECTOR_GET(s
) == WPA_AUTH_KEY_MGMT_NONE
)
347 return WPA_KEY_MGMT_WPA_NONE
;
352 static int wpa_parse_wpa_ie_wpa(const u8
*wpa_ie
, size_t wpa_ie_len
,
353 struct wpa_ie_data
*data
)
355 const struct wpa_ie_hdr
*hdr
;
360 os_memset(data
, 0, sizeof(*data
));
361 data
->pairwise_cipher
= WPA_CIPHER_TKIP
;
362 data
->group_cipher
= WPA_CIPHER_TKIP
;
363 data
->key_mgmt
= WPA_KEY_MGMT_IEEE8021X
;
364 data
->mgmt_group_cipher
= 0;
366 if (wpa_ie_len
< sizeof(struct wpa_ie_hdr
))
369 hdr
= (const struct wpa_ie_hdr
*) wpa_ie
;
371 if (hdr
->elem_id
!= WLAN_EID_VENDOR_SPECIFIC
||
372 hdr
->len
!= wpa_ie_len
- 2 ||
373 RSN_SELECTOR_GET(hdr
->oui
) != WPA_OUI_TYPE
||
374 WPA_GET_LE16(hdr
->version
) != WPA_VERSION
) {
378 pos
= (const u8
*) (hdr
+ 1);
379 left
= wpa_ie_len
- sizeof(*hdr
);
381 if (left
>= WPA_SELECTOR_LEN
) {
382 data
->group_cipher
= wpa_selector_to_bitfield(pos
);
383 pos
+= WPA_SELECTOR_LEN
;
384 left
-= WPA_SELECTOR_LEN
;
389 data
->pairwise_cipher
= 0;
390 count
= WPA_GET_LE16(pos
);
393 if (count
== 0 || left
< count
* WPA_SELECTOR_LEN
)
395 for (i
= 0; i
< count
; i
++) {
396 data
->pairwise_cipher
|= wpa_selector_to_bitfield(pos
);
397 pos
+= WPA_SELECTOR_LEN
;
398 left
-= WPA_SELECTOR_LEN
;
400 } else if (left
== 1)
405 count
= WPA_GET_LE16(pos
);
408 if (count
== 0 || left
< count
* WPA_SELECTOR_LEN
)
410 for (i
= 0; i
< count
; i
++) {
411 data
->key_mgmt
|= wpa_key_mgmt_to_bitfield(pos
);
412 pos
+= WPA_SELECTOR_LEN
;
413 left
-= WPA_SELECTOR_LEN
;
415 } else if (left
== 1)
419 data
->capabilities
= WPA_GET_LE16(pos
);
432 struct wpa_auth_okc_iter_data
{
433 struct rsn_pmksa_cache_entry
*pmksa
;
440 static int wpa_auth_okc_iter(struct wpa_authenticator
*a
, void *ctx
)
442 struct wpa_auth_okc_iter_data
*data
= ctx
;
443 data
->pmksa
= pmksa_cache_get_okc(a
->pmksa
, data
->aa
, data
->spa
,
451 int wpa_validate_wpa_ie(struct wpa_authenticator
*wpa_auth
,
452 struct wpa_state_machine
*sm
,
453 const u8
*wpa_ie
, size_t wpa_ie_len
,
454 const u8
*mdie
, size_t mdie_len
)
456 struct wpa_ie_data data
;
457 int ciphers
, key_mgmt
, res
, version
;
460 const u8
*pmkid
= NULL
;
462 if (wpa_auth
== NULL
|| sm
== NULL
)
463 return WPA_NOT_ENABLED
;
465 if (wpa_ie
== NULL
|| wpa_ie_len
< 1)
466 return WPA_INVALID_IE
;
468 if (wpa_ie
[0] == WLAN_EID_RSN
)
469 version
= WPA_PROTO_RSN
;
471 version
= WPA_PROTO_WPA
;
473 if (!(wpa_auth
->conf
.wpa
& version
)) {
474 wpa_printf(MSG_DEBUG
, "Invalid WPA proto (%d) from " MACSTR
,
475 version
, MAC2STR(sm
->addr
));
476 return WPA_INVALID_PROTO
;
479 if (version
== WPA_PROTO_RSN
) {
480 res
= wpa_parse_wpa_ie_rsn(wpa_ie
, wpa_ie_len
, &data
);
482 selector
= RSN_AUTH_KEY_MGMT_UNSPEC_802_1X
;
485 #ifdef CONFIG_IEEE80211R
486 else if (data
.key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
487 selector
= RSN_AUTH_KEY_MGMT_FT_802_1X
;
488 else if (data
.key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
489 selector
= RSN_AUTH_KEY_MGMT_FT_PSK
;
490 #endif /* CONFIG_IEEE80211R */
491 #ifdef CONFIG_IEEE80211W
492 else if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
493 selector
= RSN_AUTH_KEY_MGMT_802_1X_SHA256
;
494 else if (data
.key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
495 selector
= RSN_AUTH_KEY_MGMT_PSK_SHA256
;
496 #endif /* CONFIG_IEEE80211W */
497 else if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
498 selector
= RSN_AUTH_KEY_MGMT_UNSPEC_802_1X
;
499 else if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
)
500 selector
= RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X
;
501 wpa_auth
->dot11RSNAAuthenticationSuiteSelected
= selector
;
503 selector
= RSN_CIPHER_SUITE_CCMP
;
504 if (data
.pairwise_cipher
& WPA_CIPHER_CCMP
)
505 selector
= RSN_CIPHER_SUITE_CCMP
;
506 else if (data
.pairwise_cipher
& WPA_CIPHER_TKIP
)
507 selector
= RSN_CIPHER_SUITE_TKIP
;
508 else if (data
.pairwise_cipher
& WPA_CIPHER_WEP104
)
509 selector
= RSN_CIPHER_SUITE_WEP104
;
510 else if (data
.pairwise_cipher
& WPA_CIPHER_WEP40
)
511 selector
= RSN_CIPHER_SUITE_WEP40
;
512 else if (data
.pairwise_cipher
& WPA_CIPHER_NONE
)
513 selector
= RSN_CIPHER_SUITE_NONE
;
514 wpa_auth
->dot11RSNAPairwiseCipherSelected
= selector
;
516 selector
= RSN_CIPHER_SUITE_CCMP
;
517 if (data
.group_cipher
& WPA_CIPHER_CCMP
)
518 selector
= RSN_CIPHER_SUITE_CCMP
;
519 else if (data
.group_cipher
& WPA_CIPHER_TKIP
)
520 selector
= RSN_CIPHER_SUITE_TKIP
;
521 else if (data
.group_cipher
& WPA_CIPHER_WEP104
)
522 selector
= RSN_CIPHER_SUITE_WEP104
;
523 else if (data
.group_cipher
& WPA_CIPHER_WEP40
)
524 selector
= RSN_CIPHER_SUITE_WEP40
;
525 else if (data
.group_cipher
& WPA_CIPHER_NONE
)
526 selector
= RSN_CIPHER_SUITE_NONE
;
527 wpa_auth
->dot11RSNAGroupCipherSelected
= selector
;
529 res
= wpa_parse_wpa_ie_wpa(wpa_ie
, wpa_ie_len
, &data
);
531 selector
= WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
;
532 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
533 selector
= WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
;
534 else if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
)
535 selector
= WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X
;
536 wpa_auth
->dot11RSNAAuthenticationSuiteSelected
= selector
;
538 selector
= WPA_CIPHER_SUITE_TKIP
;
539 if (data
.pairwise_cipher
& WPA_CIPHER_CCMP
)
540 selector
= WPA_CIPHER_SUITE_CCMP
;
541 else if (data
.pairwise_cipher
& WPA_CIPHER_TKIP
)
542 selector
= WPA_CIPHER_SUITE_TKIP
;
543 else if (data
.pairwise_cipher
& WPA_CIPHER_WEP104
)
544 selector
= WPA_CIPHER_SUITE_WEP104
;
545 else if (data
.pairwise_cipher
& WPA_CIPHER_WEP40
)
546 selector
= WPA_CIPHER_SUITE_WEP40
;
547 else if (data
.pairwise_cipher
& WPA_CIPHER_NONE
)
548 selector
= WPA_CIPHER_SUITE_NONE
;
549 wpa_auth
->dot11RSNAPairwiseCipherSelected
= selector
;
551 selector
= WPA_CIPHER_SUITE_TKIP
;
552 if (data
.group_cipher
& WPA_CIPHER_CCMP
)
553 selector
= WPA_CIPHER_SUITE_CCMP
;
554 else if (data
.group_cipher
& WPA_CIPHER_TKIP
)
555 selector
= WPA_CIPHER_SUITE_TKIP
;
556 else if (data
.group_cipher
& WPA_CIPHER_WEP104
)
557 selector
= WPA_CIPHER_SUITE_WEP104
;
558 else if (data
.group_cipher
& WPA_CIPHER_WEP40
)
559 selector
= WPA_CIPHER_SUITE_WEP40
;
560 else if (data
.group_cipher
& WPA_CIPHER_NONE
)
561 selector
= WPA_CIPHER_SUITE_NONE
;
562 wpa_auth
->dot11RSNAGroupCipherSelected
= selector
;
565 wpa_printf(MSG_DEBUG
, "Failed to parse WPA/RSN IE from "
566 MACSTR
" (res=%d)", MAC2STR(sm
->addr
), res
);
567 wpa_hexdump(MSG_DEBUG
, "WPA/RSN IE", wpa_ie
, wpa_ie_len
);
568 return WPA_INVALID_IE
;
571 if (data
.group_cipher
!= wpa_auth
->conf
.wpa_group
) {
572 wpa_printf(MSG_DEBUG
, "Invalid WPA group cipher (0x%x) from "
573 MACSTR
, data
.group_cipher
, MAC2STR(sm
->addr
));
574 return WPA_INVALID_GROUP
;
577 key_mgmt
= data
.key_mgmt
& wpa_auth
->conf
.wpa_key_mgmt
;
579 wpa_printf(MSG_DEBUG
, "Invalid WPA key mgmt (0x%x) from "
580 MACSTR
, data
.key_mgmt
, MAC2STR(sm
->addr
));
581 return WPA_INVALID_AKMP
;
585 #ifdef CONFIG_IEEE80211R
586 else if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
587 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X
;
588 else if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
589 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_PSK
;
590 #endif /* CONFIG_IEEE80211R */
591 #ifdef CONFIG_IEEE80211W
592 else if (key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
593 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_IEEE8021X_SHA256
;
594 else if (key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
595 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_PSK_SHA256
;
596 #endif /* CONFIG_IEEE80211W */
597 else if (key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
598 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_IEEE8021X
;
600 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
602 if (version
== WPA_PROTO_RSN
)
603 ciphers
= data
.pairwise_cipher
& wpa_auth
->conf
.rsn_pairwise
;
605 ciphers
= data
.pairwise_cipher
& wpa_auth
->conf
.wpa_pairwise
;
607 wpa_printf(MSG_DEBUG
, "Invalid %s pairwise cipher (0x%x) "
609 version
== WPA_PROTO_RSN
? "RSN" : "WPA",
610 data
.pairwise_cipher
, MAC2STR(sm
->addr
));
611 return WPA_INVALID_PAIRWISE
;
614 #ifdef CONFIG_IEEE80211W
615 if (wpa_auth
->conf
.ieee80211w
== WPA_IEEE80211W_REQUIRED
) {
616 if (!(data
.capabilities
& WPA_CAPABILITY_MFPC
)) {
617 wpa_printf(MSG_DEBUG
, "Management frame protection "
618 "required, but client did not enable it");
619 return WPA_MGMT_FRAME_PROTECTION_VIOLATION
;
622 if (ciphers
& WPA_CIPHER_TKIP
) {
623 wpa_printf(MSG_DEBUG
, "Management frame protection "
625 return WPA_MGMT_FRAME_PROTECTION_VIOLATION
;
628 if (data
.mgmt_group_cipher
!= WPA_CIPHER_AES_128_CMAC
) {
629 wpa_printf(MSG_DEBUG
, "Unsupported management group "
630 "cipher %d", data
.mgmt_group_cipher
);
631 return WPA_INVALID_MGMT_GROUP_CIPHER
;
635 if (wpa_auth
->conf
.ieee80211w
== WPA_NO_IEEE80211W
||
636 !(data
.capabilities
& WPA_CAPABILITY_MFPC
))
637 sm
->mgmt_frame_prot
= 0;
639 sm
->mgmt_frame_prot
= 1;
640 #endif /* CONFIG_IEEE80211W */
642 #ifdef CONFIG_IEEE80211R
643 if (wpa_key_mgmt_ft(sm
->wpa_key_mgmt
)) {
644 if (mdie
== NULL
|| mdie_len
< MOBILITY_DOMAIN_ID_LEN
+ 1) {
645 wpa_printf(MSG_DEBUG
, "RSN: Trying to use FT, but "
646 "MDIE not included");
647 return WPA_INVALID_MDIE
;
649 if (os_memcmp(mdie
, wpa_auth
->conf
.mobility_domain
,
650 MOBILITY_DOMAIN_ID_LEN
) != 0) {
651 wpa_hexdump(MSG_DEBUG
, "RSN: Attempted to use unknown "
652 "MDIE", mdie
, MOBILITY_DOMAIN_ID_LEN
);
653 return WPA_INVALID_MDIE
;
656 #endif /* CONFIG_IEEE80211R */
658 if (ciphers
& WPA_CIPHER_CCMP
)
659 sm
->pairwise
= WPA_CIPHER_CCMP
;
661 sm
->pairwise
= WPA_CIPHER_TKIP
;
663 /* TODO: clear WPA/WPA2 state if STA changes from one to another */
664 if (wpa_ie
[0] == WLAN_EID_RSN
)
665 sm
->wpa
= WPA_VERSION_WPA2
;
667 sm
->wpa
= WPA_VERSION_WPA
;
670 for (i
= 0; i
< data
.num_pmkid
; i
++) {
671 wpa_hexdump(MSG_DEBUG
, "RSN IE: STA PMKID",
672 &data
.pmkid
[i
* PMKID_LEN
], PMKID_LEN
);
673 sm
->pmksa
= pmksa_cache_auth_get(wpa_auth
->pmksa
, sm
->addr
,
674 &data
.pmkid
[i
* PMKID_LEN
]);
676 pmkid
= sm
->pmksa
->pmkid
;
680 for (i
= 0; sm
->pmksa
== NULL
&& wpa_auth
->conf
.okc
&&
681 i
< data
.num_pmkid
; i
++) {
682 struct wpa_auth_okc_iter_data idata
;
684 idata
.aa
= wpa_auth
->addr
;
685 idata
.spa
= sm
->addr
;
686 idata
.pmkid
= &data
.pmkid
[i
* PMKID_LEN
];
687 wpa_auth_for_each_auth(wpa_auth
, wpa_auth_okc_iter
, &idata
);
689 wpa_auth_vlogger(wpa_auth
, sm
->addr
, LOGGER_DEBUG
,
690 "OKC match for PMKID");
691 sm
->pmksa
= pmksa_cache_add_okc(wpa_auth
->pmksa
,
700 wpa_auth_vlogger(wpa_auth
, sm
->addr
, LOGGER_DEBUG
,
701 "PMKID found from PMKSA cache "
702 "eap_type=%d vlan_id=%d",
703 sm
->pmksa
->eap_type_authsrv
,
705 os_memcpy(wpa_auth
->dot11RSNAPMKIDUsed
, pmkid
, PMKID_LEN
);
708 if (sm
->wpa_ie
== NULL
|| sm
->wpa_ie_len
< wpa_ie_len
) {
710 sm
->wpa_ie
= os_malloc(wpa_ie_len
);
711 if (sm
->wpa_ie
== NULL
)
712 return WPA_ALLOC_FAIL
;
714 os_memcpy(sm
->wpa_ie
, wpa_ie
, wpa_ie_len
);
715 sm
->wpa_ie_len
= wpa_ie_len
;
722 * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
723 * @pos: Pointer to the IE header
724 * @end: Pointer to the end of the Key Data buffer
725 * @ie: Pointer to parsed IE data
726 * Returns: 0 on success, 1 if end mark is found, -1 on failure
728 static int wpa_parse_generic(const u8
*pos
, const u8
*end
,
729 struct wpa_eapol_ie_parse
*ie
)
735 RSN_SELECTOR_GET(pos
+ 2) == WPA_OUI_TYPE
&&
736 pos
[2 + WPA_SELECTOR_LEN
] == 1 &&
737 pos
[2 + WPA_SELECTOR_LEN
+ 1] == 0) {
739 ie
->wpa_ie_len
= pos
[1] + 2;
743 if (pos
+ 1 + RSN_SELECTOR_LEN
< end
&&
744 pos
[1] >= RSN_SELECTOR_LEN
+ PMKID_LEN
&&
745 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_PMKID
) {
746 ie
->pmkid
= pos
+ 2 + RSN_SELECTOR_LEN
;
750 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
751 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_GROUPKEY
) {
752 ie
->gtk
= pos
+ 2 + RSN_SELECTOR_LEN
;
753 ie
->gtk_len
= pos
[1] - RSN_SELECTOR_LEN
;
757 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
758 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_MAC_ADDR
) {
759 ie
->mac_addr
= pos
+ 2 + RSN_SELECTOR_LEN
;
760 ie
->mac_addr_len
= pos
[1] - RSN_SELECTOR_LEN
;
764 #ifdef CONFIG_PEERKEY
765 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
766 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_SMK
) {
767 ie
->smk
= pos
+ 2 + RSN_SELECTOR_LEN
;
768 ie
->smk_len
= pos
[1] - RSN_SELECTOR_LEN
;
772 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
773 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_NONCE
) {
774 ie
->nonce
= pos
+ 2 + RSN_SELECTOR_LEN
;
775 ie
->nonce_len
= pos
[1] - RSN_SELECTOR_LEN
;
779 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
780 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_LIFETIME
) {
781 ie
->lifetime
= pos
+ 2 + RSN_SELECTOR_LEN
;
782 ie
->lifetime_len
= pos
[1] - RSN_SELECTOR_LEN
;
786 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
787 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_ERROR
) {
788 ie
->error
= pos
+ 2 + RSN_SELECTOR_LEN
;
789 ie
->error_len
= pos
[1] - RSN_SELECTOR_LEN
;
792 #endif /* CONFIG_PEERKEY */
794 #ifdef CONFIG_IEEE80211W
795 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
796 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_IGTK
) {
797 ie
->igtk
= pos
+ 2 + RSN_SELECTOR_LEN
;
798 ie
->igtk_len
= pos
[1] - RSN_SELECTOR_LEN
;
801 #endif /* CONFIG_IEEE80211W */
808 * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
809 * @buf: Pointer to the Key Data buffer
810 * @len: Key Data Length
811 * @ie: Pointer to parsed IE data
812 * Returns: 0 on success, -1 on failure
814 int wpa_parse_kde_ies(const u8
*buf
, size_t len
, struct wpa_eapol_ie_parse
*ie
)
819 os_memset(ie
, 0, sizeof(*ie
));
820 for (pos
= buf
, end
= pos
+ len
; pos
+ 1 < end
; pos
+= 2 + pos
[1]) {
821 if (pos
[0] == 0xdd &&
822 ((pos
== buf
+ len
- 1) || pos
[1] == 0)) {
826 if (pos
+ 2 + pos
[1] > end
) {
827 wpa_printf(MSG_DEBUG
, "WPA: EAPOL-Key Key Data "
828 "underflow (ie=%d len=%d pos=%d)",
829 pos
[0], pos
[1], (int) (pos
- buf
));
830 wpa_hexdump_key(MSG_DEBUG
, "WPA: Key Data",
835 if (*pos
== WLAN_EID_RSN
) {
837 ie
->rsn_ie_len
= pos
[1] + 2;
838 #ifdef CONFIG_IEEE80211R
839 } else if (*pos
== WLAN_EID_MOBILITY_DOMAIN
) {
841 ie
->mdie_len
= pos
[1] + 2;
842 #endif /* CONFIG_IEEE80211R */
843 } else if (*pos
== WLAN_EID_VENDOR_SPECIFIC
) {
844 ret
= wpa_parse_generic(pos
, end
, ie
);
852 wpa_hexdump(MSG_DEBUG
, "WPA: Unrecognized EAPOL-Key "
853 "Key Data IE", pos
, 2 + pos
[1]);
861 int wpa_auth_uses_mfp(struct wpa_state_machine
*sm
)
863 return sm
? sm
->mgmt_frame_prot
: 0;