From a7f32f5a2a3cd0e08d8ed0706ecf01ebffaec810 Mon Sep 17 00:00:00 2001 From: Shreyas Sheth Date: Tue, 29 Apr 2025 11:38:39 +0530 Subject: [PATCH] feat(esp_wifi): Add compile flag for wpa3 compatible mode --- components/esp_wifi/Kconfig | 8 +- .../esp_wifi/include/esp_wifi_types_generic.h | 2 +- components/wpa_supplicant/CMakeLists.txt | 3 + .../esp_supplicant/src/esp_hostap.c | 37 ++++-- .../esp_supplicant/src/esp_wifi_driver.h | 2 +- .../esp_supplicant/src/esp_wpa3.c | 14 +- .../esp_supplicant/src/esp_wpa_main.c | 26 +--- components/wpa_supplicant/src/ap/ap_config.c | 7 +- components/wpa_supplicant/src/ap/ap_config.h | 13 +- components/wpa_supplicant/src/ap/wpa_auth.c | 30 +++-- components/wpa_supplicant/src/ap/wpa_auth.h | 12 ++ components/wpa_supplicant/src/ap/wpa_auth_i.h | 4 + .../wpa_supplicant/src/ap/wpa_auth_ie.c | 16 ++- .../src/common/ieee802_11_common.c | 120 +++--------------- .../src/common/ieee802_11_common.h | 6 - .../src/common/ieee802_11_defs.h | 25 ---- .../wpa_supplicant/src/common/wpa_common.c | 2 + .../wpa_supplicant/src/common/wpa_common.h | 3 +- components/wpa_supplicant/src/rsn_supp/wpa.c | 68 +++++++--- components/wpa_supplicant/src/rsn_supp/wpa.h | 6 + .../wpa_supplicant/src/rsn_supp/wpa_i.h | 13 +- .../wpa_supplicant/src/rsn_supp/wpa_ie.c | 14 +- .../softAP/main/softap_example_main.c | 4 +- .../station/main/station_example_main.c | 3 + 24 files changed, 222 insertions(+), 216 deletions(-) diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index c807cd3a73..48dccc2157 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -1,4 +1,3 @@ - menu "Wi-Fi" visible if (SOC_WIFI_SUPPORTED || SOC_WIRELESS_HOST_SUPPORTED) @@ -340,6 +339,13 @@ menu "Wi-Fi" explicitly configured before attempting connection. Please refer to the Wi-Fi Driver API Guide for details. + config ESP_WIFI_WPA3_COMPATIBLE_SUPPORT + bool "Enable WPA3 Compatible support" + default y + depends on ESP_WIFI_ENABLE_SAE_H2E + help + Select this option to enable WPA3 Compatible support in softap mode. + config ESP_WIFI_SLP_IRAM_OPT bool "WiFi SLP IRAM speed optimization" select PM_SLP_DEFAULT_PARAMS_OPT diff --git a/components/esp_wifi/include/esp_wifi_types_generic.h b/components/esp_wifi/include/esp_wifi_types_generic.h index 2fb7404771..acb21d0b5f 100644 --- a/components/esp_wifi/include/esp_wifi_types_generic.h +++ b/components/esp_wifi/include/esp_wifi_types_generic.h @@ -564,7 +564,7 @@ typedef struct { uint32_t owe_enabled: 1; /**< Whether OWE is enabled for the connection */ uint32_t transition_disable: 1; /**< Whether to enable transition disable feature */ uint32_t wpa3_compatible_mode: 1; /**< Whether to enable wpa3 compatible authmode feature */ - uint32_t reserved1: 25; /**< Reserved for future feature set */ + uint32_t reserved1: 25; /**< Reserved for future feature set */ wifi_sae_pwe_method_t sae_pwe_h2e; /**< Configuration for SAE PWE derivation method */ wifi_sae_pk_mode_t sae_pk_mode; /**< Configuration for SAE-PK (Public Key) Authentication method */ uint8_t failure_retry_cnt; /**< Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config. diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index cafc14a27b..07d0f9566b 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -287,6 +287,9 @@ endif() if(CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT) target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_SAE) endif() +if(CONFIG_ESP_WIFI_WPA3_COMPATIBLE_SUPPORT) + target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_WPA3_COMPAT) +endif() if(CONFIG_ESP_WIFI_WPS_STRICT) target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_WPS_STRICT) endif() diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c index df9da91253..4eaaa50af4 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c @@ -110,15 +110,19 @@ void *hostap_init(void) } #endif /* CONFIG_IEEE80211W */ if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_AP)) { - //TODO check sae_pwe +#ifdef CONFIG_WPA3_COMPAT hapd->conf->sae_pwe = SAE_PWE_HASH_TO_ELEMENT; auth_conf->rsn_override_omit_rsnxe = 1; + hapd->conf->rsn_override_omit_rsnxe = 1; hapd->conf->rsn_override_key_mgmt = WPA_KEY_MGMT_SAE; hapd->conf->rsn_override_pairwise = WPA_CIPHER_CCMP; hapd->conf->rsn_override_mfp = MGMT_FRAME_PROTECTION_REQUIRED; auth_conf->rsn_override_key_mgmt = WPA_KEY_MGMT_SAE; auth_conf->rsn_override_pairwise = WPA_CIPHER_CCMP; auth_conf->rsn_override_mfp = MGMT_FRAME_PROTECTION_REQUIRED; +#else + wpa_printf(MSG_ERROR, "ESP_WIFI_WPA3_COMPATIBLE_SUPPORT disabled ignoring wpa3_compatible configuration"); +#endif } /* TKIP is compulsory in WPA Mode */ if (auth_conf->wpa == WPA_PROTO_WPA && pairwise_cipher == WIFI_CIPHER_TYPE_CCMP) { @@ -224,7 +228,6 @@ void *hostap_init(void) #ifdef CONFIG_SAE auth_conf->sae_require_mfp = 1; #endif /* CONFIG_SAE */ - auth_conf->rsn_override_omit_rsnxe = 1; hapd->conf->ap_max_inactivity = 5 * 60; hostapd_setup_wpa_psk(hapd->conf); @@ -409,15 +412,21 @@ uint8_t wpa_status_to_reason_code(int status) } } -bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, struct ieee802_11_elems elems, - bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason) +bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie, + u8 wpa_ie_len, u8 *rsnxe, uint16_t rsnxe_len, + bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason, uint8_t *rsn_selection_ie) { struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal(); enum wpa_validate_result res = WPA_IE_OK; int status = WLAN_STATUS_SUCCESS; bool omit_rsnxe = false; - if (!sta || !bssid || !elems.rsn_ie) { +#ifdef CONFIG_WPA3_COMPAT + uint8_t rsn_selection_variant_len = 0; + uint8_t *rsn_selection_variant_ie = NULL; +#endif + + if (!sta || !bssid || !wpa_ie) { return false; } if (hapd) { @@ -434,8 +443,16 @@ bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, struct ieee802_1 goto send_resp; } - wpa_auth_set_rsn_selection(sta->wpa_sm, elems.rsn_selection, elems.rsn_selection_len); - res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, elems.rsn_ie, elems.rsn_ie_len, elems.rsnxe, elems.rsnxe_len); +#ifdef CONFIG_WPA3_COMPAT + if (rsn_selection_ie) { + rsn_selection_variant_len = rsn_selection_ie[1] - 4; + rsn_selection_variant_ie = &rsn_selection_ie[6]; + } + + wpa_auth_set_rsn_selection(sta->wpa_sm, rsn_selection_variant_ie, rsn_selection_variant_len); +#endif + + 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) { @@ -447,13 +464,15 @@ bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, struct ieee802_1 status = wpa_res_to_status_code(res); send_resp: - if (!elems.rsnxe) { + if (!rsnxe) { omit_rsnxe = true; } +#ifdef CONFIG_WPA3_COMPAT if (hapd->conf->rsn_override_omit_rsnxe) { - omit_rsnxe = 1; + omit_rsnxe = false; } +#endif if (esp_send_assoc_resp(hapd, bssid, status, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) { status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 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 1bfdc2ccd2..874f32c97f 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -129,7 +129,7 @@ struct wpa_funcs { bool (*wpa_sta_in_4way_handshake)(void); void *(*wpa_ap_init)(void); bool (*wpa_ap_deinit)(void *data); - bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *assoc_req_ie, uint32_t len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher); + bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8* rsnxe, u16 rsnxe_len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *rsn_selection_ie); bool (*wpa_ap_remove)(u8 *bssid); uint8_t *(*wpa_ap_get_wpa_ie)(uint8_t *len); bool (*wpa_ap_rx_eapol)(void *hapd_data, void *sm, u8 *data, size_t data_len); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c index 15f138cac3..c5ef241f94 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c @@ -46,17 +46,19 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid, size_t *sae_msg_len) use_pt = 1; } +#ifdef CONFIG_WPA3_COMPAT if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA)) { rsnxe = esp_wifi_sta_get_ie((u8*)bssid, WFA_RSNXE_OVERRIDE_OUI_TYPE); + if (rsnxe) { + rsnxe_capa = rsnxe[2 + 4]; + } } +#endif if (!rsnxe) { rsnxe = esp_wifi_sta_get_ie((u8*)bssid, WLAN_EID_RSNX); - } - if (rsnxe && rsnxe[0] == WLAN_EID_VENDOR_SPECIFIC && - rsnxe[1] >= 1 + 4) { - rsnxe_capa = rsnxe[2 + 4]; - } else if (rsnxe && rsnxe[1] >= 1) { - rsnxe_capa = rsnxe[2]; + if (rsnxe) { + rsnxe_capa = rsnxe[2]; + } } #endif /* CONFIG_SAE_H2E */ diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c index f71d0f69b8..f8812b780b 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -377,37 +377,22 @@ static int check_n_add_wps_sta(struct hostapd_data *hapd, struct sta_info *sta_i } #endif -static bool hostap_sta_join(void **sta, u8 *bssid, u8 *assoc_req_ie, uint32_t assoc_ie_len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher) +static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8 *rsnxe, u16 rsnxe_len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *rsn_selection_ie) { struct sta_info *sta_info = NULL; struct hostapd_data *hapd = hostapd_get_hapd_data(); uint8_t reason = WLAN_REASON_PREV_AUTH_NOT_VALID; - struct ieee802_11_elems elems; if (!hapd) { goto fail; } - if (ieee802_11_parse_elems(assoc_req_ie, assoc_ie_len, &elems, 1) == ParseFailed) { - wpa_printf(MSG_INFO, "Failed to parse assoc req IEs"); - return -1; - } - - if (elems.rsn_ie) { - elems.rsn_ie = elems.rsn_ie - 2; - elems.rsn_ie_len = elems.rsn_ie_len + 2; - } - if (elems.rsnxe) { - elems.rsnxe = elems.rsnxe - 2; - elems.rsnxe_len = elems.rsnxe_len + 2; - } - if (*sta) { struct sta_info *old_sta = *sta; #ifdef CONFIG_SAE if (old_sta->lock && os_semphr_take(old_sta->lock, 0) != TRUE) { wpa_printf(MSG_INFO, "Ignore assoc request as softap is busy with sae calculation for station "MACSTR, MAC2STR(bssid)); - if (esp_send_assoc_resp(hapd, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, elems.rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) { + if (esp_send_assoc_resp(hapd, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) { goto fail; } return false; @@ -436,7 +421,7 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *assoc_req_ie, uint32_t as #ifdef CONFIG_SAE if (sta_info->lock && os_semphr_take(sta_info->lock, 0) != TRUE) { wpa_printf(MSG_INFO, "Ignore assoc request as softap is busy with sae calculation for station "MACSTR, MAC2STR(bssid)); - if (esp_send_assoc_resp(hapd, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, elems.rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) { + if (esp_send_assoc_resp(hapd, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) { goto fail; } return false; @@ -446,7 +431,7 @@ process_old_sta: #endif /* CONFIG_SAE */ #ifdef CONFIG_WPS_REGISTRAR - if (check_n_add_wps_sta(hapd, sta_info, elems.rsn_ie, elems.rsn_ie_len, pmf_enable, subtype) == 0) { + if (check_n_add_wps_sta(hapd, sta_info, wpa_ie, wpa_ie_len, pmf_enable, subtype) == 0) { if (sta_info->eapol_sm) { goto done; } @@ -454,8 +439,7 @@ process_old_sta: goto fail; } #endif - - if (hostap_new_assoc_sta(sta_info, bssid, elems, pmf_enable, subtype, pairwise_cipher, &reason)) { + if (hostap_new_assoc_sta(sta_info, bssid, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len, pmf_enable, subtype, pairwise_cipher, &reason, rsn_selection_ie)) { goto done; } else { goto fail; diff --git a/components/wpa_supplicant/src/ap/ap_config.c b/components/wpa_supplicant/src/ap/ap_config.c index e4e8b08f62..de1e392ab6 100644 --- a/components/wpa_supplicant/src/ap/ap_config.c +++ b/components/wpa_supplicant/src/ap/ap_config.c @@ -150,8 +150,11 @@ int hostapd_setup_sae_pt(struct hostapd_bss_config *conf) #ifdef CONFIG_SAE_H2E struct hostapd_ssid *ssid = &conf->ssid; if (conf->sae_pwe == SAE_PWE_HUNT_AND_PECK || - !wpa_key_mgmt_sae(conf->wpa_key_mgmt | - conf->rsn_override_key_mgmt)) + !wpa_key_mgmt_sae(conf->wpa_key_mgmt +#ifdef CONFIG_WPA3_COMPAT + | conf->rsn_override_key_mgmt +#endif + )) return 0; /* PT not needed */ sae_deinit_pt(ssid->pt); diff --git a/components/wpa_supplicant/src/ap/ap_config.h b/components/wpa_supplicant/src/ap/ap_config.h index 6ee3d5729c..49aa678c82 100644 --- a/components/wpa_supplicant/src/ap/ap_config.h +++ b/components/wpa_supplicant/src/ap/ap_config.h @@ -200,10 +200,14 @@ struct hostapd_bss_config { int wpa; /* bitfield of WPA_PROTO_WPA, WPA_PROTO_RSN */ int wpa_key_mgmt; +#ifdef CONFIG_WPA3_COMPAT int rsn_override_key_mgmt; +#endif #ifdef CONFIG_IEEE80211W enum mfp_options ieee80211w; +#ifdef CONFIG_WPA3_COMPAT enum mfp_options rsn_override_mfp; +#endif /* dot11AssociationSAQueryMaximumTimeout (in TUs) */ unsigned int assoc_sa_query_max_timeout; /* dot11AssociationSAQueryRetryTimeout (in TUs) */ @@ -222,7 +226,9 @@ struct hostapd_bss_config { int wpa_ptk_rekey; int rsn_pairwise; int rsn_preauth; +#ifdef CONFIG_WPA3_COMPAT int rsn_override_pairwise; +#endif char *rsn_preauth_interfaces; #ifdef CONFIG_IEEE80211R @@ -310,7 +316,9 @@ struct hostapd_bss_config { int *sae_groups; #define SAE_ANTI_CLOGGING_THRESHOLD 2 /* max number of commit msg allowed to queue without anti-clogging token request */ +#ifdef CONFIG_WPA3_COMPAT int rsn_override_omit_rsnxe; +#endif }; @@ -387,8 +395,9 @@ const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf, const u8 *addr, const u8 *prev_psk); int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf); struct sta_info; -bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, struct ieee802_11_elems elems, - bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason); +bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie, + u8 wpa_ie_len, u8 *rsnxe, uint16_t rsnxe_len, + bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason, uint8_t *rsn_selection_ie); bool wpa_ap_remove(u8* bssid); #endif /* HOSTAPD_CONFIG_H */ diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index 19a73246f9..c7c7212ead 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -197,13 +197,16 @@ static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth, return -1; } +#ifdef CONFIG_WPA3_COMPAT void wpa_auth_set_rsn_selection(struct wpa_state_machine *sm, const u8 *ie, size_t len) { if (!sm) return; - os_free(sm->rsn_selection); - sm->rsn_selection = NULL; + if (sm->rsn_selection) { + os_free(sm->rsn_selection); + sm->rsn_selection = NULL; + } sm->rsn_selection_len = 0; sm->rsn_override = false; if (ie) { @@ -216,6 +219,7 @@ void wpa_auth_set_rsn_selection(struct wpa_state_machine *sm, const u8 *ie, sm->rsn_selection_len = len; } } +#endif /* fix buf for tx for now */ #define WPA_TX_MSG_BUFF_MAXLEN 200 @@ -522,7 +526,9 @@ static void wpa_free_sta_sm(struct wpa_state_machine *sm) os_free(sm->last_rx_eapol_key); os_free(sm->wpa_ie); os_free(sm->rsnxe); +#ifdef CONFIG_WPA3_COMPAT os_free(sm->rsn_selection); +#endif os_free(sm); } @@ -1764,6 +1770,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) return; } +#ifdef CONFIG_WPA3_COMPAT /* Verify RSN Selection element for RSN overriding */ if (sm->wpa_auth->conf.rsn_override_key_mgmt && ((rsn_is_snonce_cookie(sm->SNonce) && !kde.rsn_selection) || @@ -1789,6 +1796,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) return; } +#endif sm->pending_1_of_4_timeout = 0; eloop_cancel_timeout(resend_eapol_handle, (void*)(sm->index), NULL); @@ -1886,8 +1894,10 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) struct wpa_group *gsm = sm->group; u8 *wpa_ie; int wpa_ie_len, secure, keyidx, encr = 0; +#ifdef CONFIG_WPA3_COMPAT u8 *wpa_ie_buf3 = NULL; struct wpa_auth_config *conf = &sm->wpa_auth->conf; +#endif SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk); sm->TimeoutEvt = FALSE; @@ -1916,6 +1926,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) wpa_ie = wpa_ie + wpa_ie[1] + 2; wpa_ie_len = wpa_ie[1] + 2; } +#ifdef CONFIG_WPA3_COMPAT if (conf->rsn_override_key_mgmt && !rsn_is_snonce_cookie(sm->SNonce)) { u8 *ie; @@ -1948,6 +1959,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) wpa_hexdump(MSG_DEBUG, "EAPOL-Key msg 3/4 IEs after edits", wpa_ie, wpa_ie_len); } +#endif if (sm->wpa == WPA_VERSION_WPA2) { /* WPA2 send GTK in the 4-way handshake */ secure = 1; @@ -1959,7 +1971,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) * of GTK in the BSS. */ if (os_get_random(dummy_gtk, gtk_len) < 0) - return; + goto done; gtk = dummy_gtk; } keyidx = gsm->GN; @@ -1999,8 +2011,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) } #endif /* CONFIG_IEEE80211R_AP */ kde = (u8 *)os_malloc(kde_len); - if (kde == NULL) - return; + if (!kde) + goto done; pos = kde; memcpy(pos, wpa_ie, wpa_ie_len); @@ -2011,8 +2023,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) if (res < 0) { wpa_printf( MSG_ERROR, "FT: Failed to insert " "PMKR1Name into RSN IE in EAPOL-Key data"); - os_free(kde); - return; + goto done; } pos += res; } @@ -2042,8 +2053,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) if (res < 0) { wpa_printf( MSG_ERROR, "FT: Failed to insert FTIE " "into EAPOL-Key Key Data"); - os_free(kde); - return; + goto done; } pos += res; @@ -2070,7 +2080,9 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) _rsc, sm->ANonce, kde, pos - kde, keyidx, encr); done: os_free(kde); +#ifdef CONFIG_WPA3_COMPAT os_free(wpa_ie_buf3); +#endif } diff --git a/components/wpa_supplicant/src/ap/wpa_auth.h b/components/wpa_supplicant/src/ap/wpa_auth.h index 000f93cbb1..34ae7bc54d 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.h +++ b/components/wpa_supplicant/src/ap/wpa_auth.h @@ -127,7 +127,9 @@ struct ft_remote_r1kh { struct wpa_auth_config { int wpa; int wpa_key_mgmt; +#ifdef CONFIG_WPA3_COMPAT int rsn_override_key_mgmt; +#endif int wpa_pairwise; int wpa_group; int wpa_group_rekey; @@ -135,7 +137,9 @@ struct wpa_auth_config { int wpa_gmk_rekey; int wpa_ptk_rekey; int rsn_pairwise; +#ifdef CONFIG_WPA3_COMPAT int rsn_override_pairwise; +#endif int rsn_preauth; int eapol_version; int wmm_enabled; @@ -145,7 +149,9 @@ struct wpa_auth_config { int tx_status; #ifdef CONFIG_IEEE80211W enum mfp_options ieee80211w; +#ifdef CONFIG_WPA3_COMPAT enum mfp_options rsn_override_mfp; +#endif #endif /* CONFIG_IEEE80211W */ int group_mgmt_cipher; #ifdef CONFIG_SAE @@ -171,7 +177,9 @@ struct wpa_auth_config { enum sae_pwe sae_pwe; struct rsn_sppamsdu_sup spp_sup; u8 transition_disable; +#ifdef CONFIG_WPA3_COMPAT int rsn_override_omit_rsnxe; +#endif }; typedef enum { @@ -312,8 +320,12 @@ void wpa_auth_set_rsn_selection(struct wpa_state_machine *sm, const u8 *ie, size_t len); static inline bool wpa_auth_pmf_enabled(struct wpa_auth_config *conf) { +#ifdef CONFIG_WPA3_COMPAT return conf->ieee80211w != NO_MGMT_FRAME_PROTECTION || conf->rsn_override_mfp != NO_MGMT_FRAME_PROTECTION; +#else + return conf->ieee80211w != NO_MGMT_FRAME_PROTECTION; +#endif } #endif /* WPA_AUTH_H */ diff --git a/components/wpa_supplicant/src/ap/wpa_auth_i.h b/components/wpa_supplicant/src/ap/wpa_auth_i.h index 745c32d431..c66428b1c3 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth_i.h +++ b/components/wpa_supplicant/src/ap/wpa_auth_i.h @@ -100,8 +100,10 @@ struct wpa_state_machine { size_t wpa_ie_len; u8 *rsnxe; size_t rsnxe_len; +#ifdef CONFIG_WPA3_COMPAT u8 *rsn_selection; size_t rsn_selection_len; +#endif enum { WPA_VERSION_NO_WPA = 0 /* WPA not used */, @@ -112,7 +114,9 @@ struct wpa_state_machine { int wpa_key_mgmt; /* the selected WPA_KEY_MGMT_* */ struct rsn_pmksa_cache_entry *pmksa; +#ifdef CONFIG_WPA3_COMPAT bool rsn_override; +#endif #ifdef CONFIG_IEEE80211R_AP u8 xxkey[PMK_LEN_MAX]; /* PSK or the second 256 bits of MSK, or the diff --git a/components/wpa_supplicant/src/ap/wpa_auth_ie.c b/components/wpa_supplicant/src/ap/wpa_auth_ie.c index d7ccf86a0c..60a92a5cc8 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth_ie.c +++ b/components/wpa_supplicant/src/ap/wpa_auth_ie.c @@ -346,6 +346,7 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, +#ifdef CONFIG_WPA3_COMPAT static int wpa_write_rsne_override(struct wpa_auth_config *conf, u8 *buf, size_t len) { @@ -374,6 +375,7 @@ static int wpa_write_rsne_override(struct wpa_auth_config *conf, u8 *buf, return pos - buf; } +#endif static u32 rsnxe_capab(struct wpa_auth_config *conf, int key_mgmt) @@ -419,6 +421,7 @@ int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len) return pos - buf; } +#ifdef CONFIG_WPA3_COMPAT static int wpa_write_rsnxe_override(struct wpa_auth_config *conf, u8 *buf, size_t len) { @@ -428,7 +431,6 @@ static int wpa_write_rsnxe_override(struct wpa_auth_config *conf, u8 *buf, capab = rsnxe_capab(conf, conf->rsn_override_key_mgmt); - flen = (capab & 0xff00) ? 2 : 1; if (!capab) return 0; /* no supported extended RSN capabilities */ tmp = capab; @@ -453,6 +455,7 @@ static int wpa_write_rsnxe_override(struct wpa_auth_config *conf, u8 *buf, return pos - buf; } +#endif int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth) @@ -469,9 +472,11 @@ int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth) return res; pos += res; +#ifdef CONFIG_WPA3_COMPAT if (wpa_auth->conf.rsn_override_omit_rsnxe) res = 0; else +#endif res = wpa_write_rsnxe(&wpa_auth->conf, pos, buf + sizeof(buf) - pos); @@ -496,6 +501,7 @@ int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth) pos += res; } +#ifdef CONFIG_WPA3_COMPAT if ((wpa_auth->conf.wpa & WPA_PROTO_RSN) && wpa_auth->conf.rsn_override_key_mgmt) { res = wpa_write_rsne_override(&wpa_auth->conf, @@ -513,6 +519,7 @@ int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth) return res; pos += res; } +#endif os_free(wpa_auth->wpa_ie); wpa_auth->wpa_ie = os_malloc(pos - buf); @@ -649,9 +656,11 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, return WPA_INVALID_GROUP; } +#ifdef CONFIG_WPA3_COMPAT if (sm->rsn_override) key_mgmt = data.key_mgmt & wpa_auth->conf.rsn_override_key_mgmt; else +#endif key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt; if (!key_mgmt) { wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from " @@ -686,10 +695,13 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, else sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK; +#ifdef CONFIG_WPA3_COMPAT if (version == WPA_PROTO_RSN && sm->rsn_override) ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_override_pairwise; - else if (version == WPA_PROTO_RSN) + else +#endif + if (version == WPA_PROTO_RSN) ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise; else ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise; diff --git a/components/wpa_supplicant/src/common/ieee802_11_common.c b/components/wpa_supplicant/src/common/ieee802_11_common.c index 0487dc7f63..6098dd469e 100644 --- a/components/wpa_supplicant/src/common/ieee802_11_common.c +++ b/components/wpa_supplicant/src/common/ieee802_11_common.c @@ -191,7 +191,7 @@ int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, return nei_pos - nei_rep; } -#ifdef CONFIG_WPA3_SAE +#ifdef CONFIG_SAE_PK static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, struct ieee802_11_elems *elems, int show_errors) @@ -212,105 +212,20 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, oui = WPA_GET_BE24(pos); switch (oui) { - case OUI_MICROSOFT: - /* Microsoft/Wi-Fi information elements are further typed and - * subtyped */ - switch (pos[3]) { - case 1: - break; - case WMM_OUI_TYPE: - /* WMM information element */ - if (elen < 5) { - wpa_printf(MSG_MSGDUMP, "short WMM " - "information element ignored " - "(len=%lu)", - (unsigned long) elen); - return -1; - } - switch (pos[4]) { - case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT: - case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT: - /* - * Share same pointer since only one of these - * is used and they start with same data. - * Length field can be used to distinguish the - * IEs. - */ - break; - case WMM_OUI_SUBTYPE_TSPEC_ELEMENT: - break; - default: - wpa_printf(MSG_EXCESSIVE, "unknown WMM " - "information element ignored " - "(subtype=%d len=%lu)", - pos[4], (unsigned long) elen); - return -1; - } - break; - case 4: - /* Wi-Fi Protected Setup (WPS) IE */ - break; - default: - wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft " - "information element ignored " - "(type=%d len=%lu)", - pos[3], (unsigned long) elen); - return -1; - } - break; case OUI_WFA: switch (pos[3]) { -#ifdef CONFIG_SAE_PK case SAE_PK_OUI_TYPE: elems->sae_pk = pos + 4; elems->sae_pk_len = elen - 4; break; -#endif /* CONFIG_SAE_PK */ - case P2P_OUI_TYPE: - /* Wi-Fi Alliance - P2P IE */ - break; - case WFD_OUI_TYPE: - /* Wi-Fi Alliance - WFD IE */ - break; - case HS20_INDICATION_OUI_TYPE: - /* Hotspot 2.0 */ - break; - case HS20_OSEN_OUI_TYPE: - /* Hotspot 2.0 OSEN */ - break; - case MBO_OUI_TYPE: - /* MBO-OCE */ - break; - case HS20_ROAMING_CONS_SEL_OUI_TYPE: - /* Hotspot 2.0 Roaming Consortium Selection */ - break; - case MULTI_AP_OUI_TYPE: - break; - case OWE_OUI_TYPE: - /* OWE Transition Mode element */ - break; - case DPP_CC_OUI_TYPE: - /* DPP Configurator Connectivity element */ - break; - case WFA_RSNE_OVERRIDE_OUI_TYPE: - elems->rsne_override = pos; - elems->rsne_override_len = elen; - break; - case WFA_RSN_SELECTION_OUI_TYPE: - if (elen < 4 + 1) { - wpa_printf(MSG_DEBUG, - "Too short RSN Selection element ignored"); - return -1; - } - elems->rsn_selection = pos + 4; - elems->rsn_selection_len = elen - 4; - break; default: wpa_printf(MSG_EXCESSIVE, "Unknown WFA " "information element ignored " "(type=%d len=%lu)", pos[3], (unsigned long) elen); - return -1; + //TODO discuss if to ignore it + break; + //return -1; } break; default: @@ -318,12 +233,14 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, "information element ignored (vendor OUI " "%02x:%02x:%02x len=%lu)", pos[0], pos[1], pos[2], (unsigned long) elen); - return -1; + //TODO discuss if to ignore it + break; + //return -1; } return 0; } -#endif /* CONFIG_WPA3_SAE */ +#endif /* CONFIG_SAE_PK */ #ifdef CONFIG_SAE_PK static int ieee802_11_parse_extension(const u8 *pos, size_t elen, @@ -357,13 +274,16 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen, wpa_printf(MSG_EXCESSIVE, "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)", ext_id, (unsigned int) elen); - return -1; + //TODO discuss if to ignore it + break; + //return -1; } return 0; } #endif /* CONFIG_SAE_PK */ +#if defined(CONFIG_RRM) || defined(CONFIG_WMM) || defined(CONFIG_SAE_PK) static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len, struct ieee802_11_elems *elems, int show_errors) @@ -391,8 +311,6 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len, unknown++; } break; -#endif /*CONFIG_SAE_PK*/ -#ifdef CONFIG_WPA3_SAE case WLAN_EID_VENDOR_SPECIFIC: if (ieee802_11_parse_vendor_specific(pos, elen, elems, @@ -400,15 +318,7 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len, unknown++; } break; -#endif /* CONFIG_WPA3_SAE */ - case WLAN_EID_RSN: - elems->rsn_ie = pos; - elems->rsn_ie_len = elen; - break; - case WLAN_EID_RSNX: - elems->rsnxe = pos; - elems->rsnxe_len = elen; - break; +#endif /*CONFIG_SAE_PK*/ #ifdef CONFIG_WNM case WLAN_EID_EXT_CAPAB: /* extended caps can go beyond 8 octacts but we aren't using them now */ @@ -426,6 +336,8 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len, return ParseOK; } +#endif + /** * ieee802_11_parse_elems - Parse information elements in management frames * @start: Pointer to the start of IEs @@ -434,12 +346,14 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len, * @show_errors: Whether to show parsing errors in debug log * Returns: Parsing result */ +#if defined(CONFIG_RRM) || defined(CONFIG_WMM) || defined(CONFIG_SAE_PK) ParseRes ieee802_11_parse_elems(const u8 *start, size_t len, struct ieee802_11_elems *elems, int show_errors) { os_memset(elems, 0, sizeof(*elems)); return __ieee802_11_parse_elems(start, len, elems, show_errors); } +#endif struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len, u32 oui_type) diff --git a/components/wpa_supplicant/src/common/ieee802_11_common.h b/components/wpa_supplicant/src/common/ieee802_11_common.h index 50ff9223ad..43e5a0b43b 100644 --- a/components/wpa_supplicant/src/common/ieee802_11_common.h +++ b/components/wpa_supplicant/src/common/ieee802_11_common.h @@ -70,12 +70,6 @@ struct ieee802_11_elems { const u8 *sae_pk; u8 sae_pk_len; #endif -#ifdef CONFIG_WPA3_SAE - const u8 *rsne_override; - size_t rsne_override_len; - const u8 *rsn_selection; - size_t rsn_selection_len; -#endif }; typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes; diff --git a/components/wpa_supplicant/src/common/ieee802_11_defs.h b/components/wpa_supplicant/src/common/ieee802_11_defs.h index 019a929fbf..e8adaeef0c 100644 --- a/components/wpa_supplicant/src/common/ieee802_11_defs.h +++ b/components/wpa_supplicant/src/common/ieee802_11_defs.h @@ -303,35 +303,12 @@ #define DPP_OUI_TYPE 0x1A #define OUI_WFA 0x506f9a #define WFA_RSNE_OVERRIDE_OUI_TYPE 0x29 -#define WFA_RSNE_OVERRIDE_2_OUI_TYPE 0x2a #define WFA_RSNXE_OVERRIDE_OUI_TYPE 0x2b #define WFA_RSN_SELECTION_OUI_TYPE 0x2c #define RSNE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a29 -#define RSNE_OVERRIDE_2_IE_VENDOR_TYPE 0x506f9a2a #define RSNXE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a2b #define RSN_SELECTION_IE_VENDOR_TYPE 0x506f9a2c -#define WFD_OUI_TYPE 10 -#define NAN_OUI_TYPE 0x13 -#define MBO_OUI_TYPE 22 -#define OWE_OUI_TYPE 28 -#define MULTI_AP_OUI_TYPE 0x1B -#define DPP_CC_OUI_TYPE 0x1e -#define SAE_PK_OUI_TYPE 0x1f -#define QM_IE_OUI_TYPE 0x22 -#define WFA_CAPA_OUI_TYPE 0x23 - -#define P2P_OUI_TYPE 9 -#define HS20_INDICATION_OUI_TYPE 16 -#define HS20_OSEN_OUI_TYPE 18 -#define HS20_ROAMING_CONS_SEL_OUI_TYPE 29 - -#define WMM_OUI_TYPE 2 -#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0 -#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1 -#define WMM_OUI_SUBTYPE_TSPEC_ELEMENT 2 -#define WMM_VERSION 1 - #ifdef _MSC_VER #pragma pack(push, 1) #endif /* _MSC_VER */ @@ -590,8 +567,6 @@ struct ieee80211_ht_operation { /* 2 - Reserved */ #define WMM_TSPEC_DIRECTION_BI_DIRECTIONAL 3 -#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) - * 00:50:F2 */ #define MBO_IE_VENDOR_TYPE 0x506f9a16 #define OSEN_IE_VENDOR_TYPE 0x506f9a12 #define SAE_PK_IE_VENDOR_TYPE 0x506f9a1f diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index b4cc3f58b2..4cd49d3d2f 100644 --- a/components/wpa_supplicant/src/common/wpa_common.c +++ b/components/wpa_supplicant/src/common/wpa_common.c @@ -1659,6 +1659,7 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end, return 0; } +#ifdef CONFIG_WPA3_COMPAT if (selector == RSNE_OVERRIDE_IE_VENDOR_TYPE) { ie->rsne_override = pos; ie->rsne_override_len = dlen; @@ -1685,6 +1686,7 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end, ie->rsn_selection, ie->rsn_selection_len); return 0; } +#endif return 2; } diff --git a/components/wpa_supplicant/src/common/wpa_common.h b/components/wpa_supplicant/src/common/wpa_common.h index 92d7abf8c3..5069ec7730 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -472,13 +472,14 @@ struct wpa_eapol_ie_parse { size_t transition_disable_len; const u8 *rsnxe; size_t rsnxe_len; +#ifdef CONFIG_WPA3_COMPAT const u8 *rsn_selection; size_t rsn_selection_len; const u8 *rsne_override; size_t rsne_override_len; const u8 *rsnxe_override; size_t rsnxe_override_len; - +#endif }; int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie); static inline int wpa_supplicant_parse_ies(const u8 *buf, size_t len, diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index e6363fc3b2..d2a8d7140f 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -536,7 +536,10 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, size_t mic_len, hdrlen, rlen; struct wpa_eapol_key *reply; struct wpa_eapol_key_192 *reply192; - u8 *rsn_ie_buf = NULL, *buf2 = NULL; + u8 *rsn_ie_buf = NULL; +#ifdef CONFIG_WPA3_COMPAT + u8 *buf2 = NULL; +#endif u8 *rbuf, *key_mic; if (wpa_ie == NULL) { @@ -582,6 +585,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, wpa_ie = rsn_ie_buf; } #endif /* CONFIG_IEEE80211R */ +#ifdef CONFIG_WPA3_COMPAT if (sm->rsn_override != RSN_OVERRIDE_NOT_USED) { u8 *pos; @@ -610,7 +614,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, wpa_ie_len += 2 + 4 + 1; } - +#endif wpa_hexdump(MSG_MSGDUMP, "WPA: WPA IE for msg 2/4\n", wpa_ie, wpa_ie_len); mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len); @@ -620,7 +624,9 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, &rlen, (void *) &reply); if (rbuf == NULL) { os_free(rsn_ie_buf); +#ifdef CONFIG_WPA3_COMPAT os_free(buf2); +#endif return -1; } reply192 = (struct wpa_eapol_key_192 *) reply; @@ -647,7 +653,9 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, } os_free(rsn_ie_buf); +#ifdef CONFIG_WPA3_COMPAT os_free(buf2); +#endif os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN); wpa_printf(MSG_DEBUG, "WPA Send EAPOL-Key 2/4"); @@ -733,8 +741,10 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, wpa_printf(MSG_DEBUG, "WPA: Failed to get random data for SNonce"); goto failed; } +#ifdef CONFIG_WPA3_COMPAT if (wpa_sm_rsn_overriding_supported(sm)) rsn_set_snonce_cookie(sm->snonce); +#endif sm->renew_snonce = 0; wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce", sm->snonce, WPA_NONCE_LEN); @@ -1215,6 +1225,7 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm, return -1; } +#ifdef CONFIG_WPA3_COMPAT if (sm->proto == WPA_PROTO_RSN && wpa_sm_rsn_overriding_supported(sm)) { if ((sm->ap_rsne_override && !ie->rsne_override) || (!sm->ap_rsne_override && ie->rsne_override) || @@ -1256,6 +1267,7 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm, return -1; } } +#endif return 0; } @@ -1349,10 +1361,19 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm, key_info = WPA_GET_BE16(key->key_info); - if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) + if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) { goto failed; - if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0) + } + if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0) { goto failed; + } + + if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) { + wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, + "WPA: ANonce from message 1 of 4-Way Handshake differs from 3 of 4-Way Handshake - drop packet (src=" + MACSTR ")", MAC2STR(sm->bssid)); + goto failed; + } if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) { wpa_printf(MSG_DEBUG, "WPA: GTK IE in unencrypted key data"); @@ -2258,10 +2279,12 @@ void wpa_sm_deinit(void) sm->ap_rsn_ie = NULL; os_free(sm->ap_rsnxe); sm->ap_rsnxe = NULL; +#ifdef CONFIG_WPA3_COMPAT os_free(sm->ap_rsne_override); sm->ap_rsne_override = NULL; os_free(sm->ap_rsnxe_override); sm->ap_rsnxe_override = NULL; +#endif wpa_sm_drop_sa(sm); memset(sm, 0, sizeof(*sm)); } @@ -2273,6 +2296,7 @@ void wpa_sm_deinit(void) * @value: Parameter value * Returns: 0 on success, -1 on failure */ +#ifdef CONFIG_WPA3_COMPAT int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, unsigned int value) { @@ -2293,18 +2317,21 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, } return ret; } +#endif +#ifdef CONFIG_WPA3_COMPAT static const u8 * wpa_sm_get_ap_rsne(struct wpa_sm *sm, size_t *len) { if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE) { *len = sm->ap_rsne_override_len; return sm->ap_rsne_override; } - *len = sm->ap_rsn_ie_len; return sm->ap_rsn_ie; } +#endif +#ifdef CONFIG_WPA3_COMPAT bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm) { const u8 *rsne; @@ -2314,6 +2341,7 @@ bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm) return sm->rsn_override_support && rsne; } +#endif #ifdef ESP_SUPPLICANT /** @@ -2446,13 +2474,13 @@ void wpa_set_pmk(uint8_t *pmk, size_t pmk_length, const u8 *pmkid, bool cache_pm } } -int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, u8 pairwise_cipher, u8 group_cipher, char *passphrase, u8 *ssid, size_t ssid_len) +int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, uint8_t pairwise_cipher, uint8_t group_cipher, char *passphrase, uint8_t *ssid, int ssid_len) { int res = 0; struct wpa_sm *sm = &gWpaSm; bool use_pmk_cache = !esp_wifi_skip_supp_pmkcaching(); - u8 assoc_ie[128]; - uint8_t assoc_ie_len = sizeof(assoc_ie); + uint8_t assoc_ie[128]; + uint16_t assoc_ie_len = sizeof(assoc_ie); bool reassoc_same_ess = false; int try_opportunistic = 0; const u8 *ie = NULL; @@ -2579,12 +2607,13 @@ int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, u8 pairwise_cipher, u8 group_ci wpa_sm_set_ap_rsn_ie(sm, ie, ie ? (ie[1] + 2) : 0); ie = esp_wifi_sta_get_ie(bssid, WLAN_EID_RSNX); wpa_sm_set_ap_rsnxe(sm, ie, ie ? (ie[1] + 2) : 0); - if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA)) { - ie = esp_wifi_sta_get_ie(bssid, WFA_RSNE_OVERRIDE_OUI_TYPE); - wpa_sm_set_ap_rsne_override(sm, ie, ie ? (ie[1] + 2) : 0); - ie = esp_wifi_sta_get_ie(bssid, WFA_RSNXE_OVERRIDE_OUI_TYPE); - wpa_sm_set_ap_rsnxe_override(sm, ie, ie ? (ie[1] + 2) : 0); - } + +#ifdef CONFIG_WPA3_COMPAT + ie = esp_wifi_sta_get_ie(bssid, WFA_RSNE_OVERRIDE_OUI_TYPE); + wpa_sm_set_ap_rsne_override(sm, ie, ie ? (ie[1] + 2) : 0); + ie = esp_wifi_sta_get_ie(bssid, WFA_RSNXE_OVERRIDE_OUI_TYPE); + wpa_sm_set_ap_rsnxe_override(sm, ie, ie ? (ie[1] + 2) : 0); +#endif pos = assoc_ie; res = wpa_gen_rsnxe(sm, pos, assoc_ie_len); @@ -2597,14 +2626,15 @@ int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, u8 pairwise_cipher, u8 group_ci return -1; } pos += assoc_ie_len; + +#ifdef CONFIG_WPA3_COMPAT wpa_sm_set_param(sm, WPA_PARAM_RSN_OVERRIDE_SUPPORT, esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA)); wpa_sm_set_param(sm, WPA_PARAM_RSN_OVERRIDE, RSN_OVERRIDE_NOT_USED); ie = esp_wifi_sta_get_ie(bssid, WFA_RSNE_OVERRIDE_OUI_TYPE); - if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA) && - ie && ie[0] != WLAN_EID_RSN) { + if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA) && ie) { enum rsn_selection_variant variant = RSN_SELECTION_RSNE; if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4) { @@ -2626,6 +2656,8 @@ int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, u8 pairwise_cipher, u8 group_ci *pos = variant; assoc_ie_len += 2 + 4 + 1; } +#endif + wpa_hexdump(MSG_DEBUG, "WPA: ASSOC IE LEN", assoc_ie, assoc_ie_len); esp_set_assoc_ie(bssid, assoc_ie, assoc_ie_len, true); @@ -2984,6 +3016,7 @@ int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len) } +#ifdef CONFIG_WPA3_COMPAT int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len) { if (!sm) @@ -3007,8 +3040,10 @@ int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len) return 0; } +#endif +#ifdef CONFIG_WPA3_COMPAT int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len) { if (!sm) @@ -3032,6 +3067,7 @@ int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len) return 0; } +#endif int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len) diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.h b/components/wpa_supplicant/src/rsn_supp/wpa.h index 3968184ee1..bff1c19216 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa.h @@ -35,10 +35,12 @@ struct l2_ethhdr { be16 h_proto; } STRUCT_PACKED; +#ifdef CONFIG_WPA3_COMPAT enum wpa_sm_conf_params { WPA_PARAM_RSN_OVERRIDE, WPA_PARAM_RSN_OVERRIDE_SUPPORT, }; +#endif void wpa_sm_set_state(enum wpa_states state); @@ -62,16 +64,20 @@ int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len); int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len); +#ifdef CONFIG_WPA3_COMPAT int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len); int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len); +#endif int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len); void wpa_sm_drop_sa(struct wpa_sm *sm); +#ifdef CONFIG_WPA3_COMPAT int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, unsigned int value); +#endif #ifdef CONFIG_IEEE80211R int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len); diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_i.h b/components/wpa_supplicant/src/rsn_supp/wpa_i.h index 1f272ea262..42fcbc2e49 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -22,12 +22,13 @@ struct install_key { u8 key[32]; }; +#ifdef CONFIG_WPA3_COMPAT enum wpa_rsn_override { RSN_OVERRIDE_NOT_USED, RSN_OVERRIDE_RSNE, RSN_OVERRIDE_RSNE_OVERRIDE, }; - +#endif /** * struct wpa_sm - Internal WPA state machine data */ @@ -82,8 +83,10 @@ struct wpa_sm { u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe; size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len; +#ifdef CONFIG_WPA3_COMPAT u8 *ap_rsne_override, *ap_rsnxe_override; size_t ap_rsne_override_len, ap_rsnxe_override_len; +#endif bool key_install; @@ -127,9 +130,10 @@ struct wpa_sm { #endif /* CONFIG_OWE_STA */ int (*wpa_sm_wps_disable)(void); esp_err_t (*wpa_sm_eap_disable)(void); - +#ifdef CONFIG_WPA3_COMPAT bool rsn_override_support; enum wpa_rsn_override rsn_override; +#endif }; /** @@ -215,12 +219,13 @@ void eapol_txcb(uint8_t *eapol_payload, size_t len, bool tx_failure); void wpa_set_profile(u32 wpa_proto, u8 auth_mode); -int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, u8 pairwise_cipher, u8 group_cipher, char *passphrase, u8 *ssid, size_t ssid_len); +int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, uint8_t pairwise_cipher, uint8_t group_cipher, char *passphrase, uint8_t *ssid, int ssid_len); int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len); int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, const struct wpa_eapol_key *key, struct wpa_ptk *ptk); - +#ifdef CONFIG_WPA3_COMPAT bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm); +#endif #endif /* WPA_I_H */ diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_ie.c b/components/wpa_supplicant/src/rsn_supp/wpa_ie.c index 0edbaad862..8bafca9653 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_ie.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa_ie.c @@ -39,6 +39,7 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len, return wpa_parse_wpa_ie_rsnxe(wpa_ie, wpa_ie_len, data); } else if (wpa_ie[0] == WLAN_EID_WAPI) { return 0; +#ifdef CONFIG_WPA3_COMPAT } else if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC && wpa_ie[1] >= 4 && WPA_GET_BE32(&wpa_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE) { @@ -47,7 +48,9 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len, wpa_ie[1] >= 4 && WPA_GET_BE32(&wpa_ie[2]) == RSNXE_OVERRIDE_IE_VENDOR_TYPE) { return wpa_parse_wpa_ie_rsnxe(wpa_ie, wpa_ie_len, data); +#endif } + return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data); } @@ -304,7 +307,7 @@ int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len) int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len) { u8 *pos = rsnxe; - u16 capab = 0, tmp; + u32 capab = 0, tmp; size_t flen; if (wpa_key_mgmt_sae(sm->key_mgmt) && @@ -333,12 +336,11 @@ int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len) *pos++ = WLAN_EID_RSNX; *pos++ = flen; - *pos++ = capab & 0x00ff; - capab >>= 8; - if (capab) - *pos++ = capab; + while (capab) { + *pos++ = capab & 0xff; + capab >>= 8; + } return pos - rsnxe; } - #endif // ESP_SUPPLICANT diff --git a/examples/wifi/getting_started/softAP/main/softap_example_main.c b/examples/wifi/getting_started/softAP/main/softap_example_main.c index 3543538693..a19978070b 100644 --- a/examples/wifi/getting_started/softAP/main/softap_example_main.c +++ b/examples/wifi/getting_started/softAP/main/softap_example_main.c @@ -78,7 +78,9 @@ void wifi_init_softap(void) #else /* CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT */ .authmode = WIFI_AUTH_WPA2_PSK, #endif - .wpa3_compatible_mode = 0, +#ifdef CONFIG_ESP_WIFI_WPA3_COMPATIBLE_SUPPORT + .wpa3_compatible_mode = 1, +#endif .pmf_cfg = { .required = true, }, diff --git a/examples/wifi/getting_started/station/main/station_example_main.c b/examples/wifi/getting_started/station/main/station_example_main.c index d5ed5eb1a1..45c9a14a93 100644 --- a/examples/wifi/getting_started/station/main/station_example_main.c +++ b/examples/wifi/getting_started/station/main/station_example_main.c @@ -129,6 +129,9 @@ void wifi_init_sta(void) .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD, .sae_pwe_h2e = ESP_WIFI_SAE_MODE, .sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER, +#ifdef CONFIG_ESP_WIFI_WPA3_COMPATIBLE_SUPPORT + .wpa3_compatible_mode = 1, +#endif }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );