Merge branch 'bugfix/sae_pk_transition_disable_v5.0' into 'release/v5.0'

fix(wifi): Fix bug in wrong profile checking of AP's RSNXE IE and other fixes (Backport v5.0)

See merge request espressif/esp-idf!35235
This commit is contained in:
Jiang Jiang Jian
2024-12-11 18:09:52 +08:00
11 changed files with 157 additions and 78 deletions

View File

@ -69,10 +69,13 @@ typedef enum {
WIFI_REASON_UNSPECIFIED = 1,
WIFI_REASON_AUTH_EXPIRE = 2,
WIFI_REASON_AUTH_LEAVE = 3,
WIFI_REASON_ASSOC_EXPIRE = 4,
WIFI_REASON_ASSOC_EXPIRE = 4, /* Deprecated, will be removed in next IDF major release */
WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
WIFI_REASON_ASSOC_TOOMANY = 5,
WIFI_REASON_NOT_AUTHED = 6,
WIFI_REASON_NOT_ASSOCED = 7,
WIFI_REASON_NOT_AUTHED = 6, /* Deprecated, will be removed in next IDF major release */
WIFI_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
WIFI_REASON_NOT_ASSOCED = 7, /* Deprecated, will be removed in next IDF major release */
WIFI_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
WIFI_REASON_ASSOC_LEAVE = 8,
WIFI_REASON_ASSOC_NOT_AUTHED = 9,
WIFI_REASON_DISASSOC_PWRCAP_BAD = 10,

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -7,6 +7,7 @@
#include "utils/includes.h"
#include "utils/common.h"
//#include "utils/eloop.h"
#include "crypto/sha1.h"
#include "common/ieee802_11_defs.h"
#include "common/eapol_common.h"
@ -20,6 +21,10 @@
#include "esp_wps.h"
#include "esp_wps_i.h"
#include "ap/sta_info.h"
#include "common/sae.h"
//#include "ap/ieee802_11.h"
struct hostapd_data *global_hapd;
struct hostapd_data *hostapd_get_hapd_data(void)
@ -183,3 +188,117 @@ bool hostap_deinit(void *data)
return true;
}
u16 wpa_res_to_status_code(enum wpa_validate_result res)
{
switch (res) {
case WPA_IE_OK:
return WLAN_STATUS_SUCCESS;
case WPA_INVALID_IE:
return WLAN_STATUS_INVALID_IE;
case WPA_INVALID_GROUP:
return WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
case WPA_INVALID_PAIRWISE:
return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
case WPA_INVALID_AKMP:
return WLAN_STATUS_AKMP_NOT_VALID;
case WPA_NOT_ENABLED:
return WLAN_STATUS_INVALID_IE;
case WPA_ALLOC_FAIL:
return WLAN_STATUS_UNSPECIFIED_FAILURE;
case WPA_MGMT_FRAME_PROTECTION_VIOLATION:
return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
case WPA_INVALID_MGMT_GROUP_CIPHER:
return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
case WPA_INVALID_MDIE:
return WLAN_STATUS_INVALID_MDIE;
case WPA_INVALID_PROTO:
return WLAN_STATUS_INVALID_IE;
case WPA_INVALID_PMKID:
return WLAN_STATUS_INVALID_PMKID;
case WPA_DENIED_OTHER_REASON:
return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
}
return WLAN_STATUS_INVALID_IE;
}
uint8_t wpa_status_to_reason_code(int status)
{
switch (status) {
case WLAN_STATUS_INVALID_IE:
return WLAN_REASON_INVALID_IE;
case WLAN_STATUS_GROUP_CIPHER_NOT_VALID:
return WLAN_REASON_GROUP_CIPHER_NOT_VALID;
case WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID:
return WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
case WLAN_STATUS_AKMP_NOT_VALID:
return WLAN_REASON_AKMP_NOT_VALID;
case WLAN_STATUS_CIPHER_REJECTED_PER_POLICY:
return WLAN_REASON_CIPHER_SUITE_REJECTED;
case WLAN_STATUS_INVALID_PMKID:
return WLAN_REASON_INVALID_PMKID;
case WLAN_STATUS_INVALID_MDIE:
return WLAN_REASON_INVALID_MDE;
default:
return WLAN_REASON_UNSPECIFIED;
}
}
bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie,
uint8_t wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher, uint8_t *reason)
{
struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal();
enum wpa_validate_result res = WPA_IE_OK;
int status = WLAN_STATUS_SUCCESS;
if (!sta || !bssid || !wpa_ie) {
return false;
}
if (hapd) {
if (hapd->wpa_auth->conf.wpa) {
if (sta->wpa_sm) {
wpa_auth_sta_deinit(sta->wpa_sm);
}
sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, bssid);
wpa_printf(MSG_DEBUG, "init wpa sm=%p", sta->wpa_sm);
if (sta->wpa_sm == NULL) {
status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
goto send_resp;
}
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len);
status = wpa_res_to_status_code(res);
send_resp:
if (status != WLAN_STATUS_SUCCESS) {
*reason = wpa_status_to_reason_code(status);
return false;
}
//Check whether AP uses Management Frame Protection for this connection
*pmf_enable = wpa_auth_uses_mfp(sta->wpa_sm);
*pairwise_cipher = GET_BIT_POSITION(sta->wpa_sm->pairwise);
}
wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
}
return true;
}
bool wpa_ap_remove(void* sta_info)
{
struct hostapd_data *hapd = hostapd_get_hapd_data();
if (!sta_info || !hapd) {
return false;
}
ap_free_sta(hapd, sta_info);
return true;
}

View File

@ -250,8 +250,8 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code)
{
switch (reason_code) {
case WIFI_REASON_AUTH_EXPIRE:
case WIFI_REASON_NOT_AUTHED:
case WIFI_REASON_NOT_ASSOCED:
case WIFI_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
case WIFI_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
case WIFI_REASON_INVALID_PMKID:
case WIFI_REASON_AUTH_FAIL:
@ -314,6 +314,7 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, bo
{
struct sta_info *sta_info;
struct hostapd_data *hapd = hostapd_get_hapd_data();
uint8_t reason = WLAN_REASON_PREV_AUTH_NOT_VALID;
if (!hapd) {
return 0;
@ -334,11 +335,17 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, bo
return true;
}
#endif
if (wpa_ap_join(sta_info, bssid, wpa_ie, wpa_ie_len, pmf_enable, pairwise_cipher)) {
*sta = sta_info;
return true;
if (hostap_new_assoc_sta(sta_info, bssid, wpa_ie, wpa_ie_len, pmf_enable, pairwise_cipher, &reason)) {
goto done;
} else {
goto fail;
}
done:
*sta = sta_info;
return true;
fail:
esp_wifi_ap_deauth_internal(bssid, reason);
return false;
}
#endif

View File

@ -917,7 +917,7 @@ int wps_start_msg_timer(void)
ret = 0;
} else if (sm->wps->state == RECV_M2) {
msg_timeout = 5;
wpa_printf(MSG_DEBUG, "start msg timer RECV_M2 %" PRId32 " ms", msg_timeout);
wpa_printf(MSG_DEBUG, "start msg timer RECV_M2 %" PRId32 " s", msg_timeout);
eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL);
eloop_register_timeout(msg_timeout, 0, wifi_station_wps_msg_timeout, NULL, NULL);
ret = 0;

View File

@ -373,7 +373,7 @@ const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
const u8 *addr, const u8 *prev_psk);
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
struct sta_info;
bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher);
bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher, uint8_t *reason);
bool wpa_ap_remove(void* sta_info);
#endif /* HOSTAPD_CONFIG_H */

View File

@ -2374,52 +2374,3 @@ static int wpa_sm_step(struct wpa_state_machine *sm)
}
return 0;
}
bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher)
{
struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal();
if (!sta || !bssid || !wpa_ie){
return false;
}
if (hapd) {
if (hapd->wpa_auth->conf.wpa) {
if (sta->wpa_sm){
wpa_auth_sta_deinit(sta->wpa_sm);
}
sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, bssid);
wpa_printf( MSG_DEBUG, "init wpa sm=%p\n", sta->wpa_sm);
if (sta->wpa_sm == NULL) {
return false;
}
if (wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len)) {
return false;
}
//Check whether AP uses Management Frame Protection for this connection
*pmf_enable = wpa_auth_uses_mfp(sta->wpa_sm);
*pairwise_cipher = GET_BIT_POSITION(sta->wpa_sm->pairwise);
}
wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
}
return true;
}
bool wpa_ap_remove(void* sta_info)
{
struct hostapd_data *hapd = hostapd_get_hapd_data();
if (!sta_info || !hapd) {
return false;
}
ap_free_sta(hapd, sta_info);
return true;
}

View File

@ -213,11 +213,12 @@ void wpa_deinit(struct wpa_authenticator *wpa_auth);
int wpa_reconfig(struct wpa_authenticator *wpa_auth,
struct wpa_auth_config *conf);
enum {
enum wpa_validate_result {
WPA_IE_OK, WPA_INVALID_IE, WPA_INVALID_GROUP, WPA_INVALID_PAIRWISE,
WPA_INVALID_AKMP, WPA_NOT_ENABLED, WPA_ALLOC_FAIL,
WPA_MGMT_FRAME_PROTECTION_VIOLATION, WPA_INVALID_MGMT_GROUP_CIPHER,
WPA_INVALID_MDIE, WPA_INVALID_PROTO
WPA_INVALID_MDIE, WPA_INVALID_PROTO, WPA_INVALID_PMKID,
WPA_DENIED_OTHER_REASON
};
int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,

View File

@ -184,6 +184,8 @@
#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22
#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23
#define WLAN_REASON_CIPHER_SUITE_REJECTED 24
#define WLAN_REASON_INVALID_PMKID 49
#define WLAN_REASON_INVALID_MDE 50
/* Information Element IDs (IEEE Std 802.11-2016, 9.4.2.1, Table 9-77) */
#define WLAN_EID_SSID 0

View File

@ -756,7 +756,7 @@ Association Phase
+++++++++++++++++++++
- s3.1: The association request is sent and the association timer is enabled.
- s3.2: If the association response is not received before the association timer times out, `WIFI_EVENT_STA_DISCONNECTED`_ will arise and the reason code will be WIFI_REASON_ASSOC_EXPIRE. Refer to `Wi-Fi Reason Code`_.
- s3.2: If the association response is not received before the association timer times out, `WIFI_EVENT_STA_DISCONNECTED`_ will arise and the reason code will be WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY. Refer to `Wi-Fi Reason Code`_.
- s3.3: The association response is received and the association timer is stopped.
- s3.4: The AP rejects the association in the response and `WIFI_EVENT_STA_DISCONNECTED`_ arises, while the reason code is the one specified in the association response. Refer to `Wi-Fi Reason Code`_.
@ -813,20 +813,16 @@ The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first co
For the ESP station, this reason is reported when:
- it is received from the AP.
* - ASSOC_EXPIRE
* - DISASSOC_DUE_TO_INACTIVITY
- 4
- 4
- Disassociated due to inactivity.
For the ESP station, this reason is reported when:
- assoc is timed out.
- it is received from the AP.
For the ESP AP, this reason is reported when:
- the AP has not received any packets from the station in the past five minutes.
- the AP is stopped by calling :cpp:func:`esp_wifi_stop()`.
- the station is de-authed by calling :cpp:func:`esp_wifi_deauth_sta()`.
* - ASSOC_TOOMANY
- 5
- 5
@ -839,7 +835,7 @@ The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first co
For the ESP AP, this reason is reported when:
- the stations associated with the AP reach the maximum number that the AP can support.
* - NOT_AUTHED
* - CLASS2_FRAME_FROM_NONAUTH_STA
- 6
- 6
- Class-2 frame received from a non-authenticated STA.
@ -851,7 +847,7 @@ The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first co
For the ESP AP, this reason is reported when:
- the AP receives a packet with data from a non-authenticated station.
* - NOT_ASSOCED
* - CLASS3_FRAME_FROM_NONASSOC_STA
- 7
- 7
- Class-3 frame received from a non-associated STA.
@ -1116,7 +1112,7 @@ The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first co
* - ASSOC_FAIL
- 203
- reserved
- Espressif-specific Wi-Fi reason code: the association fails, but not because of ASSOC_EXPIRE or ASSOC_TOOMANY.
- Espressif-specific Wi-Fi reason code: the association fails, but not because of DISASSOC_DUE_TO_INACTIVITY or ASSOC_TOOMANY.
* - HANDSHAKE_TIMEOUT
- 204
- reserved

View File

@ -756,7 +756,7 @@ Wi-Fi 驱动程序内部扫描阶段
+++++++++++++++++++++
- s3.1:发送关联请求并使能关联计时器。
- s3.2:如果在关联计时器超时之前未接收到关联响应,将产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件,且原因代码为 WIFI_REASON_ASSOC_EXPIRE。请参阅 `Wi-Fi 原因代码`_
- s3.2:如果在关联计时器超时之前未接收到关联响应,将产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件,且原因代码为 WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY。请参阅 `Wi-Fi 原因代码`_
- s3.3:接收到关联响应,且关联计时器终止。
- s3.4AP 在响应中拒绝关联且产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件,原因代码将在关联响应中指定。请参阅 `Wi-Fi 原因代码`_
@ -813,7 +813,7 @@ Wi-Fi 原因代码
对于 ESP station出现以下情况时报告该代码
- 从 AP 接收到该代码。
* - ASSOC_EXPIRE
* - DISASSOC_DUE_TO_INACTIVITY
- 4
- 4
- 因为 AP 不活跃association 取消。
@ -839,7 +839,7 @@ Wi-Fi 原因代码
对于 ESP AP出现以下情况时将报告该代码
- 与 AP 相关联的 station 数量已到达 AP 可支持的最大值。
* - NOT_AUTHED
* - CLASS2_FRAME_FROM_NONAUTH_STA
- 6
- 6
- 从一个未认证 station 接收到 class-2 frame。
@ -851,7 +851,7 @@ Wi-Fi 原因代码
对于 ESP AP出现以下情况时将报告该代码
- AP 从一个未认证 station 接收到数据包。
* - NOT_ASSOCED
* - CLASS3_FRAME_FROM_NONASSOC_STA
- 7
- 7
- 从一个未关联 station 接收到的 class-3 frame。
@ -1116,7 +1116,7 @@ Wi-Fi 原因代码
* - ASSOC_FAIL
- 203
- 保留
- 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 ASSOC_EXPIRE 或 ASSOC_TOOMANY 引发。
- 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 DISASSOC_DUE_TO_INACTIVITY 或 ASSOC_TOOMANY 引发。
* - HANDSHAKE_TIMEOUT
- 204
- 保留