From feecbad7db73cb36440c4415a8d81ee3f81aadb1 Mon Sep 17 00:00:00 2001 From: Nachiket Kukade Date: Wed, 16 Aug 2023 19:26:22 +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. --- components/esp_rom/esp32c2/ld/esp32c2.rom.ld | 2 +- .../esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld | 2 +- .../esp_rom/esp32c6/ld/esp32c6.rom.pp.ld | 2 +- components/esp_rom/esp32s3/ld/esp32s3.rom.ld | 2 +- components/esp_wifi/lib | 2 +- .../esp_supplicant/src/esp_wifi_driver.h | 5 +-- .../esp_supplicant/src/esp_wpa_main.c | 3 +- components/wpa_supplicant/src/rsn_supp/wpa.c | 34 ++++++++++++------- .../wpa_supplicant/src/rsn_supp/wpa_i.h | 2 +- 9 files changed, 33 insertions(+), 21 deletions(-) diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index d229752709..88a40bc6d0 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -1620,7 +1620,7 @@ rcampduuprate = 0x40001c78; rcClearCurAMPDUSched = 0x40001c7c; rcClearCurSched = 0x40001c80; rcClearCurStat = 0x40001c84; -rcGetSched = 0x40001c88; +/*rcGetSched = 0x40001c88;*/ rcLowerSched = 0x40001c8c; rcSetTxAmpduLimit = 0x40001c90; /* rcTxUpdatePer = 0x40001c94;*/ diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld index d1b71e56b2..13940e252f 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_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld index cbcf560177..10b0a3e6b3 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -124,7 +124,7 @@ rcampduuprate = 0x40000d70; rcClearCurAMPDUSched = 0x40000d74; rcClearCurSched = 0x40000d78; rcClearCurStat = 0x40000d7c; -rcGetSched = 0x40000d80; +/*rcGetSched = 0x40000d80;*/ rcLowerSched = 0x40000d84; rcSetTxAmpduLimit = 0x40000d88; rcTxUpdatePer = 0x40000d8c; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index 3d9234092b..fd55961bf3 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -1996,7 +1996,7 @@ rcampduuprate = 0x4000573c; rcClearCurAMPDUSched = 0x40005748; rcClearCurSched = 0x40005754; rcClearCurStat = 0x40005760; -rcGetSched = 0x4000576c; +/*rcGetSched = 0x4000576c;*/ rcLowerSched = 0x40005778; rcSetTxAmpduLimit = 0x40005784; /* rcTxUpdatePer = 0x40005790;*/ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index e3f12b5114..0a89d5ffd2 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit e3f12b5114210bd3d18b3063f6124ef0c584dfbf +Subproject commit 0a89d5ffd2c452407940c2e617434e54f3c34576 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 57b036f9a1..a6ffe6f93e 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -175,8 +175,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; @@ -241,6 +241,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/esp_supplicant/src/esp_wpa_main.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c index 6cb4ec0932..ea562edcd5 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -127,7 +127,7 @@ bool wpa_attach(void) bool ret = true; ret = wpa_sm_init(); 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); } esp_set_scan_ie(); return ret; @@ -189,6 +189,7 @@ bool wpa_deattach(void) if (sm->wpa_sm_wps_disable) { sm->wpa_sm_wps_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 6794e8b947..b69976caff 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -2622,30 +2622,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", 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 b4b0ce75d9..c3a7afd438 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -199,7 +199,7 @@ bool wpa_sm_init(void); 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);