From 5a2f247cac94b7ea2b5f80f6d0a6d12b22d56572 Mon Sep 17 00:00:00 2001 From: Shreyas Sheth Date: Tue, 14 Jul 2026 10:48:05 +0530 Subject: [PATCH] fix(esp_wifi): Backport dpp and other fixes 1) Fix crash while connecting to dpp akm 2) Fix phy ref cnt for power management for offchannel_tx 3) Introduced a variable to indicate dpp ap for scan results 4) Introduced WIFI_AUTH_UNKNOWN for ap with misconfigured security parameter --- .../esp_wifi/include/esp_wifi_types_generic.h | 9 +- components/esp_wifi/lib | 2 +- .../esp_supplicant/include/esp_dpp.h | 4 +- .../esp_supplicant/src/esp_dpp.c | 163 +++++++++++++----- .../esp_supplicant/src/esp_dpp_i.h | 1 + .../esp_supplicant/src/esp_wifi_driver.h | 1 + .../esp_supplicant/src/esp_wpa_main.c | 18 +- components/wpa_supplicant/port/include/os.h | 2 +- components/wpa_supplicant/src/common/defs.h | 2 +- components/wpa_supplicant/src/common/dpp.c | 37 ++-- .../wpa_supplicant/src/common/wpa_common.c | 4 +- components/wpa_supplicant/src/rsn_supp/wpa.c | 11 +- 12 files changed, 177 insertions(+), 77 deletions(-) diff --git a/components/esp_wifi/include/esp_wifi_types_generic.h b/components/esp_wifi/include/esp_wifi_types_generic.h index 74701d77c14..2db706e263d 100644 --- a/components/esp_wifi/include/esp_wifi_types_generic.h +++ b/components/esp_wifi/include/esp_wifi_types_generic.h @@ -46,11 +46,13 @@ typedef enum { typedef enum { WIFI_OFFCHAN_TX_CANCEL, /**< Cancel off-channel transmission */ WIFI_OFFCHAN_TX_REQ, /**< Request off-channel transmission */ + WIFI_OFFCHAN_TX_CONNECTING_REQ, /**< Off-channel Tx request during connecting state; not recommended for use by public APIs */ } wifi_action_tx_t; typedef enum { WIFI_ROC_CANCEL, /**< Cancel remain on channel */ WIFI_ROC_REQ, /**< Request remain on channel */ + WIFI_ROC_CONNECTING_REQ, /**< Remain-on-channel request during connecting state; not recommended for use by public APIs */ } wifi_roc_t; /** * @brief Wi-Fi country policy @@ -82,6 +84,9 @@ typedef struct { * Strength of authmodes * Personal Networks : OPEN < WEP < WPA_PSK < OWE < WPA2_PSK = WPA_WPA2_PSK < WAPI_PSK < WPA3_PSK = WPA2_WPA3_PSK = DPP * Enterprise Networks : WIFI_AUTH_WPA_ENTERPRISE < WIFI_AUTH_WPA2_ENTERPRISE < WIFI_AUTH_WPA3_ENTERPRISE = WIFI_AUTH_WPA2_WPA3_ENTERPRISE < WIFI_AUTH_WPA3_ENT_192 + * + * @note WIFI_AUTH_UNKNOWN indicates an Access Point with invalid or unparseable security configuration + * detected during scan parsing. */ typedef enum { WIFI_AUTH_OPEN = 0, /**< Authenticate mode : open */ @@ -102,6 +107,7 @@ typedef enum { WIFI_AUTH_WPA3_ENTERPRISE, /**< Authenticate mode : WPA3-Enterprise Only Mode */ WIFI_AUTH_WPA2_WPA3_ENTERPRISE, /**< Authenticate mode : WPA3-Enterprise Transition Mode */ WIFI_AUTH_WPA_ENTERPRISE, /**< Authenticate mode : WPA-Enterprise security */ + WIFI_AUTH_UNKNOWN, /**< Scan parsed authmode: Unknown or invalid security configuration parsed during scan */ WIFI_AUTH_MAX } wifi_auth_mode_t; @@ -337,7 +343,8 @@ typedef struct { uint32_t wps: 1; /**< Bit: 7 flag to identify if WPS is supported or not */ uint32_t ftm_responder: 1; /**< Bit: 8 flag to identify if FTM is supported in responder mode */ uint32_t ftm_initiator: 1; /**< Bit: 9 flag to identify if FTM is supported in initiator mode */ - uint32_t reserved: 22; /**< Bit: 10..31 reserved */ + uint32_t akm_dpp: 1; /**< Bit: 10 flag set when AP supports mixed DPP AKM (e.g., SAE + DPP or WPA2-PSK + DPP) or when AP only supports DPP AKM */ + uint32_t reserved: 21; /**< Bit: 11..31 reserved */ wifi_country_t country; /**< Country information of AP */ wifi_he_ap_info_t he_ap; /**< HE AP info */ wifi_bandwidth_t bandwidth; /**< Bandwidth of AP */ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index a002e3cab43..edd72ed3794 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit a002e3cab4317cd20cf7146402372d1051fbe1cc +Subproject commit edd72ed379485408b8c501397953e23872eabfdc diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h b/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h index 0346ee71f5f..e44ecd69d2d 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h +++ b/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h @@ -82,7 +82,9 @@ esp_err_t esp_supp_dpp_deinit(void); * Generates Out Of Band Bootstrap information as an Enrollee which can be * used by a DPP Configurator to provision the Enrollee. * - * @param chan_list List of channels device will be available on for listening + * @param chan_list Comma-separated list of channels for listening (must not be NULL). + * A single channel (e.g., "6") is recommended for reliable discovery. + * If using multiple, prefer non-overlapping channels (e.g., "1,6,11"). * @param type Bootstrap method type, only QR Code method is supported for now. * @param key (Optional) 32 byte Raw Private Key for generating a Bootstrapping Public Key * @param info (Optional) Ancillary Device Information like Serial Number diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index 0d4b3fc3735..f7e37997450 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -42,12 +42,22 @@ static struct esp_dpp_context_t s_dpp_ctx; static int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel); static wifi_action_rx_cb_t s_action_rx_cb = esp_supp_rx_action; static uint8_t s_current_tx_op_id; +enum dpp_tx_frame_type { + DPP_TX_INVALID = 0, + DPP_TX_AUTHENTICATION_RESP, + DPP_TX_PEER_DISCOVERY_REQ, + DPP_TX_GAS_CONFIG_REQ, +}; +static enum dpp_tx_frame_type s_current_tx_type; + static void tx_status_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void roc_status_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void dpp_listen_next_channel(void *data, void *user_ctx); +static void dpp_cancel_auth_gas_timeouts(struct dpp_authentication *auth); static void esp_dpp_cancel_timeouts(void); +static void esp_dpp_auth_resp_retry(void *eloop_ctx, void *timeout_ctx); static esp_err_t dpp_api_lock(void) { @@ -99,9 +109,11 @@ static void dpp_event_handler(void *arg, esp_event_base_t event_base, static uint8_t dpp_deinit_auth(void) { if (s_dpp_ctx.dpp_auth) { + dpp_cancel_auth_gas_timeouts(s_dpp_ctx.dpp_auth); dpp_auth_deinit(s_dpp_ctx.dpp_auth); s_dpp_ctx.dpp_auth = NULL; } + s_current_tx_type = DPP_TX_INVALID; return ESP_OK; } @@ -152,7 +164,8 @@ static void esp_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx) } esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len, - uint8_t channel, uint32_t wait_time_ms) + uint8_t channel, uint32_t wait_time_ms, + enum dpp_tx_frame_type type) { wifi_action_tx_req_t *req = os_zalloc(sizeof(*req) + len); if (!req) { @@ -167,7 +180,8 @@ esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint3 req->channel = channel; req->sec_channel = WIFI_SECOND_CHAN_NONE; req->wait_time_ms = wait_time_ms; - req->type = WIFI_OFFCHAN_TX_REQ; + req->type = (type == DPP_TX_PEER_DISCOVERY_REQ) ? WIFI_OFFCHAN_TX_CONNECTING_REQ + : WIFI_OFFCHAN_TX_REQ; os_memcpy(req->data, buf, req->data_len); wpa_printf(MSG_DEBUG, "DPP: Mgmt Tx - MAC:" MACSTR ", Channel-%d, WaitT-%d", @@ -182,6 +196,7 @@ esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint3 wpa_printf(MSG_DEBUG, "Sent DPP action frame %d", req->op_id); s_current_tx_op_id = req->op_id; + s_current_tx_type = type; os_free(req); return ESP_OK; } @@ -204,7 +219,8 @@ static void esp_dpp_auth_resp_retry_timeout(void *eloop_ctx, void *timeout_ctx) esp_dpp_send_action_frame(s_dpp_ctx.dpp_auth->peer_mac_addr, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg), wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg), - auth->curr_chan, 1000 + OFFCHAN_TX_WAIT_TIME); + auth->curr_chan, 1000 + OFFCHAN_TX_WAIT_TIME, + DPP_TX_AUTHENTICATION_RESP); } static esp_err_t esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_data) @@ -250,8 +266,14 @@ static esp_err_t esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t * return ESP_ERR_DPP_INVALID_ATTR; } if (s_dpp_ctx.dpp_auth) { - wpa_printf(MSG_DEBUG, "DPP: Already in DPP authentication exchange - ignore new one"); - return ESP_OK; + if (s_dpp_ctx.dpp_auth->auth_success || !s_dpp_ctx.dpp_auth->waiting_auth_conf) { + wpa_printf(MSG_INFO, "DPP: Cleaning up old completed DPP auth context for new exchange"); + dpp_cancel_auth_gas_timeouts(s_dpp_ctx.dpp_auth); + dpp_deinit_auth(); + } else { + wpa_printf(MSG_DEBUG, "DPP: Already in DPP authentication exchange - ignore new one"); + return ESP_OK; + } } s_dpp_ctx.dpp_auth = dpp_auth_req_rx(NULL, DPP_CAPAB_ENROLLEE, 0, NULL, own_bi, rx_param->channel, @@ -267,12 +289,14 @@ static esp_err_t esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t * } os_memcpy(s_dpp_ctx.dpp_auth->peer_mac_addr, rx_param->sa, ETH_ALEN); - wpa_printf(MSG_INFO, "DPP: Sending authentication response chan(%d)", rx_param->channel); + wpa_printf(MSG_INFO, "DPP: Sending authentication response chan(%d)", + s_dpp_ctx.dpp_auth->curr_chan); eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); eloop_register_timeout(0, 200000, esp_dpp_auth_resp_retry_timeout, NULL, NULL); esp_dpp_send_action_frame(rx_param->sa, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg), wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg), - rx_param->channel, 1000 + OFFCHAN_TX_WAIT_TIME); + s_dpp_ctx.dpp_auth->curr_chan, 1000 + OFFCHAN_TX_WAIT_TIME, + DPP_TX_AUTHENTICATION_RESP); return ESP_OK; } @@ -312,7 +336,8 @@ static int gas_query_req_tx(struct dpp_authentication *auth) MAC2STR(auth->peer_mac_addr), auth->curr_chan); ret = esp_dpp_send_action_frame(auth->peer_mac_addr, wpabuf_head(buf), wpabuf_len(buf), - auth->curr_chan, 1000 + OFFCHAN_TX_WAIT_TIME); + auth->curr_chan, 1000 + OFFCHAN_TX_WAIT_TIME, + DPP_TX_GAS_CONFIG_REQ); if (ret != ESP_OK) { wpabuf_free(buf); return ret; @@ -334,13 +359,24 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth, os_memcpy(wifi_cfg->sta.ssid, conf->ssid, conf->ssid_len); } - if (dpp_akm_legacy(conf->akm)) { + if (dpp_akm_legacy(conf->akm) || dpp_akm_ver2(conf->akm)) { if (conf->passphrase[0]) os_memcpy(wifi_cfg->sta.password, conf->passphrase, sizeof(wifi_cfg->sta.password)); - if (conf->akm == DPP_AKM_PSK_SAE) { - wifi_cfg->sta.pmf_cfg.required = true; - } + } + + if (dpp_akm_sae(conf->akm) || dpp_akm_dpp(conf->akm)) { + wifi_cfg->sta.pmf_cfg.capable = true; + wifi_cfg->sta.pmf_cfg.required = true; + } + + if (dpp_akm_dpp(conf->akm)) { + wifi_cfg->sta.threshold.authmode = WIFI_AUTH_DPP; + esp_wifi_sta_notify_dpp_config_set_internal(true); + } else if (dpp_akm_sae(conf->akm)) { + wifi_cfg->sta.threshold.authmode = WIFI_AUTH_WPA3_PSK; + } else if (dpp_akm_psk(conf->akm)) { + wifi_cfg->sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; } if (conf->connector) { @@ -355,8 +391,6 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth, if (atomic_load(&roc_in_progress)) { listen_stop_handler(NULL, NULL); } - /* deinit AUTH since authentication is done */ - dpp_deinit_auth(); wifi_event_dpp_config_received_t event = {0}; event.wifi_cfg = s_dpp_ctx.wifi_cfg; @@ -388,6 +422,8 @@ static int esp_dpp_rx_auth_conf(struct action_rx_param *rx_param, uint8_t *dpp_d } eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); + eloop_cancel_timeout(esp_dpp_auth_resp_retry, NULL, NULL); if (dpp_auth_conf_rx(auth, (const u8 *)&public_action->v, dpp_data, len) < 0) { @@ -440,6 +476,9 @@ static esp_err_t esp_dpp_rx_peer_disc_resp(struct action_rx_param *rx_param) wpa_printf(MSG_DEBUG, "DPP: Peer Discovery from " MACSTR, MAC2STR(rx_param->sa)); + eloop_cancel_timeout(gas_query_timeout, NULL, s_dpp_ctx.dpp_auth); + s_dpp_ctx.peer_disc_resp_received = true; + for (i = 0; i < auth->num_conf_obj; i++) { if (!auth->conf_obj[i].connector @@ -503,7 +542,7 @@ static esp_err_t esp_dpp_rx_peer_disc_resp(struct action_rx_param *rx_param) os_get_reltime(&rnow); entry->expiration = rnow.sec + seconds; entry->reauth_time = rnow.sec + seconds; - entry->network_ctx = auth; + entry->network_ctx = gWpaSm.network_ctx; pmksa_cache_add_entry(sm->pmksa, entry); @@ -517,9 +556,10 @@ static esp_err_t esp_dpp_rx_peer_disc_resp(struct action_rx_param *rx_param) goto fail; } - wpa_printf(MSG_DEBUG, - "DPP: Try connection after successful network introduction"); - dpp_connect(rx_param->sa, true); + if (dpp_connect(rx_param->sa, true) != ESP_OK) { + wpa_printf(MSG_ERROR, "DPP: Failed to trigger connection after Peer Discovery"); + goto fail; + } return ESP_OK; fail: os_memset(&intro, 0, sizeof(intro)); @@ -565,7 +605,7 @@ static esp_err_t gas_query_resp_rx(struct action_rx_param *rx_param) uint8_t *pos = rx_param->action_frm->u.public_action.v.pa_gas_resp.data; uint8_t *resp = &pos[10]; /* first byte of DPP attributes */ size_t vendor_len = rx_param->vendor_data_len; - int i, res; + int res; /* Basic structural checks on the Advertisement Protocol payload */ if (!(pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 && @@ -585,8 +625,8 @@ static esp_err_t gas_query_resp_rx(struct action_rx_param *rx_param) goto fail; } - for (i = 0; i < auth->num_conf_obj; i++) { - res = esp_dpp_handle_config_obj(auth, &auth->conf_obj[i]); + if (auth->num_conf_obj > 0) { + res = esp_dpp_handle_config_obj(auth, &auth->conf_obj[0]); if (res < 0) { wpa_printf(MSG_INFO, "DPP: Configuration parsing failed"); goto fail; @@ -856,10 +896,19 @@ static void esp_dpp_auth_resp_retry(void *eloop_ctx, void *timeout_ctx) esp_dpp_auth_resp_retry_timeout(NULL, NULL); } +static void dpp_cancel_auth_gas_timeouts(struct dpp_authentication *auth) +{ + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); + eloop_cancel_timeout(esp_dpp_auth_resp_retry, NULL, NULL); + eloop_cancel_timeout(gas_query_timeout, NULL, auth); +} + static void tx_status_eloop_handler(void *eloop_ctx, void *event_data) { struct dpp_authentication *auth = s_dpp_ctx.dpp_auth; wifi_event_action_tx_status_t *evt = event_data; + enum dpp_tx_frame_type type = s_current_tx_type; if (!evt) { return; @@ -877,24 +926,41 @@ static void tx_status_eloop_handler(void *eloop_ctx, void *event_data) evt->op_id, s_current_tx_op_id); } else if (!auth) { wpa_printf(MSG_DEBUG, "Auth already deinitialized, return"); - } else if (auth->waiting_auth_conf) { - eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); - if (evt->status == WIFI_ACTION_TX_FAILED) { - /* failed to send auth response frame */ - eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); - eloop_register_timeout(1, 0, esp_dpp_auth_resp_retry, NULL, NULL); - } else if (evt->status == WIFI_ACTION_TX_DONE) { - eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); - eloop_register_timeout(ESP_DPP_AUTH_TIMEOUT_SECS, 0, esp_dpp_auth_conf_wait_timeout, NULL, NULL); - } - } else if (auth->auth_success) { - if (evt->status == WIFI_ACTION_TX_FAILED) { - /* failed to send gas query frame, retry logic needed? */ - wpa_printf(MSG_WARNING, "DPP: failed to send GAS query frame"); - dpp_abort_with_failure(ESP_ERR_DPP_TX_FAILURE); - } else if (evt->status == WIFI_ACTION_TX_DONE) { - eloop_cancel_timeout(gas_query_timeout, NULL, auth); - eloop_register_timeout(ESP_GAS_TIMEOUT_SECS, 0, gas_query_timeout, NULL, auth); + } else { + if (type == DPP_TX_AUTHENTICATION_RESP) { + eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); + if (evt->status == WIFI_ACTION_TX_FAILED) { + /* failed to send auth response frame */ + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + eloop_register_timeout(1, 0, esp_dpp_auth_resp_retry, NULL, NULL); + } else if (evt->status == WIFI_ACTION_TX_DONE) { + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + eloop_register_timeout(ESP_DPP_AUTH_TIMEOUT_SECS, 0, esp_dpp_auth_conf_wait_timeout, NULL, NULL); + } + } else if (type == DPP_TX_GAS_CONFIG_REQ) { + if (evt->status == WIFI_ACTION_TX_FAILED) { + wpa_printf(MSG_WARNING, "DPP: failed to send GAS query frame"); + dpp_abort_with_failure(ESP_ERR_DPP_TX_FAILURE); + } else if (evt->status == WIFI_ACTION_TX_DONE) { + eloop_cancel_timeout(gas_query_timeout, NULL, auth); + eloop_register_timeout(ESP_GAS_TIMEOUT_SECS, 0, gas_query_timeout, NULL, auth); + } + } else if (type == DPP_TX_PEER_DISCOVERY_REQ) { + if (evt->status == WIFI_ACTION_TX_FAILED) { + if (!s_dpp_ctx.peer_disc_resp_received) { + wpa_printf(MSG_WARNING, "DPP: failed to send Peer Discovery frame"); + dpp_abort_with_failure(ESP_ERR_DPP_TX_FAILURE); + } else { + wpa_printf(MSG_MSGDUMP, "Peer Discovery frame failed, but Peer Discovery Response already received. Ignore"); + } + } else if (evt->status == WIFI_ACTION_TX_DONE) { + eloop_cancel_timeout(gas_query_timeout, NULL, auth); + if (!s_dpp_ctx.peer_disc_resp_received) { + eloop_register_timeout(ESP_GAS_TIMEOUT_SECS, 0, gas_query_timeout, NULL, auth); + } else { + wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Response already received, skip registering timeout"); + } + } } } os_free(evt); @@ -931,7 +997,7 @@ static void roc_status_eloop_handler(void *eloop_ctx, void *event_data) } if (evt) { - if (evt->context == (uint32_t)s_action_rx_cb) { + if (evt->context == (uint32_t)s_action_rx_cb && s_dpp_ctx.dpp_listen_ongoing) { eloop_cancel_timeout(dpp_listen_next_channel, NULL, NULL); eloop_register_timeout(0, 0, dpp_listen_next_channel, NULL, NULL); } @@ -1141,10 +1207,7 @@ static void dpp_listen_start(void *ctx, void *data) static void esp_dpp_cancel_timeouts(void) { eloop_cancel_timeout(dpp_listen_next_channel, NULL, NULL); - eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); - eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); - eloop_cancel_timeout(esp_dpp_auth_resp_retry, NULL, NULL); - eloop_cancel_timeout(gas_query_timeout, ELOOP_ALL_CTX, ELOOP_ALL_CTX); + dpp_cancel_auth_gas_timeouts(s_dpp_ctx.dpp_auth); eloop_cancel_timeout(dpp_listen_start, NULL, NULL); } @@ -1217,6 +1280,7 @@ static int esp_dpp_init(void *eloop_data, void *user_ctx) atomic_store(&dpp_shutting_down, false); atomic_store(&roc_in_progress, false); s_current_tx_op_id = 0; + s_current_tx_type = DPP_TX_INVALID; s_dpp_ctx.dpp_global = dpp_global_init(&cfg); if (!s_dpp_ctx.dpp_global) { @@ -1297,6 +1361,14 @@ esp_err_t esp_dpp_start_net_intro_protocol(uint8_t *bssid) struct wpabuf *buf = NULL; int ret = ESP_OK; + if (!auth) { + wpa_printf(MSG_ERROR, "DPP: net intro failed, no auth context"); + return ESP_ERR_INVALID_STATE; + } + + dpp_cancel_auth_gas_timeouts(auth); + s_dpp_ctx.peer_disc_resp_received = false; + for (int i = 0; i < auth->num_conf_obj; i++) { os_memcpy(auth->peer_mac_addr, bssid, ETH_ALEN); buf = dpp_build_peer_disc_req(auth, &auth->conf_obj[i]); @@ -1306,7 +1378,8 @@ esp_err_t esp_dpp_start_net_intro_protocol(uint8_t *bssid) } if (esp_dpp_send_action_frame(bssid, wpabuf_head(buf), wpabuf_len(buf), - auth->curr_chan, OFFCHAN_TX_WAIT_TIME) != ESP_OK) { + auth->curr_chan, OFFCHAN_TX_WAIT_TIME, + DPP_TX_PEER_DISCOVERY_REQ) != ESP_OK) { ret = ESP_FAIL; } diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h index a0c6c9a4750..50efb7e9c2c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h @@ -41,6 +41,7 @@ struct esp_dpp_context_t { bool dpp_init_done; bool bootstrap_done; bool dpp_listen_ongoing; + bool peer_disc_resp_received; }; #ifdef CONFIG_TESTING_OPTIONS 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 5d2893383b3..a52c62daa1f 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -296,6 +296,7 @@ uint8_t esp_wifi_sta_get_config_sae_pk_internal(void); void esp_wifi_sta_disable_sae_pk_internal(void); void esp_wifi_sta_disable_wpa2_authmode_internal(void); void esp_wifi_sta_disable_owe_trans_internal(void); +void esp_wifi_sta_notify_dpp_config_set_internal(bool configured); uint8_t esp_wifi_ap_get_max_sta_conn(void); uint8_t esp_wifi_get_config_sae_pwe_h2e_internal(uint8_t ifx); bool esp_wifi_ap_notify_node_sae_auth_done(uint8_t *mac); 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 328b3d31f14..ab29a1e2684 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -262,7 +262,7 @@ int wpa_sta_connect(uint8_t *bssid) #ifdef CONFIG_DPP struct wpa_sm *sm = &gWpaSm; - if (sm->key_mgmt == WPA_KEY_MGMT_DPP) { + if (wpa_key_mgmt_dpp(sm->key_mgmt)) { ret = dpp_connect(bssid, false); } else #endif @@ -522,10 +522,23 @@ int esp_supplicant_init(void) esp_wifi_register_owe_cb(wpa_cb); #endif /* CONFIG_OWE_STA */ - eloop_init(); + if (eloop_init() != 0) { + wpa_printf(MSG_ERROR, "Failed to initialize eloop"); + os_free(wpa_cb); + wpa_cb = NULL; + return ESP_FAIL; + } + ret = esp_supplicant_common_init(wpa_cb); if (ret != 0) { + /* + * Note: We don't need to explicitly call eloop_destroy() here because + * returning an error causes the caller (esp_wifi_init) to trigger the + * deinit path, which invokes esp_supplicant_deinit() and frees the eloop. + */ + os_free(wpa_cb); + wpa_cb = NULL; return ret; } @@ -543,6 +556,7 @@ int esp_supplicant_deinit(void) esp_supplicant_common_deinit(); esp_supplicant_unset_all_appie(); eloop_destroy(); + /* wpa_cb is freed by esp_wifi_unregister_wpa_cb_internal() */ wpa_cb = NULL; #if CONFIG_ESP_WIFI_WAPI_PSK esp_wifi_internal_wapi_deinit(); diff --git a/components/wpa_supplicant/port/include/os.h b/components/wpa_supplicant/port/include/os.h index a2de76d46d0..44050907137 100644 --- a/components/wpa_supplicant/port/include/os.h +++ b/components/wpa_supplicant/port/include/os.h @@ -353,7 +353,7 @@ extern const wifi_osi_funcs_t *wifi_funcs; #define os_mutex_lock(a) wifi_funcs->_mutex_lock((a)) #define os_mutex_unlock(a) wifi_funcs->_mutex_unlock((a)) #define os_recursive_mutex_create() wifi_funcs->_recursive_mutex_create() -#define os_mutex_create() wifi_funcs->_mutex_create(); +#define os_mutex_create() wifi_funcs->_mutex_create() #define os_mutex_delete(a) wifi_funcs->_mutex_delete(a) #define os_queue_create(a, b) wifi_funcs->_queue_create((a), (b)) diff --git a/components/wpa_supplicant/src/common/defs.h b/components/wpa_supplicant/src/common/defs.h index 543f1bbd6b5..0427d980cd7 100644 --- a/components/wpa_supplicant/src/common/defs.h +++ b/components/wpa_supplicant/src/common/defs.h @@ -124,7 +124,7 @@ static inline int wpa_key_mgmt_owe(int akm) static inline int wpa_key_mgmt_dpp(int akm) { - return akm == WPA_KEY_MGMT_DPP; + return !!(akm & WPA_KEY_MGMT_DPP); } static inline int wpa_key_mgmt_wpa(int akm) diff --git a/components/wpa_supplicant/src/common/dpp.c b/components/wpa_supplicant/src/common/dpp.c index eb1fad5f029..85537d18fdf 100644 --- a/components/wpa_supplicant/src/common/dpp.c +++ b/components/wpa_supplicant/src/common/dpp.c @@ -1117,7 +1117,7 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx, { struct dpp_authentication *auth; size_t nonce_len; - size_t secret_len; + size_t secret_len = 0; struct wpabuf *pi = NULL; const u8 *r_pubkey_hash, *i_pubkey_hash; #ifdef CONFIG_TESTING_OPTIONS @@ -1475,7 +1475,7 @@ static void dpp_auth_success(struct dpp_authentication *auth) static int dpp_auth_build_resp_ok(struct dpp_authentication *auth) { size_t nonce_len; - size_t secret_len; + size_t secret_len = 0; struct wpabuf *msg, *pr = NULL; u8 r_auth[4 + DPP_MAX_HASH_LEN]; u8 wrapped_r_auth[4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE], *w_r_auth; @@ -1540,6 +1540,7 @@ static int dpp_auth_build_resp_ok(struct dpp_authentication *auth) if (dpp_ecdh(auth->own_protocol_key, auth->peer_protocol_key, auth->Nx, &secret_len) < 0) goto fail; + auth->secret_len = secret_len; wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)", auth->Nx, auth->secret_len); @@ -1727,7 +1728,7 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual, size_t attr_len) { struct crypto_ec_key *pi = NULL; - size_t secret_len; + size_t secret_len = 0; const u8 *addr[2]; size_t len[2]; u8 *unwrapped = NULL; @@ -1737,11 +1738,13 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual, const u8 *i_nonce; const u8 *i_capab; const u8 *i_bootstrap; + const u8 *channel; u16 wrapped_data_len; u16 i_proto_len; u16 i_nonce_len; u16 i_capab_len; u16 i_bootstrap_len; + u16 channel_len; struct dpp_authentication *auth = NULL; #ifdef CONFIG_TESTING_OPTIONS u64 start_us = dpp_time_us(); @@ -1781,37 +1784,30 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual, auth->peer_version = 1; /* default to the first version */ -#if 0 channel = dpp_get_attr(attr_start, attr_len, DPP_ATTR_CHANNEL, &channel_len); if (channel) { - //int neg_freq; - if (channel_len < 2) { dpp_auth_fail(auth, "Too short Channel attribute"); goto fail; } - neg_freq = ieee80211_chan_to_freq(NULL, channel[0], channel[1]); wpa_printf(MSG_DEBUG, - "DPP: Initiator requested different channel for negotiation: op_class=%u channel=%u --> freq=%d", - channel[0], channel[1], neg_freq); - if (neg_freq < 0) { + "DPP: Initiator requested different channel for negotiation: op_class=%u channel=%u", + channel[0], channel[1]); + if (!channel[0] || !channel[1]) { dpp_auth_fail(auth, "Unsupported Channel attribute value"); goto fail; } - if (auth->curr_freq != (unsigned int) neg_freq) { + if (auth->curr_chan != channel[1]) { wpa_printf(MSG_DEBUG, - "DPP: Changing negotiation channel from %u MHz to %u MHz", - freq, neg_freq); - auth->curr_freq = neg_freq; + "DPP: Changing negotiation channel from %u to %u", + auth->curr_chan, channel[1]); } - /* rename it to chan */ - auth->curr_chan = *channel; + auth->curr_chan = channel[1]; } -#endif i_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_I_PROTOCOL_KEY, &i_proto_len); @@ -2297,7 +2293,7 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr, const u8 *attr_start, size_t attr_len) { struct crypto_ec_key *pr; - size_t secret_len; + size_t secret_len = 0; const u8 *addr[2]; size_t len[2]; u8 *unwrapped = NULL, *unwrapped2 = NULL; @@ -2432,6 +2428,7 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr, dpp_auth_fail(auth, "Failed to derive ECDH shared secret"); goto fail; } + auth->secret_len = secret_len; crypto_ec_key_deinit(auth->peer_protocol_key); auth->peer_protocol_key = pr; pr = NULL; @@ -3432,7 +3429,7 @@ skip_groups: if (!hash) { goto fail; } - if (dpp_get_config_obj_hash(signed1, signed1_len, signed2, signed1_len, hash, curve->hash_len) < 0) + if (dpp_get_config_obj_hash(signed1, signed1_len, signed2, signed2_len, hash, curve->hash_len) < 0) goto fail; r = crypto_bignum_init(); @@ -4861,7 +4858,7 @@ dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, struct wpabuf *own_key_pub = NULL; const struct dpp_curve_params *curve, *own_curve; struct dpp_signed_connector_info info; - size_t Nx_len; + size_t Nx_len = 0; u8 Nx[DPP_MAX_SHARED_SECRET_LEN]; os_memset(intro, 0, sizeof(*intro)); diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index 6f9485760ba..17d07157de5 100644 --- a/components/wpa_supplicant/src/common/wpa_common.c +++ b/components/wpa_supplicant/src/common/wpa_common.c @@ -864,7 +864,7 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce, int wpa_use_akm_defined(int akmp){ return akmp == WPA_KEY_MGMT_OSEN || akmp == WPA_KEY_MGMT_OWE || - akmp == WPA_KEY_MGMT_DPP || + wpa_key_mgmt_dpp(akmp) || wpa_key_mgmt_sae(akmp) || wpa_key_mgmt_suite_b(akmp); } @@ -882,7 +882,7 @@ int wpa_use_aes_key_wrap(int akmp) { return akmp == WPA_KEY_MGMT_OSEN || akmp == WPA_KEY_MGMT_OWE || - akmp == WPA_KEY_MGMT_DPP || + wpa_key_mgmt_dpp(akmp) || wpa_key_mgmt_ft(akmp) || wpa_key_mgmt_sha256(akmp) || wpa_key_mgmt_sae(akmp) || diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 6ac64d0ab79..ed24a0c1660 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -857,7 +857,8 @@ void wpa_supplicant_key_neg_complete(struct wpa_sm *sm, sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX, MLME_SETPROTECTION_KEY_TYPE_PAIRWISE); - if (wpa_key_mgmt_wpa_psk(sm->key_mgmt) || sm->key_mgmt == WPA_KEY_MGMT_OWE || sm->key_mgmt == WPA_KEY_MGMT_DPP) + if (wpa_key_mgmt_wpa_psk(sm->key_mgmt) || sm->key_mgmt == WPA_KEY_MGMT_OWE || + wpa_key_mgmt_dpp(sm->key_mgmt)) eapol_sm_notify_eap_success(TRUE); /* * Start preauthentication after a short wait to avoid a @@ -2352,6 +2353,10 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher, use_pmk_cache = false; } + if (wpa_key_mgmt_dpp(sm->key_mgmt)) { + use_pmk_cache = true; + } + if (os_memcmp(sm->ssid, ssid, ssid_len) == 0) { wpa_printf(MSG_DEBUG, "reassoc same ess and okc is %d", sm->okc); if (sm->okc == 1) { @@ -2504,13 +2509,13 @@ wpa_set_passphrase(char * passphrase, u8 *ssid, size_t ssid_len) if (sm->key_mgmt == WPA_KEY_MGMT_SAE || sm->key_mgmt == WPA_KEY_MGMT_OWE || sm->key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY || - sm->key_mgmt == WPA_KEY_MGMT_DPP) + wpa_key_mgmt_dpp(sm->key_mgmt)) return; /* This is really SLOW, so just re cacl while reset param */ if (esp_wifi_sta_get_reset_nvs_pmk_internal() != 0) { // check it's psk - if (strlen((char *)esp_wifi_sta_get_prof_password_internal()) == 64) { + if (os_strlen((char *)esp_wifi_sta_get_prof_password_internal()) == 64) { if (hexstr2bin((char *)esp_wifi_sta_get_prof_password_internal(), esp_wifi_sta_get_ap_info_prof_pmk_internal(), PMK_LEN) != 0) return;