diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index cabe296cf5..ae525511ba 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -56,7 +56,7 @@ typedef struct { } wifi_country_t; /* Strength of authmodes */ -/* OPEN < WEP < WPA_PSK < OWE < WPA2_PSK = WPA_WPA2_PSK < WAPI_PSK < WPA3_PSK = WPA2_WPA3_PSK */ +/* OPEN < WEP < WPA_PSK < OWE < WPA2_PSK = WPA_WPA2_PSK < WAPI_PSK < WPA3_PSK = WPA2_WPA3_PSK < WPA3_EXT_PSK */ typedef enum { WIFI_AUTH_OPEN = 0, /**< authenticate mode : open */ WIFI_AUTH_WEP, /**< authenticate mode : WEP */ @@ -70,6 +70,7 @@ typedef enum { WIFI_AUTH_WAPI_PSK, /**< authenticate mode : WAPI_PSK */ WIFI_AUTH_OWE, /**< authenticate mode : OWE */ WIFI_AUTH_WPA3_ENT_192, /**< authenticate mode : WPA3_ENT_SUITE_B_192_BIT */ + WIFI_AUTH_WPA3_EXT_PSK, /**< authenticate mode : WPA3_PSK_EXT_KEY */ WIFI_AUTH_MAX } wifi_auth_mode_t; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 557c6fa326..e88f8cebc1 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 557c6fa326dc423118576a5f9d4b34ba60e0d991 +Subproject commit e88f8cebc1b5353d979ee57f22a04e40752bfd66 diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index a5c31d8a73..b278467f9c 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -172,7 +172,7 @@ if(CONFIG_ESP_WIFI_ENABLE_SAE_PK) "src/common/sae_pk.c") endif() -if(CONFIG_ESP_WIFI_11KV_SUPPORT OR CONFIG_ESP_WIFI_11R_SUPPORT OR CONFIG_ESP_WIFI_ENABLE_SAE_PK) +if(CONFIG_ESP_WIFI_11KV_SUPPORT OR CONFIG_ESP_WIFI_11R_SUPPORT) set(srcs ${srcs} "src/common/bss.c" "src/common/scan.c" diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common.c b/components/wpa_supplicant/esp_supplicant/src/esp_common.c index 20c2c1187b..56399020c7 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common.c @@ -260,12 +260,12 @@ static int ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender, int ret = 0; switch (type) { -#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211KV) || defined(CONFIG_SAE_PK) +#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211KV) case WLAN_FC_STYPE_BEACON: case WLAN_FC_STYPE_PROBE_RESP: ret = esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf); break; -#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_SAE_PK)*/ +#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */ #ifdef CONFIG_IEEE80211R case WLAN_FC_STYPE_AUTH: ret = handle_auth_frame(frame, len, sender, rssi, channel); @@ -328,7 +328,7 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb) struct wpa_supplicant *wpa_s = &g_wpa_supp; int ret = 0; -#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_SAE_PK) +#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) #ifdef CONFIG_SUPPLICANT_TASK if (!s_supplicant_api_lock) { s_supplicant_api_lock = os_recursive_mutex_create(); @@ -361,7 +361,7 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb) #endif /* CONFIG_IEEE80211KV */ esp_scan_init(wpa_s); -#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_SAE_PK)*/ +#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */ wpa_s->type = 0; wpa_s->subtype = 0; wpa_s->type |= (1 << WLAN_FC_STYPE_ASSOC_RESP) | (1 << WLAN_FC_STYPE_REASSOC_RESP) | (1 << WLAN_FC_STYPE_AUTH); @@ -386,13 +386,13 @@ void esp_supplicant_common_deinit(void) { struct wpa_supplicant *wpa_s = &g_wpa_supp; -#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_SAE_PK) +#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) esp_scan_deinit(wpa_s); #ifdef CONFIG_IEEE80211KV wpas_rrm_reset(wpa_s); wpas_clear_beacon_rep_data(wpa_s); #endif /* CONFIG_IEEE80211KV */ -#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_SAE_PK)*/ +#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */ if (wpa_s->type) { wpa_s->type = 0; esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype); 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 a6ffe6f93e..8979dfc69d 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -72,6 +72,7 @@ enum { WPA2_AUTH_ENT_SHA384_SUITE_B = 0x0d, WPA2_AUTH_FT_PSK = 0x0e, WPA3_AUTH_OWE = 0x0f, + WPA3_AUTH_PSK_EXT_KEY = 0x10, WPA2_AUTH_INVALID }; @@ -286,7 +287,6 @@ esp_err_t esp_wifi_remain_on_channel(uint8_t ifx, uint8_t type, uint8_t channel, 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); -uint8_t esp_wifi_sta_get_use_h2e_internal(void); uint8_t esp_wifi_sta_get_config_sae_pk_internal(void); void esp_wifi_sta_disable_sae_pk_internal(void); void esp_wifi_sta_disable_wpa2_authmode_internal(void); @@ -296,5 +296,6 @@ bool esp_wifi_ap_notify_node_sae_auth_done(uint8_t *mac); bool esp_wifi_ap_is_sta_sae_reauth_node(uint8_t *mac); uint8_t* esp_wifi_sta_get_sae_identifier_internal(void); bool esp_wifi_eb_tx_status_success_internal(void *eb); +uint8_t* esp_wifi_sta_get_rsnxe(void); #endif /* _ESP_WIFI_DRIVER_H_ */ diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c index e4c9a4e03a..ab926caad4 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c @@ -17,10 +17,6 @@ #include "esp_hostap.h" #include -#ifdef CONFIG_SAE_PK -#include "common/bss.h" -extern struct wpa_supplicant g_wpa_supp; -#endif static struct sae_pt *g_sae_pt; static struct sae_data g_sae_data; @@ -33,12 +29,56 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid, size_t *sae_msg_len) { int default_group = IANA_SECP256R1; u32 len = 0; + uint8_t use_pt = 0; u8 own_addr[ETH_ALEN]; const u8 *pw = (const u8 *)esp_wifi_sta_get_prof_password_internal(); struct wifi_ssid *ssid = esp_wifi_sta_get_prof_ssid_internal(); - uint8_t use_pt = esp_wifi_sta_get_use_h2e_internal(); + uint8_t sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal(WIFI_IF_STA); char sae_pwd_id[SAE_H2E_IDENTIFIER_LEN+1] = {0}; bool valid_pwd_id = false; + const u8 *rsnxe; + u8 rsnxe_capa = 0; + + if (wpa_key_mgmt_sae_ext_key(gWpaSm.key_mgmt)) { + use_pt = 1; + } + + rsnxe = esp_wifi_sta_get_rsnxe(); + if (rsnxe && rsnxe[1] >= 1) { + rsnxe_capa = rsnxe[2]; + } + +#ifdef CONFIG_SAE_PK + bool use_pk = false; + uint8_t sae_pk_mode = esp_wifi_sta_get_config_sae_pk_internal(); + if ((rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) && + sae_pk_mode != WPA3_SAE_PK_MODE_DISABLED && + ((pw && sae_pk_valid_password((const char*)pw)))) { + use_pt = 1; + use_pk = true; + } + + if (sae_pk_mode == WPA3_SAE_PK_MODE_ONLY && !use_pk) { + wpa_printf(MSG_DEBUG, + "SAE: Cannot use PK with the selected AP"); + return ESP_FAIL; + } +#endif /* CONFIG_SAE_PK */ + if (use_pt || sae_pwe == SAE_PWE_HASH_TO_ELEMENT || + sae_pwe == SAE_PWE_BOTH) { + use_pt = !!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E)); + + if ((sae_pwe == SAE_PWE_HASH_TO_ELEMENT || + wpa_key_mgmt_sae_ext_key(gWpaSm.key_mgmt) +#ifdef CONFIG_SAE_PK + || (use_pk && sae_pk_mode == WPA3_SAE_PK_MODE_ONLY) +#endif /* CONFIG_SAE_PK */ + ) && !use_pt) { + wpa_printf(MSG_DEBUG, + "SAE: Cannot use H2E with the selected AP"); + return ESP_FAIL; + } + } if (use_pt != 0) { memcpy(sae_pwd_id, esp_wifi_sta_get_sae_identifier_internal(), SAE_H2E_IDENTIFIER_LEN); @@ -73,46 +113,14 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid, size_t *sae_msg_len) return ESP_FAIL; } + g_sae_data.akmp = gWpaSm.key_mgmt; + esp_wifi_get_macaddr_internal(WIFI_IF_STA, own_addr); if (!bssid) { wpa_printf(MSG_ERROR, "wpa3: cannot prepare SAE commit with no BSSID!"); return ESP_FAIL; } -#ifdef CONFIG_SAE_PK - bool use_pk = false; - uint8_t sae_pk_mode = esp_wifi_sta_get_config_sae_pk_internal(); - u8 rsnxe_capa = 0; - struct wpa_bss *bss = wpa_bss_get_bssid(&g_wpa_supp, (uint8_t *)bssid); - if (!bss) { - wpa_printf(MSG_ERROR, - "SAE: BSS not available, update scan result to get BSS"); - // TODO: should we trigger scan again. - return ESP_FAIL; - } - if (bss) { - const u8 *rsnxe; - - rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX); - if (rsnxe && rsnxe[1] >= 1) { - rsnxe_capa = rsnxe[2]; - } - } - - if (use_pt && (rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) && - sae_pk_mode != WPA3_SAE_PK_MODE_DISABLED && - ((pw && sae_pk_valid_password((const char*)pw)))) { - use_pt = 1; - use_pk = true; - } - - if (sae_pk_mode == WPA3_SAE_PK_MODE_ONLY && !use_pk) { - wpa_printf(MSG_DEBUG, - "SAE: Cannot use PK with the selected AP"); - return ESP_FAIL; - } -#endif /* CONFIG_SAE_PK */ - if (use_pt && sae_prepare_commit_pt(&g_sae_data, g_sae_pt, own_addr, bssid, NULL, NULL) < 0) { @@ -294,7 +302,7 @@ static int wpa3_parse_sae_confirm(u8 *buf, u32 len) } g_sae_data.state = SAE_ACCEPTED; - wpa_set_pmk(g_sae_data.pmk, g_sae_data.pmkid, true); + wpa_set_pmk(g_sae_data.pmk, g_sae_data.pmk_len, g_sae_data.pmkid, true); return ESP_OK; } 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 d3040b168e..16f8916f15 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c @@ -98,7 +98,7 @@ void wpa_supplicant_transition_disable(struct wpa_sm *sm, u8 bitmap) wpa_printf(MSG_DEBUG, "TRANSITION_DISABLE %02x", bitmap); if ((bitmap & TRANSITION_DISABLE_WPA3_PERSONAL) && - wpa_key_mgmt_sae(sm->key_mgmt)) { + wpa_key_mgmt_sae(sm->key_mgmt)) { esp_wifi_sta_disable_wpa2_authmode_internal(); } } diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index 2bffbbe758..d8f0e90c0e 100644 --- a/components/wpa_supplicant/src/common/wpa_common.c +++ b/components/wpa_supplicant/src/common/wpa_common.c @@ -855,7 +855,8 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce, */ int wpa_use_akm_defined(int akmp){ - return akmp == WPA_KEY_MGMT_OWE || + return akmp == WPA_KEY_MGMT_OSEN || + akmp == WPA_KEY_MGMT_OWE || wpa_key_mgmt_sae(akmp) || wpa_key_mgmt_suite_b(akmp); } diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index d23da66d29..06f564e084 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -424,18 +424,6 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm, //eapol_sm_notify_cached(sm->eapol); #ifdef CONFIG_IEEE80211R sm->xxkey_len = 0; -#ifdef CONFIG_WPA3_SAE - if ((sm->key_mgmt == WPA_KEY_MGMT_FT_SAE) && - sm->pmk_len == PMK_LEN) { - /* Need to allow FT key derivation to proceed with - * PMK from SAE being used as the XXKey in cases where - * the PMKID in msg 1/4 matches the PMKSA entry that was - * just added based on SAE authentication for the - * initial mobility domain association. */ - os_memcpy(sm->xxkey, sm->pmk, sm->pmk_len); - sm->xxkey_len = sm->pmk_len; - } -#endif /* CONFIG_WPA3_SAE */ #endif /* CONFIG_IEEE80211R */ } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) { int res = 0, pmk_len; @@ -2298,18 +2286,22 @@ void wpa_set_profile(u32 wpa_proto, u8 auth_mode) sm->key_mgmt = WPA_KEY_MGMT_FT_PSK; } else if (auth_mode == WPA3_AUTH_OWE) { sm->key_mgmt = WPA_KEY_MGMT_OWE; + } else if (auth_mode == WPA3_AUTH_PSK_EXT_KEY) { + sm->key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY; /* for WPA3 PSK */ } else { sm->key_mgmt = WPA_KEY_MGMT_PSK; /* fixed to PSK for now */ } } -void wpa_set_pmk(uint8_t *pmk, const u8 *pmkid, bool cache_pmksa) +void wpa_set_pmk(uint8_t *pmk, size_t pmk_length, const u8 *pmkid, bool cache_pmksa) { struct wpa_sm *sm = &gWpaSm; int pmk_len; if (wpa_key_mgmt_sha384(sm->key_mgmt)) pmk_len = PMK_LEN_SUITE_B_192; + else if (wpa_key_mgmt_sae(sm->key_mgmt)) + pmk_len = pmk_length; else pmk_len = PMK_LEN; @@ -2335,7 +2327,8 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher, /* Ideally we should use network_ctx for this purpose however currently network profile block * is part of libraries, * TODO Correct this in future during NVS restructuring */ - if ((sm->key_mgmt == WPA_KEY_MGMT_SAE) && + if ((sm->key_mgmt == WPA_KEY_MGMT_SAE || + sm->key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY) && (os_memcmp(sm->bssid, bssid, ETH_ALEN) == 0) && (os_memcmp(sm->ssid, ssid, ssid_len) != 0)) { use_pmk_cache = false; @@ -2474,7 +2467,9 @@ wpa_set_passphrase(char * passphrase, u8 *ssid, size_t ssid_len) * Here only handle passphrase string. Need extra step to handle 32B, 64Hex raw * PMK. */ - if (sm->key_mgmt == WPA_KEY_MGMT_SAE || sm->key_mgmt == WPA_KEY_MGMT_OWE) + if (sm->key_mgmt == WPA_KEY_MGMT_SAE || + sm->key_mgmt == WPA_KEY_MGMT_OWE || + sm->key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY) return; /* This is really SLOW, so just re cacl while reset param */ diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.h b/components/wpa_supplicant/src/rsn_supp/wpa.h index 4f7a768fc6..257735d270 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa.h @@ -38,7 +38,7 @@ struct l2_ethhdr { void wpa_sm_set_state(enum wpa_states state); -void wpa_set_pmk(uint8_t *pmk, const u8 *pmkid, bool cache_pmksa); +void wpa_set_pmk(uint8_t *pmk, size_t pmk_length, const u8 *pmkid, bool cache_pmksa); int wpa_michael_mic_failure(u16 isunicast); diff --git a/examples/wifi/scan/main/scan.c b/examples/wifi/scan/main/scan.c index cbb6cfdd44..6a53718e1b 100644 --- a/examples/wifi/scan/main/scan.c +++ b/examples/wifi/scan/main/scan.c @@ -55,6 +55,9 @@ static void print_auth_mode(int authmode) case WIFI_AUTH_WPA3_ENT_192: ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA3_ENT_192"); break; + case WIFI_AUTH_WPA3_EXT_PSK: + ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA3_EXT_PSK"); + break; default: ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_UNKNOWN"); break;