From 4355fc8fbc6ba2216d8911587c2a5b687eed7d96 Mon Sep 17 00:00:00 2001 From: "tarun.kumar" Date: Wed, 11 Dec 2024 22:48:36 +0530 Subject: [PATCH] feat(wifi): Add SAE-EXT-KEY feature on softAP --- .../esp_wifi/include/esp_wifi_types_generic.h | 1 + components/esp_wifi/lib | 2 +- .../esp_supplicant/src/esp_hostap.c | 65 ++++++++++++++----- .../esp_supplicant/src/esp_wifi_driver.h | 1 + components/wpa_supplicant/src/ap/ieee802_11.c | 4 +- components/wpa_supplicant/src/ap/wpa_auth.c | 43 ++++++++---- components/wpa_supplicant/src/ap/wpa_auth.h | 2 +- components/wpa_supplicant/src/ap/wpa_auth_i.h | 2 +- .../wpa_supplicant/src/ap/wpa_auth_ie.c | 39 ++++++++--- .../wpa_supplicant/src/common/wpa_common.c | 2 + 10 files changed, 116 insertions(+), 45 deletions(-) diff --git a/components/esp_wifi/include/esp_wifi_types_generic.h b/components/esp_wifi/include/esp_wifi_types_generic.h index 4e796b5896..bbccde6f09 100644 --- a/components/esp_wifi/include/esp_wifi_types_generic.h +++ b/components/esp_wifi/include/esp_wifi_types_generic.h @@ -526,6 +526,7 @@ typedef struct { wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame */ wifi_sae_pwe_method_t sae_pwe_h2e; /**< Configuration for SAE PWE derivation method */ uint8_t transition_disable; /**< Whether to enable transition disable feature */ + uint8_t sae_ext; /**< Enable SAE EXT feature. SOC_GCMP_SUPPORT is required for this feature. */ } wifi_ap_config_t; #define SAE_H2E_IDENTIFIER_LEN 32 /**< Length of the password identifier for H2E */ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 75ab1ccd8a..bf5292507e 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 75ab1ccd8a874f82203adaad2c9dc743cb86d754 +Subproject commit bf5292507e0ace431524b9be4b17ab69627108b0 diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c index f2cdaa1198..ccf7d81337 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -37,6 +37,18 @@ struct hostapd_data *hostapd_get_hapd_data(void) { return global_hapd; } +static bool authmode_has_wpa(uint8_t authmode) +{ + return (authmode == WIFI_AUTH_WPA_PSK || authmode == WIFI_AUTH_WPA_WPA2_PSK); +} + +static bool authmode_has_rsn(uint8_t authmode) +{ + return (authmode == WIFI_AUTH_WPA2_PSK || + authmode == WIFI_AUTH_WPA_WPA2_PSK || + authmode == WIFI_AUTH_WPA3_PSK || + authmode == WIFI_AUTH_WPA2_WPA3_PSK); +} void *hostap_init(void) { @@ -44,9 +56,12 @@ void *hostap_init(void) struct hostapd_data *hapd = NULL; struct wpa_auth_config *auth_conf; u16 spp_attrubute = 0; - u8 pairwise_cipher; + u16 pairwise_cipher; wifi_pmf_config_t pmf_cfg = {0}; uint8_t authmode; + uint8_t sae_ext = 0; + + sae_ext = esp_wifi_ap_get_sae_ext_config_internal(); hapd = (struct hostapd_data *)os_zalloc(sizeof(struct hostapd_data)); @@ -71,30 +86,23 @@ void *hostap_init(void) auth_conf->sae_pwe = hapd->conf->sae_pwe; authmode = esp_wifi_ap_get_prof_authmode_internal(); - if (authmode == WIFI_AUTH_WPA_PSK) { - auth_conf->wpa = WPA_PROTO_WPA; + if (authmode_has_wpa(authmode)) { + auth_conf->wpa |= WPA_PROTO_WPA; } - if (authmode == WIFI_AUTH_WPA2_PSK) { - auth_conf->wpa = WPA_PROTO_RSN; + if (authmode_has_rsn(authmode)) { + auth_conf->wpa |= WPA_PROTO_RSN; } - if (authmode == WIFI_AUTH_WPA_WPA2_PSK) { - auth_conf->wpa = WPA_PROTO_RSN | WPA_PROTO_WPA; - } - if (authmode == WIFI_AUTH_WPA3_PSK || authmode == WIFI_AUTH_WPA2_WPA3_PSK) { - auth_conf->wpa = WPA_PROTO_RSN; - } - pairwise_cipher = esp_wifi_ap_get_prof_pairwise_cipher_internal(); #ifdef CONFIG_IEEE80211W if ((auth_conf->wpa & WPA_PROTO_RSN) == WPA_PROTO_RSN) { esp_wifi_get_pmf_config_internal(&pmf_cfg, WIFI_IF_AP); - if (pmf_cfg.required) { + /* Use cipher as CCMP if pmf is enabled and TKIP is set */ + if (pmf_cfg.required && pairwise_cipher == WIFI_CIPHER_TYPE_TKIP) { pairwise_cipher = WIFI_CIPHER_TYPE_CCMP; } } #endif /* CONFIG_IEEE80211W */ - /* TKIP is compulsory in WPA Mode */ if (auth_conf->wpa == WPA_PROTO_WPA && pairwise_cipher == WIFI_CIPHER_TYPE_CCMP) { pairwise_cipher = WIFI_CIPHER_TYPE_TKIP_CCMP; @@ -107,6 +115,10 @@ void *hostap_init(void) auth_conf->wpa_group = WPA_CIPHER_CCMP; auth_conf->wpa_pairwise = WPA_CIPHER_CCMP; auth_conf->rsn_pairwise = WPA_CIPHER_CCMP; + } else if (pairwise_cipher == WIFI_CIPHER_TYPE_GCMP256) { + auth_conf->wpa_group = WPA_CIPHER_GCMP_256; + auth_conf->wpa_pairwise = WPA_CIPHER_GCMP_256; + auth_conf->rsn_pairwise = WPA_CIPHER_GCMP_256; } else { auth_conf->wpa_group = WPA_CIPHER_TKIP; auth_conf->wpa_pairwise = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP; @@ -127,7 +139,21 @@ void *hostap_init(void) auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK; wpa_printf(MSG_DEBUG, "%s : pmf optional", __func__); } - + if (auth_conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { + switch (pairwise_cipher) { + case WIFI_CIPHER_TYPE_CCMP: + auth_conf->group_mgmt_cipher = WPA_CIPHER_AES_128_CMAC; + break; + case WIFI_CIPHER_TYPE_GCMP: + auth_conf->group_mgmt_cipher = WPA_CIPHER_BIP_GMAC_128; + break; + case WIFI_CIPHER_TYPE_GCMP256: + auth_conf->group_mgmt_cipher = WPA_CIPHER_BIP_GMAC_256; + break; + default: + wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (0x%x)", pairwise_cipher); + } + } if (authmode == WIFI_AUTH_WPA2_WPA3_PSK) { auth_conf->wpa_key_mgmt |= WPA_KEY_MGMT_SAE; } @@ -135,6 +161,10 @@ void *hostap_init(void) if (authmode == WIFI_AUTH_WPA3_PSK) { auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_SAE; } + if (authmode == WIFI_AUTH_WPA3_PSK && pairwise_cipher == WIFI_CIPHER_TYPE_GCMP256 && sae_ext) { + auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY; + } + #endif /* CONFIG_IEEE80211W */ spp_attrubute = esp_wifi_get_spp_attrubute_internal(WIFI_IF_AP); @@ -370,7 +400,6 @@ bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, if (!sta || !bssid || !wpa_ie) { return false; } - if (hapd) { if (hapd->wpa_auth->conf.wpa) { if (sta->wpa_sm) { @@ -386,10 +415,10 @@ bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, } res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len); - #ifdef CONFIG_SAE if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae && sta->sae->state == SAE_ACCEPTED) { + sta->wpa_sm->pmk_len = sta->sae->pmk_len; wpa_auth_add_sae_pmkid(sta->wpa_sm, sta->sae->pmkid); } #endif /* CONFIG_SAE */ diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h index e6732989cf..df068bba20 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -284,6 +284,7 @@ bool esp_wifi_is_btm_enabled_internal(uint8_t if_index); esp_err_t esp_wifi_register_mgmt_frame_internal(uint32_t type, uint32_t subtype); esp_err_t esp_wifi_send_mgmt_frm_internal(const wifi_mgmt_frm_req_t *req); uint8_t esp_wifi_ap_get_prof_pairwise_cipher_internal(void); +uint8_t esp_wifi_ap_get_sae_ext_config_internal(void); bool esp_wifi_is_mbo_enabled_internal(uint8_t if_index); void esp_wifi_get_pmf_config_internal(wifi_pmf_config_t *pmf_cfg, uint8_t ifx); bool esp_wifi_is_ft_enabled_internal(uint8_t if_index); diff --git a/components/wpa_supplicant/src/ap/ieee802_11.c b/components/wpa_supplicant/src/ap/ieee802_11.c index 653926d70b..aa9307c0cc 100644 --- a/components/wpa_supplicant/src/ap/ieee802_11.c +++ b/components/wpa_supplicant/src/ap/ieee802_11.c @@ -247,9 +247,11 @@ void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta) #endif /* ESP_SUPPLICANT */ sta->auth_alg = WLAN_AUTH_SAE; + sta->sae->peer_commit_scalar_accepted = sta->sae->peer_commit_scalar; + sta->sae->peer_commit_scalar = NULL; sae_set_state(sta, SAE_ACCEPTED, "Accept Confirm"); wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr, - sta->sae->pmk, sta->sae->pmkid, false); + sta->sae->pmk, sta->sae->pmk_len, sta->sae->pmkid, false, sta->sae->akmp); } diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index 221098f1f5..f5715611a8 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -949,16 +949,16 @@ continue_processing: } int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, - const u8 *pmk, const u8 *pmkid, bool cache_pmksa) + const u8 *pmk, size_t pmk_len, const u8 *pmkid, bool cache_pmksa, int akmp) { if (cache_pmksa) return -1; wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK from SAE", pmk, PMK_LEN); - if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, PMK_LEN, pmkid, + if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, pmk_len, pmkid, NULL, 0, wpa_auth->addr, addr, 0, NULL, - WPA_KEY_MGMT_SAE)) + akmp)) return 0; return -1; @@ -1599,7 +1599,7 @@ SM_STATE(WPA_PTK, PTKSTART) static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, - const u8 *pmk, struct wpa_ptk *ptk) + const u8 *pmk, unsigned int pmk_len, struct wpa_ptk *ptk) { #ifdef CONFIG_IEEE80211R_AP size_t ptk_len = sm->pairwise != WPA_CIPHER_TKIP ? 48 : 64; @@ -1609,7 +1609,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, return wpa_auth_derive_ptk_ft(sm, pmk, ptk); #endif /* CONFIG_IEEE80211R_AP */ - return wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion", + return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion", sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce, ptk, sm->wpa_key_mgmt, sm->pairwise); } @@ -1625,9 +1625,11 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) struct wpa_eapol_key *key; struct wpa_eapol_ie_parse kde; + size_t pmk_len; SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk); sm->EAPOLKeyReceived = FALSE; sm->update_snonce = FALSE; + pmk_len = PMK_LEN; /* WPA with IEEE 802.1X: use the derived PMK from EAP * WPA-PSK: iterate through possible PSKs and select the one matching @@ -1642,15 +1644,17 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) break; } } else { + pmk_len = sm->pmk_len; pmk = sm->PMK; } if (!pmk && sm->pmksa) { wpa_printf(MSG_DEBUG, "WPA: Use PMK from PMKSA cache"); pmk = sm->pmksa->pmk; + pmk_len = sm->pmksa->pmk_len; } - wpa_derive_ptk(sm, sm->SNonce, pmk, &PTK); + wpa_derive_ptk(sm, sm->SNonce, pmk, pmk_len, &PTK); if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK, sm->last_rx_eapol_key, @@ -1729,7 +1733,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) /* PSK may have changed from the previous choice, so update * state machine data based on whatever PSK was selected here. */ - memcpy(sm->PMK, pmk, PMK_LEN); + memcpy(sm->PMK, pmk, pmk_len); } sm->MICVerified = TRUE; @@ -1748,13 +1752,18 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING2) #ifdef CONFIG_IEEE80211W +#define WPA_IGTK_KDE_PREFIX_LEN (2 + 6) + static int ieee80211w_kde_len(struct wpa_state_machine *sm) { + size_t len = 0; + struct wpa_authenticator *wpa_auth = sm->wpa_auth; if (sm->mgmt_frame_prot) { - return 2 + RSN_SELECTOR_LEN + sizeof(struct wpa_igtk_kde); + len += 2 + RSN_SELECTOR_LEN + WPA_IGTK_KDE_PREFIX_LEN; + len += wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); } - return 0; + return len; } @@ -1763,6 +1772,10 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos) struct wpa_igtk_kde igtk; struct wpa_group *gsm = sm->group; + struct wpa_authenticator *wpa_auth = sm->wpa_auth; + struct wpa_auth_config *conf = &wpa_auth->conf; + size_t len = wpa_cipher_key_len(conf->group_mgmt_cipher); + if (!sm->mgmt_frame_prot) return pos; @@ -1771,17 +1784,17 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos) if (gsm->wpa_group_state != WPA_GROUP_SETKEYSDONE || wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, igtk.pn) < 0) memset(igtk.pn, 0, sizeof(igtk.pn)); - memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN); + memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], len); if (sm->wpa_auth->conf.disable_gtk) { /* * Provide unique random IGTK to each STA to prevent use of * IGTK in the BSS. */ - if (os_get_random(igtk.igtk, WPA_IGTK_LEN) < 0) + if (os_get_random(igtk.igtk, len) < 0) return pos; } pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK, - (const u8 *) &igtk, sizeof(igtk), NULL, 0); + (const u8 *) &igtk, WPA_IGTK_KDE_PREFIX_LEN + len, NULL, 0); return pos; } @@ -2255,6 +2268,7 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth, struct wpa_group *group) { int ret = 0; + size_t len; memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); inc_byte_array(group->Counter, WPA_NONCE_LEN); @@ -2268,15 +2282,16 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth, #ifdef CONFIG_IEEE80211W if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) { + len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); inc_byte_array(group->Counter, WPA_NONCE_LEN); if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion", wpa_auth->addr, group->GNonce, group->IGTK[group->GN_igtk - 4], - WPA_IGTK_LEN) < 0) + len) < 0) ret = -1; wpa_hexdump_key(MSG_DEBUG, "IGTK", - group->IGTK[group->GN_igtk - 4], WPA_IGTK_LEN); + group->IGTK[group->GN_igtk - 4], len); } #endif /* CONFIG_IEEE80211W */ diff --git a/components/wpa_supplicant/src/ap/wpa_auth.h b/components/wpa_supplicant/src/ap/wpa_auth.h index 057838ce87..e2886a9fee 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.h +++ b/components/wpa_supplicant/src/ap/wpa_auth.h @@ -300,7 +300,7 @@ int wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos); int wpa_auth_uses_sae(struct wpa_state_machine *sm); int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, - const u8 *pmk, const u8 *pmkid,bool cache_pmksa); + const u8 *pmk, size_t pmk_len, const u8 *pmkid,bool cache_pmksa, int akmp); void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid); void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, const u8 *sta_addr); diff --git a/components/wpa_supplicant/src/ap/wpa_auth_i.h b/components/wpa_supplicant/src/ap/wpa_auth_i.h index 2516b34f69..09b254ca2d 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth_i.h +++ b/components/wpa_supplicant/src/ap/wpa_auth_i.h @@ -195,7 +195,7 @@ struct wpa_authenticator { int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, - const u8 *pmkid); + const u8 *pmkid, int group_mgmt_cipher); int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len); void __wpa_send_eapol(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *sm, int key_info, diff --git a/components/wpa_supplicant/src/ap/wpa_auth_ie.c b/components/wpa_supplicant/src/ap/wpa_auth_ie.c index 1eedb701c2..9453aa710d 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth_ie.c +++ b/components/wpa_supplicant/src/ap/wpa_auth_ie.c @@ -86,7 +86,7 @@ static int wpa_write_wpa_ie(struct wpa_auth_config *conf, u8 *buf, size_t len) int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, - const u8 *pmkid) + const u8 *pmkid, int group_mgmt_cipher) { struct rsn_ie_hdr *hdr; int num_suites, res; @@ -191,6 +191,11 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, pos += RSN_SELECTOR_LEN; num_suites++; } + if (conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) { + RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE_EXT_KEY); + pos += RSN_SELECTOR_LEN; + num_suites++; + } if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) { RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE); pos += RSN_SELECTOR_LEN; @@ -265,8 +270,20 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, } /* Management Group Cipher Suite */ - RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); - pos += RSN_SELECTOR_LEN; + switch (group_mgmt_cipher) { + case WPA_CIPHER_AES_128_CMAC: + RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); + break; + case WPA_CIPHER_BIP_GMAC_128: + RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_128); + break; + case WPA_CIPHER_BIP_GMAC_256: + RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_256); + break; + default: + RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); + } + pos += RSN_SELECTOR_LEN; } #endif /* CONFIG_IEEE80211W */ @@ -335,7 +352,7 @@ int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth) if (wpa_auth->conf.wpa & WPA_PROTO_RSN) { res = wpa_write_rsn_ie(&wpa_auth->conf, - pos, buf + sizeof(buf) - pos, NULL); + pos, buf + sizeof(buf) - pos, NULL, wpa_auth->conf.group_mgmt_cipher); if (res < 0) return res; pos += res; @@ -443,6 +460,8 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, #ifdef CONFIG_SAE else if (data.key_mgmt & WPA_KEY_MGMT_SAE) selector = RSN_AUTH_KEY_MGMT_SAE; + else if (data.key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) + selector = RSN_AUTH_KEY_MGMT_SAE_EXT_KEY; else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE) selector = RSN_AUTH_KEY_MGMT_FT_SAE; #endif /* CONFIG_SAE */ @@ -518,6 +537,8 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, #ifdef CONFIG_SAE else if (key_mgmt & WPA_KEY_MGMT_SAE) sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE; + else if (key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) + sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY; else if (key_mgmt & WPA_KEY_MGMT_FT_SAE) sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE; #endif /* CONFIG_SAE */ @@ -563,10 +584,8 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, "cannot use TKIP"); return WPA_MGMT_FRAME_PROTECTION_VIOLATION; } - - if (data.mgmt_group_cipher != wpa_auth->conf.group_mgmt_cipher) - { - wpa_printf(MSG_DEBUG, "Unsupported management group " + if (!wpa_cipher_valid_mgmt_group(data.mgmt_group_cipher)) { + wpa_printf( MSG_DEBUG, "Unsupported management group " "cipher %d", data.mgmt_group_cipher); return WPA_INVALID_MGMT_GROUP_CIPHER; } @@ -610,6 +629,8 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, sm->pairwise = WPA_CIPHER_CCMP; else if (ciphers & WPA_CIPHER_GCMP) sm->pairwise = WPA_CIPHER_GCMP; + else if (ciphers & WPA_CIPHER_GCMP_256) + sm->pairwise = WPA_CIPHER_GCMP_256; else sm->pairwise = WPA_CIPHER_TKIP; @@ -636,7 +657,7 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, } #ifdef CONFIG_SAE - if (sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE && data.num_pmkid && + if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE || sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY) && data.num_pmkid && !sm->pmksa) { wpa_printf(MSG_DEBUG, "No PMKSA cache entry found for SAE"); return WPA_INVALID_PMKID; diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index faa0be573c..6f9485760b 100644 --- a/components/wpa_supplicant/src/common/wpa_common.c +++ b/components/wpa_supplicant/src/common/wpa_common.c @@ -324,6 +324,8 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s) #ifdef CONFIG_WPA3_SAE if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE) return WPA_KEY_MGMT_SAE; + if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE_EXT_KEY) + return WPA_KEY_MGMT_SAE_EXT_KEY; #endif /* CONFIG_WPA3_SAE */ if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256) return WPA_KEY_MGMT_IEEE8021X_SHA256;