18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd - WPA/RSN IE and KDE definitions 340b07208ef4402da20a7f666835a62f6ec098e16Dmitry Shmidt * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_auth/eapol_auth_sm.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pmksa_cache_auth.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth_ie.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth_i.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_RSN_TESTING 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint rsn_testing = 0; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_RSN_TESTING */ 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_write_wpa_ie(struct wpa_auth_config *conf, u8 *buf, size_t len) 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ie_hdr *hdr; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_suites; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, *count; 324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u32 suite; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct wpa_ie_hdr *) buf; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(hdr->version, WPA_VERSION); 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (u8 *) (hdr + 1); 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt suite = wpa_cipher_to_suite(WPA_PROTO_WPA, conf->wpa_group); 414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (suite == 0) { 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).", 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->wpa_group); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt RSN_SELECTOR_PUT(pos, suite); 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += WPA_SELECTOR_LEN; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = pos; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt num_suites = wpa_cipher_put_suites(pos, conf->wpa_pairwise); 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_suites == 0) { 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).", 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->wpa_pairwise); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += num_suites * WPA_SELECTOR_LEN; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(count, num_suites); 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites = 0; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = pos; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X); 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += WPA_SELECTOR_LEN; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) { 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X); 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += WPA_SELECTOR_LEN; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_suites == 0) { 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid key management type (%d).", 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->wpa_key_mgmt); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(count, num_suites); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPA Capabilities; use defaults, so no need to include it */ 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->len = (pos - buf) - 2; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pmkid) 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_ie_hdr *hdr; 954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int num_suites, res; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, *count; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 capab; 984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u32 suite; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct rsn_ie_hdr *) buf; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->elem_id = WLAN_EID_RSN; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(hdr->version, RSN_VERSION); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (u8 *) (hdr + 1); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt suite = wpa_cipher_to_suite(WPA_PROTO_RSN, conf->wpa_group); 1064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (suite == 0) { 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).", 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->wpa_group); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt RSN_SELECTOR_PUT(pos, suite); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites = 0; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = pos; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_RSN_TESTING 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn_testing) { 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1)); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_RSN_TESTING */ 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt res = rsn_cipher_put_suites(pos, conf->rsn_pairwise); 1274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt num_suites += res; 1284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += res * RSN_SELECTOR_LEN; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_RSN_TESTING 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn_testing) { 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2)); 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_RSN_TESTING */ 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_suites == 0) { 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).", 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->rsn_pairwise); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(count, num_suites); 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites = 0; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = pos; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_RSN_TESTING 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn_testing) { 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1)); 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_RSN_TESTING */ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X); 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) { 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1679839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_IEEE80211R_AP 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X); 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_PSK) { 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1789839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_IEEE80211R_AP */ 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 191d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 192d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE) { 193d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE); 194d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pos += RSN_SELECTOR_LEN; 195d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt num_suites++; 196d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 197d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) { 198d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE); 199d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pos += RSN_SELECTOR_LEN; 200d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt num_suites++; 201d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 202d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 203fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) { 204fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B); 205fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt pos += RSN_SELECTOR_LEN; 206fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt num_suites++; 207fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt } 20840b07208ef4402da20a7f666835a62f6ec098e16Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) { 20940b07208ef4402da20a7f666835a62f6ec098e16Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192); 21040b07208ef4402da20a7f666835a62f6ec098e16Dmitry Shmidt pos += RSN_SELECTOR_LEN; 21140b07208ef4402da20a7f666835a62f6ec098e16Dmitry Shmidt num_suites++; 21240b07208ef4402da20a7f666835a62f6ec098e16Dmitry Shmidt } 2139839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_FILS 2149839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FILS_SHA256) { 2159839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256); 2169839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt pos += RSN_SELECTOR_LEN; 2179839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt num_suites++; 2189839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt } 2199839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FILS_SHA384) { 2209839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384); 2219839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt pos += RSN_SELECTOR_LEN; 2229839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt num_suites++; 2239839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt } 2249839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_IEEE80211R_AP 2259839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) { 2269839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA256); 2279839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt pos += RSN_SELECTOR_LEN; 2289839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt num_suites++; 2299839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt } 2309839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) { 2319839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA384); 2329839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt pos += RSN_SELECTOR_LEN; 2339839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt num_suites++; 2349839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt } 2359839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_IEEE80211R_AP */ 2369839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_FILS */ 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_RSN_TESTING 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn_testing) { 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2)); 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites++; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_RSN_TESTING */ 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_suites == 0) { 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid key management type (%d).", 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->wpa_key_mgmt); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(count, num_suites); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RSN Capabilities */ 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab = 0; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->rsn_preauth) 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= WPA_CAPABILITY_PREAUTH; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->peerkey) 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= WPA_CAPABILITY_PEERKEY_ENABLED; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wmm_enabled) { 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4 PTKSA replay counters when using WMM */ 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= WPA_CAPABILITY_MFPC; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= WPA_CAPABILITY_MFPR; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_RSN_TESTING 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn_testing) 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= BIT(8) | BIT(14) | BIT(15); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_RSN_TESTING */ 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(pos, capab); 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmkid) { 278d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (2 + PMKID_LEN > buf + len - pos) 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* PMKID Count */ 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(pos, 1); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, pmkid, PMKID_LEN); 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += PMKID_LEN; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 288d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION && 289d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->group_mgmt_cipher != WPA_CIPHER_AES_128_CMAC) { 290d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (2 + 4 > buf + len - pos) 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmkid == NULL) { 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* PMKID Count */ 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(pos, 0); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Management Group Cipher Suite */ 299b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt switch (conf->group_mgmt_cipher) { 300b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case WPA_CIPHER_AES_128_CMAC: 301b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); 302b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 303b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case WPA_CIPHER_BIP_GMAC_128: 304b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_128); 305b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 306b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case WPA_CIPHER_BIP_GMAC_256: 307b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_256); 308b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 309b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case WPA_CIPHER_BIP_CMAC_256: 310b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_CMAC_256); 311b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 312b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt default: 313b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_printf(MSG_DEBUG, 314b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt "Invalid group management cipher (0x%x)", 315b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt conf->group_mgmt_cipher); 316b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return -1; 317b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_RSN_TESTING 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn_testing) { 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fill in any defined fields and add extra data to the end of 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the element. 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pmkid_count_set = pmkid != NULL; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid_count_set = 1; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* PMKID Count */ 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(pos, 0); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ieee80211w == NO_MGMT_FRAME_PROTECTION) { 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Management Group Cipher Suite */ 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(pos, 0x12, 17); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 17; 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_RSN_TESTING */ 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->len = (pos - buf) - 2; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 351f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic u8 * wpa_write_osen(struct wpa_auth_config *conf, u8 *eid) 352f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 353f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 *len; 354f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u16 capab; 355f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 356f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt *eid++ = WLAN_EID_VENDOR_SPECIFIC; 357f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt len = eid++; /* to be filled */ 358f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt WPA_PUT_BE24(eid, OUI_WFA); 359f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += 3; 360f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt *eid++ = HS20_OSEN_OUI_TYPE; 361f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 362f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* Group Data Cipher Suite */ 363f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED); 364f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += RSN_SELECTOR_LEN; 365f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 366f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* Pairwise Cipher Suite Count and List */ 367f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt WPA_PUT_LE16(eid, 1); 368f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += 2; 369f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_CCMP); 370f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += RSN_SELECTOR_LEN; 371f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 372f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* AKM Suite Count and List */ 373f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt WPA_PUT_LE16(eid, 1); 374f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += 2; 375f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RSN_SELECTOR_PUT(eid, RSN_AUTH_KEY_MGMT_OSEN); 376f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += RSN_SELECTOR_LEN; 377f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 378f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* RSN Capabilities */ 379f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt capab = 0; 380f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (conf->wmm_enabled) { 381f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* 4 PTKSA replay counters when using WMM */ 382f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2); 383f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 384f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#ifdef CONFIG_IEEE80211W 385f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { 386f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt capab |= WPA_CAPABILITY_MFPC; 387f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) 388f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt capab |= WPA_CAPABILITY_MFPR; 389f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 390f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 391f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt WPA_PUT_LE16(eid, capab); 392f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += 2; 393f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 394f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt *len = eid - len - 1; 395f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 396f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return eid; 397f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 398f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 399f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth) 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, buf[128]; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 405d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 406d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (wpa_auth->conf.own_ie_override_len) { 407d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: Forced own IE(s) for testing", 408d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_auth->conf.own_ie_override, 409d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_auth->conf.own_ie_override_len); 410d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_free(wpa_auth->wpa_ie); 411d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_auth->wpa_ie = 412d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_malloc(wpa_auth->conf.own_ie_override_len); 413d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (wpa_auth->wpa_ie == NULL) 414d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 415d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memcpy(wpa_auth->wpa_ie, wpa_auth->conf.own_ie_override, 416d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_auth->conf.own_ie_override_len); 417d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_auth->wpa_ie_len = wpa_auth->conf.own_ie_override_len; 418d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 419d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 420d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 421d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 424f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_auth->conf.wpa == WPA_PROTO_OSEN) { 425f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos = wpa_write_osen(&wpa_auth->conf, pos); 426f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->conf.wpa & WPA_PROTO_RSN) { 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_write_rsn_ie(&wpa_auth->conf, 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, buf + sizeof(buf) - pos, NULL); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4349839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_IEEE80211R_AP 4351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_key_mgmt_ft(wpa_auth->conf.wpa_key_mgmt)) { 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_write_mdie(&wpa_auth->conf, pos, 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf + sizeof(buf) - pos); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4429839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_IEEE80211R_AP */ 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->conf.wpa & WPA_PROTO_WPA) { 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_write_wpa_ie(&wpa_auth->conf, 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, buf + sizeof(buf) - pos); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_auth->wpa_ie); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->wpa_ie = os_malloc(pos - buf); 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->wpa_ie == NULL) 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_auth->wpa_ie, buf, pos - buf); 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->wpa_ie_len = pos - buf; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len, 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data2, size_t data2_len) 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_VENDOR_SPECIFIC; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = RSN_SELECTOR_LEN + data_len + data2_len; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(pos, kde); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += RSN_SELECTOR_LEN; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, data, data_len); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += data_len; 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data2) { 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, data2, data2_len); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += data2_len; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_auth_okc_iter_data { 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_pmksa_cache_entry *pmksa; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *aa; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *spa; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pmkid; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_auth_okc_iter(struct wpa_authenticator *a, void *ctx) 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_auth_okc_iter_data *data = ctx; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pmksa = pmksa_cache_get_okc(a->pmksa, data->aa, data->spa, 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pmkid); 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->pmksa) 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm, 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wpa_ie, size_t wpa_ie_len, 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *mdie, size_t mdie_len) 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ie_data data; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ciphers, key_mgmt, res, version; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 selector; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pmkid = NULL; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL || sm == NULL) 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_NOT_ENABLED; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_ie == NULL || wpa_ie_len < 1) 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_INVALID_IE; 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_ie[0] == WLAN_EID_RSN) 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version = WPA_PROTO_RSN; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version = WPA_PROTO_WPA; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_auth->conf.wpa & version)) { 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid WPA proto (%d) from " MACSTR, 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version, MAC2STR(sm->addr)); 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_INVALID_PROTO; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (version == WPA_PROTO_RSN) { 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data); 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (0) { 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 53240b07208ef4402da20a7f666835a62f6ec098e16Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) 53340b07208ef4402da20a7f666835a62f6ec098e16Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192; 534fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) 535fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_802_1X_SUITE_B; 5369839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_FILS 5379839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_IEEE80211R_AP 5389839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) 5399839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_FT_FILS_SHA384; 5409839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) 5419839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_FT_FILS_SHA256; 5429839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_IEEE80211R_AP */ 5439839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_FILS_SHA384) 5449839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_FILS_SHA384; 5459839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_FILS_SHA256) 5469839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_FILS_SHA256; 5479839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_FILS */ 5489839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_IEEE80211R_AP 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_FT_802_1X; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_FT_PSK; 5539839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_IEEE80211R_AP */ 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_802_1X_SHA256; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_PSK_SHA256; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 560d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 561d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_SAE) 562d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt selector = RSN_AUTH_KEY_MGMT_SAE; 563d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE) 564d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt selector = RSN_AUTH_KEY_MGMT_FT_SAE; 565d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_PSK) 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt selector = wpa_cipher_to_suite(WPA_PROTO_RSN, 5734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data.pairwise_cipher); 5744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!selector) 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = RSN_CIPHER_SUITE_CCMP; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNAPairwiseCipherSelected = selector; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt selector = wpa_cipher_to_suite(WPA_PROTO_RSN, 5794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data.group_cipher); 5804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!selector) 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = RSN_CIPHER_SUITE_CCMP; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNAGroupCipherSelected = selector; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, &data); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_PSK) 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt selector = wpa_cipher_to_suite(WPA_PROTO_WPA, 5944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data.pairwise_cipher); 5954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!selector) 5964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt selector = RSN_CIPHER_SUITE_TKIP; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNAPairwiseCipherSelected = selector; 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt selector = wpa_cipher_to_suite(WPA_PROTO_WPA, 6004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data.group_cipher); 6014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!selector) 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt selector = WPA_CIPHER_SUITE_TKIP; 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNAGroupCipherSelected = selector; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to parse WPA/RSN IE from " 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " (res=%d)", MAC2STR(sm->addr), res); 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA/RSN IE", wpa_ie, wpa_ie_len); 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_INVALID_IE; 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data.group_cipher != wpa_auth->conf.wpa_group) { 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid WPA group cipher (0x%x) from " 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, data.group_cipher, MAC2STR(sm->addr)); 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_INVALID_GROUP; 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!key_mgmt) { 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from " 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, data.key_mgmt, MAC2STR(sm->addr)); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_INVALID_AKMP; 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (0) { 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 62640b07208ef4402da20a7f666835a62f6ec098e16Dmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) 62740b07208ef4402da20a7f666835a62f6ec098e16Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192; 628fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) 629fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B; 6309839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_FILS 6319839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_IEEE80211R_AP 6329839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) 6339839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA384; 6349839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt else if (data.key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) 6359839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA256; 6369839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_IEEE80211R_AP */ 6379839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_FILS_SHA384) 6389839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_FILS_SHA384; 6399839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_FILS_SHA256) 6409839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_FILS_SHA256; 6419839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_FILS */ 6429839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_IEEE80211R_AP 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X; 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_FT_PSK) 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_PSK; 6479839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_IEEE80211R_AP */ 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256; 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256) 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK_SHA256; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 654d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 655d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_SAE) 656d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE; 657d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_FT_SAE) 658d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE; 659d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X) 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X; 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK; 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (version == WPA_PROTO_RSN) 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise; 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ciphers) { 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid %s pairwise cipher (0x%x) " 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from " MACSTR, 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version == WPA_PROTO_RSN ? "RSN" : "WPA", 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.pairwise_cipher, MAC2STR(sm->addr)); 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_INVALID_PAIRWISE; 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->conf.ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) { 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(data.capabilities & WPA_CAPABILITY_MFPC)) { 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Management frame protection " 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "required, but client did not enable it"); 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_MGMT_FRAME_PROTECTION_VIOLATION; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ciphers & WPA_CIPHER_TKIP) { 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Management frame protection " 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cannot use TKIP"); 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_MGMT_FRAME_PROTECTION_VIOLATION; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 691b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (data.mgmt_group_cipher != wpa_auth->conf.group_mgmt_cipher) 692b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt { 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Unsupported management group " 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher %d", data.mgmt_group_cipher); 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_INVALID_MGMT_GROUP_CIPHER; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->conf.ieee80211w == NO_MGMT_FRAME_PROTECTION || 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(data.capabilities & WPA_CAPABILITY_MFPC)) 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->mgmt_frame_prot = 0; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->mgmt_frame_prot = 1; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7069839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_IEEE80211R_AP 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mdie == NULL || mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) { 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "RSN: Trying to use FT, but " 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MDIE not included"); 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_INVALID_MDIE; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mdie, wpa_auth->conf.mobility_domain, 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MOBILITY_DOMAIN_ID_LEN) != 0) { 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "RSN: Attempted to use unknown " 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MDIE", mdie, MOBILITY_DOMAIN_ID_LEN); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_INVALID_MDIE; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 719abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } else if (mdie != NULL) { 720abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, 721abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt "RSN: Trying to use non-FT AKM suite, but MDIE included"); 722abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return WPA_INVALID_AKMP; 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7249839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_IEEE80211R_AP */ 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 726a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sm->pairwise = wpa_pick_pairwise_cipher(ciphers, 0); 727a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sm->pairwise < 0) 728a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return WPA_INVALID_PAIRWISE; 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: clear WPA/WPA2 state if STA changes from one to another */ 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_ie[0] == WLAN_EID_RSN) 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa = WPA_VERSION_WPA2; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa = WPA_VERSION_WPA; 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmksa = NULL; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < data.num_pmkid; i++) { 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "RSN IE: STA PMKID", 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &data.pmkid[i * PMKID_LEN], PMKID_LEN); 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sm->addr, 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &data.pmkid[i * PMKID_LEN]); 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pmksa) { 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid = sm->pmksa->pmkid; 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; sm->pmksa == NULL && wpa_auth->conf.okc && 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i < data.num_pmkid; i++) { 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_auth_okc_iter_data idata; 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idata.pmksa = NULL; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idata.aa = wpa_auth->addr; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idata.spa = sm->addr; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idata.pmkid = &data.pmkid[i * PMKID_LEN]; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_for_each_auth(wpa_auth, wpa_auth_okc_iter, &idata); 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (idata.pmksa) { 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OKC match for PMKID"); 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmksa = pmksa_cache_add_okc(wpa_auth->pmksa, 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idata.pmksa, 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->addr, 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idata.pmkid); 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid = idata.pmkid; 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7667832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (sm->pmksa && pmkid) { 76757c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt struct vlan_description *vlan; 76857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt 76957c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt vlan = sm->pmksa->vlan_desc; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 77157c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt "PMKID found from PMKSA cache eap_type=%d vlan=%d%s", 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmksa->eap_type_authsrv, 77357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt vlan ? vlan->untagged : 0, 77457c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt (vlan && vlan->tagged[0]) ? "+" : ""); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN); 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) { 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->wpa_ie); 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ie = os_malloc(wpa_ie_len); 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_ie == NULL) 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_ALLOC_FAIL; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->wpa_ie, wpa_ie, wpa_ie_len); 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ie_len = wpa_ie_len; 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IE_OK; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 791f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#ifdef CONFIG_HS20 792f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtint wpa_validate_osen(struct wpa_authenticator *wpa_auth, 793f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct wpa_state_machine *sm, 794f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const u8 *osen_ie, size_t osen_ie_len) 795f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 796f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_auth == NULL || sm == NULL) 797f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 798f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 799f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* TODO: parse OSEN element */ 800f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->wpa_key_mgmt = WPA_KEY_MGMT_OSEN; 801f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->mgmt_frame_prot = 1; 802f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->pairwise = WPA_CIPHER_CCMP; 803f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->wpa = WPA_VERSION_WPA2; 804f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 805f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sm->wpa_ie == NULL || sm->wpa_ie_len < osen_ie_len) { 806f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_free(sm->wpa_ie); 807f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->wpa_ie = os_malloc(osen_ie_len); 808f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sm->wpa_ie == NULL) 809f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 810f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 811f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 812f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memcpy(sm->wpa_ie, osen_ie, osen_ie_len); 813f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->wpa_ie_len = osen_ie_len; 814f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 815f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return 0; 816f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 817f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 818f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#endif /* CONFIG_HS20 */ 819f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 820f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pos: Pointer to the IE header 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @end: Pointer to the end of the Key Data buffer 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ie: Pointer to parsed IE data 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, 1 if end mark is found, -1 on failure 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_parse_generic(const u8 *pos, const u8 *end, 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse *ie) 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[1] == 0) 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[1] >= 6 && 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE && 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[2 + WPA_SELECTOR_LEN] == 1 && 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[2 + WPA_SELECTOR_LEN + 1] == 0) { 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->wpa_ie = pos; 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->wpa_ie_len = pos[1] + 2; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 843f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (pos[1] >= 4 && WPA_GET_BE32(pos + 2) == OSEN_IE_VENDOR_TYPE) { 844f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ie->osen = pos; 845f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ie->osen_len = pos[1] + 2; 846f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return 0; 847f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 848f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 849d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (1 + RSN_SELECTOR_LEN < end - pos && 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN && 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) { 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->pmkid = pos + 2 + RSN_SELECTOR_LEN; 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[1] > RSN_SELECTOR_LEN + 2 && 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) { 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->gtk = pos + 2 + RSN_SELECTOR_LEN; 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->gtk_len = pos[1] - RSN_SELECTOR_LEN; 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[1] > RSN_SELECTOR_LEN + 2 && 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) { 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[1] > RSN_SELECTOR_LEN + 2 && 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) { 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->smk = pos + 2 + RSN_SELECTOR_LEN; 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->smk_len = pos[1] - RSN_SELECTOR_LEN; 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[1] > RSN_SELECTOR_LEN + 2 && 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) { 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->nonce = pos + 2 + RSN_SELECTOR_LEN; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->nonce_len = pos[1] - RSN_SELECTOR_LEN; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[1] > RSN_SELECTOR_LEN + 2 && 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) { 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->lifetime = pos + 2 + RSN_SELECTOR_LEN; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[1] > RSN_SELECTOR_LEN + 2 && 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) { 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->error = pos + 2 + RSN_SELECTOR_LEN; 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->error_len = pos[1] - RSN_SELECTOR_LEN; 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */ 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[1] > RSN_SELECTOR_LEN + 2 && 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) { 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->igtk = pos + 2 + RSN_SELECTOR_LEN; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->igtk_len = pos[1] - RSN_SELECTOR_LEN; 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 909cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 910cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (pos[1] >= RSN_SELECTOR_LEN + 1 && 911cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_REQ) { 912cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ie->ip_addr_req = pos + 2 + RSN_SELECTOR_LEN; 913cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key", 914cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ie->ip_addr_req, pos[1] - RSN_SELECTOR_LEN); 915cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 916cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 917cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 918cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (pos[1] >= RSN_SELECTOR_LEN + 3 * 4 && 919cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_ALLOC) { 920cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ie->ip_addr_alloc = pos + 2 + RSN_SELECTOR_LEN; 921cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump(MSG_DEBUG, 922cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "WPA: IP Address Allocation in EAPOL-Key", 923cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ie->ip_addr_alloc, pos[1] - RSN_SELECTOR_LEN); 924cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 925cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 926cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 927cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Pointer to the Key Data buffer 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Key Data Length 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ie: Pointer to parsed IE data 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie) 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(ie, 0, sizeof(*ie)); 945d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (pos = buf, end = pos + len; end - pos > 1; pos += 2 + pos[1]) { 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == 0xdd && 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((pos == buf + len - 1) || pos[1] == 0)) { 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ignore padding */ 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 951d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (2 + pos[1] > end - pos) { 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data " 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "underflow (ie=%d len=%d pos=%d)", 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[0], pos[1], (int) (pos - buf)); 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data", 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, len); 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == WLAN_EID_RSN) { 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->rsn_ie = pos; 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->rsn_ie_len = pos[1] + 2; 9639839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_IEEE80211R_AP 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) { 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->mdie = pos; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->mdie_len = pos[1] + 2; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) { 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->ftie = pos; 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->ftie_len = pos[1] + 2; 9709839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_IEEE80211R_AP */ 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) { 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = wpa_parse_generic(pos, end, ie); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret > 0) { 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key " 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Key Data IE", pos, 2 + pos[1]); 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_uses_mfp(struct wpa_state_machine *sm) 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm ? sm->mgmt_frame_prot : 0; 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 993