From 7fd73ede7f207f2c095c508c2e734ccf357b3488 Mon Sep 17 00:00:00 2001 From: Sarvesh Bodakhe Date: Tue, 2 Apr 2024 02:01:33 +0530 Subject: [PATCH 1/2] fix(wifi): Add bugfix to avoid RSNXE and KDE mismatch during 4-way-handshake --- components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c | 3 ++- components/wpa_supplicant/src/rsn_supp/wpa.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) 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 88d43e7e59..b60627b039 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -312,7 +312,8 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, bo } if (*sta) { - ap_free_sta(hapd, *sta); + ap_free_sta(hapd, *sta); + *sta = NULL; } sta_info = ap_sta_add(hapd, bssid); if (!sta_info) { diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 8104a71a6d..db648dda38 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -2481,6 +2481,7 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher, sm->ap_notify_completed_rsne = esp_wifi_sta_is_ap_notify_completed_rsne_internal(); sm->use_ext_key_id = (sm->proto == WPA_PROTO_WPA); pmksa_cache_clear_current(sm); + sm->sae_pwe = esp_wifi_sta_get_config_sae_pwe_h2e_internal(); struct rsn_pmksa_cache_entry *pmksa = NULL; if (use_pmk_cache) { From af72ce1f757f16fedf314d8987f87c2555b9d38e Mon Sep 17 00:00:00 2001 From: Sarvesh Bodakhe Date: Fri, 28 Jun 2024 13:06:39 +0530 Subject: [PATCH 2/2] fix(esp_wifi): Fix some wifi bugs 1. Fix issues related to mgmt packets encryption in GCMP 2. Fix issue of wrong decryption of mgmt packets when PMF is enabled 3. Fix frame subtype in send_mgmt_frame 4. Fix issue of wrong Rx control information of espnow packets for esp32 and esp32s2 5. Fix send mgmt err when eapol process --- components/esp_rom/esp32c2/ld/esp32c2.rom.ld | 6 +++--- components/esp_wifi/lib | 2 +- components/wpa_supplicant/esp_supplicant/src/esp_common.c | 8 ++++---- .../wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h | 2 +- .../wpa_supplicant/esp_supplicant/src/esp_wpa_main.c | 4 ++-- components/wpa_supplicant/src/ap/ap_config.h | 4 ++-- components/wpa_supplicant/src/ap/wpa_auth.c | 3 ++- components/wpa_supplicant/src/crypto/ccmp.c | 2 +- components/wpa_supplicant/src/utils/common.h | 4 ++++ 9 files changed, 20 insertions(+), 15 deletions(-) diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index 5e85eaf3a8..90de6b2688 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -1865,8 +1865,8 @@ ieee80211_decap = 0x40001ffc; ieee80211_set_tx_pti = 0x40002000; wifi_is_started = 0x40002004; ieee80211_gettid = 0x40002008; -ieee80211_ccmp_decrypt = 0x4000200c; -ieee80211_ccmp_encrypt = 0x40002010; +/* ieee80211_ccmp_decrypt = 0x4000200c; */ +/* ieee80211_ccmp_encrypt = 0x40002010; */ ccmp_encap = 0x40002014; ccmp_decap = 0x40002018; tkip_encap = 0x4000201c; @@ -1920,7 +1920,7 @@ ieee80211_crypto_aes_128_cmac_encrypt = 0x40002100; ieee80211_alloc_tx_buf = 0x40002108; /* ieee80211_output_do = 0x4000210c; */ /* ieee80211_send_nulldata = 0x40002110; */ -ieee80211_setup_robust_mgmtframe = 0x40002114; +/* ieee80211_setup_robust_mgmtframe = 0x40002114; */ ieee80211_encap_null_data = 0x4000211c; ieee80211_send_deauth = 0x40002120; ieee80211_alloc_deauth = 0x40002124; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 87ac448921..ca20e89439 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 87ac448921a733c73ea0a3903cc5711f8629a000 +Subproject commit ca20e894399e28aabb8c9f87bf70883fccad9ba0 diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common.c b/components/wpa_supplicant/esp_supplicant/src/esp_common.c index 262427430f..22083ac0c6 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common.c @@ -778,10 +778,10 @@ int wpa_drv_send_action(struct wpa_supplicant *wpa_s, goto cleanup; } - req->ifx = WIFI_IF_STA; - req->subtype = WLAN_FC_STYPE_ACTION; - req->data_len = data_len; - os_memcpy(req->data, data, req->data_len); + req->ifx = WIFI_IF_STA; + req->subtype = (WLAN_FC_STYPE_ACTION << 4); + req->data_len = data_len; + os_memcpy(req->data, data, req->data_len); if (esp_wifi_send_mgmt_frm_internal(req) != 0) { wpa_printf(MSG_ERROR, "action frame sending failed"); 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 d8eb7ab96d..b6199ed48e 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -124,7 +124,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 *wpa_ie, u8 wpa_ie_len, bool *pmf_enable); + bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher); bool (*wpa_ap_remove)(void *sm); 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_wpa_main.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c index b60627b039..6fe1d9ad27 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -302,7 +302,7 @@ 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 *wpa_ie, u8 wpa_ie_len, bool *pmf_enable) +static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher) { struct sta_info *sta_info; struct hostapd_data *hapd = hostapd_get_hapd_data(); @@ -326,7 +326,7 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, bo return true; } #endif - if (wpa_ap_join(sta_info, bssid, wpa_ie, wpa_ie_len, pmf_enable)) { + if (wpa_ap_join(sta_info, bssid, wpa_ie, wpa_ie_len, pmf_enable, pairwise_cipher)) { *sta = sta_info; return true; } diff --git a/components/wpa_supplicant/src/ap/ap_config.h b/components/wpa_supplicant/src/ap/ap_config.h index 0b6fc253f9..118da6e578 100644 --- a/components/wpa_supplicant/src/ap/ap_config.h +++ b/components/wpa_supplicant/src/ap/ap_config.h @@ -331,7 +331,7 @@ struct hostapd_config { char country[3]; /* first two octets: country code as described in * ISO/IEC 3166-1. Third octet: * ' ' (ascii 32): all environments - * 'O': Outdoor environemnt only + * 'O': Outdoor environment only * 'I': Indoor environment only */ @@ -373,7 +373,7 @@ 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 wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, bool *pmf_enable); +bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher); bool wpa_ap_remove(void* sta_info); #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 e5fa908136..53941c2913 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -2375,7 +2375,7 @@ static int wpa_sm_step(struct wpa_state_machine *sm) return 0; } -bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, bool *pmf_enable) +bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher) { struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal(); @@ -2402,6 +2402,7 @@ bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t //Check whether AP uses Management Frame Protection for this connection *pmf_enable = wpa_auth_uses_mfp(sta->wpa_sm); + *pairwise_cipher = GET_BIT_POSITION(sta->wpa_sm->pairwise); } wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); diff --git a/components/wpa_supplicant/src/crypto/ccmp.c b/components/wpa_supplicant/src/crypto/ccmp.c index 0842e9d361..9b1cfa0e9d 100644 --- a/components/wpa_supplicant/src/crypto/ccmp.c +++ b/components/wpa_supplicant/src/crypto/ccmp.c @@ -222,7 +222,7 @@ u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, wpa_hexdump(MSG_MSGDUMP, "CCMP AAD", aad, aad_len); wpa_hexdump(MSG_MSGDUMP, "CCMP nonce", nonce, 13); - if (aes_ccm_ae(tk, 16, nonce, 8, frame + hdrlen, plen, aad, aad_len, + if (aes_ccm_ae(tk, 16, nonce, 8, frame + hdrlen + 8, plen, aad, aad_len, pos, pos + plen) < 0) { wpa_printf(MSG_ERROR, "aes ccm ae failed"); os_free(crypt); diff --git a/components/wpa_supplicant/src/utils/common.h b/components/wpa_supplicant/src/utils/common.h index 31fa00a0d4..2dcfa54c89 100644 --- a/components/wpa_supplicant/src/utils/common.h +++ b/components/wpa_supplicant/src/utils/common.h @@ -335,6 +335,10 @@ void perror(const char *s); #define BIT(x) (1U << (x)) #endif +#ifndef GET_BIT_POSITION +#define GET_BIT_POSITION(value) (__builtin_ffs(value) - 1) +#endif + /* * Definitions for sparse validation * (http://kernel.org/pub/linux/kernel/people/josh/sparse/)