From 7ec1705c0f1223ffd7984c3a6d9a0907fd937157 Mon Sep 17 00:00:00 2001 From: Nachiket Kukade Date: Thu, 17 Aug 2023 10:40:33 +0530 Subject: [PATCH] fix(wifi): Fix EAPOL Key TxDone callback implementation Fix issues arising due to not distinguishing between M2 and M4 TxDone during 4-way handshake. Also fix EAPOL frame rate to lowest possible rate. --- .../esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld | 2 +- components/esp_wifi/lib | 2 +- .../src/esp_supplicant/esp_wifi_driver.h | 5 +-- .../src/esp_supplicant/esp_wpa_main.c | 3 +- components/wpa_supplicant/src/rsn_supp/wpa.c | 34 ++++++++++++------- .../wpa_supplicant/src/rsn_supp/wpa_i.h | 2 +- 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld index 32bb981416..ee5f22ad25 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld @@ -7,7 +7,7 @@ esf_buf_alloc_dynamic = 0x400015c0; esf_buf_recycle = 0x400015c4; /*lmacTxDone = 0x4000162c;*/ ppMapTxQueue = 0x400016d8; -rcGetSched = 0x40001764; +/*rcGetSched = 0x40001764;*/ wDevCheckBlockError = 0x400017b4; ppProcTxDone = 0x40001804; /*sta_input = rom_sta_input;*/ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index b87057673c..d693bf2166 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit b87057673c9a0e5d17516d8a25401d7fd9448b16 +Subproject commit d693bf21662e3f6fab16767362d1a3cb8d6e640d diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h b/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h index 5154588603..5438f760b1 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h @@ -1,4 +1,4 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// Copyright 2019-2023 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -174,8 +174,8 @@ typedef enum wps_status { WPS_STATUS_MAX, } WPS_STATUS_t; -#define WIFI_TXCB_EAPOL_ID 3 typedef void(*wifi_tx_cb_t)(void *); +typedef void(* eapol_txcb_t)(uint8_t *, size_t, bool); typedef int (*wifi_ipc_fn_t)(void *); typedef struct { wifi_ipc_fn_t fn; @@ -236,6 +236,7 @@ bool esp_wifi_wpa_ptk_init_done_internal(uint8_t *mac); uint8_t esp_wifi_sta_set_reset_param_internal(uint8_t reset_flag); uint8_t esp_wifi_get_sta_gtk_index_internal(void); int esp_wifi_register_tx_cb_internal(wifi_tx_cb_t fn, u8 id); +int esp_wifi_register_eapol_txdonecb_internal(eapol_txcb_t fn); int esp_wifi_register_wpa_cb_internal(struct wpa_funcs *cb); int esp_wifi_unregister_wpa_cb_internal(void); int esp_wifi_get_assoc_bssid_internal(uint8_t *bssid); diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c index 70febadf52..56bd981255 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c @@ -115,7 +115,7 @@ bool wpa_attach(void) ret = wpa_sm_init(NULL, wpa_sendto_wrapper, wpa_config_assoc_ie, wpa_install_key, wpa_get_key, wpa_deauthenticate, wpa_neg_complete); if(ret) { - ret = (esp_wifi_register_tx_cb_internal(eapol_txcb, WIFI_TXCB_EAPOL_ID) == ESP_OK); + ret = (esp_wifi_register_eapol_txdonecb_internal(eapol_txcb) == ESP_OK); } return ret; } @@ -161,6 +161,7 @@ void wpa_ap_get_peer_spp_msg(void *sm_data, bool *spp_cap, bool *spp_req) bool wpa_deattach(void) { esp_wifi_sta_wpa2_ent_disable(); + esp_wifi_register_eapol_txdonecb_internal(NULL); wpa_sm_deinit(); return true; } diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index a029224560..4c5decf05d 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -2568,30 +2568,40 @@ int wpa_michael_mic_failure(u16 isunicast) eapol tx callback function to make sure new key install after 4-way handoff */ -void eapol_txcb(void *eb) +void eapol_txcb(uint8_t *eapol_payload, size_t len, bool tx_failure) { + struct ieee802_1x_hdr *hdr; + struct wpa_eapol_key *key; struct wpa_sm *sm = &gWpaSm; u8 isdeauth = 0; //no_zero value is the reason for deauth - if (false == esp_wifi_sta_is_running_internal()){ + if (len < (sizeof(struct ieee802_1x_hdr) + sizeof(struct wpa_eapol_key))) { + wpa_printf(MSG_ERROR, "EAPOL TxDone with invalid payload len! (len - %d)", len); return; } + hdr = (struct ieee802_1x_hdr *) eapol_payload; + key = (struct wpa_eapol_key *) (hdr + 1); switch(WPA_SM_STATE(sm)) { case WPA_FIRST_HALF_4WAY_HANDSHAKE: - break; case WPA_LAST_HALF_4WAY_HANDSHAKE: + if (WPA_GET_BE16(key->key_data_length) == 0 || + (WPA_GET_BE16(key->key_info) & WPA_KEY_INFO_SECURE)) { + /* msg 4/4 Tx Done */ + if (tx_failure) { + wpa_printf(MSG_ERROR, "Eapol message 4/4 tx failure, not installing keys"); + return; + } - if (esp_wifi_eb_tx_status_success_internal(eb) != true) { - wpa_printf(MSG_ERROR, "Eapol message 4/4 tx failure, not installing keys"); - return; - } - - if (sm->txcb_flags & WPA_4_4_HANDSHAKE_BIT) { - sm->txcb_flags &= ~WPA_4_4_HANDSHAKE_BIT; - isdeauth = wpa_supplicant_send_4_of_4_txcallback(sm); + if (sm->txcb_flags & WPA_4_4_HANDSHAKE_BIT) { + sm->txcb_flags &= ~WPA_4_4_HANDSHAKE_BIT; + isdeauth = wpa_supplicant_send_4_of_4_txcallback(sm); + } else { + wpa_printf(MSG_DEBUG, "4/4 txcb, flags=%d", sm->txcb_flags); + } } else { - wpa_printf(MSG_DEBUG, "4/4 txcb, flags=%d\n", sm->txcb_flags); + /* msg 2/4 Tx Done */ + wpa_printf(MSG_DEBUG, "2/4 txcb, flags=%d, txfail %d", sm->txcb_flags, tx_failure); } break; case WPA_GROUP_HANDSHAKE: diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_i.h b/components/wpa_supplicant/src/rsn_supp/wpa_i.h index d7b1714295..9ded2ec367 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -171,7 +171,7 @@ bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func, \ void wpa_sm_deinit(void); -void eapol_txcb(void *eb); +void eapol_txcb(uint8_t *eapol_payload, size_t len, bool tx_failure); void wpa_set_profile(u32 wpa_proto, u8 auth_mode);