From 2d83e3e7f43568bba42cbbf4c0864fc626d93e93 Mon Sep 17 00:00:00 2001 From: Sarvesh Bodakhe Date: Mon, 15 May 2023 18:09:52 +0530 Subject: [PATCH] fix(wpa_supplicant): Add some bugfixes in wpa_supplicant 1) Add parameter to configure reason code of deauth frame 2) Add logs to indicate MIC failure 4-Way-Handshake 3) Process RSNXE capabilities only if AP advertises them --- components/wpa_supplicant/src/ap/wpa_auth.c | 42 +++++++++++++------ components/wpa_supplicant/src/ap/wpa_auth_i.h | 1 + components/wpa_supplicant/src/rsn_supp/wpa.c | 14 ++++--- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index 5b0b4ae901..713a384bb7 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -217,10 +217,10 @@ int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth, } static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth, - const u8 *addr) + const u8 *addr, u16 reason) { wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr)); - esp_wifi_ap_deauth_internal((uint8_t*)addr, WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT); + esp_wifi_ap_deauth_internal((uint8_t*)addr, reason); return; } @@ -797,7 +797,8 @@ continue_processing: "collect more entropy for random number " "generation"); random_mark_pool_ready(); - wpa_sta_disconnect(wpa_auth, sm->addr); + wpa_sta_disconnect(wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); return; } if (wpa_parse_kde_ies((u8 *) (key + 1), key_data_length, @@ -824,12 +825,14 @@ continue_processing: wpa_hexdump(MSG_DEBUG, "WPA IE in msg 2/4", eapol_key_ie, eapol_key_ie_len); /* MLME-DEAUTHENTICATE.request */ - wpa_sta_disconnect(wpa_auth, sm->addr); + wpa_sta_disconnect(wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); return; } #ifdef CONFIG_IEEE80211R_AP if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) { - wpa_sta_disconnect(wpa_auth, sm->addr); + wpa_sta_disconnect(wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); return; } #endif /* CONFIG_IEEE80211R_AP */ @@ -863,6 +866,8 @@ continue_processing: if (sm->PTK_valid && !sm->update_snonce) { if (wpa_verify_key_mic(sm->wpa_key_mgmt, &sm->PTK, data, data_len)) { + wpa_printf(MSG_INFO, + "received EAPOL-Key with invalid MIC"); return; } sm->MICVerified = TRUE; @@ -876,6 +881,8 @@ continue_processing: memcpy(sm->req_replay_counter, key->replay_counter, WPA_REPLAY_COUNTER_LEN); } else { + wpa_printf(MSG_INFO, + "received EAPOL-Key request with invalid MIC"); return; } @@ -1359,9 +1366,14 @@ SM_STATE(WPA_PTK, INITIALIZE) SM_STATE(WPA_PTK, DISCONNECT) { + u16 reason = sm->disconnect_reason; + SM_ENTRY_MA(WPA_PTK, DISCONNECT, wpa_ptk); sm->Disconnect = FALSE; - wpa_sta_disconnect(sm->wpa_auth, sm->addr); + sm->disconnect_reason = 0; + if (!reason) + reason = WLAN_REASON_PREV_AUTH_NOT_VALID; + wpa_sta_disconnect(sm->wpa_auth, sm->addr, reason); } @@ -1431,7 +1443,8 @@ SM_STATE(WPA_PTK, AUTHENTICATION2) if (os_get_random(sm->ANonce, WPA_NONCE_LEN)) { wpa_printf( MSG_ERROR, "WPA: Failed to get random data for " "ANonce."); - wpa_sta_disconnect(sm->wpa_auth, sm->addr); + wpa_sta_disconnect(sm->wpa_auth, sm->addr, + WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT); return; } wpa_hexdump(MSG_DEBUG, "WPA: Assign ANonce", sm->ANonce, @@ -1645,11 +1658,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK, sm->last_rx_eapol_key, sm->last_rx_eapol_key_len) == 0) { - wpa_printf( MSG_DEBUG, "mic verify ok, pmk=%p", pmk); ok = 1; break; - } else { - wpa_printf( MSG_DEBUG, "mic verify fail, pmk=%p", pmk); } if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) || @@ -1660,6 +1670,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) } if (!ok) { + wpa_printf(MSG_INFO, "invalid MIC in msg 2/4 of 4-Way Handshake"); return; } @@ -1705,7 +1716,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) sm->rsnxe, sm->rsnxe_len); wpa_hexdump(MSG_DEBUG, "RSNXE in EAPOL-Key msg 2/4", kde.rsnxe, kde.rsnxe_len); - wpa_sta_disconnect(sm->wpa_auth, sm->addr); + wpa_sta_disconnect(sm->wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); return; } @@ -1950,7 +1962,8 @@ SM_STATE(WPA_PTK, PTKINITDONE) int klen = wpa_cipher_key_len(sm->pairwise); if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0, sm->PTK.tk, klen)) { - wpa_sta_disconnect(sm->wpa_auth, sm->addr); + wpa_sta_disconnect(sm->wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); return; } /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ @@ -2062,6 +2075,8 @@ SM_STEP(WPA_PTK) SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); else if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { + sm->disconnect_reason = + WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT; SM_ENTER(WPA_PTK, DISCONNECT); } else if (sm->TimeoutEvt) SM_ENTER(WPA_PTK, PTKSTART); @@ -2086,6 +2101,8 @@ SM_STEP(WPA_PTK) SM_ENTER(WPA_PTK, PTKINITDONE); else if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { + sm->disconnect_reason = + WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT; SM_ENTER(WPA_PTK, DISCONNECT); } else if (sm->TimeoutEvt) SM_ENTER(WPA_PTK, PTKINITNEGOTIATING); @@ -2191,6 +2208,7 @@ SM_STATE(WPA_PTK_GROUP, KEYERROR) sm->group->GKeyDoneStations--; sm->GUpdateStationKeys = FALSE; sm->Disconnect = TRUE; + sm->disconnect_reason = WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT; } diff --git a/components/wpa_supplicant/src/ap/wpa_auth_i.h b/components/wpa_supplicant/src/ap/wpa_auth_i.h index 672cc09425..2516b34f69 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth_i.h +++ b/components/wpa_supplicant/src/ap/wpa_auth_i.h @@ -47,6 +47,7 @@ struct wpa_state_machine { Boolean AuthenticationRequest; Boolean ReAuthenticationRequest; Boolean Disconnect; + u16 disconnect_reason; /* specific reason code to use with Disconnect */ int TimeoutCtr; int GTimeoutCtr; Boolean TimeoutEvt; diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 94cfa95fbc..42c8912b1b 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -2740,14 +2740,16 @@ int wpa_sm_set_ap_rsnxe(const u8 *ie, size_t len) sm->ap_rsnxe_len = len; } - sm->sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal(WIFI_IF_STA); + if (sm->ap_rsnxe != NULL) { + sm->sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal(WIFI_IF_STA); #ifdef CONFIG_SAE_PK - const u8 *pw = (const u8 *)esp_wifi_sta_get_prof_password_internal(); - if (esp_wifi_sta_get_config_sae_pk_internal() != WPA3_SAE_PK_MODE_DISABLED && - sae_pk_valid_password((const char*)pw)) { - sm->sae_pk = true; - } + const u8 *pw = (const u8 *)esp_wifi_sta_get_prof_password_internal(); + if (esp_wifi_sta_get_config_sae_pk_internal() != WPA3_SAE_PK_MODE_DISABLED && + sae_pk_valid_password((const char*)pw)) { + sm->sae_pk = true; + } #endif /* CONFIG_SAE_PK */ + } return 0; }