570
570
#endif /* CONFIG_IEEE80211R */
574
* rsn_pmkid - Calculate PMK identifier
575
* @pmk: Pairwise master key
576
* @pmk_len: Length of pmk in bytes
577
* @aa: Authenticator address
578
* @spa: Supplicant address
579
* @pmkid: Buffer for PMKID
580
* @use_sha256: Whether to use SHA256-based KDF
582
* IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
583
* PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
585
void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
586
u8 *pmkid, int use_sha256)
588
char *title = "PMK Name";
590
const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
591
unsigned char hash[SHA256_MAC_LEN];
593
addr[0] = (u8 *) title;
597
#ifdef CONFIG_IEEE80211W
599
hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
601
#endif /* CONFIG_IEEE80211W */
602
hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
603
os_memcpy(pmkid, hash, PMKID_LEN);
608
* wpa_cipher_txt - Convert cipher suite to a text string
609
* @cipher: Cipher suite (WPA_CIPHER_* enum)
610
* Returns: Pointer to a text string of the cipher suite name
612
const char * wpa_cipher_txt(int cipher)
615
case WPA_CIPHER_NONE:
617
case WPA_CIPHER_WEP40:
619
case WPA_CIPHER_WEP104:
621
case WPA_CIPHER_TKIP:
623
case WPA_CIPHER_CCMP:
625
case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
634
* wpa_key_mgmt_txt - Convert key management suite to a text string
635
* @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
636
* @proto: WPA/WPA2 version (WPA_PROTO_*)
637
* Returns: Pointer to a text string of the key management suite name
639
const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
642
case WPA_KEY_MGMT_IEEE8021X:
643
if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
644
return "WPA2+WPA/IEEE 802.1X/EAP";
645
return proto == WPA_PROTO_RSN ?
646
"WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
647
case WPA_KEY_MGMT_PSK:
648
if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
649
return "WPA2-PSK+WPA-PSK";
650
return proto == WPA_PROTO_RSN ?
651
"WPA2-PSK" : "WPA-PSK";
652
case WPA_KEY_MGMT_NONE:
654
case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
655
return "IEEE 802.1X (no WPA)";
656
#ifdef CONFIG_IEEE80211R
657
case WPA_KEY_MGMT_FT_IEEE8021X:
659
case WPA_KEY_MGMT_FT_PSK:
661
#endif /* CONFIG_IEEE80211R */
662
#ifdef CONFIG_IEEE80211W
663
case WPA_KEY_MGMT_IEEE8021X_SHA256:
664
return "WPA2-EAP-SHA256";
665
case WPA_KEY_MGMT_PSK_SHA256:
666
return "WPA2-PSK-SHA256";
667
#endif /* CONFIG_IEEE80211W */
674
int wpa_compare_rsn_ie(int ft_initial_assoc,
675
const u8 *ie1, size_t ie1len,
676
const u8 *ie2, size_t ie2len)
678
if (ie1 == NULL || ie2 == NULL)
681
if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0)
682
return 0; /* identical IEs */
684
#ifdef CONFIG_IEEE80211R
685
if (ft_initial_assoc) {
686
struct wpa_ie_data ie1d, ie2d;
688
* The PMKID-List in RSN IE is different between Beacon/Probe
689
* Response/(Re)Association Request frames and EAPOL-Key
690
* messages in FT initial mobility domain association. Allow
691
* for this, but verify that other parts of the RSN IEs are
694
if (wpa_parse_wpa_ie_rsn(ie1, ie1len, &ie1d) < 0 ||
695
wpa_parse_wpa_ie_rsn(ie2, ie2len, &ie2d) < 0)
697
if (ie1d.proto == ie2d.proto &&
698
ie1d.pairwise_cipher == ie2d.pairwise_cipher &&
699
ie1d.group_cipher == ie2d.group_cipher &&
700
ie1d.key_mgmt == ie2d.key_mgmt &&
701
ie1d.capabilities == ie2d.capabilities &&
702
ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
705
#endif /* CONFIG_IEEE80211R */
711
#ifdef CONFIG_IEEE80211R
712
int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid)
714
u8 *start, *end, *rpos, *rend;
720
while (start < end) {
721
if (*start == WLAN_EID_RSN)
723
start += 2 + start[1];
726
wpa_printf(MSG_ERROR, "FT: Could not find RSN IE in "
730
wpa_hexdump(MSG_DEBUG, "FT: RSN IE before modification",
731
start, 2 + start[1]);
733
/* Find start of PMKID-Count */
735
rend = rpos + start[1];
737
/* Skip Version and Group Data Cipher Suite */
739
/* Skip Pairwise Cipher Suite Count and List */
740
rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
741
/* Skip AKM Suite Count and List */
742
rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
745
/* Add RSN Capabilities */
746
os_memmove(rpos + 2, rpos, end - rpos);
750
/* Skip RSN Capabilities */
753
wpa_printf(MSG_ERROR, "FT: Could not parse RSN IE in "
760
/* No PMKID-Count field included; add it */
761
os_memmove(rpos + 2 + PMKID_LEN, rpos, end - rpos);
762
WPA_PUT_LE16(rpos, 1);
764
os_memcpy(rpos, pmkid, PMKID_LEN);
765
added += 2 + PMKID_LEN;
766
start[1] += 2 + PMKID_LEN;
768
/* PMKID-Count was included; use it */
769
if (WPA_GET_LE16(rpos) != 0) {
770
wpa_printf(MSG_ERROR, "FT: Unexpected PMKID "
771
"in RSN IE in EAPOL-Key data");
774
WPA_PUT_LE16(rpos, 1);
776
os_memmove(rpos + PMKID_LEN, rpos, end - rpos);
777
os_memcpy(rpos, pmkid, PMKID_LEN);
779
start[1] += PMKID_LEN;
782
wpa_hexdump(MSG_DEBUG, "FT: RSN IE after modification "
783
"(PMKID inserted)", start, 2 + start[1]);
787
#endif /* CONFIG_IEEE80211R */