2 * WPA/RSN - Shared functions for supplicant and authenticator
3 * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "crypto/md5.h"
13 #include "crypto/sha1.h"
14 #include "crypto/sha256.h"
15 #include "crypto/aes_wrap.h"
16 #include "crypto/crypto.h"
17 #include "ieee802_11_defs.h"
19 #include "wpa_common.h"
23 * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
24 * @key: EAPOL-Key Key Confirmation Key (KCK)
25 * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
26 * @buf: Pointer to the beginning of the EAPOL header (version field)
27 * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
28 * @mic: Pointer to the buffer to which the EAPOL-Key MIC is written
29 * Returns: 0 on success, -1 on failure
31 * Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has
32 * to be cleared (all zeroes) when calling this function.
34 * Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the
35 * description of the Key MIC calculation. It includes packet data from the
36 * beginning of the EAPOL-Key header, not EAPOL header. This incorrect change
37 * happened during final editing of the standard and the correct behavior is
38 * defined in the last draft (IEEE 802.11i/D10).
40 int wpa_eapol_key_mic(const u8
*key
, int ver
, const u8
*buf
, size_t len
,
43 u8 hash
[SHA1_MAC_LEN
];
47 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
:
48 return hmac_md5(key
, 16, buf
, len
, mic
);
49 #endif /* CONFIG_FIPS */
50 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
:
51 if (hmac_sha1(key
, 16, buf
, len
, hash
))
53 os_memcpy(mic
, hash
, MD5_MAC_LEN
);
55 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
56 case WPA_KEY_INFO_TYPE_AES_128_CMAC
:
57 return omac1_aes_128(key
, buf
, len
, mic
);
58 #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
60 case WPA_KEY_INFO_TYPE_AKM_DEFINED
:
61 /* FIX: This should be based on negotiated AKM */
62 return omac1_aes_128(key
, buf
, len
, mic
);
63 #endif /* CONFIG_HS20 */
73 * wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces
74 * @pmk: Pairwise master key
75 * @pmk_len: Length of PMK
76 * @label: Label to use in derivation
79 * @nonce1: ANonce or SNonce
80 * @nonce2: SNonce or ANonce
81 * @ptk: Buffer for pairwise transient key
82 * @ptk_len: Length of PTK
83 * @use_sha256: Whether to use SHA256-based KDF
85 * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
86 * PTK = PRF-X(PMK, "Pairwise key expansion",
87 * Min(AA, SA) || Max(AA, SA) ||
88 * Min(ANonce, SNonce) || Max(ANonce, SNonce))
90 * STK = PRF-X(SMK, "Peer key expansion",
91 * Min(MAC_I, MAC_P) || Max(MAC_I, MAC_P) ||
92 * Min(INonce, PNonce) || Max(INonce, PNonce))
94 void wpa_pmk_to_ptk(const u8
*pmk
, size_t pmk_len
, const char *label
,
95 const u8
*addr1
, const u8
*addr2
,
96 const u8
*nonce1
, const u8
*nonce2
,
97 u8
*ptk
, size_t ptk_len
, int use_sha256
)
99 u8 data
[2 * ETH_ALEN
+ 2 * WPA_NONCE_LEN
];
101 if (os_memcmp(addr1
, addr2
, ETH_ALEN
) < 0) {
102 os_memcpy(data
, addr1
, ETH_ALEN
);
103 os_memcpy(data
+ ETH_ALEN
, addr2
, ETH_ALEN
);
105 os_memcpy(data
, addr2
, ETH_ALEN
);
106 os_memcpy(data
+ ETH_ALEN
, addr1
, ETH_ALEN
);
109 if (os_memcmp(nonce1
, nonce2
, WPA_NONCE_LEN
) < 0) {
110 os_memcpy(data
+ 2 * ETH_ALEN
, nonce1
, WPA_NONCE_LEN
);
111 os_memcpy(data
+ 2 * ETH_ALEN
+ WPA_NONCE_LEN
, nonce2
,
114 os_memcpy(data
+ 2 * ETH_ALEN
, nonce2
, WPA_NONCE_LEN
);
115 os_memcpy(data
+ 2 * ETH_ALEN
+ WPA_NONCE_LEN
, nonce1
,
119 #ifdef CONFIG_IEEE80211W
121 sha256_prf(pmk
, pmk_len
, label
, data
, sizeof(data
),
124 #endif /* CONFIG_IEEE80211W */
125 sha1_prf(pmk
, pmk_len
, label
, data
, sizeof(data
), ptk
,
128 wpa_printf(MSG_DEBUG
, "WPA: PTK derivation - A1=" MACSTR
" A2=" MACSTR
,
129 MAC2STR(addr1
), MAC2STR(addr2
));
130 wpa_hexdump(MSG_DEBUG
, "WPA: Nonce1", nonce1
, WPA_NONCE_LEN
);
131 wpa_hexdump(MSG_DEBUG
, "WPA: Nonce2", nonce2
, WPA_NONCE_LEN
);
132 wpa_hexdump_key(MSG_DEBUG
, "WPA: PMK", pmk
, pmk_len
);
133 wpa_hexdump_key(MSG_DEBUG
, "WPA: PTK", ptk
, ptk_len
);
137 #ifdef CONFIG_IEEE80211R
138 int wpa_ft_mic(const u8
*kck
, const u8
*sta_addr
, const u8
*ap_addr
,
139 u8 transaction_seqnum
, const u8
*mdie
, size_t mdie_len
,
140 const u8
*ftie
, size_t ftie_len
,
141 const u8
*rsnie
, size_t rsnie_len
,
142 const u8
*ric
, size_t ric_len
, u8
*mic
)
147 buf_len
= 2 * ETH_ALEN
+ 1 + mdie_len
+ ftie_len
+ rsnie_len
+ ric_len
;
148 buf
= os_malloc(buf_len
);
153 os_memcpy(pos
, sta_addr
, ETH_ALEN
);
155 os_memcpy(pos
, ap_addr
, ETH_ALEN
);
157 *pos
++ = transaction_seqnum
;
159 os_memcpy(pos
, rsnie
, rsnie_len
);
163 os_memcpy(pos
, mdie
, mdie_len
);
167 struct rsn_ftie
*_ftie
;
168 os_memcpy(pos
, ftie
, ftie_len
);
169 if (ftie_len
< 2 + sizeof(*_ftie
)) {
173 _ftie
= (struct rsn_ftie
*) (pos
+ 2);
174 os_memset(_ftie
->mic
, 0, sizeof(_ftie
->mic
));
178 os_memcpy(pos
, ric
, ric_len
);
182 wpa_hexdump(MSG_MSGDUMP
, "FT: MIC data", buf
, pos
- buf
);
183 if (omac1_aes_128(kck
, buf
, pos
- buf
, mic
)) {
194 static int wpa_ft_parse_ftie(const u8
*ie
, size_t ie_len
,
195 struct wpa_ft_ies
*parse
)
200 parse
->ftie_len
= ie_len
;
202 pos
= ie
+ sizeof(struct rsn_ftie
);
205 while (pos
+ 2 <= end
&& pos
+ 2 + pos
[1] <= end
) {
207 case FTIE_SUBELEM_R1KH_ID
:
208 if (pos
[1] != FT_R1KH_ID_LEN
) {
209 wpa_printf(MSG_DEBUG
, "FT: Invalid R1KH-ID "
210 "length in FTIE: %d", pos
[1]);
213 parse
->r1kh_id
= pos
+ 2;
215 case FTIE_SUBELEM_GTK
:
216 parse
->gtk
= pos
+ 2;
217 parse
->gtk_len
= pos
[1];
219 case FTIE_SUBELEM_R0KH_ID
:
220 if (pos
[1] < 1 || pos
[1] > FT_R0KH_ID_MAX_LEN
) {
221 wpa_printf(MSG_DEBUG
, "FT: Invalid R0KH-ID "
222 "length in FTIE: %d", pos
[1]);
225 parse
->r0kh_id
= pos
+ 2;
226 parse
->r0kh_id_len
= pos
[1];
228 #ifdef CONFIG_IEEE80211W
229 case FTIE_SUBELEM_IGTK
:
230 parse
->igtk
= pos
+ 2;
231 parse
->igtk_len
= pos
[1];
233 #endif /* CONFIG_IEEE80211W */
243 int wpa_ft_parse_ies(const u8
*ies
, size_t ies_len
,
244 struct wpa_ft_ies
*parse
)
247 struct wpa_ie_data data
;
249 const struct rsn_ftie
*ftie
;
250 int prot_ie_count
= 0;
252 os_memset(parse
, 0, sizeof(*parse
));
258 while (pos
+ 2 <= end
&& pos
+ 2 + pos
[1] <= end
) {
261 parse
->rsn
= pos
+ 2;
262 parse
->rsn_len
= pos
[1];
263 ret
= wpa_parse_wpa_ie_rsn(parse
->rsn
- 2,
267 wpa_printf(MSG_DEBUG
, "FT: Failed to parse "
271 if (data
.num_pmkid
== 1 && data
.pmkid
)
272 parse
->rsn_pmkid
= data
.pmkid
;
274 case WLAN_EID_MOBILITY_DOMAIN
:
275 parse
->mdie
= pos
+ 2;
276 parse
->mdie_len
= pos
[1];
278 case WLAN_EID_FAST_BSS_TRANSITION
:
279 if (pos
[1] < sizeof(*ftie
))
281 ftie
= (const struct rsn_ftie
*) (pos
+ 2);
282 prot_ie_count
= ftie
->mic_control
[1];
283 if (wpa_ft_parse_ftie(pos
+ 2, pos
[1], parse
) < 0)
286 case WLAN_EID_TIMEOUT_INTERVAL
:
287 parse
->tie
= pos
+ 2;
288 parse
->tie_len
= pos
[1];
290 case WLAN_EID_RIC_DATA
:
291 if (parse
->ric
== NULL
)
299 if (prot_ie_count
== 0)
300 return 0; /* no MIC */
303 * Check that the protected IE count matches with IEs included in the
312 if (prot_ie_count
< 0) {
313 wpa_printf(MSG_DEBUG
, "FT: Some required IEs not included in "
314 "the protected IE count");
318 if (prot_ie_count
== 0 && parse
->ric
) {
319 wpa_printf(MSG_DEBUG
, "FT: RIC IE(s) in the frame, but not "
320 "included in protected IE count");
324 /* Determine the end of the RIC IE(s) */
326 while (pos
&& pos
+ 2 <= end
&& pos
+ 2 + pos
[1] <= end
&&
331 parse
->ric_len
= pos
- parse
->ric
;
333 wpa_printf(MSG_DEBUG
, "FT: %d protected IEs missing from "
334 "frame", (int) prot_ie_count
);
340 #endif /* CONFIG_IEEE80211R */
343 static int rsn_selector_to_bitfield(const u8
*s
)
345 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_NONE
)
346 return WPA_CIPHER_NONE
;
347 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_WEP40
)
348 return WPA_CIPHER_WEP40
;
349 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_TKIP
)
350 return WPA_CIPHER_TKIP
;
351 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_CCMP
)
352 return WPA_CIPHER_CCMP
;
353 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_WEP104
)
354 return WPA_CIPHER_WEP104
;
355 #ifdef CONFIG_IEEE80211W
356 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_AES_128_CMAC
)
357 return WPA_CIPHER_AES_128_CMAC
;
358 #endif /* CONFIG_IEEE80211W */
359 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_GCMP
)
360 return WPA_CIPHER_GCMP
;
361 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_CCMP_256
)
362 return WPA_CIPHER_CCMP_256
;
363 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_GCMP_256
)
364 return WPA_CIPHER_GCMP_256
;
365 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_BIP_GMAC_128
)
366 return WPA_CIPHER_BIP_GMAC_128
;
367 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_BIP_GMAC_256
)
368 return WPA_CIPHER_BIP_GMAC_256
;
369 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_BIP_CMAC_256
)
370 return WPA_CIPHER_BIP_CMAC_256
;
371 if (RSN_SELECTOR_GET(s
) == RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED
)
372 return WPA_CIPHER_GTK_NOT_USED
;
377 static int rsn_key_mgmt_to_bitfield(const u8
*s
)
379 if (RSN_SELECTOR_GET(s
) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X
)
380 return WPA_KEY_MGMT_IEEE8021X
;
381 if (RSN_SELECTOR_GET(s
) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X
)
382 return WPA_KEY_MGMT_PSK
;
383 #ifdef CONFIG_IEEE80211R
384 if (RSN_SELECTOR_GET(s
) == RSN_AUTH_KEY_MGMT_FT_802_1X
)
385 return WPA_KEY_MGMT_FT_IEEE8021X
;
386 if (RSN_SELECTOR_GET(s
) == RSN_AUTH_KEY_MGMT_FT_PSK
)
387 return WPA_KEY_MGMT_FT_PSK
;
388 #endif /* CONFIG_IEEE80211R */
389 #ifdef CONFIG_IEEE80211W
390 if (RSN_SELECTOR_GET(s
) == RSN_AUTH_KEY_MGMT_802_1X_SHA256
)
391 return WPA_KEY_MGMT_IEEE8021X_SHA256
;
392 if (RSN_SELECTOR_GET(s
) == RSN_AUTH_KEY_MGMT_PSK_SHA256
)
393 return WPA_KEY_MGMT_PSK_SHA256
;
394 #endif /* CONFIG_IEEE80211W */
396 if (RSN_SELECTOR_GET(s
) == RSN_AUTH_KEY_MGMT_SAE
)
397 return WPA_KEY_MGMT_SAE
;
398 if (RSN_SELECTOR_GET(s
) == RSN_AUTH_KEY_MGMT_FT_SAE
)
399 return WPA_KEY_MGMT_FT_SAE
;
400 #endif /* CONFIG_SAE */
405 static int wpa_cipher_valid_group(int cipher
)
407 return wpa_cipher_valid_pairwise(cipher
) ||
408 cipher
== WPA_CIPHER_WEP104
||
409 cipher
== WPA_CIPHER_WEP40
||
410 cipher
== WPA_CIPHER_GTK_NOT_USED
;
414 #ifdef CONFIG_IEEE80211W
415 int wpa_cipher_valid_mgmt_group(int cipher
)
417 return cipher
== WPA_CIPHER_AES_128_CMAC
||
418 cipher
== WPA_CIPHER_BIP_GMAC_128
||
419 cipher
== WPA_CIPHER_BIP_GMAC_256
||
420 cipher
== WPA_CIPHER_BIP_CMAC_256
;
422 #endif /* CONFIG_IEEE80211W */
426 * wpa_parse_wpa_ie_rsn - Parse RSN IE
427 * @rsn_ie: Buffer containing RSN IE
428 * @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
429 * @data: Pointer to structure that will be filled in with parsed data
430 * Returns: 0 on success, <0 on failure
432 int wpa_parse_wpa_ie_rsn(const u8
*rsn_ie
, size_t rsn_ie_len
,
433 struct wpa_ie_data
*data
)
435 const struct rsn_ie_hdr
*hdr
;
440 os_memset(data
, 0, sizeof(*data
));
441 data
->proto
= WPA_PROTO_RSN
;
442 data
->pairwise_cipher
= WPA_CIPHER_CCMP
;
443 data
->group_cipher
= WPA_CIPHER_CCMP
;
444 data
->key_mgmt
= WPA_KEY_MGMT_IEEE8021X
;
445 data
->capabilities
= 0;
448 #ifdef CONFIG_IEEE80211W
449 data
->mgmt_group_cipher
= WPA_CIPHER_AES_128_CMAC
;
450 #else /* CONFIG_IEEE80211W */
451 data
->mgmt_group_cipher
= 0;
452 #endif /* CONFIG_IEEE80211W */
454 if (rsn_ie_len
== 0) {
455 /* No RSN IE - fail silently */
459 if (rsn_ie_len
< sizeof(struct rsn_ie_hdr
)) {
460 wpa_printf(MSG_DEBUG
, "%s: ie len too short %lu",
461 __func__
, (unsigned long) rsn_ie_len
);
465 hdr
= (const struct rsn_ie_hdr
*) rsn_ie
;
467 if (hdr
->elem_id
!= WLAN_EID_RSN
||
468 hdr
->len
!= rsn_ie_len
- 2 ||
469 WPA_GET_LE16(hdr
->version
) != RSN_VERSION
) {
470 wpa_printf(MSG_DEBUG
, "%s: malformed ie or unknown version",
475 pos
= (const u8
*) (hdr
+ 1);
476 left
= rsn_ie_len
- sizeof(*hdr
);
478 if (left
>= RSN_SELECTOR_LEN
) {
479 data
->group_cipher
= rsn_selector_to_bitfield(pos
);
480 if (!wpa_cipher_valid_group(data
->group_cipher
)) {
481 wpa_printf(MSG_DEBUG
, "%s: invalid group cipher 0x%x",
482 __func__
, data
->group_cipher
);
485 pos
+= RSN_SELECTOR_LEN
;
486 left
-= RSN_SELECTOR_LEN
;
487 } else if (left
> 0) {
488 wpa_printf(MSG_DEBUG
, "%s: ie length mismatch, %u too much",
494 data
->pairwise_cipher
= 0;
495 count
= WPA_GET_LE16(pos
);
498 if (count
== 0 || left
< count
* RSN_SELECTOR_LEN
) {
499 wpa_printf(MSG_DEBUG
, "%s: ie count botch (pairwise), "
500 "count %u left %u", __func__
, count
, left
);
503 for (i
= 0; i
< count
; i
++) {
504 data
->pairwise_cipher
|= rsn_selector_to_bitfield(pos
);
505 pos
+= RSN_SELECTOR_LEN
;
506 left
-= RSN_SELECTOR_LEN
;
508 #ifdef CONFIG_IEEE80211W
509 if (data
->pairwise_cipher
& WPA_CIPHER_AES_128_CMAC
) {
510 wpa_printf(MSG_DEBUG
, "%s: AES-128-CMAC used as "
511 "pairwise cipher", __func__
);
514 #endif /* CONFIG_IEEE80211W */
515 } else if (left
== 1) {
516 wpa_printf(MSG_DEBUG
, "%s: ie too short (for key mgmt)",
523 count
= WPA_GET_LE16(pos
);
526 if (count
== 0 || left
< count
* RSN_SELECTOR_LEN
) {
527 wpa_printf(MSG_DEBUG
, "%s: ie count botch (key mgmt), "
528 "count %u left %u", __func__
, count
, left
);
531 for (i
= 0; i
< count
; i
++) {
532 data
->key_mgmt
|= rsn_key_mgmt_to_bitfield(pos
);
533 pos
+= RSN_SELECTOR_LEN
;
534 left
-= RSN_SELECTOR_LEN
;
536 } else if (left
== 1) {
537 wpa_printf(MSG_DEBUG
, "%s: ie too short (for capabilities)",
543 data
->capabilities
= WPA_GET_LE16(pos
);
549 data
->num_pmkid
= WPA_GET_LE16(pos
);
552 if (left
< (int) data
->num_pmkid
* PMKID_LEN
) {
553 wpa_printf(MSG_DEBUG
, "%s: PMKID underflow "
554 "(num_pmkid=%lu left=%d)",
555 __func__
, (unsigned long) data
->num_pmkid
,
561 pos
+= data
->num_pmkid
* PMKID_LEN
;
562 left
-= data
->num_pmkid
* PMKID_LEN
;
566 #ifdef CONFIG_IEEE80211W
568 data
->mgmt_group_cipher
= rsn_selector_to_bitfield(pos
);
569 if (!wpa_cipher_valid_mgmt_group(data
->mgmt_group_cipher
)) {
570 wpa_printf(MSG_DEBUG
, "%s: Unsupported management "
571 "group cipher 0x%x", __func__
,
572 data
->mgmt_group_cipher
);
575 pos
+= RSN_SELECTOR_LEN
;
576 left
-= RSN_SELECTOR_LEN
;
578 #endif /* CONFIG_IEEE80211W */
581 wpa_hexdump(MSG_DEBUG
,
582 "wpa_parse_wpa_ie_rsn: ignore trailing bytes",
590 static int wpa_selector_to_bitfield(const u8
*s
)
592 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_NONE
)
593 return WPA_CIPHER_NONE
;
594 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_WEP40
)
595 return WPA_CIPHER_WEP40
;
596 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_TKIP
)
597 return WPA_CIPHER_TKIP
;
598 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_CCMP
)
599 return WPA_CIPHER_CCMP
;
600 if (RSN_SELECTOR_GET(s
) == WPA_CIPHER_SUITE_WEP104
)
601 return WPA_CIPHER_WEP104
;
606 static int wpa_key_mgmt_to_bitfield(const u8
*s
)
608 if (RSN_SELECTOR_GET(s
) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X
)
609 return WPA_KEY_MGMT_IEEE8021X
;
610 if (RSN_SELECTOR_GET(s
) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X
)
611 return WPA_KEY_MGMT_PSK
;
612 if (RSN_SELECTOR_GET(s
) == WPA_AUTH_KEY_MGMT_NONE
)
613 return WPA_KEY_MGMT_WPA_NONE
;
618 int wpa_parse_wpa_ie_wpa(const u8
*wpa_ie
, size_t wpa_ie_len
,
619 struct wpa_ie_data
*data
)
621 const struct wpa_ie_hdr
*hdr
;
626 os_memset(data
, 0, sizeof(*data
));
627 data
->proto
= WPA_PROTO_WPA
;
628 data
->pairwise_cipher
= WPA_CIPHER_TKIP
;
629 data
->group_cipher
= WPA_CIPHER_TKIP
;
630 data
->key_mgmt
= WPA_KEY_MGMT_IEEE8021X
;
631 data
->capabilities
= 0;
634 data
->mgmt_group_cipher
= 0;
636 if (wpa_ie_len
== 0) {
637 /* No WPA IE - fail silently */
641 if (wpa_ie_len
< sizeof(struct wpa_ie_hdr
)) {
642 wpa_printf(MSG_DEBUG
, "%s: ie len too short %lu",
643 __func__
, (unsigned long) wpa_ie_len
);
647 hdr
= (const struct wpa_ie_hdr
*) wpa_ie
;
649 if (hdr
->elem_id
!= WLAN_EID_VENDOR_SPECIFIC
||
650 hdr
->len
!= wpa_ie_len
- 2 ||
651 RSN_SELECTOR_GET(hdr
->oui
) != WPA_OUI_TYPE
||
652 WPA_GET_LE16(hdr
->version
) != WPA_VERSION
) {
653 wpa_printf(MSG_DEBUG
, "%s: malformed ie or unknown version",
658 pos
= (const u8
*) (hdr
+ 1);
659 left
= wpa_ie_len
- sizeof(*hdr
);
661 if (left
>= WPA_SELECTOR_LEN
) {
662 data
->group_cipher
= wpa_selector_to_bitfield(pos
);
663 pos
+= WPA_SELECTOR_LEN
;
664 left
-= WPA_SELECTOR_LEN
;
665 } else if (left
> 0) {
666 wpa_printf(MSG_DEBUG
, "%s: ie length mismatch, %u too much",
672 data
->pairwise_cipher
= 0;
673 count
= WPA_GET_LE16(pos
);
676 if (count
== 0 || left
< count
* WPA_SELECTOR_LEN
) {
677 wpa_printf(MSG_DEBUG
, "%s: ie count botch (pairwise), "
678 "count %u left %u", __func__
, count
, left
);
681 for (i
= 0; i
< count
; i
++) {
682 data
->pairwise_cipher
|= wpa_selector_to_bitfield(pos
);
683 pos
+= WPA_SELECTOR_LEN
;
684 left
-= WPA_SELECTOR_LEN
;
686 } else if (left
== 1) {
687 wpa_printf(MSG_DEBUG
, "%s: ie too short (for key mgmt)",
694 count
= WPA_GET_LE16(pos
);
697 if (count
== 0 || left
< count
* WPA_SELECTOR_LEN
) {
698 wpa_printf(MSG_DEBUG
, "%s: ie count botch (key mgmt), "
699 "count %u left %u", __func__
, count
, left
);
702 for (i
= 0; i
< count
; i
++) {
703 data
->key_mgmt
|= wpa_key_mgmt_to_bitfield(pos
);
704 pos
+= WPA_SELECTOR_LEN
;
705 left
-= WPA_SELECTOR_LEN
;
707 } else if (left
== 1) {
708 wpa_printf(MSG_DEBUG
, "%s: ie too short (for capabilities)",
714 data
->capabilities
= WPA_GET_LE16(pos
);
720 wpa_hexdump(MSG_DEBUG
,
721 "wpa_parse_wpa_ie_wpa: ignore trailing bytes",
729 #ifdef CONFIG_IEEE80211R
732 * wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name
734 * IEEE Std 802.11r-2008 - 8.5.1.5.3
736 void wpa_derive_pmk_r0(const u8
*xxkey
, size_t xxkey_len
,
737 const u8
*ssid
, size_t ssid_len
,
738 const u8
*mdid
, const u8
*r0kh_id
, size_t r0kh_id_len
,
739 const u8
*s0kh_id
, u8
*pmk_r0
, u8
*pmk_r0_name
)
741 u8 buf
[1 + WPA_MAX_SSID_LEN
+ MOBILITY_DOMAIN_ID_LEN
+ 1 +
742 FT_R0KH_ID_MAX_LEN
+ ETH_ALEN
];
743 u8
*pos
, r0_key_data
[48], hash
[32];
748 * R0-Key-Data = KDF-384(XXKey, "FT-R0",
749 * SSIDlength || SSID || MDID || R0KHlength ||
750 * R0KH-ID || S0KH-ID)
751 * XXKey is either the second 256 bits of MSK or PSK.
752 * PMK-R0 = L(R0-Key-Data, 0, 256)
753 * PMK-R0Name-Salt = L(R0-Key-Data, 256, 128)
755 if (ssid_len
> WPA_MAX_SSID_LEN
|| r0kh_id_len
> FT_R0KH_ID_MAX_LEN
)
759 os_memcpy(pos
, ssid
, ssid_len
);
761 os_memcpy(pos
, mdid
, MOBILITY_DOMAIN_ID_LEN
);
762 pos
+= MOBILITY_DOMAIN_ID_LEN
;
763 *pos
++ = r0kh_id_len
;
764 os_memcpy(pos
, r0kh_id
, r0kh_id_len
);
766 os_memcpy(pos
, s0kh_id
, ETH_ALEN
);
769 sha256_prf(xxkey
, xxkey_len
, "FT-R0", buf
, pos
- buf
,
770 r0_key_data
, sizeof(r0_key_data
));
771 os_memcpy(pmk_r0
, r0_key_data
, PMK_LEN
);
774 * PMKR0Name = Truncate-128(SHA-256("FT-R0N" || PMK-R0Name-Salt)
776 addr
[0] = (const u8
*) "FT-R0N";
778 addr
[1] = r0_key_data
+ PMK_LEN
;
781 sha256_vector(2, addr
, len
, hash
);
782 os_memcpy(pmk_r0_name
, hash
, WPA_PMK_NAME_LEN
);
787 * wpa_derive_pmk_r1_name - Derive PMKR1Name
789 * IEEE Std 802.11r-2008 - 8.5.1.5.4
791 void wpa_derive_pmk_r1_name(const u8
*pmk_r0_name
, const u8
*r1kh_id
,
792 const u8
*s1kh_id
, u8
*pmk_r1_name
)
799 * PMKR1Name = Truncate-128(SHA-256("FT-R1N" || PMKR0Name ||
800 * R1KH-ID || S1KH-ID))
802 addr
[0] = (const u8
*) "FT-R1N";
804 addr
[1] = pmk_r0_name
;
805 len
[1] = WPA_PMK_NAME_LEN
;
807 len
[2] = FT_R1KH_ID_LEN
;
811 sha256_vector(4, addr
, len
, hash
);
812 os_memcpy(pmk_r1_name
, hash
, WPA_PMK_NAME_LEN
);
817 * wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0
819 * IEEE Std 802.11r-2008 - 8.5.1.5.4
821 void wpa_derive_pmk_r1(const u8
*pmk_r0
, const u8
*pmk_r0_name
,
822 const u8
*r1kh_id
, const u8
*s1kh_id
,
823 u8
*pmk_r1
, u8
*pmk_r1_name
)
825 u8 buf
[FT_R1KH_ID_LEN
+ ETH_ALEN
];
828 /* PMK-R1 = KDF-256(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */
830 os_memcpy(pos
, r1kh_id
, FT_R1KH_ID_LEN
);
831 pos
+= FT_R1KH_ID_LEN
;
832 os_memcpy(pos
, s1kh_id
, ETH_ALEN
);
835 sha256_prf(pmk_r0
, PMK_LEN
, "FT-R1", buf
, pos
- buf
, pmk_r1
, PMK_LEN
);
837 wpa_derive_pmk_r1_name(pmk_r0_name
, r1kh_id
, s1kh_id
, pmk_r1_name
);
842 * wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1
844 * IEEE Std 802.11r-2008 - 8.5.1.5.5
846 void wpa_pmk_r1_to_ptk(const u8
*pmk_r1
, const u8
*snonce
, const u8
*anonce
,
847 const u8
*sta_addr
, const u8
*bssid
,
848 const u8
*pmk_r1_name
,
849 u8
*ptk
, size_t ptk_len
, u8
*ptk_name
)
851 u8 buf
[2 * WPA_NONCE_LEN
+ 2 * ETH_ALEN
];
857 * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
861 os_memcpy(pos
, snonce
, WPA_NONCE_LEN
);
862 pos
+= WPA_NONCE_LEN
;
863 os_memcpy(pos
, anonce
, WPA_NONCE_LEN
);
864 pos
+= WPA_NONCE_LEN
;
865 os_memcpy(pos
, bssid
, ETH_ALEN
);
867 os_memcpy(pos
, sta_addr
, ETH_ALEN
);
870 sha256_prf(pmk_r1
, PMK_LEN
, "FT-PTK", buf
, pos
- buf
, ptk
, ptk_len
);
873 * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce ||
874 * ANonce || BSSID || STA-ADDR))
876 addr
[0] = pmk_r1_name
;
877 len
[0] = WPA_PMK_NAME_LEN
;
878 addr
[1] = (const u8
*) "FT-PTKN";
881 len
[2] = WPA_NONCE_LEN
;
883 len
[3] = WPA_NONCE_LEN
;
889 sha256_vector(6, addr
, len
, hash
);
890 os_memcpy(ptk_name
, hash
, WPA_PMK_NAME_LEN
);
893 #endif /* CONFIG_IEEE80211R */
897 * rsn_pmkid - Calculate PMK identifier
898 * @pmk: Pairwise master key
899 * @pmk_len: Length of pmk in bytes
900 * @aa: Authenticator address
901 * @spa: Supplicant address
902 * @pmkid: Buffer for PMKID
903 * @use_sha256: Whether to use SHA256-based KDF
905 * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
906 * PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
908 void rsn_pmkid(const u8
*pmk
, size_t pmk_len
, const u8
*aa
, const u8
*spa
,
909 u8
*pmkid
, int use_sha256
)
911 char *title
= "PMK Name";
913 const size_t len
[3] = { 8, ETH_ALEN
, ETH_ALEN
};
914 unsigned char hash
[SHA256_MAC_LEN
];
916 addr
[0] = (u8
*) title
;
920 #ifdef CONFIG_IEEE80211W
922 hmac_sha256_vector(pmk
, pmk_len
, 3, addr
, len
, hash
);
924 #endif /* CONFIG_IEEE80211W */
925 hmac_sha1_vector(pmk
, pmk_len
, 3, addr
, len
, hash
);
926 os_memcpy(pmkid
, hash
, PMKID_LEN
);
931 * wpa_cipher_txt - Convert cipher suite to a text string
932 * @cipher: Cipher suite (WPA_CIPHER_* enum)
933 * Returns: Pointer to a text string of the cipher suite name
935 const char * wpa_cipher_txt(int cipher
)
938 case WPA_CIPHER_NONE
:
940 case WPA_CIPHER_WEP40
:
942 case WPA_CIPHER_WEP104
:
944 case WPA_CIPHER_TKIP
:
946 case WPA_CIPHER_CCMP
:
948 case WPA_CIPHER_CCMP
| WPA_CIPHER_TKIP
:
950 case WPA_CIPHER_GCMP
:
952 case WPA_CIPHER_GCMP_256
:
954 case WPA_CIPHER_CCMP_256
:
956 case WPA_CIPHER_GTK_NOT_USED
:
957 return "GTK_NOT_USED";
965 * wpa_key_mgmt_txt - Convert key management suite to a text string
966 * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
967 * @proto: WPA/WPA2 version (WPA_PROTO_*)
968 * Returns: Pointer to a text string of the key management suite name
970 const char * wpa_key_mgmt_txt(int key_mgmt
, int proto
)
973 case WPA_KEY_MGMT_IEEE8021X
:
974 if (proto
== (WPA_PROTO_RSN
| WPA_PROTO_WPA
))
975 return "WPA2+WPA/IEEE 802.1X/EAP";
976 return proto
== WPA_PROTO_RSN
?
977 "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
978 case WPA_KEY_MGMT_PSK
:
979 if (proto
== (WPA_PROTO_RSN
| WPA_PROTO_WPA
))
980 return "WPA2-PSK+WPA-PSK";
981 return proto
== WPA_PROTO_RSN
?
982 "WPA2-PSK" : "WPA-PSK";
983 case WPA_KEY_MGMT_NONE
:
985 case WPA_KEY_MGMT_IEEE8021X_NO_WPA
:
986 return "IEEE 802.1X (no WPA)";
987 #ifdef CONFIG_IEEE80211R
988 case WPA_KEY_MGMT_FT_IEEE8021X
:
990 case WPA_KEY_MGMT_FT_PSK
:
992 #endif /* CONFIG_IEEE80211R */
993 #ifdef CONFIG_IEEE80211W
994 case WPA_KEY_MGMT_IEEE8021X_SHA256
:
995 return "WPA2-EAP-SHA256";
996 case WPA_KEY_MGMT_PSK_SHA256
:
997 return "WPA2-PSK-SHA256";
998 #endif /* CONFIG_IEEE80211W */
1005 int wpa_compare_rsn_ie(int ft_initial_assoc
,
1006 const u8
*ie1
, size_t ie1len
,
1007 const u8
*ie2
, size_t ie2len
)
1009 if (ie1
== NULL
|| ie2
== NULL
)
1012 if (ie1len
== ie2len
&& os_memcmp(ie1
, ie2
, ie1len
) == 0)
1013 return 0; /* identical IEs */
1015 #ifdef CONFIG_IEEE80211R
1016 if (ft_initial_assoc
) {
1017 struct wpa_ie_data ie1d
, ie2d
;
1019 * The PMKID-List in RSN IE is different between Beacon/Probe
1020 * Response/(Re)Association Request frames and EAPOL-Key
1021 * messages in FT initial mobility domain association. Allow
1022 * for this, but verify that other parts of the RSN IEs are
1025 if (wpa_parse_wpa_ie_rsn(ie1
, ie1len
, &ie1d
) < 0 ||
1026 wpa_parse_wpa_ie_rsn(ie2
, ie2len
, &ie2d
) < 0)
1028 if (ie1d
.proto
== ie2d
.proto
&&
1029 ie1d
.pairwise_cipher
== ie2d
.pairwise_cipher
&&
1030 ie1d
.group_cipher
== ie2d
.group_cipher
&&
1031 ie1d
.key_mgmt
== ie2d
.key_mgmt
&&
1032 ie1d
.capabilities
== ie2d
.capabilities
&&
1033 ie1d
.mgmt_group_cipher
== ie2d
.mgmt_group_cipher
)
1036 #endif /* CONFIG_IEEE80211R */
1042 #ifdef CONFIG_IEEE80211R
1043 int wpa_insert_pmkid(u8
*ies
, size_t ies_len
, const u8
*pmkid
)
1045 u8
*start
, *end
, *rpos
, *rend
;
1049 end
= ies
+ ies_len
;
1051 while (start
< end
) {
1052 if (*start
== WLAN_EID_RSN
)
1054 start
+= 2 + start
[1];
1057 wpa_printf(MSG_ERROR
, "FT: Could not find RSN IE in "
1061 wpa_hexdump(MSG_DEBUG
, "FT: RSN IE before modification",
1062 start
, 2 + start
[1]);
1064 /* Find start of PMKID-Count */
1066 rend
= rpos
+ start
[1];
1068 /* Skip Version and Group Data Cipher Suite */
1070 /* Skip Pairwise Cipher Suite Count and List */
1071 rpos
+= 2 + WPA_GET_LE16(rpos
) * RSN_SELECTOR_LEN
;
1072 /* Skip AKM Suite Count and List */
1073 rpos
+= 2 + WPA_GET_LE16(rpos
) * RSN_SELECTOR_LEN
;
1076 /* Add RSN Capabilities */
1077 os_memmove(rpos
+ 2, rpos
, end
- rpos
);
1081 /* Skip RSN Capabilities */
1084 wpa_printf(MSG_ERROR
, "FT: Could not parse RSN IE in "
1091 /* No PMKID-Count field included; add it */
1092 os_memmove(rpos
+ 2 + PMKID_LEN
, rpos
, end
- rpos
);
1093 WPA_PUT_LE16(rpos
, 1);
1095 os_memcpy(rpos
, pmkid
, PMKID_LEN
);
1096 added
+= 2 + PMKID_LEN
;
1097 start
[1] += 2 + PMKID_LEN
;
1099 /* PMKID-Count was included; use it */
1100 if (WPA_GET_LE16(rpos
) != 0) {
1101 wpa_printf(MSG_ERROR
, "FT: Unexpected PMKID "
1102 "in RSN IE in EAPOL-Key data");
1105 WPA_PUT_LE16(rpos
, 1);
1107 os_memmove(rpos
+ PMKID_LEN
, rpos
, end
- rpos
);
1108 os_memcpy(rpos
, pmkid
, PMKID_LEN
);
1110 start
[1] += PMKID_LEN
;
1113 wpa_hexdump(MSG_DEBUG
, "FT: RSN IE after modification "
1114 "(PMKID inserted)", start
, 2 + start
[1]);
1118 #endif /* CONFIG_IEEE80211R */
1121 int wpa_cipher_key_len(int cipher
)
1124 case WPA_CIPHER_CCMP_256
:
1125 case WPA_CIPHER_GCMP_256
:
1126 case WPA_CIPHER_BIP_GMAC_256
:
1127 case WPA_CIPHER_BIP_CMAC_256
:
1129 case WPA_CIPHER_CCMP
:
1130 case WPA_CIPHER_GCMP
:
1131 case WPA_CIPHER_AES_128_CMAC
:
1132 case WPA_CIPHER_BIP_GMAC_128
:
1134 case WPA_CIPHER_TKIP
:
1136 case WPA_CIPHER_WEP104
:
1138 case WPA_CIPHER_WEP40
:
1146 int wpa_cipher_rsc_len(int cipher
)
1149 case WPA_CIPHER_CCMP_256
:
1150 case WPA_CIPHER_GCMP_256
:
1151 case WPA_CIPHER_CCMP
:
1152 case WPA_CIPHER_GCMP
:
1153 case WPA_CIPHER_TKIP
:
1155 case WPA_CIPHER_WEP104
:
1156 case WPA_CIPHER_WEP40
:
1164 int wpa_cipher_to_alg(int cipher
)
1167 case WPA_CIPHER_CCMP_256
:
1168 return WPA_ALG_CCMP_256
;
1169 case WPA_CIPHER_GCMP_256
:
1170 return WPA_ALG_GCMP_256
;
1171 case WPA_CIPHER_CCMP
:
1172 return WPA_ALG_CCMP
;
1173 case WPA_CIPHER_GCMP
:
1174 return WPA_ALG_GCMP
;
1175 case WPA_CIPHER_TKIP
:
1176 return WPA_ALG_TKIP
;
1177 case WPA_CIPHER_WEP104
:
1178 case WPA_CIPHER_WEP40
:
1180 case WPA_CIPHER_AES_128_CMAC
:
1181 return WPA_ALG_IGTK
;
1182 case WPA_CIPHER_BIP_GMAC_128
:
1183 return WPA_ALG_BIP_GMAC_128
;
1184 case WPA_CIPHER_BIP_GMAC_256
:
1185 return WPA_ALG_BIP_GMAC_256
;
1186 case WPA_CIPHER_BIP_CMAC_256
:
1187 return WPA_ALG_BIP_CMAC_256
;
1189 return WPA_ALG_NONE
;
1193 int wpa_cipher_valid_pairwise(int cipher
)
1195 return cipher
== WPA_CIPHER_CCMP_256
||
1196 cipher
== WPA_CIPHER_GCMP_256
||
1197 cipher
== WPA_CIPHER_CCMP
||
1198 cipher
== WPA_CIPHER_GCMP
||
1199 cipher
== WPA_CIPHER_TKIP
;
1203 u32
wpa_cipher_to_suite(int proto
, int cipher
)
1205 if (cipher
& WPA_CIPHER_CCMP_256
)
1206 return RSN_CIPHER_SUITE_CCMP_256
;
1207 if (cipher
& WPA_CIPHER_GCMP_256
)
1208 return RSN_CIPHER_SUITE_GCMP_256
;
1209 if (cipher
& WPA_CIPHER_CCMP
)
1210 return (proto
== WPA_PROTO_RSN
?
1211 RSN_CIPHER_SUITE_CCMP
: WPA_CIPHER_SUITE_CCMP
);
1212 if (cipher
& WPA_CIPHER_GCMP
)
1213 return RSN_CIPHER_SUITE_GCMP
;
1214 if (cipher
& WPA_CIPHER_TKIP
)
1215 return (proto
== WPA_PROTO_RSN
?
1216 RSN_CIPHER_SUITE_TKIP
: WPA_CIPHER_SUITE_TKIP
);
1217 if (cipher
& WPA_CIPHER_WEP104
)
1218 return (proto
== WPA_PROTO_RSN
?
1219 RSN_CIPHER_SUITE_WEP104
: WPA_CIPHER_SUITE_WEP104
);
1220 if (cipher
& WPA_CIPHER_WEP40
)
1221 return (proto
== WPA_PROTO_RSN
?
1222 RSN_CIPHER_SUITE_WEP40
: WPA_CIPHER_SUITE_WEP40
);
1223 if (cipher
& WPA_CIPHER_NONE
)
1224 return (proto
== WPA_PROTO_RSN
?
1225 RSN_CIPHER_SUITE_NONE
: WPA_CIPHER_SUITE_NONE
);
1226 if (cipher
& WPA_CIPHER_GTK_NOT_USED
)
1227 return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED
;
1228 if (cipher
& WPA_CIPHER_AES_128_CMAC
)
1229 return RSN_CIPHER_SUITE_AES_128_CMAC
;
1230 if (cipher
& WPA_CIPHER_BIP_GMAC_128
)
1231 return RSN_CIPHER_SUITE_BIP_GMAC_128
;
1232 if (cipher
& WPA_CIPHER_BIP_GMAC_256
)
1233 return RSN_CIPHER_SUITE_BIP_GMAC_256
;
1234 if (cipher
& WPA_CIPHER_BIP_CMAC_256
)
1235 return RSN_CIPHER_SUITE_BIP_CMAC_256
;
1240 int rsn_cipher_put_suites(u8
*start
, int ciphers
)
1244 if (ciphers
& WPA_CIPHER_CCMP_256
) {
1245 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_CCMP_256
);
1246 pos
+= RSN_SELECTOR_LEN
;
1248 if (ciphers
& WPA_CIPHER_GCMP_256
) {
1249 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_GCMP_256
);
1250 pos
+= RSN_SELECTOR_LEN
;
1252 if (ciphers
& WPA_CIPHER_CCMP
) {
1253 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_CCMP
);
1254 pos
+= RSN_SELECTOR_LEN
;
1256 if (ciphers
& WPA_CIPHER_GCMP
) {
1257 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_GCMP
);
1258 pos
+= RSN_SELECTOR_LEN
;
1260 if (ciphers
& WPA_CIPHER_TKIP
) {
1261 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_TKIP
);
1262 pos
+= RSN_SELECTOR_LEN
;
1264 if (ciphers
& WPA_CIPHER_NONE
) {
1265 RSN_SELECTOR_PUT(pos
, RSN_CIPHER_SUITE_NONE
);
1266 pos
+= RSN_SELECTOR_LEN
;
1269 return (pos
- start
) / RSN_SELECTOR_LEN
;
1273 int wpa_cipher_put_suites(u8
*start
, int ciphers
)
1277 if (ciphers
& WPA_CIPHER_CCMP
) {
1278 RSN_SELECTOR_PUT(pos
, WPA_CIPHER_SUITE_CCMP
);
1279 pos
+= WPA_SELECTOR_LEN
;
1281 if (ciphers
& WPA_CIPHER_TKIP
) {
1282 RSN_SELECTOR_PUT(pos
, WPA_CIPHER_SUITE_TKIP
);
1283 pos
+= WPA_SELECTOR_LEN
;
1285 if (ciphers
& WPA_CIPHER_NONE
) {
1286 RSN_SELECTOR_PUT(pos
, WPA_CIPHER_SUITE_NONE
);
1287 pos
+= WPA_SELECTOR_LEN
;
1290 return (pos
- start
) / RSN_SELECTOR_LEN
;
1294 int wpa_pick_pairwise_cipher(int ciphers
, int none_allowed
)
1296 if (ciphers
& WPA_CIPHER_CCMP_256
)
1297 return WPA_CIPHER_CCMP_256
;
1298 if (ciphers
& WPA_CIPHER_GCMP_256
)
1299 return WPA_CIPHER_GCMP_256
;
1300 if (ciphers
& WPA_CIPHER_CCMP
)
1301 return WPA_CIPHER_CCMP
;
1302 if (ciphers
& WPA_CIPHER_GCMP
)
1303 return WPA_CIPHER_GCMP
;
1304 if (ciphers
& WPA_CIPHER_TKIP
)
1305 return WPA_CIPHER_TKIP
;
1306 if (none_allowed
&& (ciphers
& WPA_CIPHER_NONE
))
1307 return WPA_CIPHER_NONE
;
1312 int wpa_pick_group_cipher(int ciphers
)
1314 if (ciphers
& WPA_CIPHER_CCMP_256
)
1315 return WPA_CIPHER_CCMP_256
;
1316 if (ciphers
& WPA_CIPHER_GCMP_256
)
1317 return WPA_CIPHER_GCMP_256
;
1318 if (ciphers
& WPA_CIPHER_CCMP
)
1319 return WPA_CIPHER_CCMP
;
1320 if (ciphers
& WPA_CIPHER_GCMP
)
1321 return WPA_CIPHER_GCMP
;
1322 if (ciphers
& WPA_CIPHER_GTK_NOT_USED
)
1323 return WPA_CIPHER_GTK_NOT_USED
;
1324 if (ciphers
& WPA_CIPHER_TKIP
)
1325 return WPA_CIPHER_TKIP
;
1326 if (ciphers
& WPA_CIPHER_WEP104
)
1327 return WPA_CIPHER_WEP104
;
1328 if (ciphers
& WPA_CIPHER_WEP40
)
1329 return WPA_CIPHER_WEP40
;
1334 int wpa_parse_cipher(const char *value
)
1337 char *start
, *end
, *buf
;
1339 buf
= os_strdup(value
);
1344 while (*start
!= '\0') {
1345 while (*start
== ' ' || *start
== '\t')
1350 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
1352 last
= *end
== '\0';
1354 if (os_strcmp(start
, "CCMP-256") == 0)
1355 val
|= WPA_CIPHER_CCMP_256
;
1356 else if (os_strcmp(start
, "GCMP-256") == 0)
1357 val
|= WPA_CIPHER_GCMP_256
;
1358 else if (os_strcmp(start
, "CCMP") == 0)
1359 val
|= WPA_CIPHER_CCMP
;
1360 else if (os_strcmp(start
, "GCMP") == 0)
1361 val
|= WPA_CIPHER_GCMP
;
1362 else if (os_strcmp(start
, "TKIP") == 0)
1363 val
|= WPA_CIPHER_TKIP
;
1364 else if (os_strcmp(start
, "WEP104") == 0)
1365 val
|= WPA_CIPHER_WEP104
;
1366 else if (os_strcmp(start
, "WEP40") == 0)
1367 val
|= WPA_CIPHER_WEP40
;
1368 else if (os_strcmp(start
, "NONE") == 0)
1369 val
|= WPA_CIPHER_NONE
;
1370 else if (os_strcmp(start
, "GTK_NOT_USED") == 0)
1371 val
|= WPA_CIPHER_GTK_NOT_USED
;
1387 int wpa_write_ciphers(char *start
, char *end
, int ciphers
, const char *delim
)
1392 if (ciphers
& WPA_CIPHER_CCMP_256
) {
1393 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP-256",
1394 pos
== start
? "" : delim
);
1395 if (ret
< 0 || ret
>= end
- pos
)
1399 if (ciphers
& WPA_CIPHER_GCMP_256
) {
1400 ret
= os_snprintf(pos
, end
- pos
, "%sGCMP-256",
1401 pos
== start
? "" : delim
);
1402 if (ret
< 0 || ret
>= end
- pos
)
1406 if (ciphers
& WPA_CIPHER_CCMP
) {
1407 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP",
1408 pos
== start
? "" : delim
);
1409 if (ret
< 0 || ret
>= end
- pos
)
1413 if (ciphers
& WPA_CIPHER_GCMP
) {
1414 ret
= os_snprintf(pos
, end
- pos
, "%sGCMP",
1415 pos
== start
? "" : delim
);
1416 if (ret
< 0 || ret
>= end
- pos
)
1420 if (ciphers
& WPA_CIPHER_TKIP
) {
1421 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP",
1422 pos
== start
? "" : delim
);
1423 if (ret
< 0 || ret
>= end
- pos
)
1427 if (ciphers
& WPA_CIPHER_WEP104
) {
1428 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
1429 pos
== start
? "" : delim
);
1430 if (ret
< 0 || ret
>= end
- pos
)
1434 if (ciphers
& WPA_CIPHER_WEP40
) {
1435 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40",
1436 pos
== start
? "" : delim
);
1437 if (ret
< 0 || ret
>= end
- pos
)
1441 if (ciphers
& WPA_CIPHER_NONE
) {
1442 ret
= os_snprintf(pos
, end
- pos
, "%sNONE",
1443 pos
== start
? "" : delim
);
1444 if (ret
< 0 || ret
>= end
- pos
)
1453 int wpa_select_ap_group_cipher(int wpa
, int wpa_pairwise
, int rsn_pairwise
)
1457 /* Select group cipher based on the enabled pairwise cipher suites */
1459 pairwise
|= wpa_pairwise
;
1461 pairwise
|= rsn_pairwise
;
1463 if (pairwise
& WPA_CIPHER_TKIP
)
1464 return WPA_CIPHER_TKIP
;
1465 if ((pairwise
& (WPA_CIPHER_CCMP
| WPA_CIPHER_GCMP
)) == WPA_CIPHER_GCMP
)
1466 return WPA_CIPHER_GCMP
;
1467 if ((pairwise
& (WPA_CIPHER_GCMP_256
| WPA_CIPHER_CCMP
|
1468 WPA_CIPHER_GCMP
)) == WPA_CIPHER_GCMP_256
)
1469 return WPA_CIPHER_GCMP_256
;
1470 if ((pairwise
& (WPA_CIPHER_CCMP_256
| WPA_CIPHER_CCMP
|
1471 WPA_CIPHER_GCMP
)) == WPA_CIPHER_CCMP_256
)
1472 return WPA_CIPHER_CCMP_256
;
1473 return WPA_CIPHER_CCMP
;