2 * hostapd - WPA/RSN IE and KDE definitions
3 * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
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"
17 #include "pmksa_cache_auth.h"
18 #include "wpa_auth_ie.h"
19 #include "wpa_auth_i.h"
22 #ifdef CONFIG_RSN_TESTING
24 #endif /* CONFIG_RSN_TESTING */
27 static int wpa_write_wpa_ie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
)
29 struct wpa_ie_hdr
*hdr
;
34 hdr
= (struct wpa_ie_hdr
*) buf
;
35 hdr
->elem_id
= WLAN_EID_VENDOR_SPECIFIC
;
36 RSN_SELECTOR_PUT(hdr
->oui
, WPA_OUI_TYPE
);
37 WPA_PUT_LE16(hdr
->version
, WPA_VERSION
);
38 pos
= (u8
*) (hdr
+ 1);
40 suite
= wpa_cipher_to_suite(WPA_PROTO_WPA
, conf
->wpa_group
);
42 wpa_printf(MSG_DEBUG
, "Invalid group cipher (%d).",
46 RSN_SELECTOR_PUT(pos
, suite
);
47 pos
+= WPA_SELECTOR_LEN
;
52 num_suites
= wpa_cipher_put_suites(pos
, conf
->wpa_pairwise
);
53 if (num_suites
== 0) {
54 wpa_printf(MSG_DEBUG
, "Invalid pairwise cipher (%d).",
58 pos
+= num_suites
* WPA_SELECTOR_LEN
;
59 WPA_PUT_LE16(count
, num_suites
);
65 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
66 RSN_SELECTOR_PUT(pos
, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
);
67 pos
+= WPA_SELECTOR_LEN
;
70 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
) {
71 RSN_SELECTOR_PUT(pos
, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X
);
72 pos
+= WPA_SELECTOR_LEN
;
76 if (num_suites
== 0) {
77 wpa_printf(MSG_DEBUG
, "Invalid key management type (%d).",
81 WPA_PUT_LE16(count
, num_suites
);
83 /* WPA Capabilities; use defaults, so no need to include it */
85 hdr
->len
= (pos
- buf
) - 2;
91 int wpa_write_rsn_ie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
,
94 struct rsn_ie_hdr
*hdr
;
100 hdr
= (struct rsn_ie_hdr
*) buf
;
101 hdr
->elem_id
= WLAN_EID_RSN
;
102 WPA_PUT_LE16(hdr
->version
, RSN_VERSION
);
103 pos
= (u8
*) (hdr
+ 1);
105 suite
= wpa_cipher_to_suite(WPA_PROTO_RSN
, conf
->wpa_group
);
107 wpa_printf(MSG_DEBUG
, "Invalid group cipher (%d).",
111 RSN_SELECTOR_PUT(pos
, suite
);
112 pos
+= RSN_SELECTOR_LEN
;
118 #ifdef CONFIG_RSN_TESTING
120 RSN_SELECTOR_PUT(pos
, RSN_SELECTOR(0x12, 0x34, 0x56, 1));
121 pos
+= RSN_SELECTOR_LEN
;
124 #endif /* CONFIG_RSN_TESTING */
126 res
= rsn_cipher_put_suites(pos
, conf
->rsn_pairwise
);
128 pos
+= res
* RSN_SELECTOR_LEN
;
130 #ifdef CONFIG_RSN_TESTING
132 RSN_SELECTOR_PUT(pos
, RSN_SELECTOR(0x12, 0x34, 0x56, 2));
133 pos
+= RSN_SELECTOR_LEN
;
136 #endif /* CONFIG_RSN_TESTING */
138 if (num_suites
== 0) {
139 wpa_printf(MSG_DEBUG
, "Invalid pairwise cipher (%d).",
143 WPA_PUT_LE16(count
, num_suites
);
149 #ifdef CONFIG_RSN_TESTING
151 RSN_SELECTOR_PUT(pos
, RSN_SELECTOR(0x12, 0x34, 0x56, 1));
152 pos
+= RSN_SELECTOR_LEN
;
155 #endif /* CONFIG_RSN_TESTING */
157 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
158 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X
);
159 pos
+= RSN_SELECTOR_LEN
;
162 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
) {
163 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X
);
164 pos
+= RSN_SELECTOR_LEN
;
167 #ifdef CONFIG_IEEE80211R
168 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
) {
169 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_FT_802_1X
);
170 pos
+= RSN_SELECTOR_LEN
;
173 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_FT_PSK
) {
174 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_FT_PSK
);
175 pos
+= RSN_SELECTOR_LEN
;
178 #endif /* CONFIG_IEEE80211R */
179 #ifdef CONFIG_IEEE80211W
180 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
) {
181 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_802_1X_SHA256
);
182 pos
+= RSN_SELECTOR_LEN
;
185 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
) {
186 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_PSK_SHA256
);
187 pos
+= RSN_SELECTOR_LEN
;
190 #endif /* CONFIG_IEEE80211W */
192 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_SAE
) {
193 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_SAE
);
194 pos
+= RSN_SELECTOR_LEN
;
197 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_FT_SAE
) {
198 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_FT_SAE
);
199 pos
+= RSN_SELECTOR_LEN
;
202 #endif /* CONFIG_SAE */
203 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B
) {
204 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B
);
205 pos
+= RSN_SELECTOR_LEN
;
208 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B_192
) {
209 RSN_SELECTOR_PUT(pos
, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192
);
210 pos
+= RSN_SELECTOR_LEN
;
214 #ifdef CONFIG_RSN_TESTING
216 RSN_SELECTOR_PUT(pos
, RSN_SELECTOR(0x12, 0x34, 0x56, 2));
217 pos
+= RSN_SELECTOR_LEN
;
220 #endif /* CONFIG_RSN_TESTING */
222 if (num_suites
== 0) {
223 wpa_printf(MSG_DEBUG
, "Invalid key management type (%d).",
227 WPA_PUT_LE16(count
, num_suites
);
229 /* RSN Capabilities */
231 if (conf
->rsn_preauth
)
232 capab
|= WPA_CAPABILITY_PREAUTH
;
234 capab
|= WPA_CAPABILITY_PEERKEY_ENABLED
;
235 if (conf
->wmm_enabled
) {
236 /* 4 PTKSA replay counters when using WMM */
237 capab
|= (RSN_NUM_REPLAY_COUNTERS_16
<< 2);
239 #ifdef CONFIG_IEEE80211W
240 if (conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
241 capab
|= WPA_CAPABILITY_MFPC
;
242 if (conf
->ieee80211w
== MGMT_FRAME_PROTECTION_REQUIRED
)
243 capab
|= WPA_CAPABILITY_MFPR
;
245 #endif /* CONFIG_IEEE80211W */
246 #ifdef CONFIG_RSN_TESTING
248 capab
|= BIT(8) | BIT(14) | BIT(15);
249 #endif /* CONFIG_RSN_TESTING */
250 WPA_PUT_LE16(pos
, capab
);
254 if (pos
+ 2 + PMKID_LEN
> buf
+ len
)
257 WPA_PUT_LE16(pos
, 1);
259 os_memcpy(pos
, pmkid
, PMKID_LEN
);
263 #ifdef CONFIG_IEEE80211W
264 if (conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
265 if (pos
+ 2 + 4 > buf
+ len
)
269 WPA_PUT_LE16(pos
, 0);
273 /* Management Group Cipher Suite */
274 switch (conf
->group_mgmt_cipher
) {
275 case WPA_CIPHER_AES_128_CMAC
:
276 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_AES_128_CMAC
);
278 case WPA_CIPHER_BIP_GMAC_128
:
279 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_BIP_GMAC_128
);
281 case WPA_CIPHER_BIP_GMAC_256
:
282 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_BIP_GMAC_256
);
284 case WPA_CIPHER_BIP_CMAC_256
:
285 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_BIP_CMAC_256
);
288 wpa_printf(MSG_DEBUG
,
289 "Invalid group management cipher (0x%x)",
290 conf
->group_mgmt_cipher
);
293 pos
+= RSN_SELECTOR_LEN
;
295 #endif /* CONFIG_IEEE80211W */
297 #ifdef CONFIG_RSN_TESTING
300 * Fill in any defined fields and add extra data to the end of
303 int pmkid_count_set
= pmkid
!= NULL
;
304 if (conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
)
307 WPA_PUT_LE16(pos
, 0);
309 if (conf
->ieee80211w
== NO_MGMT_FRAME_PROTECTION
) {
310 /* Management Group Cipher Suite */
311 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_AES_128_CMAC
);
312 pos
+= RSN_SELECTOR_LEN
;
315 os_memset(pos
, 0x12, 17);
318 #endif /* CONFIG_RSN_TESTING */
320 hdr
->len
= (pos
- buf
) - 2;
326 static u8
* wpa_write_osen(struct wpa_auth_config
*conf
, u8
*eid
)
331 *eid
++ = WLAN_EID_VENDOR_SPECIFIC
;
332 len
= eid
++; /* to be filled */
333 WPA_PUT_BE24(eid
, OUI_WFA
);
335 *eid
++ = HS20_OSEN_OUI_TYPE
;
337 /* Group Data Cipher Suite */
338 RSN_SELECTOR_PUT(eid
, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED
);
339 eid
+= RSN_SELECTOR_LEN
;
341 /* Pairwise Cipher Suite Count and List */
342 WPA_PUT_LE16(eid
, 1);
344 RSN_SELECTOR_PUT(eid
, RSN_CIPHER_SUITE_CCMP
);
345 eid
+= RSN_SELECTOR_LEN
;
347 /* AKM Suite Count and List */
348 WPA_PUT_LE16(eid
, 1);
350 RSN_SELECTOR_PUT(eid
, RSN_AUTH_KEY_MGMT_OSEN
);
351 eid
+= RSN_SELECTOR_LEN
;
353 /* RSN Capabilities */
355 if (conf
->wmm_enabled
) {
356 /* 4 PTKSA replay counters when using WMM */
357 capab
|= (RSN_NUM_REPLAY_COUNTERS_16
<< 2);
359 #ifdef CONFIG_IEEE80211W
360 if (conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
361 capab
|= WPA_CAPABILITY_MFPC
;
362 if (conf
->ieee80211w
== MGMT_FRAME_PROTECTION_REQUIRED
)
363 capab
|= WPA_CAPABILITY_MFPR
;
365 #endif /* CONFIG_IEEE80211W */
366 WPA_PUT_LE16(eid
, capab
);
369 *len
= eid
- len
- 1;
375 int wpa_auth_gen_wpa_ie(struct wpa_authenticator
*wpa_auth
)
382 if (wpa_auth
->conf
.wpa
== WPA_PROTO_OSEN
) {
383 pos
= wpa_write_osen(&wpa_auth
->conf
, pos
);
385 if (wpa_auth
->conf
.wpa
& WPA_PROTO_RSN
) {
386 res
= wpa_write_rsn_ie(&wpa_auth
->conf
,
387 pos
, buf
+ sizeof(buf
) - pos
, NULL
);
392 #ifdef CONFIG_IEEE80211R
393 if (wpa_key_mgmt_ft(wpa_auth
->conf
.wpa_key_mgmt
)) {
394 res
= wpa_write_mdie(&wpa_auth
->conf
, pos
,
395 buf
+ sizeof(buf
) - pos
);
400 #endif /* CONFIG_IEEE80211R */
401 if (wpa_auth
->conf
.wpa
& WPA_PROTO_WPA
) {
402 res
= wpa_write_wpa_ie(&wpa_auth
->conf
,
403 pos
, buf
+ sizeof(buf
) - pos
);
409 os_free(wpa_auth
->wpa_ie
);
410 wpa_auth
->wpa_ie
= os_malloc(pos
- buf
);
411 if (wpa_auth
->wpa_ie
== NULL
)
413 os_memcpy(wpa_auth
->wpa_ie
, buf
, pos
- buf
);
414 wpa_auth
->wpa_ie_len
= pos
- buf
;
420 u8
* wpa_add_kde(u8
*pos
, u32 kde
, const u8
*data
, size_t data_len
,
421 const u8
*data2
, size_t data2_len
)
423 *pos
++ = WLAN_EID_VENDOR_SPECIFIC
;
424 *pos
++ = RSN_SELECTOR_LEN
+ data_len
+ data2_len
;
425 RSN_SELECTOR_PUT(pos
, kde
);
426 pos
+= RSN_SELECTOR_LEN
;
427 os_memcpy(pos
, data
, data_len
);
430 os_memcpy(pos
, data2
, data2_len
);
437 struct wpa_auth_okc_iter_data
{
438 struct rsn_pmksa_cache_entry
*pmksa
;
445 static int wpa_auth_okc_iter(struct wpa_authenticator
*a
, void *ctx
)
447 struct wpa_auth_okc_iter_data
*data
= ctx
;
448 data
->pmksa
= pmksa_cache_get_okc(a
->pmksa
, data
->aa
, data
->spa
,
456 int wpa_validate_wpa_ie(struct wpa_authenticator
*wpa_auth
,
457 struct wpa_state_machine
*sm
,
458 const u8
*wpa_ie
, size_t wpa_ie_len
,
459 const u8
*mdie
, size_t mdie_len
)
461 struct wpa_ie_data data
;
462 int ciphers
, key_mgmt
, res
, version
;
465 const u8
*pmkid
= NULL
;
467 if (wpa_auth
== NULL
|| sm
== NULL
)
468 return WPA_NOT_ENABLED
;
470 if (wpa_ie
== NULL
|| wpa_ie_len
< 1)
471 return WPA_INVALID_IE
;
473 if (wpa_ie
[0] == WLAN_EID_RSN
)
474 version
= WPA_PROTO_RSN
;
476 version
= WPA_PROTO_WPA
;
478 if (!(wpa_auth
->conf
.wpa
& version
)) {
479 wpa_printf(MSG_DEBUG
, "Invalid WPA proto (%d) from " MACSTR
,
480 version
, MAC2STR(sm
->addr
));
481 return WPA_INVALID_PROTO
;
484 if (version
== WPA_PROTO_RSN
) {
485 res
= wpa_parse_wpa_ie_rsn(wpa_ie
, wpa_ie_len
, &data
);
487 selector
= RSN_AUTH_KEY_MGMT_UNSPEC_802_1X
;
490 else if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B_192
)
491 selector
= RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192
;
492 else if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B
)
493 selector
= RSN_AUTH_KEY_MGMT_802_1X_SUITE_B
;
494 #ifdef CONFIG_IEEE80211R
495 else if (data
.key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
496 selector
= RSN_AUTH_KEY_MGMT_FT_802_1X
;
497 else if (data
.key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
498 selector
= RSN_AUTH_KEY_MGMT_FT_PSK
;
499 #endif /* CONFIG_IEEE80211R */
500 #ifdef CONFIG_IEEE80211W
501 else if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
502 selector
= RSN_AUTH_KEY_MGMT_802_1X_SHA256
;
503 else if (data
.key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
504 selector
= RSN_AUTH_KEY_MGMT_PSK_SHA256
;
505 #endif /* CONFIG_IEEE80211W */
507 else if (data
.key_mgmt
& WPA_KEY_MGMT_SAE
)
508 selector
= RSN_AUTH_KEY_MGMT_SAE
;
509 else if (data
.key_mgmt
& WPA_KEY_MGMT_FT_SAE
)
510 selector
= RSN_AUTH_KEY_MGMT_FT_SAE
;
511 #endif /* CONFIG_SAE */
512 else if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
513 selector
= RSN_AUTH_KEY_MGMT_UNSPEC_802_1X
;
514 else if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
)
515 selector
= RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X
;
516 wpa_auth
->dot11RSNAAuthenticationSuiteSelected
= selector
;
518 selector
= wpa_cipher_to_suite(WPA_PROTO_RSN
,
519 data
.pairwise_cipher
);
521 selector
= RSN_CIPHER_SUITE_CCMP
;
522 wpa_auth
->dot11RSNAPairwiseCipherSelected
= selector
;
524 selector
= wpa_cipher_to_suite(WPA_PROTO_RSN
,
527 selector
= RSN_CIPHER_SUITE_CCMP
;
528 wpa_auth
->dot11RSNAGroupCipherSelected
= selector
;
530 res
= wpa_parse_wpa_ie_wpa(wpa_ie
, wpa_ie_len
, &data
);
532 selector
= WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
;
533 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
534 selector
= WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
;
535 else if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
)
536 selector
= WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X
;
537 wpa_auth
->dot11RSNAAuthenticationSuiteSelected
= selector
;
539 selector
= wpa_cipher_to_suite(WPA_PROTO_WPA
,
540 data
.pairwise_cipher
);
542 selector
= RSN_CIPHER_SUITE_TKIP
;
543 wpa_auth
->dot11RSNAPairwiseCipherSelected
= selector
;
545 selector
= wpa_cipher_to_suite(WPA_PROTO_WPA
,
548 selector
= WPA_CIPHER_SUITE_TKIP
;
549 wpa_auth
->dot11RSNAGroupCipherSelected
= selector
;
552 wpa_printf(MSG_DEBUG
, "Failed to parse WPA/RSN IE from "
553 MACSTR
" (res=%d)", MAC2STR(sm
->addr
), res
);
554 wpa_hexdump(MSG_DEBUG
, "WPA/RSN IE", wpa_ie
, wpa_ie_len
);
555 return WPA_INVALID_IE
;
558 if (data
.group_cipher
!= wpa_auth
->conf
.wpa_group
) {
559 wpa_printf(MSG_DEBUG
, "Invalid WPA group cipher (0x%x) from "
560 MACSTR
, data
.group_cipher
, MAC2STR(sm
->addr
));
561 return WPA_INVALID_GROUP
;
564 key_mgmt
= data
.key_mgmt
& wpa_auth
->conf
.wpa_key_mgmt
;
566 wpa_printf(MSG_DEBUG
, "Invalid WPA key mgmt (0x%x) from "
567 MACSTR
, data
.key_mgmt
, MAC2STR(sm
->addr
));
568 return WPA_INVALID_AKMP
;
572 else if (key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B_192
)
573 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_IEEE8021X_SUITE_B_192
;
574 else if (key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B
)
575 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_IEEE8021X_SUITE_B
;
576 #ifdef CONFIG_IEEE80211R
577 else if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
578 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X
;
579 else if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
580 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_PSK
;
581 #endif /* CONFIG_IEEE80211R */
582 #ifdef CONFIG_IEEE80211W
583 else if (key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
584 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_IEEE8021X_SHA256
;
585 else if (key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
586 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_PSK_SHA256
;
587 #endif /* CONFIG_IEEE80211W */
589 else if (key_mgmt
& WPA_KEY_MGMT_SAE
)
590 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_SAE
;
591 else if (key_mgmt
& WPA_KEY_MGMT_FT_SAE
)
592 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_SAE
;
593 #endif /* CONFIG_SAE */
594 else if (key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
595 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_IEEE8021X
;
597 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
599 if (version
== WPA_PROTO_RSN
)
600 ciphers
= data
.pairwise_cipher
& wpa_auth
->conf
.rsn_pairwise
;
602 ciphers
= data
.pairwise_cipher
& wpa_auth
->conf
.wpa_pairwise
;
604 wpa_printf(MSG_DEBUG
, "Invalid %s pairwise cipher (0x%x) "
606 version
== WPA_PROTO_RSN
? "RSN" : "WPA",
607 data
.pairwise_cipher
, MAC2STR(sm
->addr
));
608 return WPA_INVALID_PAIRWISE
;
611 #ifdef CONFIG_IEEE80211W
612 if (wpa_auth
->conf
.ieee80211w
== MGMT_FRAME_PROTECTION_REQUIRED
) {
613 if (!(data
.capabilities
& WPA_CAPABILITY_MFPC
)) {
614 wpa_printf(MSG_DEBUG
, "Management frame protection "
615 "required, but client did not enable it");
616 return WPA_MGMT_FRAME_PROTECTION_VIOLATION
;
619 if (ciphers
& WPA_CIPHER_TKIP
) {
620 wpa_printf(MSG_DEBUG
, "Management frame protection "
622 return WPA_MGMT_FRAME_PROTECTION_VIOLATION
;
625 if (data
.mgmt_group_cipher
!= wpa_auth
->conf
.group_mgmt_cipher
)
627 wpa_printf(MSG_DEBUG
, "Unsupported management group "
628 "cipher %d", data
.mgmt_group_cipher
);
629 return WPA_INVALID_MGMT_GROUP_CIPHER
;
633 if (wpa_auth
->conf
.ieee80211w
== NO_MGMT_FRAME_PROTECTION
||
634 !(data
.capabilities
& WPA_CAPABILITY_MFPC
))
635 sm
->mgmt_frame_prot
= 0;
637 sm
->mgmt_frame_prot
= 1;
638 #endif /* CONFIG_IEEE80211W */
640 #ifdef CONFIG_IEEE80211R
641 if (wpa_key_mgmt_ft(sm
->wpa_key_mgmt
)) {
642 if (mdie
== NULL
|| mdie_len
< MOBILITY_DOMAIN_ID_LEN
+ 1) {
643 wpa_printf(MSG_DEBUG
, "RSN: Trying to use FT, but "
644 "MDIE not included");
645 return WPA_INVALID_MDIE
;
647 if (os_memcmp(mdie
, wpa_auth
->conf
.mobility_domain
,
648 MOBILITY_DOMAIN_ID_LEN
) != 0) {
649 wpa_hexdump(MSG_DEBUG
, "RSN: Attempted to use unknown "
650 "MDIE", mdie
, MOBILITY_DOMAIN_ID_LEN
);
651 return WPA_INVALID_MDIE
;
654 #endif /* CONFIG_IEEE80211R */
656 sm
->pairwise
= wpa_pick_pairwise_cipher(ciphers
, 0);
657 if (sm
->pairwise
< 0)
658 return WPA_INVALID_PAIRWISE
;
660 /* TODO: clear WPA/WPA2 state if STA changes from one to another */
661 if (wpa_ie
[0] == WLAN_EID_RSN
)
662 sm
->wpa
= WPA_VERSION_WPA2
;
664 sm
->wpa
= WPA_VERSION_WPA
;
667 for (i
= 0; i
< data
.num_pmkid
; i
++) {
668 wpa_hexdump(MSG_DEBUG
, "RSN IE: STA PMKID",
669 &data
.pmkid
[i
* PMKID_LEN
], PMKID_LEN
);
670 sm
->pmksa
= pmksa_cache_auth_get(wpa_auth
->pmksa
, sm
->addr
,
671 &data
.pmkid
[i
* PMKID_LEN
]);
673 pmkid
= sm
->pmksa
->pmkid
;
677 for (i
= 0; sm
->pmksa
== NULL
&& wpa_auth
->conf
.okc
&&
678 i
< data
.num_pmkid
; i
++) {
679 struct wpa_auth_okc_iter_data idata
;
681 idata
.aa
= wpa_auth
->addr
;
682 idata
.spa
= sm
->addr
;
683 idata
.pmkid
= &data
.pmkid
[i
* PMKID_LEN
];
684 wpa_auth_for_each_auth(wpa_auth
, wpa_auth_okc_iter
, &idata
);
686 wpa_auth_vlogger(wpa_auth
, sm
->addr
, LOGGER_DEBUG
,
687 "OKC match for PMKID");
688 sm
->pmksa
= pmksa_cache_add_okc(wpa_auth
->pmksa
,
696 if (sm
->pmksa
&& pmkid
) {
697 wpa_auth_vlogger(wpa_auth
, sm
->addr
, LOGGER_DEBUG
,
698 "PMKID found from PMKSA cache "
699 "eap_type=%d vlan_id=%d",
700 sm
->pmksa
->eap_type_authsrv
,
702 os_memcpy(wpa_auth
->dot11RSNAPMKIDUsed
, pmkid
, PMKID_LEN
);
705 if (sm
->wpa_ie
== NULL
|| sm
->wpa_ie_len
< wpa_ie_len
) {
707 sm
->wpa_ie
= os_malloc(wpa_ie_len
);
708 if (sm
->wpa_ie
== NULL
)
709 return WPA_ALLOC_FAIL
;
711 os_memcpy(sm
->wpa_ie
, wpa_ie
, wpa_ie_len
);
712 sm
->wpa_ie_len
= wpa_ie_len
;
719 int wpa_validate_osen(struct wpa_authenticator
*wpa_auth
,
720 struct wpa_state_machine
*sm
,
721 const u8
*osen_ie
, size_t osen_ie_len
)
723 if (wpa_auth
== NULL
|| sm
== NULL
)
726 /* TODO: parse OSEN element */
727 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_OSEN
;
728 sm
->mgmt_frame_prot
= 1;
729 sm
->pairwise
= WPA_CIPHER_CCMP
;
730 sm
->wpa
= WPA_VERSION_WPA2
;
732 if (sm
->wpa_ie
== NULL
|| sm
->wpa_ie_len
< osen_ie_len
) {
734 sm
->wpa_ie
= os_malloc(osen_ie_len
);
735 if (sm
->wpa_ie
== NULL
)
739 os_memcpy(sm
->wpa_ie
, osen_ie
, osen_ie_len
);
740 sm
->wpa_ie_len
= osen_ie_len
;
745 #endif /* CONFIG_HS20 */
749 * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
750 * @pos: Pointer to the IE header
751 * @end: Pointer to the end of the Key Data buffer
752 * @ie: Pointer to parsed IE data
753 * Returns: 0 on success, 1 if end mark is found, -1 on failure
755 static int wpa_parse_generic(const u8
*pos
, const u8
*end
,
756 struct wpa_eapol_ie_parse
*ie
)
762 RSN_SELECTOR_GET(pos
+ 2) == WPA_OUI_TYPE
&&
763 pos
[2 + WPA_SELECTOR_LEN
] == 1 &&
764 pos
[2 + WPA_SELECTOR_LEN
+ 1] == 0) {
766 ie
->wpa_ie_len
= pos
[1] + 2;
770 if (pos
[1] >= 4 && WPA_GET_BE32(pos
+ 2) == OSEN_IE_VENDOR_TYPE
) {
772 ie
->osen_len
= pos
[1] + 2;
776 if (pos
+ 1 + RSN_SELECTOR_LEN
< end
&&
777 pos
[1] >= RSN_SELECTOR_LEN
+ PMKID_LEN
&&
778 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_PMKID
) {
779 ie
->pmkid
= pos
+ 2 + RSN_SELECTOR_LEN
;
783 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
784 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_GROUPKEY
) {
785 ie
->gtk
= pos
+ 2 + RSN_SELECTOR_LEN
;
786 ie
->gtk_len
= pos
[1] - RSN_SELECTOR_LEN
;
790 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
791 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_MAC_ADDR
) {
792 ie
->mac_addr
= pos
+ 2 + RSN_SELECTOR_LEN
;
793 ie
->mac_addr_len
= pos
[1] - RSN_SELECTOR_LEN
;
797 #ifdef CONFIG_PEERKEY
798 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
799 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_SMK
) {
800 ie
->smk
= pos
+ 2 + RSN_SELECTOR_LEN
;
801 ie
->smk_len
= pos
[1] - RSN_SELECTOR_LEN
;
805 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
806 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_NONCE
) {
807 ie
->nonce
= pos
+ 2 + RSN_SELECTOR_LEN
;
808 ie
->nonce_len
= pos
[1] - RSN_SELECTOR_LEN
;
812 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
813 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_LIFETIME
) {
814 ie
->lifetime
= pos
+ 2 + RSN_SELECTOR_LEN
;
815 ie
->lifetime_len
= pos
[1] - RSN_SELECTOR_LEN
;
819 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
820 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_ERROR
) {
821 ie
->error
= pos
+ 2 + RSN_SELECTOR_LEN
;
822 ie
->error_len
= pos
[1] - RSN_SELECTOR_LEN
;
825 #endif /* CONFIG_PEERKEY */
827 #ifdef CONFIG_IEEE80211W
828 if (pos
[1] > RSN_SELECTOR_LEN
+ 2 &&
829 RSN_SELECTOR_GET(pos
+ 2) == RSN_KEY_DATA_IGTK
) {
830 ie
->igtk
= pos
+ 2 + RSN_SELECTOR_LEN
;
831 ie
->igtk_len
= pos
[1] - RSN_SELECTOR_LEN
;
834 #endif /* CONFIG_IEEE80211W */
837 if (pos
[1] >= RSN_SELECTOR_LEN
+ 1 &&
838 RSN_SELECTOR_GET(pos
+ 2) == WFA_KEY_DATA_IP_ADDR_REQ
) {
839 ie
->ip_addr_req
= pos
+ 2 + RSN_SELECTOR_LEN
;
840 wpa_hexdump(MSG_DEBUG
, "WPA: IP Address Request in EAPOL-Key",
841 ie
->ip_addr_req
, pos
[1] - RSN_SELECTOR_LEN
);
845 if (pos
[1] >= RSN_SELECTOR_LEN
+ 3 * 4 &&
846 RSN_SELECTOR_GET(pos
+ 2) == WFA_KEY_DATA_IP_ADDR_ALLOC
) {
847 ie
->ip_addr_alloc
= pos
+ 2 + RSN_SELECTOR_LEN
;
848 wpa_hexdump(MSG_DEBUG
,
849 "WPA: IP Address Allocation in EAPOL-Key",
850 ie
->ip_addr_alloc
, pos
[1] - RSN_SELECTOR_LEN
);
853 #endif /* CONFIG_P2P */
860 * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
861 * @buf: Pointer to the Key Data buffer
862 * @len: Key Data Length
863 * @ie: Pointer to parsed IE data
864 * Returns: 0 on success, -1 on failure
866 int wpa_parse_kde_ies(const u8
*buf
, size_t len
, struct wpa_eapol_ie_parse
*ie
)
871 os_memset(ie
, 0, sizeof(*ie
));
872 for (pos
= buf
, end
= pos
+ len
; pos
+ 1 < end
; pos
+= 2 + pos
[1]) {
873 if (pos
[0] == 0xdd &&
874 ((pos
== buf
+ len
- 1) || pos
[1] == 0)) {
878 if (pos
+ 2 + pos
[1] > end
) {
879 wpa_printf(MSG_DEBUG
, "WPA: EAPOL-Key Key Data "
880 "underflow (ie=%d len=%d pos=%d)",
881 pos
[0], pos
[1], (int) (pos
- buf
));
882 wpa_hexdump_key(MSG_DEBUG
, "WPA: Key Data",
887 if (*pos
== WLAN_EID_RSN
) {
889 ie
->rsn_ie_len
= pos
[1] + 2;
890 #ifdef CONFIG_IEEE80211R
891 } else if (*pos
== WLAN_EID_MOBILITY_DOMAIN
) {
893 ie
->mdie_len
= pos
[1] + 2;
894 } else if (*pos
== WLAN_EID_FAST_BSS_TRANSITION
) {
896 ie
->ftie_len
= pos
[1] + 2;
897 #endif /* CONFIG_IEEE80211R */
898 } else if (*pos
== WLAN_EID_VENDOR_SPECIFIC
) {
899 ret
= wpa_parse_generic(pos
, end
, ie
);
907 wpa_hexdump(MSG_DEBUG
, "WPA: Unrecognized EAPOL-Key "
908 "Key Data IE", pos
, 2 + pos
[1]);
916 int wpa_auth_uses_mfp(struct wpa_state_machine
*sm
)
918 return sm
? sm
->mgmt_frame_prot
: 0;