feat(esp_wifi): Add compile flag for wpa3 compatible mode

This commit is contained in:
Shreyas Sheth
2025-04-29 11:38:39 +05:30
committed by Kapil Gupta
parent 1b33c9daae
commit a7f32f5a2a
24 changed files with 222 additions and 216 deletions

View File

@@ -1,4 +1,3 @@
menu "Wi-Fi" menu "Wi-Fi"
visible if (SOC_WIFI_SUPPORTED || SOC_WIRELESS_HOST_SUPPORTED) visible if (SOC_WIFI_SUPPORTED || SOC_WIRELESS_HOST_SUPPORTED)
@@ -340,6 +339,13 @@ menu "Wi-Fi"
explicitly configured before attempting connection. Please refer to the Wi-Fi Driver API Guide explicitly configured before attempting connection. Please refer to the Wi-Fi Driver API Guide
for details. for details.
config ESP_WIFI_WPA3_COMPATIBLE_SUPPORT
bool "Enable WPA3 Compatible support"
default y
depends on ESP_WIFI_ENABLE_SAE_H2E
help
Select this option to enable WPA3 Compatible support in softap mode.
config ESP_WIFI_SLP_IRAM_OPT config ESP_WIFI_SLP_IRAM_OPT
bool "WiFi SLP IRAM speed optimization" bool "WiFi SLP IRAM speed optimization"
select PM_SLP_DEFAULT_PARAMS_OPT select PM_SLP_DEFAULT_PARAMS_OPT

View File

@@ -287,6 +287,9 @@ endif()
if(CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT) if(CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT)
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_SAE) target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_SAE)
endif() endif()
if(CONFIG_ESP_WIFI_WPA3_COMPATIBLE_SUPPORT)
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_WPA3_COMPAT)
endif()
if(CONFIG_ESP_WIFI_WPS_STRICT) if(CONFIG_ESP_WIFI_WPS_STRICT)
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_WPS_STRICT) target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_WPS_STRICT)
endif() endif()

View File

@@ -110,15 +110,19 @@ void *hostap_init(void)
} }
#endif /* CONFIG_IEEE80211W */ #endif /* CONFIG_IEEE80211W */
if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_AP)) { if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_AP)) {
//TODO check sae_pwe #ifdef CONFIG_WPA3_COMPAT
hapd->conf->sae_pwe = SAE_PWE_HASH_TO_ELEMENT; hapd->conf->sae_pwe = SAE_PWE_HASH_TO_ELEMENT;
auth_conf->rsn_override_omit_rsnxe = 1; auth_conf->rsn_override_omit_rsnxe = 1;
hapd->conf->rsn_override_omit_rsnxe = 1;
hapd->conf->rsn_override_key_mgmt = WPA_KEY_MGMT_SAE; hapd->conf->rsn_override_key_mgmt = WPA_KEY_MGMT_SAE;
hapd->conf->rsn_override_pairwise = WPA_CIPHER_CCMP; hapd->conf->rsn_override_pairwise = WPA_CIPHER_CCMP;
hapd->conf->rsn_override_mfp = MGMT_FRAME_PROTECTION_REQUIRED; hapd->conf->rsn_override_mfp = MGMT_FRAME_PROTECTION_REQUIRED;
auth_conf->rsn_override_key_mgmt = WPA_KEY_MGMT_SAE; auth_conf->rsn_override_key_mgmt = WPA_KEY_MGMT_SAE;
auth_conf->rsn_override_pairwise = WPA_CIPHER_CCMP; auth_conf->rsn_override_pairwise = WPA_CIPHER_CCMP;
auth_conf->rsn_override_mfp = MGMT_FRAME_PROTECTION_REQUIRED; auth_conf->rsn_override_mfp = MGMT_FRAME_PROTECTION_REQUIRED;
#else
wpa_printf(MSG_ERROR, "ESP_WIFI_WPA3_COMPATIBLE_SUPPORT disabled ignoring wpa3_compatible configuration");
#endif
} }
/* TKIP is compulsory in WPA Mode */ /* TKIP is compulsory in WPA Mode */
if (auth_conf->wpa == WPA_PROTO_WPA && pairwise_cipher == WIFI_CIPHER_TYPE_CCMP) { if (auth_conf->wpa == WPA_PROTO_WPA && pairwise_cipher == WIFI_CIPHER_TYPE_CCMP) {
@@ -224,7 +228,6 @@ void *hostap_init(void)
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
auth_conf->sae_require_mfp = 1; auth_conf->sae_require_mfp = 1;
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
auth_conf->rsn_override_omit_rsnxe = 1;
hapd->conf->ap_max_inactivity = 5 * 60; hapd->conf->ap_max_inactivity = 5 * 60;
hostapd_setup_wpa_psk(hapd->conf); hostapd_setup_wpa_psk(hapd->conf);
@@ -409,15 +412,21 @@ uint8_t wpa_status_to_reason_code(int status)
} }
} }
bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, struct ieee802_11_elems elems, bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie,
bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason) u8 wpa_ie_len, u8 *rsnxe, uint16_t rsnxe_len,
bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason, uint8_t *rsn_selection_ie)
{ {
struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal(); struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal();
enum wpa_validate_result res = WPA_IE_OK; enum wpa_validate_result res = WPA_IE_OK;
int status = WLAN_STATUS_SUCCESS; int status = WLAN_STATUS_SUCCESS;
bool omit_rsnxe = false; bool omit_rsnxe = false;
if (!sta || !bssid || !elems.rsn_ie) { #ifdef CONFIG_WPA3_COMPAT
uint8_t rsn_selection_variant_len = 0;
uint8_t *rsn_selection_variant_ie = NULL;
#endif
if (!sta || !bssid || !wpa_ie) {
return false; return false;
} }
if (hapd) { if (hapd) {
@@ -434,8 +443,16 @@ bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, struct ieee802_1
goto send_resp; goto send_resp;
} }
wpa_auth_set_rsn_selection(sta->wpa_sm, elems.rsn_selection, elems.rsn_selection_len); #ifdef CONFIG_WPA3_COMPAT
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, elems.rsn_ie, elems.rsn_ie_len, elems.rsnxe, elems.rsnxe_len); if (rsn_selection_ie) {
rsn_selection_variant_len = rsn_selection_ie[1] - 4;
rsn_selection_variant_ie = &rsn_selection_ie[6];
}
wpa_auth_set_rsn_selection(sta->wpa_sm, rsn_selection_variant_ie, rsn_selection_variant_len);
#endif
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len);
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae && if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae &&
sta->sae->state == SAE_ACCEPTED) { sta->sae->state == SAE_ACCEPTED) {
@@ -447,13 +464,15 @@ bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, struct ieee802_1
status = wpa_res_to_status_code(res); status = wpa_res_to_status_code(res);
send_resp: send_resp:
if (!elems.rsnxe) { if (!rsnxe) {
omit_rsnxe = true; omit_rsnxe = true;
} }
#ifdef CONFIG_WPA3_COMPAT
if (hapd->conf->rsn_override_omit_rsnxe) { if (hapd->conf->rsn_override_omit_rsnxe) {
omit_rsnxe = 1; omit_rsnxe = false;
} }
#endif
if (esp_send_assoc_resp(hapd, bssid, status, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) { if (esp_send_assoc_resp(hapd, bssid, status, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) {
status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;

View File

@@ -129,7 +129,7 @@ struct wpa_funcs {
bool (*wpa_sta_in_4way_handshake)(void); bool (*wpa_sta_in_4way_handshake)(void);
void *(*wpa_ap_init)(void); void *(*wpa_ap_init)(void);
bool (*wpa_ap_deinit)(void *data); bool (*wpa_ap_deinit)(void *data);
bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *assoc_req_ie, uint32_t len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher); bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8* rsnxe, u16 rsnxe_len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *rsn_selection_ie);
bool (*wpa_ap_remove)(u8 *bssid); bool (*wpa_ap_remove)(u8 *bssid);
uint8_t *(*wpa_ap_get_wpa_ie)(uint8_t *len); 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); bool (*wpa_ap_rx_eapol)(void *hapd_data, void *sm, u8 *data, size_t data_len);

View File

@@ -46,18 +46,20 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid, size_t *sae_msg_len)
use_pt = 1; use_pt = 1;
} }
#ifdef CONFIG_WPA3_COMPAT
if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA)) { if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA)) {
rsnxe = esp_wifi_sta_get_ie((u8*)bssid, WFA_RSNXE_OVERRIDE_OUI_TYPE); rsnxe = esp_wifi_sta_get_ie((u8*)bssid, WFA_RSNXE_OVERRIDE_OUI_TYPE);
if (rsnxe) {
rsnxe_capa = rsnxe[2 + 4];
} }
}
#endif
if (!rsnxe) { if (!rsnxe) {
rsnxe = esp_wifi_sta_get_ie((u8*)bssid, WLAN_EID_RSNX); rsnxe = esp_wifi_sta_get_ie((u8*)bssid, WLAN_EID_RSNX);
} if (rsnxe) {
if (rsnxe && rsnxe[0] == WLAN_EID_VENDOR_SPECIFIC &&
rsnxe[1] >= 1 + 4) {
rsnxe_capa = rsnxe[2 + 4];
} else if (rsnxe && rsnxe[1] >= 1) {
rsnxe_capa = rsnxe[2]; rsnxe_capa = rsnxe[2];
} }
}
#endif /* CONFIG_SAE_H2E */ #endif /* CONFIG_SAE_H2E */
#ifdef CONFIG_SAE_PK #ifdef CONFIG_SAE_PK

View File

@@ -377,37 +377,22 @@ static int check_n_add_wps_sta(struct hostapd_data *hapd, struct sta_info *sta_i
} }
#endif #endif
static bool hostap_sta_join(void **sta, u8 *bssid, u8 *assoc_req_ie, uint32_t assoc_ie_len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher) static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8 *rsnxe, u16 rsnxe_len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *rsn_selection_ie)
{ {
struct sta_info *sta_info = NULL; struct sta_info *sta_info = NULL;
struct hostapd_data *hapd = hostapd_get_hapd_data(); struct hostapd_data *hapd = hostapd_get_hapd_data();
uint8_t reason = WLAN_REASON_PREV_AUTH_NOT_VALID; uint8_t reason = WLAN_REASON_PREV_AUTH_NOT_VALID;
struct ieee802_11_elems elems;
if (!hapd) { if (!hapd) {
goto fail; goto fail;
} }
if (ieee802_11_parse_elems(assoc_req_ie, assoc_ie_len, &elems, 1) == ParseFailed) {
wpa_printf(MSG_INFO, "Failed to parse assoc req IEs");
return -1;
}
if (elems.rsn_ie) {
elems.rsn_ie = elems.rsn_ie - 2;
elems.rsn_ie_len = elems.rsn_ie_len + 2;
}
if (elems.rsnxe) {
elems.rsnxe = elems.rsnxe - 2;
elems.rsnxe_len = elems.rsnxe_len + 2;
}
if (*sta) { if (*sta) {
struct sta_info *old_sta = *sta; struct sta_info *old_sta = *sta;
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
if (old_sta->lock && os_semphr_take(old_sta->lock, 0) != TRUE) { if (old_sta->lock && os_semphr_take(old_sta->lock, 0) != TRUE) {
wpa_printf(MSG_INFO, "Ignore assoc request as softap is busy with sae calculation for station "MACSTR, MAC2STR(bssid)); wpa_printf(MSG_INFO, "Ignore assoc request as softap is busy with sae calculation for station "MACSTR, MAC2STR(bssid));
if (esp_send_assoc_resp(hapd, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, elems.rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) { if (esp_send_assoc_resp(hapd, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) {
goto fail; goto fail;
} }
return false; return false;
@@ -436,7 +421,7 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *assoc_req_ie, uint32_t as
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
if (sta_info->lock && os_semphr_take(sta_info->lock, 0) != TRUE) { if (sta_info->lock && os_semphr_take(sta_info->lock, 0) != TRUE) {
wpa_printf(MSG_INFO, "Ignore assoc request as softap is busy with sae calculation for station "MACSTR, MAC2STR(bssid)); wpa_printf(MSG_INFO, "Ignore assoc request as softap is busy with sae calculation for station "MACSTR, MAC2STR(bssid));
if (esp_send_assoc_resp(hapd, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, elems.rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) { if (esp_send_assoc_resp(hapd, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) {
goto fail; goto fail;
} }
return false; return false;
@@ -446,7 +431,7 @@ process_old_sta:
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
#ifdef CONFIG_WPS_REGISTRAR #ifdef CONFIG_WPS_REGISTRAR
if (check_n_add_wps_sta(hapd, sta_info, elems.rsn_ie, elems.rsn_ie_len, pmf_enable, subtype) == 0) { if (check_n_add_wps_sta(hapd, sta_info, wpa_ie, wpa_ie_len, pmf_enable, subtype) == 0) {
if (sta_info->eapol_sm) { if (sta_info->eapol_sm) {
goto done; goto done;
} }
@@ -454,8 +439,7 @@ process_old_sta:
goto fail; goto fail;
} }
#endif #endif
if (hostap_new_assoc_sta(sta_info, bssid, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len, pmf_enable, subtype, pairwise_cipher, &reason, rsn_selection_ie)) {
if (hostap_new_assoc_sta(sta_info, bssid, elems, pmf_enable, subtype, pairwise_cipher, &reason)) {
goto done; goto done;
} else { } else {
goto fail; goto fail;

View File

@@ -150,8 +150,11 @@ int hostapd_setup_sae_pt(struct hostapd_bss_config *conf)
#ifdef CONFIG_SAE_H2E #ifdef CONFIG_SAE_H2E
struct hostapd_ssid *ssid = &conf->ssid; struct hostapd_ssid *ssid = &conf->ssid;
if (conf->sae_pwe == SAE_PWE_HUNT_AND_PECK || if (conf->sae_pwe == SAE_PWE_HUNT_AND_PECK ||
!wpa_key_mgmt_sae(conf->wpa_key_mgmt | !wpa_key_mgmt_sae(conf->wpa_key_mgmt
conf->rsn_override_key_mgmt)) #ifdef CONFIG_WPA3_COMPAT
| conf->rsn_override_key_mgmt
#endif
))
return 0; /* PT not needed */ return 0; /* PT not needed */
sae_deinit_pt(ssid->pt); sae_deinit_pt(ssid->pt);

View File

@@ -200,10 +200,14 @@ struct hostapd_bss_config {
int wpa; /* bitfield of WPA_PROTO_WPA, WPA_PROTO_RSN */ int wpa; /* bitfield of WPA_PROTO_WPA, WPA_PROTO_RSN */
int wpa_key_mgmt; int wpa_key_mgmt;
#ifdef CONFIG_WPA3_COMPAT
int rsn_override_key_mgmt; int rsn_override_key_mgmt;
#endif
#ifdef CONFIG_IEEE80211W #ifdef CONFIG_IEEE80211W
enum mfp_options ieee80211w; enum mfp_options ieee80211w;
#ifdef CONFIG_WPA3_COMPAT
enum mfp_options rsn_override_mfp; enum mfp_options rsn_override_mfp;
#endif
/* dot11AssociationSAQueryMaximumTimeout (in TUs) */ /* dot11AssociationSAQueryMaximumTimeout (in TUs) */
unsigned int assoc_sa_query_max_timeout; unsigned int assoc_sa_query_max_timeout;
/* dot11AssociationSAQueryRetryTimeout (in TUs) */ /* dot11AssociationSAQueryRetryTimeout (in TUs) */
@@ -222,7 +226,9 @@ struct hostapd_bss_config {
int wpa_ptk_rekey; int wpa_ptk_rekey;
int rsn_pairwise; int rsn_pairwise;
int rsn_preauth; int rsn_preauth;
#ifdef CONFIG_WPA3_COMPAT
int rsn_override_pairwise; int rsn_override_pairwise;
#endif
char *rsn_preauth_interfaces; char *rsn_preauth_interfaces;
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
@@ -310,7 +316,9 @@ struct hostapd_bss_config {
int *sae_groups; int *sae_groups;
#define SAE_ANTI_CLOGGING_THRESHOLD 2 /* max number of commit msg allowed to queue without anti-clogging token request */ #define SAE_ANTI_CLOGGING_THRESHOLD 2 /* max number of commit msg allowed to queue without anti-clogging token request */
#ifdef CONFIG_WPA3_COMPAT
int rsn_override_omit_rsnxe; int rsn_override_omit_rsnxe;
#endif
}; };
@@ -387,8 +395,9 @@ const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
const u8 *addr, const u8 *prev_psk); const u8 *addr, const u8 *prev_psk);
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf); int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
struct sta_info; struct sta_info;
bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, struct ieee802_11_elems elems, bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie,
bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason); u8 wpa_ie_len, u8 *rsnxe, uint16_t rsnxe_len,
bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason, uint8_t *rsn_selection_ie);
bool wpa_ap_remove(u8* bssid); bool wpa_ap_remove(u8* bssid);
#endif /* HOSTAPD_CONFIG_H */ #endif /* HOSTAPD_CONFIG_H */

View File

@@ -197,13 +197,16 @@ static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
return -1; return -1;
} }
#ifdef CONFIG_WPA3_COMPAT
void wpa_auth_set_rsn_selection(struct wpa_state_machine *sm, const u8 *ie, void wpa_auth_set_rsn_selection(struct wpa_state_machine *sm, const u8 *ie,
size_t len) size_t len)
{ {
if (!sm) if (!sm)
return; return;
if (sm->rsn_selection) {
os_free(sm->rsn_selection); os_free(sm->rsn_selection);
sm->rsn_selection = NULL; sm->rsn_selection = NULL;
}
sm->rsn_selection_len = 0; sm->rsn_selection_len = 0;
sm->rsn_override = false; sm->rsn_override = false;
if (ie) { if (ie) {
@@ -216,6 +219,7 @@ void wpa_auth_set_rsn_selection(struct wpa_state_machine *sm, const u8 *ie,
sm->rsn_selection_len = len; sm->rsn_selection_len = len;
} }
} }
#endif
/* fix buf for tx for now */ /* fix buf for tx for now */
#define WPA_TX_MSG_BUFF_MAXLEN 200 #define WPA_TX_MSG_BUFF_MAXLEN 200
@@ -522,7 +526,9 @@ static void wpa_free_sta_sm(struct wpa_state_machine *sm)
os_free(sm->last_rx_eapol_key); os_free(sm->last_rx_eapol_key);
os_free(sm->wpa_ie); os_free(sm->wpa_ie);
os_free(sm->rsnxe); os_free(sm->rsnxe);
#ifdef CONFIG_WPA3_COMPAT
os_free(sm->rsn_selection); os_free(sm->rsn_selection);
#endif
os_free(sm); os_free(sm);
} }
@@ -1764,6 +1770,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
return; return;
} }
#ifdef CONFIG_WPA3_COMPAT
/* Verify RSN Selection element for RSN overriding */ /* Verify RSN Selection element for RSN overriding */
if (sm->wpa_auth->conf.rsn_override_key_mgmt && if (sm->wpa_auth->conf.rsn_override_key_mgmt &&
((rsn_is_snonce_cookie(sm->SNonce) && !kde.rsn_selection) || ((rsn_is_snonce_cookie(sm->SNonce) && !kde.rsn_selection) ||
@@ -1789,6 +1796,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
return; return;
} }
#endif
sm->pending_1_of_4_timeout = 0; sm->pending_1_of_4_timeout = 0;
eloop_cancel_timeout(resend_eapol_handle, (void*)(sm->index), NULL); eloop_cancel_timeout(resend_eapol_handle, (void*)(sm->index), NULL);
@@ -1886,8 +1894,10 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
struct wpa_group *gsm = sm->group; struct wpa_group *gsm = sm->group;
u8 *wpa_ie; u8 *wpa_ie;
int wpa_ie_len, secure, keyidx, encr = 0; int wpa_ie_len, secure, keyidx, encr = 0;
#ifdef CONFIG_WPA3_COMPAT
u8 *wpa_ie_buf3 = NULL; u8 *wpa_ie_buf3 = NULL;
struct wpa_auth_config *conf = &sm->wpa_auth->conf; struct wpa_auth_config *conf = &sm->wpa_auth->conf;
#endif
SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk); SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk);
sm->TimeoutEvt = FALSE; sm->TimeoutEvt = FALSE;
@@ -1916,6 +1926,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
wpa_ie = wpa_ie + wpa_ie[1] + 2; wpa_ie = wpa_ie + wpa_ie[1] + 2;
wpa_ie_len = wpa_ie[1] + 2; wpa_ie_len = wpa_ie[1] + 2;
} }
#ifdef CONFIG_WPA3_COMPAT
if (conf->rsn_override_key_mgmt && if (conf->rsn_override_key_mgmt &&
!rsn_is_snonce_cookie(sm->SNonce)) { !rsn_is_snonce_cookie(sm->SNonce)) {
u8 *ie; u8 *ie;
@@ -1948,6 +1959,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
wpa_hexdump(MSG_DEBUG, "EAPOL-Key msg 3/4 IEs after edits", wpa_hexdump(MSG_DEBUG, "EAPOL-Key msg 3/4 IEs after edits",
wpa_ie, wpa_ie_len); wpa_ie, wpa_ie_len);
} }
#endif
if (sm->wpa == WPA_VERSION_WPA2) { if (sm->wpa == WPA_VERSION_WPA2) {
/* WPA2 send GTK in the 4-way handshake */ /* WPA2 send GTK in the 4-way handshake */
secure = 1; secure = 1;
@@ -1959,7 +1971,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
* of GTK in the BSS. * of GTK in the BSS.
*/ */
if (os_get_random(dummy_gtk, gtk_len) < 0) if (os_get_random(dummy_gtk, gtk_len) < 0)
return; goto done;
gtk = dummy_gtk; gtk = dummy_gtk;
} }
keyidx = gsm->GN; keyidx = gsm->GN;
@@ -1999,8 +2011,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
} }
#endif /* CONFIG_IEEE80211R_AP */ #endif /* CONFIG_IEEE80211R_AP */
kde = (u8 *)os_malloc(kde_len); kde = (u8 *)os_malloc(kde_len);
if (kde == NULL) if (!kde)
return; goto done;
pos = kde; pos = kde;
memcpy(pos, wpa_ie, wpa_ie_len); memcpy(pos, wpa_ie, wpa_ie_len);
@@ -2011,8 +2023,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
if (res < 0) { if (res < 0) {
wpa_printf( MSG_ERROR, "FT: Failed to insert " wpa_printf( MSG_ERROR, "FT: Failed to insert "
"PMKR1Name into RSN IE in EAPOL-Key data"); "PMKR1Name into RSN IE in EAPOL-Key data");
os_free(kde); goto done;
return;
} }
pos += res; pos += res;
} }
@@ -2042,8 +2053,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
if (res < 0) { if (res < 0) {
wpa_printf( MSG_ERROR, "FT: Failed to insert FTIE " wpa_printf( MSG_ERROR, "FT: Failed to insert FTIE "
"into EAPOL-Key Key Data"); "into EAPOL-Key Key Data");
os_free(kde); goto done;
return;
} }
pos += res; pos += res;
@@ -2070,7 +2080,9 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
_rsc, sm->ANonce, kde, pos - kde, keyidx, encr); _rsc, sm->ANonce, kde, pos - kde, keyidx, encr);
done: done:
os_free(kde); os_free(kde);
#ifdef CONFIG_WPA3_COMPAT
os_free(wpa_ie_buf3); os_free(wpa_ie_buf3);
#endif
} }

View File

@@ -127,7 +127,9 @@ struct ft_remote_r1kh {
struct wpa_auth_config { struct wpa_auth_config {
int wpa; int wpa;
int wpa_key_mgmt; int wpa_key_mgmt;
#ifdef CONFIG_WPA3_COMPAT
int rsn_override_key_mgmt; int rsn_override_key_mgmt;
#endif
int wpa_pairwise; int wpa_pairwise;
int wpa_group; int wpa_group;
int wpa_group_rekey; int wpa_group_rekey;
@@ -135,7 +137,9 @@ struct wpa_auth_config {
int wpa_gmk_rekey; int wpa_gmk_rekey;
int wpa_ptk_rekey; int wpa_ptk_rekey;
int rsn_pairwise; int rsn_pairwise;
#ifdef CONFIG_WPA3_COMPAT
int rsn_override_pairwise; int rsn_override_pairwise;
#endif
int rsn_preauth; int rsn_preauth;
int eapol_version; int eapol_version;
int wmm_enabled; int wmm_enabled;
@@ -145,7 +149,9 @@ struct wpa_auth_config {
int tx_status; int tx_status;
#ifdef CONFIG_IEEE80211W #ifdef CONFIG_IEEE80211W
enum mfp_options ieee80211w; enum mfp_options ieee80211w;
#ifdef CONFIG_WPA3_COMPAT
enum mfp_options rsn_override_mfp; enum mfp_options rsn_override_mfp;
#endif
#endif /* CONFIG_IEEE80211W */ #endif /* CONFIG_IEEE80211W */
int group_mgmt_cipher; int group_mgmt_cipher;
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
@@ -171,7 +177,9 @@ struct wpa_auth_config {
enum sae_pwe sae_pwe; enum sae_pwe sae_pwe;
struct rsn_sppamsdu_sup spp_sup; struct rsn_sppamsdu_sup spp_sup;
u8 transition_disable; u8 transition_disable;
#ifdef CONFIG_WPA3_COMPAT
int rsn_override_omit_rsnxe; int rsn_override_omit_rsnxe;
#endif
}; };
typedef enum { typedef enum {
@@ -312,8 +320,12 @@ void wpa_auth_set_rsn_selection(struct wpa_state_machine *sm, const u8 *ie,
size_t len); size_t len);
static inline bool wpa_auth_pmf_enabled(struct wpa_auth_config *conf) static inline bool wpa_auth_pmf_enabled(struct wpa_auth_config *conf)
{ {
#ifdef CONFIG_WPA3_COMPAT
return conf->ieee80211w != NO_MGMT_FRAME_PROTECTION || return conf->ieee80211w != NO_MGMT_FRAME_PROTECTION ||
conf->rsn_override_mfp != NO_MGMT_FRAME_PROTECTION; conf->rsn_override_mfp != NO_MGMT_FRAME_PROTECTION;
#else
return conf->ieee80211w != NO_MGMT_FRAME_PROTECTION;
#endif
} }
#endif /* WPA_AUTH_H */ #endif /* WPA_AUTH_H */

View File

@@ -100,8 +100,10 @@ struct wpa_state_machine {
size_t wpa_ie_len; size_t wpa_ie_len;
u8 *rsnxe; u8 *rsnxe;
size_t rsnxe_len; size_t rsnxe_len;
#ifdef CONFIG_WPA3_COMPAT
u8 *rsn_selection; u8 *rsn_selection;
size_t rsn_selection_len; size_t rsn_selection_len;
#endif
enum { enum {
WPA_VERSION_NO_WPA = 0 /* WPA not used */, WPA_VERSION_NO_WPA = 0 /* WPA not used */,
@@ -112,7 +114,9 @@ struct wpa_state_machine {
int wpa_key_mgmt; /* the selected WPA_KEY_MGMT_* */ int wpa_key_mgmt; /* the selected WPA_KEY_MGMT_* */
struct rsn_pmksa_cache_entry *pmksa; struct rsn_pmksa_cache_entry *pmksa;
#ifdef CONFIG_WPA3_COMPAT
bool rsn_override; bool rsn_override;
#endif
#ifdef CONFIG_IEEE80211R_AP #ifdef CONFIG_IEEE80211R_AP
u8 xxkey[PMK_LEN_MAX]; /* PSK or the second 256 bits of MSK, or the u8 xxkey[PMK_LEN_MAX]; /* PSK or the second 256 bits of MSK, or the

View File

@@ -346,6 +346,7 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
#ifdef CONFIG_WPA3_COMPAT
static int wpa_write_rsne_override(struct wpa_auth_config *conf, u8 *buf, static int wpa_write_rsne_override(struct wpa_auth_config *conf, u8 *buf,
size_t len) size_t len)
{ {
@@ -374,6 +375,7 @@ static int wpa_write_rsne_override(struct wpa_auth_config *conf, u8 *buf,
return pos - buf; return pos - buf;
} }
#endif
static u32 rsnxe_capab(struct wpa_auth_config *conf, int key_mgmt) static u32 rsnxe_capab(struct wpa_auth_config *conf, int key_mgmt)
@@ -419,6 +421,7 @@ int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len)
return pos - buf; return pos - buf;
} }
#ifdef CONFIG_WPA3_COMPAT
static int wpa_write_rsnxe_override(struct wpa_auth_config *conf, u8 *buf, static int wpa_write_rsnxe_override(struct wpa_auth_config *conf, u8 *buf,
size_t len) size_t len)
{ {
@@ -428,7 +431,6 @@ static int wpa_write_rsnxe_override(struct wpa_auth_config *conf, u8 *buf,
capab = rsnxe_capab(conf, conf->rsn_override_key_mgmt); capab = rsnxe_capab(conf, conf->rsn_override_key_mgmt);
flen = (capab & 0xff00) ? 2 : 1;
if (!capab) if (!capab)
return 0; /* no supported extended RSN capabilities */ return 0; /* no supported extended RSN capabilities */
tmp = capab; tmp = capab;
@@ -453,6 +455,7 @@ static int wpa_write_rsnxe_override(struct wpa_auth_config *conf, u8 *buf,
return pos - buf; return pos - buf;
} }
#endif
int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth) int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
@@ -469,9 +472,11 @@ int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
return res; return res;
pos += res; pos += res;
#ifdef CONFIG_WPA3_COMPAT
if (wpa_auth->conf.rsn_override_omit_rsnxe) if (wpa_auth->conf.rsn_override_omit_rsnxe)
res = 0; res = 0;
else else
#endif
res = wpa_write_rsnxe(&wpa_auth->conf, pos, res = wpa_write_rsnxe(&wpa_auth->conf, pos,
buf + sizeof(buf) - pos); buf + sizeof(buf) - pos);
@@ -496,6 +501,7 @@ int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
pos += res; pos += res;
} }
#ifdef CONFIG_WPA3_COMPAT
if ((wpa_auth->conf.wpa & WPA_PROTO_RSN) && if ((wpa_auth->conf.wpa & WPA_PROTO_RSN) &&
wpa_auth->conf.rsn_override_key_mgmt) { wpa_auth->conf.rsn_override_key_mgmt) {
res = wpa_write_rsne_override(&wpa_auth->conf, res = wpa_write_rsne_override(&wpa_auth->conf,
@@ -513,6 +519,7 @@ int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
return res; return res;
pos += res; pos += res;
} }
#endif
os_free(wpa_auth->wpa_ie); os_free(wpa_auth->wpa_ie);
wpa_auth->wpa_ie = os_malloc(pos - buf); wpa_auth->wpa_ie = os_malloc(pos - buf);
@@ -649,9 +656,11 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
return WPA_INVALID_GROUP; return WPA_INVALID_GROUP;
} }
#ifdef CONFIG_WPA3_COMPAT
if (sm->rsn_override) if (sm->rsn_override)
key_mgmt = data.key_mgmt & wpa_auth->conf.rsn_override_key_mgmt; key_mgmt = data.key_mgmt & wpa_auth->conf.rsn_override_key_mgmt;
else else
#endif
key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt; key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt;
if (!key_mgmt) { if (!key_mgmt) {
wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from " wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from "
@@ -686,10 +695,13 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
else else
sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK; sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
#ifdef CONFIG_WPA3_COMPAT
if (version == WPA_PROTO_RSN && sm->rsn_override) if (version == WPA_PROTO_RSN && sm->rsn_override)
ciphers = data.pairwise_cipher & ciphers = data.pairwise_cipher &
wpa_auth->conf.rsn_override_pairwise; wpa_auth->conf.rsn_override_pairwise;
else if (version == WPA_PROTO_RSN) else
#endif
if (version == WPA_PROTO_RSN)
ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise; ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise;
else else
ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise; ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise;

View File

@@ -191,7 +191,7 @@ int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
return nei_pos - nei_rep; return nei_pos - nei_rep;
} }
#ifdef CONFIG_WPA3_SAE #ifdef CONFIG_SAE_PK
static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
struct ieee802_11_elems *elems, struct ieee802_11_elems *elems,
int show_errors) int show_errors)
@@ -212,105 +212,20 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
oui = WPA_GET_BE24(pos); oui = WPA_GET_BE24(pos);
switch (oui) { switch (oui) {
case OUI_MICROSOFT:
/* Microsoft/Wi-Fi information elements are further typed and
* subtyped */
switch (pos[3]) {
case 1:
break;
case WMM_OUI_TYPE:
/* WMM information element */
if (elen < 5) {
wpa_printf(MSG_MSGDUMP, "short WMM "
"information element ignored "
"(len=%lu)",
(unsigned long) elen);
return -1;
}
switch (pos[4]) {
case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT:
case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT:
/*
* Share same pointer since only one of these
* is used and they start with same data.
* Length field can be used to distinguish the
* IEs.
*/
break;
case WMM_OUI_SUBTYPE_TSPEC_ELEMENT:
break;
default:
wpa_printf(MSG_EXCESSIVE, "unknown WMM "
"information element ignored "
"(subtype=%d len=%lu)",
pos[4], (unsigned long) elen);
return -1;
}
break;
case 4:
/* Wi-Fi Protected Setup (WPS) IE */
break;
default:
wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft "
"information element ignored "
"(type=%d len=%lu)",
pos[3], (unsigned long) elen);
return -1;
}
break;
case OUI_WFA: case OUI_WFA:
switch (pos[3]) { switch (pos[3]) {
#ifdef CONFIG_SAE_PK
case SAE_PK_OUI_TYPE: case SAE_PK_OUI_TYPE:
elems->sae_pk = pos + 4; elems->sae_pk = pos + 4;
elems->sae_pk_len = elen - 4; elems->sae_pk_len = elen - 4;
break; break;
#endif /* CONFIG_SAE_PK */
case P2P_OUI_TYPE:
/* Wi-Fi Alliance - P2P IE */
break;
case WFD_OUI_TYPE:
/* Wi-Fi Alliance - WFD IE */
break;
case HS20_INDICATION_OUI_TYPE:
/* Hotspot 2.0 */
break;
case HS20_OSEN_OUI_TYPE:
/* Hotspot 2.0 OSEN */
break;
case MBO_OUI_TYPE:
/* MBO-OCE */
break;
case HS20_ROAMING_CONS_SEL_OUI_TYPE:
/* Hotspot 2.0 Roaming Consortium Selection */
break;
case MULTI_AP_OUI_TYPE:
break;
case OWE_OUI_TYPE:
/* OWE Transition Mode element */
break;
case DPP_CC_OUI_TYPE:
/* DPP Configurator Connectivity element */
break;
case WFA_RSNE_OVERRIDE_OUI_TYPE:
elems->rsne_override = pos;
elems->rsne_override_len = elen;
break;
case WFA_RSN_SELECTION_OUI_TYPE:
if (elen < 4 + 1) {
wpa_printf(MSG_DEBUG,
"Too short RSN Selection element ignored");
return -1;
}
elems->rsn_selection = pos + 4;
elems->rsn_selection_len = elen - 4;
break;
default: default:
wpa_printf(MSG_EXCESSIVE, "Unknown WFA " wpa_printf(MSG_EXCESSIVE, "Unknown WFA "
"information element ignored " "information element ignored "
"(type=%d len=%lu)", "(type=%d len=%lu)",
pos[3], (unsigned long) elen); pos[3], (unsigned long) elen);
return -1; //TODO discuss if to ignore it
break;
//return -1;
} }
break; break;
default: default:
@@ -318,12 +233,14 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
"information element ignored (vendor OUI " "information element ignored (vendor OUI "
"%02x:%02x:%02x len=%lu)", "%02x:%02x:%02x len=%lu)",
pos[0], pos[1], pos[2], (unsigned long) elen); pos[0], pos[1], pos[2], (unsigned long) elen);
return -1; //TODO discuss if to ignore it
break;
//return -1;
} }
return 0; return 0;
} }
#endif /* CONFIG_WPA3_SAE */ #endif /* CONFIG_SAE_PK */
#ifdef CONFIG_SAE_PK #ifdef CONFIG_SAE_PK
static int ieee802_11_parse_extension(const u8 *pos, size_t elen, static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
@@ -357,13 +274,16 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
wpa_printf(MSG_EXCESSIVE, wpa_printf(MSG_EXCESSIVE,
"IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)", "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
ext_id, (unsigned int) elen); ext_id, (unsigned int) elen);
return -1; //TODO discuss if to ignore it
break;
//return -1;
} }
return 0; return 0;
} }
#endif /* CONFIG_SAE_PK */ #endif /* CONFIG_SAE_PK */
#if defined(CONFIG_RRM) || defined(CONFIG_WMM) || defined(CONFIG_SAE_PK)
static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len, static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len,
struct ieee802_11_elems *elems, struct ieee802_11_elems *elems,
int show_errors) int show_errors)
@@ -391,8 +311,6 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len,
unknown++; unknown++;
} }
break; break;
#endif /*CONFIG_SAE_PK*/
#ifdef CONFIG_WPA3_SAE
case WLAN_EID_VENDOR_SPECIFIC: case WLAN_EID_VENDOR_SPECIFIC:
if (ieee802_11_parse_vendor_specific(pos, elen, if (ieee802_11_parse_vendor_specific(pos, elen,
elems, elems,
@@ -400,15 +318,7 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len,
unknown++; unknown++;
} }
break; break;
#endif /* CONFIG_WPA3_SAE */ #endif /*CONFIG_SAE_PK*/
case WLAN_EID_RSN:
elems->rsn_ie = pos;
elems->rsn_ie_len = elen;
break;
case WLAN_EID_RSNX:
elems->rsnxe = pos;
elems->rsnxe_len = elen;
break;
#ifdef CONFIG_WNM #ifdef CONFIG_WNM
case WLAN_EID_EXT_CAPAB: case WLAN_EID_EXT_CAPAB:
/* extended caps can go beyond 8 octacts but we aren't using them now */ /* extended caps can go beyond 8 octacts but we aren't using them now */
@@ -426,6 +336,8 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len,
return ParseOK; return ParseOK;
} }
#endif
/** /**
* ieee802_11_parse_elems - Parse information elements in management frames * ieee802_11_parse_elems - Parse information elements in management frames
* @start: Pointer to the start of IEs * @start: Pointer to the start of IEs
@@ -434,12 +346,14 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len,
* @show_errors: Whether to show parsing errors in debug log * @show_errors: Whether to show parsing errors in debug log
* Returns: Parsing result * Returns: Parsing result
*/ */
#if defined(CONFIG_RRM) || defined(CONFIG_WMM) || defined(CONFIG_SAE_PK)
ParseRes ieee802_11_parse_elems(const u8 *start, size_t len, struct ieee802_11_elems *elems, int show_errors) ParseRes ieee802_11_parse_elems(const u8 *start, size_t len, struct ieee802_11_elems *elems, int show_errors)
{ {
os_memset(elems, 0, sizeof(*elems)); os_memset(elems, 0, sizeof(*elems));
return __ieee802_11_parse_elems(start, len, elems, show_errors); return __ieee802_11_parse_elems(start, len, elems, show_errors);
} }
#endif
struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len, struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
u32 oui_type) u32 oui_type)

View File

@@ -70,12 +70,6 @@ struct ieee802_11_elems {
const u8 *sae_pk; const u8 *sae_pk;
u8 sae_pk_len; u8 sae_pk_len;
#endif #endif
#ifdef CONFIG_WPA3_SAE
const u8 *rsne_override;
size_t rsne_override_len;
const u8 *rsn_selection;
size_t rsn_selection_len;
#endif
}; };
typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes; typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;

View File

@@ -303,35 +303,12 @@
#define DPP_OUI_TYPE 0x1A #define DPP_OUI_TYPE 0x1A
#define OUI_WFA 0x506f9a #define OUI_WFA 0x506f9a
#define WFA_RSNE_OVERRIDE_OUI_TYPE 0x29 #define WFA_RSNE_OVERRIDE_OUI_TYPE 0x29
#define WFA_RSNE_OVERRIDE_2_OUI_TYPE 0x2a
#define WFA_RSNXE_OVERRIDE_OUI_TYPE 0x2b #define WFA_RSNXE_OVERRIDE_OUI_TYPE 0x2b
#define WFA_RSN_SELECTION_OUI_TYPE 0x2c #define WFA_RSN_SELECTION_OUI_TYPE 0x2c
#define RSNE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a29 #define RSNE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a29
#define RSNE_OVERRIDE_2_IE_VENDOR_TYPE 0x506f9a2a
#define RSNXE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a2b #define RSNXE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a2b
#define RSN_SELECTION_IE_VENDOR_TYPE 0x506f9a2c #define RSN_SELECTION_IE_VENDOR_TYPE 0x506f9a2c
#define WFD_OUI_TYPE 10
#define NAN_OUI_TYPE 0x13
#define MBO_OUI_TYPE 22
#define OWE_OUI_TYPE 28
#define MULTI_AP_OUI_TYPE 0x1B
#define DPP_CC_OUI_TYPE 0x1e
#define SAE_PK_OUI_TYPE 0x1f
#define QM_IE_OUI_TYPE 0x22
#define WFA_CAPA_OUI_TYPE 0x23
#define P2P_OUI_TYPE 9
#define HS20_INDICATION_OUI_TYPE 16
#define HS20_OSEN_OUI_TYPE 18
#define HS20_ROAMING_CONS_SEL_OUI_TYPE 29
#define WMM_OUI_TYPE 2
#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1
#define WMM_OUI_SUBTYPE_TSPEC_ELEMENT 2
#define WMM_VERSION 1
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma pack(push, 1) #pragma pack(push, 1)
#endif /* _MSC_VER */ #endif /* _MSC_VER */
@@ -590,8 +567,6 @@ struct ieee80211_ht_operation {
/* 2 - Reserved */ /* 2 - Reserved */
#define WMM_TSPEC_DIRECTION_BI_DIRECTIONAL 3 #define WMM_TSPEC_DIRECTION_BI_DIRECTIONAL 3
#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
* 00:50:F2 */
#define MBO_IE_VENDOR_TYPE 0x506f9a16 #define MBO_IE_VENDOR_TYPE 0x506f9a16
#define OSEN_IE_VENDOR_TYPE 0x506f9a12 #define OSEN_IE_VENDOR_TYPE 0x506f9a12
#define SAE_PK_IE_VENDOR_TYPE 0x506f9a1f #define SAE_PK_IE_VENDOR_TYPE 0x506f9a1f

View File

@@ -1659,6 +1659,7 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end,
return 0; return 0;
} }
#ifdef CONFIG_WPA3_COMPAT
if (selector == RSNE_OVERRIDE_IE_VENDOR_TYPE) { if (selector == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
ie->rsne_override = pos; ie->rsne_override = pos;
ie->rsne_override_len = dlen; ie->rsne_override_len = dlen;
@@ -1685,6 +1686,7 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end,
ie->rsn_selection, ie->rsn_selection_len); ie->rsn_selection, ie->rsn_selection_len);
return 0; return 0;
} }
#endif
return 2; return 2;
} }

View File

@@ -472,13 +472,14 @@ struct wpa_eapol_ie_parse {
size_t transition_disable_len; size_t transition_disable_len;
const u8 *rsnxe; const u8 *rsnxe;
size_t rsnxe_len; size_t rsnxe_len;
#ifdef CONFIG_WPA3_COMPAT
const u8 *rsn_selection; const u8 *rsn_selection;
size_t rsn_selection_len; size_t rsn_selection_len;
const u8 *rsne_override; const u8 *rsne_override;
size_t rsne_override_len; size_t rsne_override_len;
const u8 *rsnxe_override; const u8 *rsnxe_override;
size_t rsnxe_override_len; size_t rsnxe_override_len;
#endif
}; };
int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie); int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie);
static inline int wpa_supplicant_parse_ies(const u8 *buf, size_t len, static inline int wpa_supplicant_parse_ies(const u8 *buf, size_t len,

View File

@@ -536,7 +536,10 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
size_t mic_len, hdrlen, rlen; size_t mic_len, hdrlen, rlen;
struct wpa_eapol_key *reply; struct wpa_eapol_key *reply;
struct wpa_eapol_key_192 *reply192; struct wpa_eapol_key_192 *reply192;
u8 *rsn_ie_buf = NULL, *buf2 = NULL; u8 *rsn_ie_buf = NULL;
#ifdef CONFIG_WPA3_COMPAT
u8 *buf2 = NULL;
#endif
u8 *rbuf, *key_mic; u8 *rbuf, *key_mic;
if (wpa_ie == NULL) { if (wpa_ie == NULL) {
@@ -582,6 +585,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
wpa_ie = rsn_ie_buf; wpa_ie = rsn_ie_buf;
} }
#endif /* CONFIG_IEEE80211R */ #endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_WPA3_COMPAT
if (sm->rsn_override != RSN_OVERRIDE_NOT_USED) { if (sm->rsn_override != RSN_OVERRIDE_NOT_USED) {
u8 *pos; u8 *pos;
@@ -610,7 +614,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
wpa_ie_len += 2 + 4 + 1; wpa_ie_len += 2 + 4 + 1;
} }
#endif
wpa_hexdump(MSG_MSGDUMP, "WPA: WPA IE for msg 2/4\n", wpa_ie, wpa_ie_len); wpa_hexdump(MSG_MSGDUMP, "WPA: WPA IE for msg 2/4\n", wpa_ie, wpa_ie_len);
mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len); mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
@@ -620,7 +624,9 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
&rlen, (void *) &reply); &rlen, (void *) &reply);
if (rbuf == NULL) { if (rbuf == NULL) {
os_free(rsn_ie_buf); os_free(rsn_ie_buf);
#ifdef CONFIG_WPA3_COMPAT
os_free(buf2); os_free(buf2);
#endif
return -1; return -1;
} }
reply192 = (struct wpa_eapol_key_192 *) reply; reply192 = (struct wpa_eapol_key_192 *) reply;
@@ -647,7 +653,9 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
} }
os_free(rsn_ie_buf); os_free(rsn_ie_buf);
#ifdef CONFIG_WPA3_COMPAT
os_free(buf2); os_free(buf2);
#endif
os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN); os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
wpa_printf(MSG_DEBUG, "WPA Send EAPOL-Key 2/4"); wpa_printf(MSG_DEBUG, "WPA Send EAPOL-Key 2/4");
@@ -733,8 +741,10 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
wpa_printf(MSG_DEBUG, "WPA: Failed to get random data for SNonce"); wpa_printf(MSG_DEBUG, "WPA: Failed to get random data for SNonce");
goto failed; goto failed;
} }
#ifdef CONFIG_WPA3_COMPAT
if (wpa_sm_rsn_overriding_supported(sm)) if (wpa_sm_rsn_overriding_supported(sm))
rsn_set_snonce_cookie(sm->snonce); rsn_set_snonce_cookie(sm->snonce);
#endif
sm->renew_snonce = 0; sm->renew_snonce = 0;
wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce", wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
sm->snonce, WPA_NONCE_LEN); sm->snonce, WPA_NONCE_LEN);
@@ -1215,6 +1225,7 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
return -1; return -1;
} }
#ifdef CONFIG_WPA3_COMPAT
if (sm->proto == WPA_PROTO_RSN && wpa_sm_rsn_overriding_supported(sm)) { if (sm->proto == WPA_PROTO_RSN && wpa_sm_rsn_overriding_supported(sm)) {
if ((sm->ap_rsne_override && !ie->rsne_override) || if ((sm->ap_rsne_override && !ie->rsne_override) ||
(!sm->ap_rsne_override && ie->rsne_override) || (!sm->ap_rsne_override && ie->rsne_override) ||
@@ -1256,6 +1267,7 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
return -1; return -1;
} }
} }
#endif
return 0; return 0;
} }
@@ -1349,10 +1361,19 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
key_info = WPA_GET_BE16(key->key_info); key_info = WPA_GET_BE16(key->key_info);
if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
goto failed; goto failed;
if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0) }
if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0) {
goto failed; goto failed;
}
if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: ANonce from message 1 of 4-Way Handshake differs from 3 of 4-Way Handshake - drop packet (src="
MACSTR ")", MAC2STR(sm->bssid));
goto failed;
}
if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) { if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
wpa_printf(MSG_DEBUG, "WPA: GTK IE in unencrypted key data"); wpa_printf(MSG_DEBUG, "WPA: GTK IE in unencrypted key data");
@@ -2258,10 +2279,12 @@ void wpa_sm_deinit(void)
sm->ap_rsn_ie = NULL; sm->ap_rsn_ie = NULL;
os_free(sm->ap_rsnxe); os_free(sm->ap_rsnxe);
sm->ap_rsnxe = NULL; sm->ap_rsnxe = NULL;
#ifdef CONFIG_WPA3_COMPAT
os_free(sm->ap_rsne_override); os_free(sm->ap_rsne_override);
sm->ap_rsne_override = NULL; sm->ap_rsne_override = NULL;
os_free(sm->ap_rsnxe_override); os_free(sm->ap_rsnxe_override);
sm->ap_rsnxe_override = NULL; sm->ap_rsnxe_override = NULL;
#endif
wpa_sm_drop_sa(sm); wpa_sm_drop_sa(sm);
memset(sm, 0, sizeof(*sm)); memset(sm, 0, sizeof(*sm));
} }
@@ -2273,6 +2296,7 @@ void wpa_sm_deinit(void)
* @value: Parameter value * @value: Parameter value
* Returns: 0 on success, -1 on failure * Returns: 0 on success, -1 on failure
*/ */
#ifdef CONFIG_WPA3_COMPAT
int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
unsigned int value) unsigned int value)
{ {
@@ -2293,18 +2317,21 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
} }
return ret; return ret;
} }
#endif
#ifdef CONFIG_WPA3_COMPAT
static const u8 * wpa_sm_get_ap_rsne(struct wpa_sm *sm, size_t *len) static const u8 * wpa_sm_get_ap_rsne(struct wpa_sm *sm, size_t *len)
{ {
if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE) { if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE) {
*len = sm->ap_rsne_override_len; *len = sm->ap_rsne_override_len;
return sm->ap_rsne_override; return sm->ap_rsne_override;
} }
*len = sm->ap_rsn_ie_len; *len = sm->ap_rsn_ie_len;
return sm->ap_rsn_ie; return sm->ap_rsn_ie;
} }
#endif
#ifdef CONFIG_WPA3_COMPAT
bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm) bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm)
{ {
const u8 *rsne; const u8 *rsne;
@@ -2314,6 +2341,7 @@ bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm)
return sm->rsn_override_support && rsne; return sm->rsn_override_support && rsne;
} }
#endif
#ifdef ESP_SUPPLICANT #ifdef ESP_SUPPLICANT
/** /**
@@ -2446,13 +2474,13 @@ void wpa_set_pmk(uint8_t *pmk, size_t pmk_length, const u8 *pmkid, bool cache_pm
} }
} }
int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, u8 pairwise_cipher, u8 group_cipher, char *passphrase, u8 *ssid, size_t ssid_len) int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, uint8_t pairwise_cipher, uint8_t group_cipher, char *passphrase, uint8_t *ssid, int ssid_len)
{ {
int res = 0; int res = 0;
struct wpa_sm *sm = &gWpaSm; struct wpa_sm *sm = &gWpaSm;
bool use_pmk_cache = !esp_wifi_skip_supp_pmkcaching(); bool use_pmk_cache = !esp_wifi_skip_supp_pmkcaching();
u8 assoc_ie[128]; uint8_t assoc_ie[128];
uint8_t assoc_ie_len = sizeof(assoc_ie); uint16_t assoc_ie_len = sizeof(assoc_ie);
bool reassoc_same_ess = false; bool reassoc_same_ess = false;
int try_opportunistic = 0; int try_opportunistic = 0;
const u8 *ie = NULL; const u8 *ie = NULL;
@@ -2579,12 +2607,13 @@ int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, u8 pairwise_cipher, u8 group_ci
wpa_sm_set_ap_rsn_ie(sm, ie, ie ? (ie[1] + 2) : 0); wpa_sm_set_ap_rsn_ie(sm, ie, ie ? (ie[1] + 2) : 0);
ie = esp_wifi_sta_get_ie(bssid, WLAN_EID_RSNX); ie = esp_wifi_sta_get_ie(bssid, WLAN_EID_RSNX);
wpa_sm_set_ap_rsnxe(sm, ie, ie ? (ie[1] + 2) : 0); wpa_sm_set_ap_rsnxe(sm, ie, ie ? (ie[1] + 2) : 0);
if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA)) {
#ifdef CONFIG_WPA3_COMPAT
ie = esp_wifi_sta_get_ie(bssid, WFA_RSNE_OVERRIDE_OUI_TYPE); ie = esp_wifi_sta_get_ie(bssid, WFA_RSNE_OVERRIDE_OUI_TYPE);
wpa_sm_set_ap_rsne_override(sm, ie, ie ? (ie[1] + 2) : 0); wpa_sm_set_ap_rsne_override(sm, ie, ie ? (ie[1] + 2) : 0);
ie = esp_wifi_sta_get_ie(bssid, WFA_RSNXE_OVERRIDE_OUI_TYPE); ie = esp_wifi_sta_get_ie(bssid, WFA_RSNXE_OVERRIDE_OUI_TYPE);
wpa_sm_set_ap_rsnxe_override(sm, ie, ie ? (ie[1] + 2) : 0); wpa_sm_set_ap_rsnxe_override(sm, ie, ie ? (ie[1] + 2) : 0);
} #endif
pos = assoc_ie; pos = assoc_ie;
res = wpa_gen_rsnxe(sm, pos, assoc_ie_len); res = wpa_gen_rsnxe(sm, pos, assoc_ie_len);
@@ -2597,14 +2626,15 @@ int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, u8 pairwise_cipher, u8 group_ci
return -1; return -1;
} }
pos += assoc_ie_len; pos += assoc_ie_len;
#ifdef CONFIG_WPA3_COMPAT
wpa_sm_set_param(sm, WPA_PARAM_RSN_OVERRIDE_SUPPORT, wpa_sm_set_param(sm, WPA_PARAM_RSN_OVERRIDE_SUPPORT,
esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA)); esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA));
wpa_sm_set_param(sm, WPA_PARAM_RSN_OVERRIDE, wpa_sm_set_param(sm, WPA_PARAM_RSN_OVERRIDE,
RSN_OVERRIDE_NOT_USED); RSN_OVERRIDE_NOT_USED);
ie = esp_wifi_sta_get_ie(bssid, WFA_RSNE_OVERRIDE_OUI_TYPE); ie = esp_wifi_sta_get_ie(bssid, WFA_RSNE_OVERRIDE_OUI_TYPE);
if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA) && if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA) && ie) {
ie && ie[0] != WLAN_EID_RSN) {
enum rsn_selection_variant variant = RSN_SELECTION_RSNE; enum rsn_selection_variant variant = RSN_SELECTION_RSNE;
if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4) { if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4) {
@@ -2626,6 +2656,8 @@ int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, u8 pairwise_cipher, u8 group_ci
*pos = variant; *pos = variant;
assoc_ie_len += 2 + 4 + 1; assoc_ie_len += 2 + 4 + 1;
} }
#endif
wpa_hexdump(MSG_DEBUG, "WPA: ASSOC IE LEN", assoc_ie, assoc_ie_len); wpa_hexdump(MSG_DEBUG, "WPA: ASSOC IE LEN", assoc_ie, assoc_ie_len);
esp_set_assoc_ie(bssid, assoc_ie, assoc_ie_len, true); esp_set_assoc_ie(bssid, assoc_ie, assoc_ie_len, true);
@@ -2984,6 +3016,7 @@ int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len)
} }
#ifdef CONFIG_WPA3_COMPAT
int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len) int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len)
{ {
if (!sm) if (!sm)
@@ -3007,8 +3040,10 @@ int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len)
return 0; return 0;
} }
#endif
#ifdef CONFIG_WPA3_COMPAT
int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len) int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len)
{ {
if (!sm) if (!sm)
@@ -3032,6 +3067,7 @@ int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len)
return 0; return 0;
} }
#endif
int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len) int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len)

View File

@@ -35,10 +35,12 @@ struct l2_ethhdr {
be16 h_proto; be16 h_proto;
} STRUCT_PACKED; } STRUCT_PACKED;
#ifdef CONFIG_WPA3_COMPAT
enum wpa_sm_conf_params { enum wpa_sm_conf_params {
WPA_PARAM_RSN_OVERRIDE, WPA_PARAM_RSN_OVERRIDE,
WPA_PARAM_RSN_OVERRIDE_SUPPORT, WPA_PARAM_RSN_OVERRIDE_SUPPORT,
}; };
#endif
void wpa_sm_set_state(enum wpa_states state); void wpa_sm_set_state(enum wpa_states state);
@@ -62,16 +64,20 @@ int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len); int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
#ifdef CONFIG_WPA3_COMPAT
int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len); int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len); int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len);
#endif
int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len); int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
void wpa_sm_drop_sa(struct wpa_sm *sm); void wpa_sm_drop_sa(struct wpa_sm *sm);
#ifdef CONFIG_WPA3_COMPAT
int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
unsigned int value); unsigned int value);
#endif
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len); int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len);

View File

@@ -22,12 +22,13 @@ struct install_key {
u8 key[32]; u8 key[32];
}; };
#ifdef CONFIG_WPA3_COMPAT
enum wpa_rsn_override { enum wpa_rsn_override {
RSN_OVERRIDE_NOT_USED, RSN_OVERRIDE_NOT_USED,
RSN_OVERRIDE_RSNE, RSN_OVERRIDE_RSNE,
RSN_OVERRIDE_RSNE_OVERRIDE, RSN_OVERRIDE_RSNE_OVERRIDE,
}; };
#endif
/** /**
* struct wpa_sm - Internal WPA state machine data * struct wpa_sm - Internal WPA state machine data
*/ */
@@ -82,8 +83,10 @@ struct wpa_sm {
u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe; u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe;
size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len; size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len;
#ifdef CONFIG_WPA3_COMPAT
u8 *ap_rsne_override, *ap_rsnxe_override; u8 *ap_rsne_override, *ap_rsnxe_override;
size_t ap_rsne_override_len, ap_rsnxe_override_len; size_t ap_rsne_override_len, ap_rsnxe_override_len;
#endif
bool key_install; bool key_install;
@@ -127,9 +130,10 @@ struct wpa_sm {
#endif /* CONFIG_OWE_STA */ #endif /* CONFIG_OWE_STA */
int (*wpa_sm_wps_disable)(void); int (*wpa_sm_wps_disable)(void);
esp_err_t (*wpa_sm_eap_disable)(void); esp_err_t (*wpa_sm_eap_disable)(void);
#ifdef CONFIG_WPA3_COMPAT
bool rsn_override_support; bool rsn_override_support;
enum wpa_rsn_override rsn_override; enum wpa_rsn_override rsn_override;
#endif
}; };
/** /**
@@ -215,12 +219,13 @@ void eapol_txcb(uint8_t *eapol_payload, size_t len, bool tx_failure);
void wpa_set_profile(u32 wpa_proto, u8 auth_mode); void wpa_set_profile(u32 wpa_proto, u8 auth_mode);
int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, u8 pairwise_cipher, u8 group_cipher, char *passphrase, u8 *ssid, size_t ssid_len); int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, uint8_t pairwise_cipher, uint8_t group_cipher, char *passphrase, uint8_t *ssid, int ssid_len);
int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len); int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len);
int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
const struct wpa_eapol_key *key, struct wpa_ptk *ptk); const struct wpa_eapol_key *key, struct wpa_ptk *ptk);
#ifdef CONFIG_WPA3_COMPAT
bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm); bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm);
#endif
#endif /* WPA_I_H */ #endif /* WPA_I_H */

View File

@@ -39,6 +39,7 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
return wpa_parse_wpa_ie_rsnxe(wpa_ie, wpa_ie_len, data); return wpa_parse_wpa_ie_rsnxe(wpa_ie, wpa_ie_len, data);
} else if (wpa_ie[0] == WLAN_EID_WAPI) { } else if (wpa_ie[0] == WLAN_EID_WAPI) {
return 0; return 0;
#ifdef CONFIG_WPA3_COMPAT
} else if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC && } else if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC &&
wpa_ie[1] >= 4 && wpa_ie[1] >= 4 &&
WPA_GET_BE32(&wpa_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE) { WPA_GET_BE32(&wpa_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
@@ -47,7 +48,9 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
wpa_ie[1] >= 4 && wpa_ie[1] >= 4 &&
WPA_GET_BE32(&wpa_ie[2]) == RSNXE_OVERRIDE_IE_VENDOR_TYPE) { WPA_GET_BE32(&wpa_ie[2]) == RSNXE_OVERRIDE_IE_VENDOR_TYPE) {
return wpa_parse_wpa_ie_rsnxe(wpa_ie, wpa_ie_len, data); return wpa_parse_wpa_ie_rsnxe(wpa_ie, wpa_ie_len, data);
#endif
} }
return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data); return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
} }
@@ -304,7 +307,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_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len)
{ {
u8 *pos = rsnxe; u8 *pos = rsnxe;
u16 capab = 0, tmp; u32 capab = 0, tmp;
size_t flen; size_t flen;
if (wpa_key_mgmt_sae(sm->key_mgmt) && if (wpa_key_mgmt_sae(sm->key_mgmt) &&
@@ -333,12 +336,11 @@ int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len)
*pos++ = WLAN_EID_RSNX; *pos++ = WLAN_EID_RSNX;
*pos++ = flen; *pos++ = flen;
*pos++ = capab & 0x00ff; while (capab) {
*pos++ = capab & 0xff;
capab >>= 8; capab >>= 8;
if (capab) }
*pos++ = capab;
return pos - rsnxe; return pos - rsnxe;
} }
#endif // ESP_SUPPLICANT #endif // ESP_SUPPLICANT

View File

@@ -78,7 +78,9 @@ void wifi_init_softap(void)
#else /* CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT */ #else /* CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT */
.authmode = WIFI_AUTH_WPA2_PSK, .authmode = WIFI_AUTH_WPA2_PSK,
#endif #endif
.wpa3_compatible_mode = 0, #ifdef CONFIG_ESP_WIFI_WPA3_COMPATIBLE_SUPPORT
.wpa3_compatible_mode = 1,
#endif
.pmf_cfg = { .pmf_cfg = {
.required = true, .required = true,
}, },

View File

@@ -129,6 +129,9 @@ void wifi_init_sta(void)
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD, .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
.sae_pwe_h2e = ESP_WIFI_SAE_MODE, .sae_pwe_h2e = ESP_WIFI_SAE_MODE,
.sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER, .sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER,
#ifdef CONFIG_ESP_WIFI_WPA3_COMPATIBLE_SUPPORT
.wpa3_compatible_mode = 1,
#endif
}, },
}; };
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );