Просмотр исходного кода

Merge branch 'bugfix/eapol_txdone_cb_issue' into 'master'

fix(wifi): Fix EAPOL Key TxDone callback implementation

Closes WIFIBUG-14

See merge request espressif/esp-idf!25153
Jiang Jiang Jian 2 лет назад
Родитель
Сommit
3e891bef25

+ 1 - 1
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;*/

+ 1 - 1
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;*/

+ 1 - 1
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;

+ 1 - 1
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;*/

+ 1 - 1
components/esp_wifi/lib

@@ -1 +1 @@
-Subproject commit e3f12b5114210bd3d18b3063f6124ef0c584dfbf
+Subproject commit 0a89d5ffd2c452407940c2e617434e54f3c34576

+ 3 - 2
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);

+ 2 - 1
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;

+ 22 - 12
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:

+ 1 - 1
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);