esp_wifi: WPA3 softap set PMF required true

1) Set NVS PMF required true if not specified by application when
   authmode is WPA3
2) Fix issue regarding cleanup of non associated sta_info
3) Fix implementation of sta lock to avoid concurrency issues
4) Fix softAP deinit crash when password is configured with max length
This commit is contained in:
Shreyas Sheth 2023-03-02 12:21:10 +05:30 committed by BOT
parent ce9d466324
commit 888b909e79
9 changed files with 29 additions and 23 deletions

@ -1 +1 @@
Subproject commit 2394f288120349d894b074bf47057eb389ce1053
Subproject commit 56d5c4a85f9b1551a6253b3fadd7e562010104f0

View File

@ -19,6 +19,8 @@
#include "esp_wifi_types.h"
#include "esp_wpa3_i.h"
#define WIFI_PASSWORD_LEN_MAX 65
struct hostapd_data *global_hapd;
#ifdef CONFIG_SAE
@ -139,7 +141,7 @@ void *hostap_init(void)
memcpy(hapd->conf->ssid.ssid, ssid->ssid, ssid->len);
hapd->conf->ssid.ssid_len = ssid->len;
hapd->conf->wpa_key_mgmt = auth_conf->wpa_key_mgmt;
hapd->conf->ssid.wpa_passphrase = (char *)os_zalloc(64);
hapd->conf->ssid.wpa_passphrase = (char *)os_zalloc(WIFI_PASSWORD_LEN_MAX);
if (hapd->conf->ssid.wpa_passphrase == NULL) {
os_free(auth_conf);
os_free(hapd->conf);
@ -163,7 +165,7 @@ void *hostap_init(void)
#endif /* CONFIG_SAE */
os_memcpy(hapd->conf->ssid.wpa_passphrase, esp_wifi_ap_get_prof_password_internal(), strlen((char *)esp_wifi_ap_get_prof_password_internal()));
hapd->conf->ssid.wpa_passphrase[WIFI_PASSWORD_LEN_MAX - 1] = '\0';
hapd->conf->max_num_sta = esp_wifi_ap_get_max_sta_conn();
hapd->conf->ap_max_inactivity = 5 * 60;
@ -190,6 +192,8 @@ void hostapd_cleanup(struct hostapd_data *hapd)
}
if (hapd->conf) {
forced_memzero(hapd->conf->ssid.wpa_passphrase, WIFI_PASSWORD_LEN_MAX);
os_free(hapd->conf->ssid.wpa_passphrase);
hostapd_config_free_bss(hapd->conf);
hapd->conf = NULL;
}

View File

@ -124,7 +124,7 @@ struct wpa_funcs {
void *(*wpa_ap_init)(void);
bool (*wpa_ap_deinit)(void *data);
bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8* rsnxe, u8 rsnxe_len, bool *pmf_enable, int subtype);
bool (*wpa_ap_remove)(void *sta_info);
bool (*wpa_ap_remove)(u8 *bssid);
uint8_t *(*wpa_ap_get_wpa_ie)(uint8_t *len);
bool (*wpa_ap_rx_eapol)(void *hapd_data, void *sm, u8 *data, size_t data_len);
void (*wpa_ap_get_peer_spp_msg)(void *sm, bool *spp_cap, bool *spp_req);

View File

@ -409,7 +409,7 @@ static void wpa3_process_rx_commit(wpa3_hostap_auth_event_t *evt)
goto free;
}
}
if (sta->lock && os_mutex_lock(sta->lock)) {
if (sta->lock && os_semphr_take(sta->lock, 0)) {
sta->sae_commit_processing = true;
ret = handle_auth_sae(hapd, sta, frm->msg, frm->len, frm->bssid, frm->auth_transaction, frm->status);
@ -418,7 +418,7 @@ static void wpa3_process_rx_commit(wpa3_hostap_auth_event_t *evt)
goto free;
}
sta->sae_commit_processing = false;
os_mutex_unlock(sta->lock);
os_semphr_give(sta->lock);
uint16_t aid = 0;
if (ret != WLAN_STATUS_SUCCESS &&
ret != WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ) {
@ -447,7 +447,7 @@ static void wpa3_process_rx_confirm(wpa3_hostap_auth_event_t *evt)
return;
}
if (sta->lock && os_mutex_lock(sta->lock)) {
if (sta->lock && os_semphr_take(sta->lock, 0)) {
ret = handle_auth_sae(hapd, sta, frm->msg, frm->len, frm->bssid, frm->auth_transaction, frm->status);
if (sta->remove_pending) {
@ -460,7 +460,7 @@ static void wpa3_process_rx_confirm(wpa3_hostap_auth_event_t *evt)
goto done;
}
}
os_mutex_unlock(sta->lock);
os_semphr_give(sta->lock);
if (ret != WLAN_STATUS_SUCCESS) {
uint16_t aid = -1;
if (esp_wifi_ap_get_sta_aid(frm->bssid, &aid) == ESP_OK && aid == 0) {

View File

@ -291,9 +291,8 @@ void hostapd_config_clear_wpa_psk(struct hostapd_wpa_psk **l)
void hostapd_config_free_bss(struct hostapd_bss_config *conf)
{
hostapd_config_clear_wpa_psk(&conf->ssid.wpa_psk);
str_clear_free(conf->ssid.wpa_passphrase);
#ifdef CONFIG_SAE
sae_deinit_pt(conf->ssid.pt);
sae_deinit_pt(conf->ssid.pt);
#endif /* CONFIG_SAE */
os_free(conf);
}

View File

@ -385,6 +385,6 @@ struct sta_info;
bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie,
uint8_t wpa_ie_len,uint8_t *rsnxe, uint8_t rsnxe_len,
bool *pmf_enable, int subtype);
bool wpa_ap_remove(void* sta_info);
bool wpa_ap_remove(u8* bssid);
#endif /* HOSTAPD_CONFIG_H */

View File

@ -109,7 +109,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
sae_clear_data(sta->sae);
os_free(sta->sae);
if (sta->lock) {
os_mutex_unlock(sta->lock);
os_semphr_give(sta->lock);
os_mutex_delete(sta->lock);
sta->lock = NULL;
}
@ -175,7 +175,7 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
#ifdef CONFIG_SAE
sta->sae_commit_processing = false;
sta->remove_pending = false;
sta->lock = os_mutex_create();
sta->lock = os_semphr_create(1, 1);
#endif /* CONFIG_SAE */
return sta;

View File

@ -2578,19 +2578,21 @@ static void ap_free_sta_timeout(void *ctx, void *data)
}
#endif
bool wpa_ap_remove(void* sta_info)
bool wpa_ap_remove(u8* bssid)
{
struct hostapd_data *hapd = hostapd_get_hapd_data();
if (!sta_info || !hapd) {
if (!hapd) {
return false;
}
struct sta_info *sta = ap_get_sta(hapd, bssid);
if (!sta) {
return false;
}
struct sta_info *sta = NULL;
sta = (struct sta_info*)sta_info;
#ifdef CONFIG_SAE
if (sta->lock) {
if (os_mutex_lock(sta->lock)) {
if (os_semphr_take(sta->lock, 0)) {
ap_free_sta(hapd, sta);
} else {
sta->remove_pending = true;

View File

@ -51,7 +51,7 @@ Depending on PMF configurations on Station and AP side, the resulting connection
API & Usage
+++++++++++
{IDF_TARGET_NAME} supports PMF in both Station and SoftAP mode. For both, the default mode is PMF Optional and disabling PMF is not possible. For even higher security, PMF required mode can be enabled by setting the ``required`` flag in `pmf_cfg` while using the :cpp:func:`esp_wifi_set_config` API. This will result in the device only connecting to a PMF enabled device and rejecting others.
{IDF_TARGET_NAME} supports PMF in both Station and SoftAP mode. For both, the default mode is PMF Optional. For even higher security, PMF required mode can be enabled by setting the ``required`` flag in `pmf_cfg` while using the :cpp:func:`esp_wifi_set_config` API. This will result in the device only connecting to a PMF enabled device and rejecting others. PMF optional can be disabled using :cpp:func:`esp_wifi_disable_pmf_config` API. If softAP is started in WPA3 or WPA2/WPA3 mixed mode trying to disable PMF will result in error.
.. attention::
@ -75,11 +75,12 @@ Please refer to `Security <https://www.wi-fi.org/discover-wi-fi/security>`_ sect
Setting up WPA3 with {IDF_TARGET_NAME}
++++++++++++++++++++++++++++++++++++++
In IDF Menuconfig under Wi-Fi component, a config option "Enable WPA3-Personal" is provided to Enable/Disable WPA3. By default it is kept enabled, if disabled {IDF_TARGET_NAME} will not be able to establish a WPA3 connection. WPA3 is supported by station as well as softAP. Additionally, since PMF is mandated by WPA3 protocol, PMF Mode should be set to either Optional or Required while setting WiFi config.
In IDF Menuconfig under Wi-Fi component, a config option "Enable WPA3-Personal" is provided to Enable/Disable WPA3 for station. By default it is kept enabled, if disabled {IDF_TARGET_NAME} will not be able to establish a WPA3 connection. Also under WI-FI component a config option "ESP_WIFI_SOFTAP_SAE_SUPPORT" is provided to Enable/Disable WPA3 for softAP. Additionally, since PMF is mandated by WPA3 protocol, PMF Mode Optional is set by default for station and softAP. PMF Required can be configured using WiFi config. For WPA3 softAP, PMF required is mandatory and will be configured and stored in NVS implicitly if not specified by user.
Refer to `Protected Management Frames (PMF)`_ on how to set this mode.
After these settings are done, Station is ready to use WPA3-Personal. Application developers need not worry about the underlying security mode of the AP. WPA3-Personal is now the highest supported protocol in terms of security, so it will be automatically selected for the connection whenever available. For example, if an AP is configured to be in WPA3 Transition Mode, where it will advertise as both WPA2 and WPA3 capable, Station will choose WPA3 for the connection with above settings.
Note that Wi-Fi stack size requirement will increase 3kB when WPA3 is used.
After configuring all required settings for WPA3-Personal station, application developers need not worry about the underlying security mode of the AP. WPA3-Personal is now the highest supported protocol in terms of security, so it will be automatically selected for the connection whenever available. For example, if an AP is configured to be in WPA3 Transition Mode, where it will advertise as both WPA2 and WPA3 capable, Station will choose WPA3 for the connection with above settings.
Note that Wi-Fi stack size requirement will increase 3kB when "Enable WPA3-Personal" is used.
To configure WPA3 for softAP you have set up authmode as WIFI_AUTH_WPA3_PSK in config. For WPA3 softAP PMF is mandatory.
After configuring all required setting for WPA3-Personal softAP, application developers have to set ``WIFI_AUTH_WPA3_PSK`` as WiFi config authmode to start AP in softAP. SoftAP can be also configured to use ``WIFI_AUTH_WPA2_WPA3_PSK`` mixed mode.
Note that flash size will be increased by 6kB after enabling "ESP_WIFI_SOFTAP_SAE_SUPPORT".