From a6006f5a56ce03933a64fa9d3b91e0341145744e Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Mon, 7 Oct 2024 10:23:40 +0530 Subject: [PATCH 1/6] fix(esp_wifi): Added prints in btm roam for error condition --- components/wpa_supplicant/src/common/wnm_sta.c | 6 ++++-- examples/wifi/roaming/README.md | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/components/wpa_supplicant/src/common/wnm_sta.c b/components/wpa_supplicant/src/common/wnm_sta.c index 4d2c7752e5..f3110ee126 100644 --- a/components/wpa_supplicant/src/common/wnm_sta.c +++ b/components/wpa_supplicant/src/common/wnm_sta.c @@ -691,8 +691,10 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail) enum mbo_transition_reject_reason reason = MBO_TRANSITION_REJECT_REASON_UNSPECIFIED; - if (!wpa_s->wnm_neighbor_report_elements) + if (!wpa_s->wnm_neighbor_report_elements) { + wpa_printf(MSG_INFO, "WNM: Neighbor report not available"); return 0; + } wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Process scan results for BSS Transition Management"); @@ -706,7 +708,7 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail) /* Compare the Neighbor Report and scan results */ bss = compare_scan_neighbor_results(wpa_s, 0, &reason); if (!bss) { - wpa_printf(MSG_DEBUG, "WNM: No BSS transition candidate match found"); + wpa_printf(MSG_INFO, "WNM: No BSS transition candidate match found"); status = WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES; goto send_bss_resp_fail; } diff --git a/examples/wifi/roaming/README.md b/examples/wifi/roaming/README.md index 77b69d89fe..e0e82b3101 100644 --- a/examples/wifi/roaming/README.md +++ b/examples/wifi/roaming/README.md @@ -5,7 +5,7 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example demonstrate a roaming example using 11k and 11v APIs. +This example demonstrates a roaming example using 802.11k and 802.11v APIs. 802.11r(FT-PSK) is enabled by default in this example. ## How to use example From 8baaec05be7fe465c9331a3a31f2c8e69d6e83ee Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Thu, 19 Sep 2024 23:07:36 +0530 Subject: [PATCH 2/6] fix(esp_wifi): Deinit WPS registrar during hostapd deinit --- components/wpa_supplicant/esp_supplicant/src/esp_hostap.c | 4 ++++ components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c | 4 ++++ components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h | 1 + 3 files changed, 9 insertions(+) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c index 3beb7590da..faf643b75c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c @@ -19,6 +19,7 @@ #include "esp_wifi_types.h" #include "esp_wpa3_i.h" #include "esp_wps.h" +#include "esp_wps_i.h" #define WIFI_PASSWORD_LEN_MAX 65 @@ -238,6 +239,9 @@ bool hostap_deinit(void *data) esp_wifi_unset_appie_internal(WIFI_APPIE_WPA); esp_wifi_unset_appie_internal(WIFI_APPIE_ASSOC_RESP); +#ifdef CONFIG_WPS_REGISTRAR + wifi_ap_wps_disable_internal(); +#endif #ifdef CONFIG_SAE wpa3_hostap_auth_deinit(); /* Wait till lock is released by wpa3 task */ diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c index 9f849af4b3..58575b1807 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c @@ -358,16 +358,19 @@ int wpa3_hostap_post_evt(uint32_t evt_id, uint32_t data) if (g_wpa3_hostap_evt_queue == NULL) { WPA3_HOSTAP_AUTH_API_UNLOCK(); os_free(evt); + wpa_printf(MSG_DEBUG, "hostap evt queue NULL"); return ESP_FAIL; } } else { os_free(evt); + wpa_printf(MSG_DEBUG, "g_wpa3_hostap_auth_api_lock not found"); return ESP_FAIL; } if (evt->id == SIG_WPA3_RX_CONFIRM || evt->id == SIG_TASK_DEL) { /* prioritising confirm for completing handshake for committed sta */ if (os_queue_send_to_front(g_wpa3_hostap_evt_queue, &evt, 0) != pdPASS) { WPA3_HOSTAP_AUTH_API_UNLOCK(); + wpa_printf(MSG_DEBUG, "failed to add msg to queue front"); os_free(evt); return ESP_FAIL; } @@ -375,6 +378,7 @@ int wpa3_hostap_post_evt(uint32_t evt_id, uint32_t data) if (os_queue_send(g_wpa3_hostap_evt_queue, &evt, 0) != pdPASS) { WPA3_HOSTAP_AUTH_API_UNLOCK(); os_free(evt); + wpa_printf(MSG_DEBUG, "failed to send msg to queue"); return ESP_FAIL; } } diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h index e7d030f37a..f7868df895 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h @@ -147,3 +147,4 @@ static inline int wps_set_status(uint32_t status) bool is_wps_enabled(void); int wps_init_cfg_pin(struct wps_config *cfg); void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx); +int wifi_ap_wps_disable_internal(void); From beb46af39036ca8a73efd1396650618e1ba9fff0 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 20 Sep 2024 14:16:01 +0800 Subject: [PATCH 3/6] fix(esp_wifi): Allow connection with WPA mode in WPS --- .../esp_supplicant/src/esp_wps.c | 50 +++++++++---------- .../esp_supplicant/src/esp_wps_i.h | 16 ++---- .../wpa_supplicant/src/wps/wps_attr_parse.h | 4 ++ 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index 35a8b123c0..3a6c18c7bc 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -418,11 +418,11 @@ wps_parse_scan_result(struct wps_scan_ie *scan) wpabuf_free(buf); if (scan->ssid[1] > SSID_MAX_LEN) { return false; - } + } esp_wifi_enable_sta_privacy_internal(); - os_memset(sm->ssid[0], 0, SSID_MAX_LEN); - os_memcpy(sm->ssid[0], (char *)&scan->ssid[2], (int)scan->ssid[1]); - sm->ssid_len[0] = scan->ssid[1]; + os_memset(sm->creds[0].ssid, 0, SSID_MAX_LEN); + os_memcpy(sm->creds[0].ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]); + sm->creds[0].ssid_len = scan->ssid[1]; if (scan->bssid && memcmp(sm->bssid, scan->bssid, ETH_ALEN) != 0) { wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR, MAC2STR(sm->bssid), MAC2STR(scan->bssid)); @@ -436,7 +436,7 @@ wps_parse_scan_result(struct wps_scan_ie *scan) wps_build_ic_appie_wps_ar(); } } - wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->ssid); + wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->creds[0].ssid); sm->channel = scan->chan; return true; @@ -764,8 +764,7 @@ static int wps_sm_init(struct wps_sm *sm) sm->scan_cnt = 0; sm->discover_ssid_cnt = 0; os_bzero(sm->bssid, ETH_ALEN); - os_bzero(sm->ssid, sizeof(sm->ssid)); - os_bzero(sm->ssid_len, sizeof(sm->ssid_len)); + os_bzero(sm->creds, sizeof(sm->creds)); sm->ap_cred_cnt = 0; return 0; @@ -816,9 +815,16 @@ int wps_finish(void) } esp_wifi_get_config(WIFI_IF_STA, config); - os_memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]); - os_memcpy(config->sta.password, sm->key[0], sm->key_len[0]); + os_memcpy(config->sta.ssid, sm->creds[0].ssid, sm->creds[0].ssid_len); + os_memcpy(config->sta.password, sm->creds[0].key, sm->creds[0].key_len); os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN); +#ifndef CONFIG_WPS_STRICT + /* Some APs support AES in WPA IE, enable connection with them */ + if (sm->creds[0].auth_type == WPS_AUTH_WPAPSK && + (sm->creds[0].encr_type & WPS_ENCR_AES)) { + config->sta.threshold.authmode = WIFI_AUTH_WPA_PSK; + } +#endif config->sta.bssid_set = 0; config->sta.sae_pwe_h2e = 0; esp_wifi_set_config(WIFI_IF_STA, config); @@ -834,8 +840,7 @@ int wps_finish(void) if (sm->ignore_sel_reg) { sm->discover_ssid_cnt = 0; esp_wifi_disconnect(); - os_bzero(sm->ssid, sizeof(sm->ssid)); - os_bzero(sm->ssid_len, sizeof(sm->ssid_len)); + os_bzero(sm->creds, sizeof(sm->creds)); wps_add_discard_ap(sm->bssid); } else { ret = wps_stop_process(WPS_FAIL_REASON_NORMAL); @@ -1285,8 +1290,7 @@ wifi_station_wps_msg_timeout_internal(void) if (sm->ignore_sel_reg) { esp_wifi_disconnect(); wps_add_discard_ap(sm->bssid); - os_bzero(sm->ssid, sizeof(sm->ssid)); - os_bzero(sm->ssid_len, sizeof(sm->ssid_len)); + os_bzero(sm->creds, sizeof(sm->creds)); os_bzero(sm->bssid, ETH_ALEN); sm->discover_ssid_cnt = 0; wifi_wps_scan(NULL, NULL); @@ -1316,8 +1320,8 @@ void wifi_station_wps_success_internal(void) if (sm->ap_cred_cnt > 1) { evt.ap_cred_cnt = sm->ap_cred_cnt; for (i = 0; i < MAX_WPS_AP_CRED; i++) { - os_memcpy(evt.ap_cred[i].ssid, sm->ssid[i], sm->ssid_len[i]); - os_memcpy(evt.ap_cred[i].passphrase, sm->key[i], sm->key_len[i]); + os_memcpy(evt.ap_cred[i].ssid, sm->creds[i].ssid, sm->creds[i].ssid_len); + os_memcpy(evt.ap_cred[i].passphrase, sm->creds[i].key, sm->creds[i].key_len); } esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_SUCCESS, &evt, sizeof(evt), OS_BLOCK); @@ -1355,17 +1359,13 @@ void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx) static int save_credentials_cb(void *ctx, const struct wps_credential *cred) { - if (!gWpsSm || !cred || gWpsSm->ap_cred_cnt > 2) { + struct wps_credential *creds; + if (!gWpsSm || !cred || gWpsSm->ap_cred_cnt > MAX_CRED_COUNT) { return ESP_FAIL; } - os_memset(gWpsSm->ssid[gWpsSm->ap_cred_cnt], 0x00, sizeof(gWpsSm->ssid[gWpsSm->ap_cred_cnt])); - os_memset(gWpsSm->key[gWpsSm->ap_cred_cnt], 0x00, sizeof(gWpsSm->key[gWpsSm->ap_cred_cnt])); - - os_memcpy(gWpsSm->ssid[gWpsSm->ap_cred_cnt], cred->ssid, cred->ssid_len); - gWpsSm->ssid_len[gWpsSm->ap_cred_cnt] = cred->ssid_len; - os_memcpy(gWpsSm->key[gWpsSm->ap_cred_cnt], cred->key, cred->key_len); - gWpsSm->key_len[gWpsSm->ap_cred_cnt] = cred->key_len; + creds = &gWpsSm->creds[gWpsSm->ap_cred_cnt]; + memcpy(creds, cred, sizeof(*creds)); gWpsSm->ap_cred_cnt++; @@ -1618,11 +1618,11 @@ wifi_wps_scan_done(void *arg, ETS_STATUS status) esp_wifi_disconnect(); os_memcpy(wifi_config.sta.bssid, sm->bssid, ETH_ALEN); - os_memcpy(wifi_config.sta.ssid, (char *)sm->ssid[0], sm->ssid_len[0]); + os_memcpy(wifi_config.sta.ssid, (char *)sm->creds[0].ssid, sm->creds[0].ssid_len); wifi_config.sta.bssid_set = 1; wifi_config.sta.channel = sm->channel; wpa_printf(MSG_INFO, "WPS: connecting to %s, bssid=" MACSTR, - (char *)sm->ssid[0], MAC2STR(wifi_config.sta.bssid)); + (char *)sm->creds[0].ssid, MAC2STR(wifi_config.sta.bssid)); esp_wifi_set_config(0, &wifi_config); wpa_printf(MSG_DEBUG, "WPS: neg start"); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h index f7868df895..1b413a128b 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h @@ -6,6 +6,8 @@ #include "esp_wifi_driver.h" #include "esp_wps.h" +#include "wps/wps.h" +#include "wps/wps_attr_parse.h" /* WPS message flag */ enum wps_msg_flag { @@ -57,15 +59,6 @@ struct discard_ap_list_t{ u8 bssid[6]; }; -#ifndef MAX_PASSPHRASE_LEN -#define MAX_PASSPHRASE_LEN 64 -#endif - -#ifndef MAX_CRED_COUNT -#define MAX_CRED_COUNT 10 -#endif - -#define WPS_OUTBUF_SIZE 500 struct wps_sm { u8 state; struct wps_config *wps_cfg; @@ -75,10 +68,7 @@ struct wps_sm { u8 identity_len; u8 ownaddr[ETH_ALEN]; u8 bssid[ETH_ALEN]; - u8 ssid[MAX_CRED_COUNT][SSID_MAX_LEN]; - u8 ssid_len[MAX_CRED_COUNT]; - char key[MAX_CRED_COUNT][MAX_PASSPHRASE_LEN]; - u8 key_len[MAX_CRED_COUNT]; + struct wps_credential creds[MAX_CRED_COUNT]; u8 ap_cred_cnt; struct wps_device_data *dev; u8 uuid[16]; diff --git a/components/wpa_supplicant/src/wps/wps_attr_parse.h b/components/wpa_supplicant/src/wps/wps_attr_parse.h index 4de27b26d4..ea5c1106ab 100644 --- a/components/wpa_supplicant/src/wps/wps_attr_parse.h +++ b/components/wpa_supplicant/src/wps/wps_attr_parse.h @@ -84,7 +84,11 @@ struct wps_parse_attr { u16 oob_dev_password_len; /* attributes that can occur multiple times */ +#ifdef ESP_SUPPLICANT +#define MAX_CRED_COUNT MAX_WPS_AP_CRED +#else #define MAX_CRED_COUNT 10 +#endif #define MAX_REQ_DEV_TYPE_COUNT 10 unsigned int num_cred; From 7810b9f4ffc4ee2b24dcc55ca22213624ac3ba58 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Mon, 2 Sep 2024 12:38:57 +0530 Subject: [PATCH 4/6] fix(esp_wifi): Disable WPS timers once WPS succeed --- components/wpa_supplicant/esp_supplicant/src/esp_wps.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index 3a6c18c7bc..f8be84948c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -72,6 +72,7 @@ void wifi_station_wps_msg_timeout(void *data, void *user_ctx); void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx); void wifi_station_wps_success(void *data, void *user_ctx); void wifi_station_wps_timeout(void *data, void *user_ctx); +int wps_delete_timer(void); struct wps_sm *gWpsSm = NULL; static wps_factory_information_t *s_factory_info = NULL; @@ -805,7 +806,8 @@ int wps_finish(void) if (sm->wps->state == WPS_FINISHED) { wpa_printf(MSG_DEBUG, "wps finished------>"); wps_set_status(WPS_STATUS_SUCCESS); - wps_stop_connection_timers(sm); + /* WPS finished, dequeue all timers */ + wps_delete_timer(); if (sm->ap_cred_cnt == 1) { wifi_config_t *config = os_zalloc(sizeof(wifi_config_t)); @@ -815,6 +817,7 @@ int wps_finish(void) } esp_wifi_get_config(WIFI_IF_STA, config); + esp_wifi_disconnect(); os_memcpy(config->sta.ssid, sm->creds[0].ssid, sm->creds[0].ssid_len); os_memcpy(config->sta.password, sm->creds[0].key, sm->creds[0].key_len); os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN); @@ -828,6 +831,7 @@ int wps_finish(void) config->sta.bssid_set = 0; config->sta.sae_pwe_h2e = 0; esp_wifi_set_config(WIFI_IF_STA, config); + esp_wifi_connect(); os_free(config); } From 60552ecfa13f8e3b13e664e3533d5816fa3a2789 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Mon, 9 Sep 2024 17:02:54 +0530 Subject: [PATCH 5/6] fix(esp_wifi): Mask some error conditions in WPS Mask some error conditions in WPS to increase the probability of WPS success. --- .../wpa_supplicant/esp_supplicant/src/esp_wps.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index f8be84948c..789ab2beb5 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -592,15 +592,15 @@ int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) if (sm->state == WAIT_START) { if (expd->opcode != WSC_Start) { wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d " - "in WAIT_START state", expd->opcode); - return ESP_FAIL; + "in WAIT_START state", expd->opcode); + return ESP_ERR_INVALID_STATE; } wpa_printf(MSG_DEBUG, "EAP-WSC: Received start"); sm->state = WPA_MESG; - } else if (expd->opcode == WSC_Start){ + } else if (expd->opcode == WSC_Start) { wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d", - expd->opcode); - return ESP_FAIL; + expd->opcode); + return ESP_ERR_INVALID_STATE; } flag = *(u8 *)(ubuf + sizeof(struct eap_expand)); @@ -1067,6 +1067,8 @@ int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len) wpa_printf(MSG_DEBUG, "sm->wps->state = %d", sm->wps->state); wps_start_msg_timer(); } + } else if (ret == ESP_ERR_INVALID_STATE) { + ret = ESP_OK; } else { ret = ESP_FAIL; } @@ -1630,6 +1632,7 @@ wifi_wps_scan_done(void *arg, ETS_STATUS status) esp_wifi_set_config(0, &wifi_config); wpa_printf(MSG_DEBUG, "WPS: neg start"); + wifi_config.sta.failure_retry_cnt = 2; esp_wifi_connect(); sm->state = WAIT_START; eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL); From 6938abf90c77eda6279b398cf56250be0215a135 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Sat, 21 Sep 2024 14:38:09 +0530 Subject: [PATCH 6/6] fix(esp_wifi): Prevent memory overflow in WPS --- components/wpa_supplicant/esp_supplicant/src/esp_wps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index 789ab2beb5..648a961fed 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -1366,7 +1366,7 @@ void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx) static int save_credentials_cb(void *ctx, const struct wps_credential *cred) { struct wps_credential *creds; - if (!gWpsSm || !cred || gWpsSm->ap_cred_cnt > MAX_CRED_COUNT) { + if (!gWpsSm || !cred || gWpsSm->ap_cred_cnt >= MAX_CRED_COUNT) { return ESP_FAIL; }