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"
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
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
bool "WiFi SLP IRAM speed optimization"
select PM_SLP_DEFAULT_PARAMS_OPT

View File

@@ -564,7 +564,7 @@ typedef struct {
uint32_t owe_enabled: 1; /**< Whether OWE is enabled for the connection */
uint32_t transition_disable: 1; /**< Whether to enable transition disable feature */
uint32_t wpa3_compatible_mode: 1; /**< Whether to enable wpa3 compatible authmode feature */
uint32_t reserved1: 25; /**< Reserved for future feature set */
uint32_t reserved1: 25; /**< Reserved for future feature set */
wifi_sae_pwe_method_t sae_pwe_h2e; /**< Configuration for SAE PWE derivation method */
wifi_sae_pk_mode_t sae_pk_mode; /**< Configuration for SAE-PK (Public Key) Authentication method */
uint8_t failure_retry_cnt; /**< Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config.

View File

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

View File

@@ -110,15 +110,19 @@ void *hostap_init(void)
}
#endif /* CONFIG_IEEE80211W */
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;
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_pairwise = WPA_CIPHER_CCMP;
hapd->conf->rsn_override_mfp = MGMT_FRAME_PROTECTION_REQUIRED;
auth_conf->rsn_override_key_mgmt = WPA_KEY_MGMT_SAE;
auth_conf->rsn_override_pairwise = WPA_CIPHER_CCMP;
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 */
if (auth_conf->wpa == WPA_PROTO_WPA && pairwise_cipher == WIFI_CIPHER_TYPE_CCMP) {
@@ -224,7 +228,6 @@ void *hostap_init(void)
#ifdef CONFIG_SAE
auth_conf->sae_require_mfp = 1;
#endif /* CONFIG_SAE */
auth_conf->rsn_override_omit_rsnxe = 1;
hapd->conf->ap_max_inactivity = 5 * 60;
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 *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason)
bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie,
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();
enum wpa_validate_result res = WPA_IE_OK;
int status = WLAN_STATUS_SUCCESS;
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;
}
if (hapd) {
@@ -434,8 +443,16 @@ bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, struct ieee802_1
goto send_resp;
}
wpa_auth_set_rsn_selection(sta->wpa_sm, elems.rsn_selection, elems.rsn_selection_len);
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, elems.rsn_ie, elems.rsn_ie_len, elems.rsnxe, elems.rsnxe_len);
#ifdef CONFIG_WPA3_COMPAT
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
if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae &&
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);
send_resp:
if (!elems.rsnxe) {
if (!rsnxe) {
omit_rsnxe = true;
}
#ifdef CONFIG_WPA3_COMPAT
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) {
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);
void *(*wpa_ap_init)(void);
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);
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);

View File

@@ -46,17 +46,19 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid, size_t *sae_msg_len)
use_pt = 1;
}
#ifdef CONFIG_WPA3_COMPAT
if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA)) {
rsnxe = esp_wifi_sta_get_ie((u8*)bssid, WFA_RSNXE_OVERRIDE_OUI_TYPE);
if (rsnxe) {
rsnxe_capa = rsnxe[2 + 4];
}
}
#endif
if (!rsnxe) {
rsnxe = esp_wifi_sta_get_ie((u8*)bssid, WLAN_EID_RSNX);
}
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];
if (rsnxe) {
rsnxe_capa = rsnxe[2];
}
}
#endif /* CONFIG_SAE_H2E */

View File

@@ -377,37 +377,22 @@ static int check_n_add_wps_sta(struct hostapd_data *hapd, struct sta_info *sta_i
}
#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 hostapd_data *hapd = hostapd_get_hapd_data();
uint8_t reason = WLAN_REASON_PREV_AUTH_NOT_VALID;
struct ieee802_11_elems elems;
if (!hapd) {
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) {
struct sta_info *old_sta = *sta;
#ifdef CONFIG_SAE
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));
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;
}
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
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));
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;
}
return false;
@@ -446,7 +431,7 @@ process_old_sta:
#endif /* CONFIG_SAE */
#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) {
goto done;
}
@@ -454,8 +439,7 @@ process_old_sta:
goto fail;
}
#endif
if (hostap_new_assoc_sta(sta_info, bssid, elems, pmf_enable, subtype, pairwise_cipher, &reason)) {
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)) {
goto done;
} else {
goto fail;

View File

@@ -150,8 +150,11 @@ int hostapd_setup_sae_pt(struct hostapd_bss_config *conf)
#ifdef CONFIG_SAE_H2E
struct hostapd_ssid *ssid = &conf->ssid;
if (conf->sae_pwe == SAE_PWE_HUNT_AND_PECK ||
!wpa_key_mgmt_sae(conf->wpa_key_mgmt |
conf->rsn_override_key_mgmt))
!wpa_key_mgmt_sae(conf->wpa_key_mgmt
#ifdef CONFIG_WPA3_COMPAT
| conf->rsn_override_key_mgmt
#endif
))
return 0; /* PT not needed */
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_key_mgmt;
#ifdef CONFIG_WPA3_COMPAT
int rsn_override_key_mgmt;
#endif
#ifdef CONFIG_IEEE80211W
enum mfp_options ieee80211w;
#ifdef CONFIG_WPA3_COMPAT
enum mfp_options rsn_override_mfp;
#endif
/* dot11AssociationSAQueryMaximumTimeout (in TUs) */
unsigned int assoc_sa_query_max_timeout;
/* dot11AssociationSAQueryRetryTimeout (in TUs) */
@@ -222,7 +226,9 @@ struct hostapd_bss_config {
int wpa_ptk_rekey;
int rsn_pairwise;
int rsn_preauth;
#ifdef CONFIG_WPA3_COMPAT
int rsn_override_pairwise;
#endif
char *rsn_preauth_interfaces;
#ifdef CONFIG_IEEE80211R
@@ -310,7 +316,9 @@ struct hostapd_bss_config {
int *sae_groups;
#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;
#endif
};
@@ -387,8 +395,9 @@ 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 hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, struct ieee802_11_elems elems,
bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason);
bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie,
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);
#endif /* HOSTAPD_CONFIG_H */

View File

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

View File

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

View File

@@ -100,8 +100,10 @@ struct wpa_state_machine {
size_t wpa_ie_len;
u8 *rsnxe;
size_t rsnxe_len;
#ifdef CONFIG_WPA3_COMPAT
u8 *rsn_selection;
size_t rsn_selection_len;
#endif
enum {
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_* */
struct rsn_pmksa_cache_entry *pmksa;
#ifdef CONFIG_WPA3_COMPAT
bool rsn_override;
#endif
#ifdef CONFIG_IEEE80211R_AP
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,
size_t len)
{
@@ -374,6 +375,7 @@ static int wpa_write_rsne_override(struct wpa_auth_config *conf, u8 *buf,
return pos - buf;
}
#endif
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;
}
#ifdef CONFIG_WPA3_COMPAT
static int wpa_write_rsnxe_override(struct wpa_auth_config *conf, u8 *buf,
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);
flen = (capab & 0xff00) ? 2 : 1;
if (!capab)
return 0; /* no supported extended RSN capabilities */
tmp = capab;
@@ -453,6 +455,7 @@ static int wpa_write_rsnxe_override(struct wpa_auth_config *conf, u8 *buf,
return pos - buf;
}
#endif
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;
pos += res;
#ifdef CONFIG_WPA3_COMPAT
if (wpa_auth->conf.rsn_override_omit_rsnxe)
res = 0;
else
#endif
res = wpa_write_rsnxe(&wpa_auth->conf, pos,
buf + sizeof(buf) - pos);
@@ -496,6 +501,7 @@ int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
pos += res;
}
#ifdef CONFIG_WPA3_COMPAT
if ((wpa_auth->conf.wpa & WPA_PROTO_RSN) &&
wpa_auth->conf.rsn_override_key_mgmt) {
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;
pos += res;
}
#endif
os_free(wpa_auth->wpa_ie);
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;
}
#ifdef CONFIG_WPA3_COMPAT
if (sm->rsn_override)
key_mgmt = data.key_mgmt & wpa_auth->conf.rsn_override_key_mgmt;
else
#endif
key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt;
if (!key_mgmt) {
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
sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
#ifdef CONFIG_WPA3_COMPAT
if (version == WPA_PROTO_RSN && sm->rsn_override)
ciphers = data.pairwise_cipher &
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;
else
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;
}
#ifdef CONFIG_WPA3_SAE
#ifdef CONFIG_SAE_PK
static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
struct ieee802_11_elems *elems,
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);
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:
switch (pos[3]) {
#ifdef CONFIG_SAE_PK
case SAE_PK_OUI_TYPE:
elems->sae_pk = pos + 4;
elems->sae_pk_len = elen - 4;
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:
wpa_printf(MSG_EXCESSIVE, "Unknown WFA "
"information element ignored "
"(type=%d len=%lu)",
pos[3], (unsigned long) elen);
return -1;
//TODO discuss if to ignore it
break;
//return -1;
}
break;
default:
@@ -318,12 +233,14 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
"information element ignored (vendor OUI "
"%02x:%02x:%02x len=%lu)",
pos[0], pos[1], pos[2], (unsigned long) elen);
return -1;
//TODO discuss if to ignore it
break;
//return -1;
}
return 0;
}
#endif /* CONFIG_WPA3_SAE */
#endif /* CONFIG_SAE_PK */
#ifdef CONFIG_SAE_PK
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,
"IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
ext_id, (unsigned int) elen);
return -1;
//TODO discuss if to ignore it
break;
//return -1;
}
return 0;
}
#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,
struct ieee802_11_elems *elems,
int show_errors)
@@ -391,8 +311,6 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len,
unknown++;
}
break;
#endif /*CONFIG_SAE_PK*/
#ifdef CONFIG_WPA3_SAE
case WLAN_EID_VENDOR_SPECIFIC:
if (ieee802_11_parse_vendor_specific(pos, elen,
elems,
@@ -400,15 +318,7 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len,
unknown++;
}
break;
#endif /* CONFIG_WPA3_SAE */
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;
#endif /*CONFIG_SAE_PK*/
#ifdef CONFIG_WNM
case WLAN_EID_EXT_CAPAB:
/* 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;
}
#endif
/**
* ieee802_11_parse_elems - Parse information elements in management frames
* @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
* 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)
{
os_memset(elems, 0, sizeof(*elems));
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,
u32 oui_type)

View File

@@ -70,12 +70,6 @@ struct ieee802_11_elems {
const u8 *sae_pk;
u8 sae_pk_len;
#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;

View File

@@ -303,35 +303,12 @@
#define DPP_OUI_TYPE 0x1A
#define OUI_WFA 0x506f9a
#define WFA_RSNE_OVERRIDE_OUI_TYPE 0x29
#define WFA_RSNE_OVERRIDE_2_OUI_TYPE 0x2a
#define WFA_RSNXE_OVERRIDE_OUI_TYPE 0x2b
#define WFA_RSN_SELECTION_OUI_TYPE 0x2c
#define RSNE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a29
#define RSNE_OVERRIDE_2_IE_VENDOR_TYPE 0x506f9a2a
#define RSNXE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a2b
#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
#pragma pack(push, 1)
#endif /* _MSC_VER */
@@ -590,8 +567,6 @@ struct ieee80211_ht_operation {
/* 2 - Reserved */
#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 OSEN_IE_VENDOR_TYPE 0x506f9a12
#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;
}
#ifdef CONFIG_WPA3_COMPAT
if (selector == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
ie->rsne_override = pos;
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);
return 0;
}
#endif
return 2;
}

View File

@@ -472,13 +472,14 @@ struct wpa_eapol_ie_parse {
size_t transition_disable_len;
const u8 *rsnxe;
size_t rsnxe_len;
#ifdef CONFIG_WPA3_COMPAT
const u8 *rsn_selection;
size_t rsn_selection_len;
const u8 *rsne_override;
size_t rsne_override_len;
const u8 *rsnxe_override;
size_t rsnxe_override_len;
#endif
};
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,

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;
struct wpa_eapol_key *reply;
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;
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;
}
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_WPA3_COMPAT
if (sm->rsn_override != RSN_OVERRIDE_NOT_USED) {
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;
}
#endif
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);
@@ -620,7 +624,9 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
&rlen, (void *) &reply);
if (rbuf == NULL) {
os_free(rsn_ie_buf);
#ifdef CONFIG_WPA3_COMPAT
os_free(buf2);
#endif
return -1;
}
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);
#ifdef CONFIG_WPA3_COMPAT
os_free(buf2);
#endif
os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
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");
goto failed;
}
#ifdef CONFIG_WPA3_COMPAT
if (wpa_sm_rsn_overriding_supported(sm))
rsn_set_snonce_cookie(sm->snonce);
#endif
sm->renew_snonce = 0;
wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
sm->snonce, WPA_NONCE_LEN);
@@ -1215,6 +1225,7 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
return -1;
}
#ifdef CONFIG_WPA3_COMPAT
if (sm->proto == WPA_PROTO_RSN && wpa_sm_rsn_overriding_supported(sm)) {
if ((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;
}
}
#endif
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);
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;
if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
}
if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0) {
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)) {
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;
os_free(sm->ap_rsnxe);
sm->ap_rsnxe = NULL;
#ifdef CONFIG_WPA3_COMPAT
os_free(sm->ap_rsne_override);
sm->ap_rsne_override = NULL;
os_free(sm->ap_rsnxe_override);
sm->ap_rsnxe_override = NULL;
#endif
wpa_sm_drop_sa(sm);
memset(sm, 0, sizeof(*sm));
}
@@ -2273,6 +2296,7 @@ void wpa_sm_deinit(void)
* @value: Parameter value
* 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,
unsigned int value)
{
@@ -2293,18 +2317,21 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
}
return ret;
}
#endif
#ifdef CONFIG_WPA3_COMPAT
static const u8 * wpa_sm_get_ap_rsne(struct wpa_sm *sm, size_t *len)
{
if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE) {
*len = sm->ap_rsne_override_len;
return sm->ap_rsne_override;
}
*len = sm->ap_rsn_ie_len;
return sm->ap_rsn_ie;
}
#endif
#ifdef CONFIG_WPA3_COMPAT
bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm)
{
const u8 *rsne;
@@ -2314,6 +2341,7 @@ bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm)
return sm->rsn_override_support && rsne;
}
#endif
#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;
struct wpa_sm *sm = &gWpaSm;
bool use_pmk_cache = !esp_wifi_skip_supp_pmkcaching();
u8 assoc_ie[128];
uint8_t assoc_ie_len = sizeof(assoc_ie);
uint8_t assoc_ie[128];
uint16_t assoc_ie_len = sizeof(assoc_ie);
bool reassoc_same_ess = false;
int try_opportunistic = 0;
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);
ie = esp_wifi_sta_get_ie(bssid, WLAN_EID_RSNX);
wpa_sm_set_ap_rsnxe(sm, ie, ie ? (ie[1] + 2) : 0);
if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA)) {
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);
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);
}
#ifdef CONFIG_WPA3_COMPAT
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);
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);
#endif
pos = assoc_ie;
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;
}
pos += assoc_ie_len;
#ifdef CONFIG_WPA3_COMPAT
wpa_sm_set_param(sm, WPA_PARAM_RSN_OVERRIDE_SUPPORT,
esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA));
wpa_sm_set_param(sm, WPA_PARAM_RSN_OVERRIDE,
RSN_OVERRIDE_NOT_USED);
ie = esp_wifi_sta_get_ie(bssid, WFA_RSNE_OVERRIDE_OUI_TYPE);
if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA) &&
ie && ie[0] != WLAN_EID_RSN) {
if (esp_wifi_wpa3_compatible_mode_enabled(WIFI_IF_STA) && ie) {
enum rsn_selection_variant variant = RSN_SELECTION_RSNE;
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;
assoc_ie_len += 2 + 4 + 1;
}
#endif
wpa_hexdump(MSG_DEBUG, "WPA: ASSOC IE LEN", assoc_ie, assoc_ie_len);
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)
{
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;
}
#endif
#ifdef CONFIG_WPA3_COMPAT
int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len)
{
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;
}
#endif
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;
} STRUCT_PACKED;
#ifdef CONFIG_WPA3_COMPAT
enum wpa_sm_conf_params {
WPA_PARAM_RSN_OVERRIDE,
WPA_PARAM_RSN_OVERRIDE_SUPPORT,
};
#endif
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);
#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_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);
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,
unsigned int value);
#endif
#ifdef CONFIG_IEEE80211R
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];
};
#ifdef CONFIG_WPA3_COMPAT
enum wpa_rsn_override {
RSN_OVERRIDE_NOT_USED,
RSN_OVERRIDE_RSNE,
RSN_OVERRIDE_RSNE_OVERRIDE,
};
#endif
/**
* struct wpa_sm - Internal WPA state machine data
*/
@@ -82,8 +83,10 @@ struct wpa_sm {
u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe;
size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len;
#ifdef CONFIG_WPA3_COMPAT
u8 *ap_rsne_override, *ap_rsnxe_override;
size_t ap_rsne_override_len, ap_rsnxe_override_len;
#endif
bool key_install;
@@ -127,9 +130,10 @@ struct wpa_sm {
#endif /* CONFIG_OWE_STA */
int (*wpa_sm_wps_disable)(void);
esp_err_t (*wpa_sm_eap_disable)(void);
#ifdef CONFIG_WPA3_COMPAT
bool rsn_override_support;
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);
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_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
const struct wpa_eapol_key *key, struct wpa_ptk *ptk);
#ifdef CONFIG_WPA3_COMPAT
bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm);
#endif
#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);
} else if (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 &&
wpa_ie[1] >= 4 &&
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_GET_BE32(&wpa_ie[2]) == RSNXE_OVERRIDE_IE_VENDOR_TYPE) {
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);
}
@@ -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)
{
u8 *pos = rsnxe;
u16 capab = 0, tmp;
u32 capab = 0, tmp;
size_t flen;
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++ = flen;
*pos++ = capab & 0x00ff;
capab >>= 8;
if (capab)
*pos++ = capab;
while (capab) {
*pos++ = capab & 0xff;
capab >>= 8;
}
return pos - rsnxe;
}
#endif // ESP_SUPPLICANT

View File

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

View File

@@ -129,6 +129,9 @@ void wifi_init_sta(void)
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
.sae_pwe_h2e = ESP_WIFI_SAE_MODE,
.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) );