diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index dd1019d8462..618653ee3d0 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -693,7 +693,7 @@ hal_agreement_del_rx_ba = 0x40001e14; /*hal_crypto_set_key_entry = 0x40001e18;*/ hal_crypto_get_key_entry = 0x40001e1c; hal_crypto_clr_key_entry = 0x40001e20; -config_get_wifi_task_stack_size = 0x40001e24; +/*config_get_wifi_task_stack_size = 0x40001e24;*/ pp_create_task = 0x40001e28; hal_set_sta_tsf_wakeup = 0x40001e2c; hal_set_rx_beacon_pti = 0x40001e30; diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 0f8109d8d60..d37c9da0e6e 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -122,6 +122,7 @@ typedef struct { bool dump_hesigb_enable; /**< enable dump sigb field */ bool privacy_enhancements; /**< WiFi privacy enhancements (enables random mac, seq number, dialogue token number, vendor seq number cnt). Supported on station interface only; softAP may be added in future */ uint8_t rmac_auto_reset_int; /**< Random MAC auto-reset interval in hours (1-24) while not connected */ + int wifi_task_stack_size; /**< WIFI task stack size */ int magic; /**< WiFi init magic number, it should be the last field */ } wifi_init_config_t; @@ -298,6 +299,24 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs; #define WIFI_ENABLE_OWE_SOFTAP 0 #endif +#if CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA +#define WIFI_ENABLE_WPA3_OWE_STA (1<<11) +#else +#define WIFI_ENABLE_WPA3_OWE_STA 0 +#endif + +#if CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA || CONFIG_ESP_WIFI_ENABLE_WPA3_SAE +#define WIFI_TASK_STACK_SIZE_BASE 6144 +#else +#define WIFI_TASK_STACK_SIZE_BASE 3072 +#endif + +#if !WIFI_NANO_FORMAT_ENABLED +#define WIFI_TASK_STACK_SIZE (WIFI_TASK_STACK_SIZE_BASE + 512) +#else +#define WIFI_TASK_STACK_SIZE WIFI_TASK_STACK_SIZE_BASE +#endif + #define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0) #define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1) #define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2) @@ -309,6 +328,7 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs; #define CONFIG_FEATURE_BSS_MAX_IDLE_BIT (1<<8) #define CONFIG_FEATURE_WIFI_PASSIVE_HIDDEN_AP_BIT (1<<9) #define CONFIG_FEATURE_OWE_SOFTAP_BIT (1<<10) +#define CONFIG_FEATURE_WPA3_OWE_STA_BIT (1<<11) /* Set additional WiFi features and capabilities */ #define WIFI_FEATURE_CAPS (WIFI_ENABLE_WPA3_SAE | \ @@ -321,7 +341,8 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs; WIFI_ENABLE_ENTERPRISE | \ WIFI_ENABLE_BSS_MAX_IDLE | \ WIFI_ENABLE_PASSIVE_HIDDEN_AP | \ - WIFI_ENABLE_OWE_SOFTAP) + WIFI_ENABLE_OWE_SOFTAP | \ + WIFI_ENABLE_WPA3_OWE_STA) #if CONFIG_ESP_WIFI_PRIVACY_ENHANCEMENTS_ENABLED #define WIFI_PRIVACY_ENHANCEMENTS_ENABLED true @@ -363,6 +384,7 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs; .dump_hesigb_enable = WIFI_DUMP_HESIGB_ENABLED, \ .privacy_enhancements = WIFI_PRIVACY_ENHANCEMENTS_ENABLED, \ .rmac_auto_reset_int = WIFI_RMAC_AUTO_RESET_INTERVAL, \ + .wifi_task_stack_size = WIFI_TASK_STACK_SIZE, \ .magic = WIFI_INIT_CONFIG_MAGIC\ } @@ -483,13 +505,14 @@ esp_err_t esp_wifi_restore(void); * @attention 4. This API attempts to connect to an Access Point (AP) only once. To enable reconnection in case of a connection failure, please use * the 'failure_retry_cnt' feature in the 'wifi_sta_config_t'. Users are suggested to implement reconnection logic in their application * for scenarios where the specified AP does not exist, or reconnection is desired after the device has received a disconnect event. + * @attention 5. This API will return ESP_ERR_WIFI_CONN if the station is already in CONNECTING state. * * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start * - ESP_ERR_WIFI_MODE: WiFi mode error - * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong, or station is already in CONNECTING state * - ESP_ERR_WIFI_SSID: SSID of AP which station connects is invalid */ esp_err_t esp_wifi_connect(void); @@ -1829,28 +1852,38 @@ esp_err_t esp_wifi_get_bandwidths(wifi_interface_t ifx, wifi_bandwidths_t *bw); /** * @brief Send action frame on target channel * + * @attention 1. This API will return ESP_FAIL when called for STA interface (req->ifx == WIFI_IF_STA) + * while the station is in CONNECTING state. + * @attention 2. When PMF is enabled, broadcast action frames must be non-robust. + * @attention 3. wait_time_ms must be greater than 0. If wait_time_ms is 0, the API returns ESP_ERR_WIFI_ARG. + * * @param req action tx request structure containing relevant fields * * @return * - ESP_OK: succeed * - ESP_ERR_NO_MEM: failed to allocate memory - * - ESP_ERR_INVALID_ARG: the pair is invalid - * - ESP_FAIL: failed to send frame + * - ESP_ERR_WIFI_MODE: WiFi mode is wrong + * - ESP_ERR_WIFI_ARG: the pair is invalid or destination MAC address is all zeros, or wait_time_ms is 0 + * - ESP_FAIL: failed to send frame or STA is in CONNECTING state */ esp_err_t esp_wifi_action_tx_req(wifi_action_tx_req_t *req); /** * @brief Remain on the target channel for required duration * - * @attention 1. The API returns ESP_ERR_INVALID_ARG when `req->allow_broadcast` is true and the device operates in AP+STA mode. + * @attention 1. The API returns ESP_ERR_WIFI_ARG when `req->allow_broadcast` is true and the device operates in AP+STA mode. + * @attention 2. The API returns ESP_FAIL when called for STA interface (req->ifx == WIFI_IF_STA) + * while the station is in CONNECTING state. + * @attention 3. wait_time_ms must be greater than 0 for WIFI_ROC_REQ only. * * @param req roc request structure containing relevant fields * * @return * - ESP_OK: succeed * - ESP_ERR_NO_MEM: failed to allocate memory - * - ESP_ERR_INVALID_ARG: the pair is invalid - * - ESP_FAIL: failed to perform roc operation + * - ESP_ERR_WIFI_MODE: WiFi mode is wrong + * - ESP_ERR_WIFI_ARG: the pair is invalid, allow_broadcast is true in AP+STA mode, or wait_time_ms is 0 for WIFI_ROC_REQ + * - ESP_FAIL: failed to perform roc operation or STA is in CONNECTING state */ esp_err_t esp_wifi_remain_on_channel(wifi_roc_req_t * req); diff --git a/components/esp_wifi/include/esp_wifi_types_generic.h b/components/esp_wifi/include/esp_wifi_types_generic.h index 0469df0e63e..838d40b9417 100644 --- a/components/esp_wifi/include/esp_wifi_types_generic.h +++ b/components/esp_wifi/include/esp_wifi_types_generic.h @@ -199,7 +199,8 @@ typedef enum { .scan_time.active.min = WIFI_ACTIVE_SCAN_MIN_DEFAULT_TIME, \ .scan_time.active.max = WIFI_ACTIVE_SCAN_MAX_DEFAULT_TIME, \ .scan_time.passive = WIFI_PASSIVE_SCAN_DEFAULT_TIME, \ - .home_chan_dwell_time = WIFI_SCAN_HOME_CHANNEL_DWELL_DEFAULT_TIME\ + .home_chan_dwell_time = WIFI_SCAN_HOME_CHANNEL_DWELL_DEFAULT_TIME, \ + .max_offchan_duration_ms = 0 \ } /** @@ -265,6 +266,7 @@ typedef struct { typedef struct { wifi_scan_time_t scan_time; /**< Scan time per channel */ uint8_t home_chan_dwell_time;/**< Time spent at home channel between scanning consecutive channels.*/ + uint16_t max_offchan_duration_ms; /**< Maximum accumulated off-channel scan duration before returning to home channel (0 = use WIFI_ACTIVE_SCAN_MAX_DEFAULT_TIME, range: 1-4500ms). */ } wifi_scan_default_params_t; /** @@ -832,7 +834,7 @@ typedef struct { wifi_action_tx_t type; /**< ACTION TX operation type */ uint8_t channel; /**< Channel on which to perform ACTION TX Operation */ wifi_second_chan_t sec_channel; /**< Secondary channel */ - uint32_t wait_time_ms; /**< Duration to wait for on target channel */ + uint32_t wait_time_ms; /**< Duration to wait for on target channel (must be greater than 0) */ bool no_ack; /**< Indicates no ack required */ wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive action frames */ uint8_t op_id; /**< Unique Identifier for operation provided by wifi driver */ @@ -868,7 +870,7 @@ typedef struct { wifi_roc_t type; /**< ROC operation type */ uint8_t channel; /**< Channel on which to perform ROC Operation */ wifi_second_chan_t sec_channel; /**< Secondary channel */ - uint32_t wait_time_ms; /**< Duration to wait for on target channel */ + uint32_t wait_time_ms; /**< Duration to wait for on target channel (must be greater than 0 for WIFI_ROC_REQ only) */ wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive action mgmt frames */ uint8_t op_id; /**< ID of this specific ROC operation provided by wifi driver */ wifi_action_roc_done_cb_t done_cb; /**< Callback to function that will be called upon ROC done. If assigned, WIFI_EVENT_ROC_DONE event will not be posted */ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 9e91edcb2e6..de151f5eb98 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 9e91edcb2e64b5b137c78c9755296f97f414050c +Subproject commit de151f5eb98969915e4ab56d9d0bbcdf539acf4d diff --git a/components/esp_wifi/remote/include/injected/esp_wifi.h b/components/esp_wifi/remote/include/injected/esp_wifi.h index b043ccf4cb8..9d91f39cc8d 100644 --- a/components/esp_wifi/remote/include/injected/esp_wifi.h +++ b/components/esp_wifi/remote/include/injected/esp_wifi.h @@ -122,6 +122,7 @@ typedef struct { bool dump_hesigb_enable; /**< enable dump sigb field */ bool privacy_enhancements; /**< WiFi privacy enhancements (enables random mac, seq number, dialogue token number, vendor seq number cnt). Supported on station interface only; softAP may be added in future */ uint8_t rmac_auto_reset_int; /**< Random MAC auto-reset interval in hours (1-24) while not connected */ + int wifi_task_stack_size; /**< WIFI task stack size */ int magic; /**< WiFi init magic number, it should be the last field */ } wifi_init_config_t; @@ -298,6 +299,24 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs; #define WIFI_ENABLE_OWE_SOFTAP 0 #endif +#if CONFIG_WIFI_RMT_ENABLE_WPA3_OWE_STA +#define WIFI_ENABLE_WPA3_OWE_STA (1<<11) +#else +#define WIFI_ENABLE_WPA3_OWE_STA 0 +#endif + +#if CONFIG_WIFI_RMT_ENABLE_WPA3_OWE_STA || CONFIG_WIFI_RMT_ENABLE_WPA3_SAE +#define WIFI_TASK_STACK_SIZE_BASE 6144 +#else +#define WIFI_TASK_STACK_SIZE_BASE 3072 +#endif + +#if !WIFI_NANO_FORMAT_ENABLED +#define WIFI_TASK_STACK_SIZE (WIFI_TASK_STACK_SIZE_BASE + 512) +#else +#define WIFI_TASK_STACK_SIZE WIFI_TASK_STACK_SIZE_BASE +#endif + #define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0) #define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1) #define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2) @@ -309,6 +328,7 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs; #define CONFIG_FEATURE_BSS_MAX_IDLE_BIT (1<<8) #define CONFIG_FEATURE_WIFI_PASSIVE_HIDDEN_AP_BIT (1<<9) #define CONFIG_FEATURE_OWE_SOFTAP_BIT (1<<10) +#define CONFIG_FEATURE_WPA3_OWE_STA_BIT (1<<11) /* Set additional WiFi features and capabilities */ #define WIFI_FEATURE_CAPS (WIFI_ENABLE_WPA3_SAE | \ @@ -321,7 +341,8 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs; WIFI_ENABLE_ENTERPRISE | \ WIFI_ENABLE_BSS_MAX_IDLE | \ WIFI_ENABLE_PASSIVE_HIDDEN_AP | \ - WIFI_ENABLE_OWE_SOFTAP) + WIFI_ENABLE_OWE_SOFTAP | \ + WIFI_ENABLE_WPA3_OWE_STA) #if CONFIG_WIFI_RMT_PRIVACY_ENHANCEMENTS_ENABLED #define WIFI_PRIVACY_ENHANCEMENTS_ENABLED true @@ -363,6 +384,7 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs; .dump_hesigb_enable = WIFI_DUMP_HESIGB_ENABLED, \ .privacy_enhancements = WIFI_PRIVACY_ENHANCEMENTS_ENABLED, \ .rmac_auto_reset_int = WIFI_RMAC_AUTO_RESET_INTERVAL, \ + .wifi_task_stack_size = WIFI_TASK_STACK_SIZE, \ .magic = WIFI_INIT_CONFIG_MAGIC\ } @@ -483,13 +505,14 @@ esp_err_t esp_wifi_restore(void); * @attention 4. This API attempts to connect to an Access Point (AP) only once. To enable reconnection in case of a connection failure, please use * the 'failure_retry_cnt' feature in the 'wifi_sta_config_t'. Users are suggested to implement reconnection logic in their application * for scenarios where the specified AP does not exist, or reconnection is desired after the device has received a disconnect event. + * @attention 5. This API will return ESP_ERR_WIFI_CONN if the station is already in CONNECTING state. * * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start * - ESP_ERR_WIFI_MODE: WiFi mode error - * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong, or station is already in CONNECTING state * - ESP_ERR_WIFI_SSID: SSID of AP which station connects is invalid */ esp_err_t esp_wifi_connect(void); @@ -1829,28 +1852,38 @@ esp_err_t esp_wifi_get_bandwidths(wifi_interface_t ifx, wifi_bandwidths_t *bw); /** * @brief Send action frame on target channel * + * @attention 1. This API will return ESP_FAIL when called for STA interface (req->ifx == WIFI_IF_STA) + * while the station is in CONNECTING state. + * @attention 2. When PMF is enabled, broadcast action frames must be non-robust. + * @attention 3. wait_time_ms must be greater than 0. If wait_time_ms is 0, the API returns ESP_ERR_WIFI_ARG. + * * @param req action tx request structure containing relevant fields * * @return * - ESP_OK: succeed * - ESP_ERR_NO_MEM: failed to allocate memory - * - ESP_ERR_INVALID_ARG: the pair is invalid - * - ESP_FAIL: failed to send frame + * - ESP_ERR_WIFI_MODE: WiFi mode is wrong + * - ESP_ERR_WIFI_ARG: the pair is invalid or destination MAC address is all zeros, or wait_time_ms is 0 + * - ESP_FAIL: failed to send frame or STA is in CONNECTING state */ esp_err_t esp_wifi_action_tx_req(wifi_action_tx_req_t *req); /** * @brief Remain on the target channel for required duration * - * @attention 1. The API returns ESP_ERR_INVALID_ARG when `req->allow_broadcast` is true and the device operates in AP+STA mode. + * @attention 1. The API returns ESP_ERR_WIFI_ARG when `req->allow_broadcast` is true and the device operates in AP+STA mode. + * @attention 2. The API returns ESP_FAIL when called for STA interface (req->ifx == WIFI_IF_STA) + * while the station is in CONNECTING state. + * @attention 3. wait_time_ms must be greater than 0 for WIFI_ROC_REQ only. * * @param req roc request structure containing relevant fields * * @return * - ESP_OK: succeed * - ESP_ERR_NO_MEM: failed to allocate memory - * - ESP_ERR_INVALID_ARG: the pair is invalid - * - ESP_FAIL: failed to perform roc operation + * - ESP_ERR_WIFI_MODE: WiFi mode is wrong + * - ESP_ERR_WIFI_ARG: the pair is invalid, allow_broadcast is true in AP+STA mode, or wait_time_ms is 0 for WIFI_ROC_REQ + * - ESP_FAIL: failed to perform roc operation or STA is in CONNECTING state */ esp_err_t esp_wifi_remain_on_channel(wifi_roc_req_t * req); diff --git a/components/esp_wifi/remote/include/injected/esp_wifi_types_generic.h b/components/esp_wifi/remote/include/injected/esp_wifi_types_generic.h index 56b40bd4a7d..ea1362f9d03 100644 --- a/components/esp_wifi/remote/include/injected/esp_wifi_types_generic.h +++ b/components/esp_wifi/remote/include/injected/esp_wifi_types_generic.h @@ -199,7 +199,8 @@ typedef enum { .scan_time.active.min = WIFI_ACTIVE_SCAN_MIN_DEFAULT_TIME, \ .scan_time.active.max = WIFI_ACTIVE_SCAN_MAX_DEFAULT_TIME, \ .scan_time.passive = WIFI_PASSIVE_SCAN_DEFAULT_TIME, \ - .home_chan_dwell_time = WIFI_SCAN_HOME_CHANNEL_DWELL_DEFAULT_TIME\ + .home_chan_dwell_time = WIFI_SCAN_HOME_CHANNEL_DWELL_DEFAULT_TIME, \ + .max_offchan_duration_ms = 0 \ } /** @@ -265,6 +266,7 @@ typedef struct { typedef struct { wifi_scan_time_t scan_time; /**< Scan time per channel */ uint8_t home_chan_dwell_time;/**< Time spent at home channel between scanning consecutive channels.*/ + uint16_t max_offchan_duration_ms; /**< Maximum accumulated off-channel scan duration before returning to home channel (0 = use WIFI_ACTIVE_SCAN_MAX_DEFAULT_TIME, range: 1-4500ms). */ } wifi_scan_default_params_t; /** @@ -832,7 +834,7 @@ typedef struct { wifi_action_tx_t type; /**< ACTION TX operation type */ uint8_t channel; /**< Channel on which to perform ACTION TX Operation */ wifi_second_chan_t sec_channel; /**< Secondary channel */ - uint32_t wait_time_ms; /**< Duration to wait for on target channel */ + uint32_t wait_time_ms; /**< Duration to wait for on target channel (must be greater than 0) */ bool no_ack; /**< Indicates no ack required */ wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive action frames */ uint8_t op_id; /**< Unique Identifier for operation provided by wifi driver */ @@ -868,7 +870,7 @@ typedef struct { wifi_roc_t type; /**< ROC operation type */ uint8_t channel; /**< Channel on which to perform ROC Operation */ wifi_second_chan_t sec_channel; /**< Secondary channel */ - uint32_t wait_time_ms; /**< Duration to wait for on target channel */ + uint32_t wait_time_ms; /**< Duration to wait for on target channel (must be greater than 0 for WIFI_ROC_REQ only) */ wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive action mgmt frames */ uint8_t op_id; /**< ID of this specific ROC operation provided by wifi driver */ wifi_action_roc_done_cb_t done_cb; /**< Callback to function that will be called upon ROC done. If assigned, WIFI_EVENT_ROC_DONE event will not be posted */ 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 4e9dcdeae94..cef94e6b28a 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -163,6 +163,7 @@ struct wpa_funcs { int (*owe_process_assoc_resp)(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_ie, size_t dh_len); void (*wpa_sta_clear_curr_pmksa)(void); void (*wpa_config_reload)(void); + int (*wpa_parse_wpa_ie_scan_only)(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data); }; struct wpa2_funcs { 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 45e7d763f65..3a7473d8a16 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -277,12 +277,15 @@ void wpa_config_done(void) esp_set_scan_ie(); } -int wpa_parse_wpa_ie_wrapper(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data) +static int wpa_parse_wpa_ie_to_public(const u8 *wpa_ie, size_t wpa_ie_len, + wifi_wpa_ie_t *data, + int (*parse_fn)(const u8 *, size_t, + struct wpa_ie_data *)) { - struct wpa_ie_data ie; - int ret = 0; + struct wpa_ie_data ie = {0}; + int ret; - ret = wpa_parse_wpa_ie(wpa_ie, wpa_ie_len, &ie); + ret = parse_fn(wpa_ie, wpa_ie_len, &ie); data->proto = ie.proto; data->pairwise_cipher = cipher_type_map_supp_to_public(ie.pairwise_cipher); data->group_cipher = cipher_type_map_supp_to_public(ie.group_cipher); @@ -295,6 +298,18 @@ int wpa_parse_wpa_ie_wrapper(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t return ret; } +int wpa_parse_wpa_ie_wrapper(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data) +{ + return wpa_parse_wpa_ie_to_public(wpa_ie, wpa_ie_len, data, wpa_parse_wpa_ie); +} + +int wpa_parse_wpa_ie_scan_only_wrapper(const u8 *wpa_ie, size_t wpa_ie_len, + wifi_wpa_ie_t *data) +{ + return wpa_parse_wpa_ie_to_public(wpa_ie, wpa_ie_len, data, + wpa_parse_wpa_ie_scan_only); +} + static void wpa_sta_connected_cb(uint8_t *bssid) { supplicant_sta_conn_handler(bssid); @@ -539,6 +554,7 @@ int esp_supplicant_init(void) wpa_cb->wpa_config_parse_string = wpa_config_parse_string; wpa_cb->wpa_parse_wpa_ie = wpa_parse_wpa_ie_wrapper; + wpa_cb->wpa_parse_wpa_ie_scan_only = wpa_parse_wpa_ie_scan_only_wrapper; wpa_cb->wpa_config_bss = NULL;//wpa_config_bss; wpa_cb->wpa_michael_mic_failure = wpa_michael_mic_failure; wpa_cb->wpa_config_done = wpa_config_done; diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index 2e72886327e..c6ac9bc80ca 100644 --- a/components/wpa_supplicant/src/common/wpa_common.c +++ b/components/wpa_supplicant/src/common/wpa_common.c @@ -373,6 +373,72 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s) return 0; } +static int rsn_selector_to_bitfield_scan_only(const u8 *s) +{ + u32 sel = RSN_SELECTOR_GET(s); + + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 0)) + return WPA_CIPHER_NONE; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 1)) + return WPA_CIPHER_WEP40; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 2)) + return WPA_CIPHER_TKIP; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 4)) + return WPA_CIPHER_CCMP; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 5)) + return WPA_CIPHER_WEP104; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 6)) + return WPA_CIPHER_AES_128_CMAC; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 7)) + return WPA_CIPHER_GTK_NOT_USED; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 8)) + return WPA_CIPHER_GCMP; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 9)) + return WPA_CIPHER_GCMP_256; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 11)) + return WPA_CIPHER_BIP_GMAC_128; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 12)) + return WPA_CIPHER_BIP_GMAC_256; + + return 0; +} + +static int rsn_key_mgmt_to_bitfield_scan_only(const u8 *s) +{ + u32 sel = RSN_SELECTOR_GET(s); + + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 1)) + return WPA_KEY_MGMT_IEEE8021X; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 2)) + return WPA_KEY_MGMT_PSK; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 3)) + return WPA_KEY_MGMT_FT_IEEE8021X; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 4)) + return WPA_KEY_MGMT_FT_PSK; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 5)) + return WPA_KEY_MGMT_IEEE8021X_SHA256; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 6)) + return WPA_KEY_MGMT_PSK_SHA256; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 8)) + return WPA_KEY_MGMT_SAE; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 9)) + return WPA_KEY_MGMT_FT_SAE; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 11)) + return WPA_KEY_MGMT_IEEE8021X_SUITE_B; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 12)) + return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 13)) + return WPA_KEY_MGMT_FT_IEEE8021X_SHA384; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 18)) + return WPA_KEY_MGMT_OWE; + if (sel == RSN_SELECTOR(0x00, 0x0f, 0xac, 24)) + return WPA_KEY_MGMT_SAE_EXT_KEY; + if (sel == RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x02)) + return WPA_KEY_MGMT_DPP; + + return 0; +} + static int wpa_selector_to_bitfield(const u8 *s) { if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE) @@ -431,15 +497,31 @@ int wpa_parse_wpa_ie_rsnxe(const u8 *rsnxe_ie, size_t rsnxe_ie_len, return 0; } -/** - * wpa_parse_wpa_ie_rsn - Parse RSN IE - * @rsn_ie: Buffer containing RSN IE - * @rsn_ie_len: RSN IE buffer length (including IE number and length octets) - * @data: Pointer to structure that will be filled in with parsed data - * Returns: 0 on success, <0 on failure - */ -int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, - struct wpa_ie_data *data) +int wpa_parse_wpa_ie_rsnxe_scan_only(const u8 *rsnxe_ie, size_t rsnxe_ie_len, + struct wpa_ie_data *data) +{ + uint8_t rsnxe_capa = 0; + + memset(data, 0, sizeof(*data)); + + if (rsnxe_ie_len < 3 || !rsnxe_ie) { + return -1; + } + if (rsnxe_ie[0] == WLAN_EID_VENDOR_SPECIFIC && + rsnxe_ie[1] >= 1 + 4) { + rsnxe_capa = rsnxe_ie[2 + 4]; + } else { + rsnxe_capa = rsnxe_ie[2]; + } + data->rsnxe_capa = rsnxe_capa; + return 0; +} + +static int wpa_parse_wpa_ie_rsn_common(const u8 *rsn_ie, size_t rsn_ie_len, + struct wpa_ie_data *data, + int (*selector_to_bitfield)(const u8 *), + int (*key_mgmt_to_bitfield)(const u8 *), + bool validate_mgmt_group) { const u8 *pos; int left; @@ -468,9 +550,9 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, } if (rsn_ie_len >= 2 + 4 + 2 && rsn_ie[1] >= 4 + 2 && - rsn_ie[1] == rsn_ie_len - 2 && - (WPA_GET_BE32(&rsn_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE) && - WPA_GET_LE16(&rsn_ie[2 + 4]) == RSN_VERSION) { + rsn_ie[1] == rsn_ie_len - 2 && + (WPA_GET_BE32(&rsn_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE) && + WPA_GET_LE16(&rsn_ie[2 + 4]) == RSN_VERSION) { pos = rsn_ie + 2 + 4 + 2; left = rsn_ie_len - 2 - 4 - 2; } else { @@ -491,7 +573,7 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, } if (left >= RSN_SELECTOR_LEN) { - data->group_cipher = rsn_selector_to_bitfield(pos); + data->group_cipher = selector_to_bitfield(pos); data->has_group = 1; pos += RSN_SELECTOR_LEN; left -= RSN_SELECTOR_LEN; @@ -514,7 +596,7 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, if (count) data->has_pairwise = 1; for (i = 0; i < count; i++) { - data->pairwise_cipher |= rsn_selector_to_bitfield(pos); + data->pairwise_cipher |= selector_to_bitfield(pos); pos += RSN_SELECTOR_LEN; left -= RSN_SELECTOR_LEN; } @@ -535,7 +617,7 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, return -6; } for (i = 0; i < count; i++) { - data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos); + data->key_mgmt |= key_mgmt_to_bitfield(pos); pos += RSN_SELECTOR_LEN; left -= RSN_SELECTOR_LEN; } @@ -570,8 +652,9 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, } if (left >= 4) { - data->mgmt_group_cipher = rsn_selector_to_bitfield(pos); - if (!wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) { + data->mgmt_group_cipher = selector_to_bitfield(pos); + if (validate_mgmt_group && + !wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) { wpa_printf(MSG_DEBUG, "%s: Unsupported management group cipher 0x%x (%08x)", __func__, data->mgmt_group_cipher, @@ -590,6 +673,30 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, return 0; } +/** + * wpa_parse_wpa_ie_rsn - Parse RSN IE + * @rsn_ie: Buffer containing RSN IE + * @rsn_ie_len: RSN IE buffer length (including IE number and length octets) + * @data: Pointer to structure that will be filled in with parsed data + * Returns: 0 on success, <0 on failure + */ +int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, + struct wpa_ie_data *data) +{ + return wpa_parse_wpa_ie_rsn_common(rsn_ie, rsn_ie_len, data, + rsn_selector_to_bitfield, + rsn_key_mgmt_to_bitfield, true); +} + +int wpa_parse_wpa_ie_rsn_scan_only(const u8 *rsn_ie, size_t rsn_ie_len, + struct wpa_ie_data *data) +{ + return wpa_parse_wpa_ie_rsn_common(rsn_ie, rsn_ie_len, data, + rsn_selector_to_bitfield_scan_only, + rsn_key_mgmt_to_bitfield_scan_only, + false); +} + int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, struct wpa_ie_data *data) { diff --git a/components/wpa_supplicant/src/common/wpa_common.h b/components/wpa_supplicant/src/common/wpa_common.h index e5b2d345165..1c1ada6f91c 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -455,10 +455,16 @@ const char * wpa_cipher_txt(int cipher); int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, struct wpa_ie_data *data); +int wpa_parse_wpa_ie_rsn_scan_only(const u8 *rsn_ie, size_t rsn_ie_len, + struct wpa_ie_data *data); int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len, struct wpa_ie_data *data); +int wpa_parse_wpa_ie_scan_only(const u8 *wpa_ie, size_t wpa_ie_len, + struct wpa_ie_data *data); int wpa_parse_wpa_ie_rsnxe(const u8 *rsnxe_ie, size_t rsnxe_ie_len, struct wpa_ie_data *data); +int wpa_parse_wpa_ie_rsnxe_scan_only(const u8 *rsnxe_ie, size_t rsnxe_ie_len, + struct wpa_ie_data *data); u32 wpa_akm_to_suite(int akm); int wpa_compare_rsn_ie(int ft_initial_assoc, const u8 *ie1, size_t ie1len, diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index bda26a5747d..33712aebe58 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -3378,8 +3378,10 @@ int owe_process_assoc_resp(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_i wpa_sm_set_pmk_from_pmksa(sm); goto done; } else { - /* If PMKID mismatches, derive keys again */ + /* If PMKID mismatches, abort assoc due to invalid pmkid*/ wpa_printf(MSG_DEBUG, "OWE : Invalid PMKID in response"); + os_free(parsed_rsn_data); + return 1; } } @@ -3392,11 +3394,8 @@ int owe_process_assoc_resp(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_i goto fail; } - /* If STA or AP does not have PMKID, or PMKID mismatches, proceed with normal association */ - dh_len += 2; - + dh_len -=1; dh_ie += 3; - dh_len -=3; group = WPA_GET_LE16(dh_ie); /* Only group 19 is supported */ diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_ie.c b/components/wpa_supplicant/src/rsn_supp/wpa_ie.c index 4e0d75ee050..1baa2cabda2 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_ie.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa_ie.c @@ -37,7 +37,7 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len, return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data); } else if (wpa_ie_len >=1 && wpa_ie[0] == WLAN_EID_RSNX){ return wpa_parse_wpa_ie_rsnxe(wpa_ie, wpa_ie_len, data); - } else if (wpa_ie[0] == WLAN_EID_WAPI) { + } else if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_WAPI) { return 0; #ifdef CONFIG_WPA3_COMPAT } else if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC && @@ -54,6 +54,38 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len, return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data); } +/** + * wpa_parse_wpa_ie_scan_only - Parse WPA/RSN IE for scan result display + * @wpa_ie: Pointer to WPA or RSN IE + * @wpa_ie_len: Length of the WPA/RSN IE + * @data: Pointer to data area for parsing results + * Returns: 0 on success, -1 on failure + * + * Parse WPA/RSN IE without build-time feature restrictions so scan results + * can report all advertised ciphers and AKMs. + */ +int wpa_parse_wpa_ie_scan_only(const u8 *wpa_ie, size_t wpa_ie_len, + struct wpa_ie_data *data) +{ + if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN) { + return wpa_parse_wpa_ie_rsn_scan_only(wpa_ie, wpa_ie_len, data); + } else if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSNX) { + return wpa_parse_wpa_ie_rsnxe_scan_only(wpa_ie, wpa_ie_len, data); + } else if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_WAPI) { + return 0; + } else if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC && + wpa_ie[1] >= 4 && + WPA_GET_BE32(&wpa_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE) { + return wpa_parse_wpa_ie_rsn_scan_only(wpa_ie, wpa_ie_len, data); + } else if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC && + wpa_ie[1] >= 4 && + WPA_GET_BE32(&wpa_ie[2]) == RSNXE_OVERRIDE_IE_VENDOR_TYPE) { + return wpa_parse_wpa_ie_rsnxe_scan_only(wpa_ie, wpa_ie_len, data); + } + + return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data); +} + static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len, int pairwise_cipher, int group_cipher, diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_ie.h b/components/wpa_supplicant/src/rsn_supp/wpa_ie.h index 17089b9988e..d549e7e3ba6 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_ie.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_ie.h @@ -19,5 +19,7 @@ int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len); int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len); int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len, struct wpa_ie_data *data); +int wpa_parse_wpa_ie_scan_only(const u8 *wpa_ie, size_t wpa_ie_len, + struct wpa_ie_data *data); #endif /* WPA_IE_H */