wpa_supplicant: Fix WPA3 and WPA2 transition related failures

1. If Device is connected to AP in WPA3-PSK mode, AP switching
security to WPA2-PSK causes connection failures even after reset.
Fix is to not store WPA3's PMK in NVS for caching.

2. AP switching back to WPA3 causes even more connection failures.
This is due to device not clearing Supplicant level PMK Cache when
it is no longer valid. Fix is to clear the Cache when 4-way handshake
fails and to check Key Mgmt of Cache before using.

3. When AP switches from WPA3 to WPA2, device's PMF config in
Supplicant remains enabled. This may cause failures during
4-way handshake. So clear PMF config in when PMF is no longer used.
This commit is contained in:
Nachiket Kukade 2020-07-08 16:40:40 +05:30 committed by bot
parent 48ea44f3d1
commit e9a07592fc
5 changed files with 17 additions and 3 deletions

View file

@ -695,7 +695,8 @@ static int wpa2_start_eapol_internal(void)
if (!sm) {
return ESP_FAIL;
}
if (wpa_sta_is_cur_pmksa_set()) {
if (wpa_sta_cur_pmksa_matches_akm()) {
wpa_printf(MSG_DEBUG,
"RSN: PMKSA caching - do not send EAPOL-Start");
return ESP_FAIL;

View file

@ -32,7 +32,7 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid)
u8 own_addr[ETH_ALEN];
const u8 *pw;
if (wpa_sta_is_cur_pmksa_set()) {
if (wpa_sta_cur_pmksa_matches_akm()) {
wpa_printf(MSG_INFO, "wpa3: Skip SAE and use cached PMK instead");
return ESP_FAIL;
}
@ -201,7 +201,6 @@ 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);
memcpy(esp_wifi_sta_get_ap_info_prof_pmk_internal(), g_sae_data.pmk, PMK_LEN);
return ESP_OK;
}

View file

@ -189,6 +189,7 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code)
case WIFI_REASON_AUTH_FAIL:
case WIFI_REASON_ASSOC_FAIL:
case WIFI_REASON_CONNECTION_FAIL:
case WIFI_REASON_HANDSHAKE_TIMEOUT:
esp_wpa3_free_sae_data();
wpa_sta_clear_curr_pmksa();
break;

View file

@ -2130,6 +2130,9 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher,
esp_wifi_get_config(ESP_IF_WIFI_STA, &wifi_cfg);
sm->pmf_cfg = wifi_cfg.sta.pmf_cfg;
sm->mgmt_group_cipher = cipher_type_map_public_to_supp(esp_wifi_sta_get_mgmt_group_cipher());
} else {
memset(&sm->pmf_cfg, 0, sizeof(sm->pmf_cfg));
sm->mgmt_group_cipher = WPA_CIPHER_NONE;
}
#endif
@ -2363,6 +2366,15 @@ bool wpa_sta_is_cur_pmksa_set(void) {
return (pmksa_cache_get_current(sm) != NULL);
}
bool wpa_sta_cur_pmksa_matches_akm(void) {
struct wpa_sm *sm = &gWpaSm;
struct rsn_pmksa_cache_entry *pmksa;
pmksa = pmksa_cache_get_current(sm);
return (pmksa != NULL &&
sm->key_mgmt == pmksa->akmp);
}
void wpa_sta_clear_curr_pmksa(void) {
struct wpa_sm *sm = &gWpaSm;

View file

@ -31,6 +31,7 @@ struct wpa_sm;
int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len);
bool wpa_sta_is_cur_pmksa_set(void);
bool wpa_sta_in_4way_handshake(void);
bool wpa_sta_cur_pmksa_matches_akm(void);
#define WPA_ASSERT assert