diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index 3c010a6ce3..67ea558d6d 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -284,7 +284,8 @@ typedef struct { uint32_t mbo_enabled:1; /**< Whether MBO is enabled for the connection */ uint32_t ft_enabled:1; /**< Whether FT is enabled for the connection */ uint32_t owe_enabled:1; /**< Whether OWE is enabled for the connection */ - uint32_t reserved:27; /**< Reserved for future feature set */ + uint32_t transition_disable:1; /**< Whether to enable transition disable feature */ + uint32_t reserved:26; /**< Reserved for future feature set */ wifi_sae_pwe_method_t sae_pwe_h2e; /**< Whether SAE hash to element is enabled */ 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. Note: Enabling this may cause connection time to increase incase best AP doesn't behave properly. */ } wifi_sta_config_t; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index ccb8fbbeb4..2bf3370730 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit ccb8fbbeb4e61f1fc54b6eae80d42532dbc8ece3 +Subproject commit 2bf33707304806dde88aafe2780b2f233a100604 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 856d40d5c5..e0b2b5de22 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -281,5 +281,6 @@ 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); uint8_t esp_wifi_sta_get_config_sae_pwe_h2e_internal(void); uint8_t esp_wifi_sta_get_use_h2e_internal(void); +void esp_wifi_sta_disable_wpa2_authmode_internal(void); #endif /* _ESP_WIFI_DRIVER_H_ */ diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c index a250db8672..9cb75ba086 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c @@ -93,6 +93,15 @@ int hostapd_send_eapol(const u8 *source, const u8 *sta_addr, } +void wpa_supplicant_transition_disable(void *sm, u8 bitmap) +{ + wpa_printf(MSG_INFO, "TRANSITION_DISABLE %02x", bitmap); + + if (bitmap & TRANSITION_DISABLE_WPA3_PERSONAL) { + esp_wifi_sta_disable_wpa2_authmode_internal(); + } +} + u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type, const void *data, u16 data_len, size_t *msg_len, void **data_pos) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h index 220a01c633..11f5b3ddff 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h @@ -31,6 +31,8 @@ void wpa_free_eapol(u8 *buffer); int wpa_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *data, size_t data_len); +void wpa_supplicant_transition_disable(void *sm, u8 bitmap); + int hostapd_send_eapol(const u8 *source, const u8 *sta_addr, const u8 *data, size_t data_len); #endif /* WPAS_GLUE_H */ diff --git a/components/wpa_supplicant/src/common/wpa_common.h b/components/wpa_supplicant/src/common/wpa_common.h index 86e158505c..b827c36fe0 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -94,6 +94,8 @@ RSN_SELECTOR(0x00, 0x0f, 0xac, 13) #define RSN_KEY_DATA_IGTK RSN_SELECTOR(0x00, 0x0f, 0xac, 9) #endif /* CONFIG_IEEE80211W */ +#define WFA_KEY_DATA_TRANSITION_DISABLE RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x20) + #define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1) #define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *) (a), (val)) @@ -305,6 +307,9 @@ struct rsn_rdie { #endif /* CONFIG_IEEE80211R */ +/* WFA Transition Disable KDE (using OUI_WFA) */ +/* Transition Disable Bitmap bits */ +#define TRANSITION_DISABLE_WPA3_PERSONAL BIT(0) #ifdef CONFIG_IEEE80211R int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index f8449360a5..acfecb5c8e 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -1305,6 +1305,10 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm, goto failed; } + if (ie.transition_disable) { + wpa_supplicant_transition_disable(sm, ie.transition_disable[0]); + } + if (sm->key_install && sm->key_info & WPA_KEY_INFO_INSTALL && sm->use_ext_key_id) { wpa_supplicant_install_ptk(sm, KEY_FLAG_RX); } diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_ie.c b/components/wpa_supplicant/src/rsn_supp/wpa_ie.c index 7e4102addd..021f79a8af 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_ie.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa_ie.c @@ -383,6 +383,15 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end, return 0; } #endif + if (pos[1] >= RSN_SELECTOR_LEN + 1 && + RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_TRANSITION_DISABLE) { + ie->transition_disable = pos + 2 + RSN_SELECTOR_LEN; + ie->transition_disable_len = pos[1] - RSN_SELECTOR_LEN; + wpa_hexdump(MSG_DEBUG, + "WPA: Transition Disable KDE in EAPOL-Key", + pos, pos[1] + 2); + return 0; + } return 0; } diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_ie.h b/components/wpa_supplicant/src/rsn_supp/wpa_ie.h index 5a9b77de0e..b799064635 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_ie.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_ie.h @@ -37,6 +37,8 @@ struct wpa_eapol_ie_parse { const u8 *reassoc_deadline; const u8 *key_lifetime; #endif /* CONFIG_IEEE80211R */ + const u8 *transition_disable; + size_t transition_disable_len; const u8 *rsnxe; size_t rsnxe_len; };