From b92f61885c14b4475d9cf84d691518f00890551d Mon Sep 17 00:00:00 2001 From: Utkarsh Soni Date: Thu, 20 Oct 2022 14:45:18 +0530 Subject: [PATCH] Don't use default RSNE/RSNXE when the driver indicates cross SSID roaming During cross SSID roaming wpa_supplicant ended up using the default RSNE/RSNXE in EAPOL-Key msg 2/4 though the driver indicated (Re)Association Request frame elements without RSNE/RSNXE. This causes RSNE/RSNXE mismatch between (Re)Association Request frame and EAPOL-Key msg 2/4. To avoid this skip copying the default RSNE/RSNXE if the driver indicates the actually used (Re)Association Request frame elements in the association event. Signed-off-by: Utkarsh Soni --- wpa_supplicant/events.c | 14 ++++++++++--- wpa_supplicant/sme.c | 9 ++++++--- wpa_supplicant/wpa_supplicant.c | 33 +++++++++++++++++++------------ wpa_supplicant/wpa_supplicant_i.h | 3 ++- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 7ed3576a8..0356c809a 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -182,7 +182,8 @@ static void wpa_supplicant_update_link_bss(struct wpa_supplicant *wpa_s, } -static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s) +static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) { struct wpa_ssid *ssid, *old_ssid; u8 drv_ssid[SSID_MAX_LEN]; @@ -255,8 +256,15 @@ static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s) if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) { u8 wpa_ie[80]; size_t wpa_ie_len = sizeof(wpa_ie); + bool skip_default_rsne; + + /* Do not override RSNE/RSNXE with the default values if the + * driver indicated the actual values used in the + * (Re)Association Request frame. */ + skip_default_rsne = data && data->assoc_info.req_ies; if (wpa_supplicant_set_suites(wpa_s, NULL, ssid, - wpa_ie, &wpa_ie_len) < 0) + wpa_ie, &wpa_ie_len, + skip_default_rsne) < 0) wpa_dbg(wpa_s, MSG_DEBUG, "Could not set WPA suites"); } else { wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); @@ -3557,7 +3565,7 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) { wpa_clear_keys(wpa_s, bssid); } - if (wpa_supplicant_select_config(wpa_s) < 0) { + if (wpa_supplicant_select_config(wpa_s, data) < 0) { wpa_supplicant_deauthenticate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); return; diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 28ac03f23..98a975c09 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -501,7 +501,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); if (wpa_supplicant_set_suites(wpa_s, bss, ssid, wpa_s->sme.assoc_req_ie, - &wpa_s->sme.assoc_req_ie_len)) { + &wpa_s->sme.assoc_req_ie_len, + false)) { wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " "key management and encryption suites"); wpas_connect_work_done(wpa_s); @@ -514,7 +515,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); if (wpa_supplicant_set_suites(wpa_s, bss, ssid, wpa_s->sme.assoc_req_ie, - &wpa_s->sme.assoc_req_ie_len)) { + &wpa_s->sme.assoc_req_ie_len, + false)) { wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " "key management and encryption suites"); wpas_connect_work_done(wpa_s); @@ -534,7 +536,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); if (wpa_supplicant_set_suites(wpa_s, NULL, ssid, wpa_s->sme.assoc_req_ie, - &wpa_s->sme.assoc_req_ie_len)) { + &wpa_s->sme.assoc_req_ie_len, + false)) { wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " "key management and encryption suites (no " "scan results)"); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index ef5d0cd71..b55612aec 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1565,6 +1565,7 @@ static void wpas_update_allowed_key_mgmt(struct wpa_supplicant *wpa_s, * @wpa_ie: Buffer for the WPA/RSN IE * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the * used buffer length in case the functions returns success. + * @skip_default_rsne: Whether to skip setting of the default RSNE/RSNXE * Returns: 0 on success or -1 on failure * * This function is used to configure authentication and encryption parameters @@ -1573,7 +1574,8 @@ static void wpas_update_allowed_key_mgmt(struct wpa_supplicant *wpa_s, */ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, struct wpa_ssid *ssid, - u8 *wpa_ie, size_t *wpa_ie_len) + u8 *wpa_ie, size_t *wpa_ie_len, + bool skip_default_rsne) { struct wpa_ie_data ie; int sel, proto, sae_pwe; @@ -1961,16 +1963,21 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_USE_EXT_KEY_ID, 0); } - if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) { - wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE"); - return -1; - } + if (!skip_default_rsne) { + if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, + wpa_ie_len)) { + wpa_msg(wpa_s, MSG_WARNING, + "RSN: Failed to generate RSNE/WPA IE"); + return -1; + } - wpa_s->rsnxe_len = sizeof(wpa_s->rsnxe); - if (wpa_sm_set_assoc_rsnxe_default(wpa_s->wpa, wpa_s->rsnxe, - &wpa_s->rsnxe_len)) { - wpa_msg(wpa_s, MSG_WARNING, "RSN: Failed to generate RSNXE"); - return -1; + wpa_s->rsnxe_len = sizeof(wpa_s->rsnxe); + if (wpa_sm_set_assoc_rsnxe_default(wpa_s->wpa, wpa_s->rsnxe, + &wpa_s->rsnxe_len)) { + wpa_msg(wpa_s, MSG_WARNING, + "RSN: Failed to generate RSNXE"); + return -1; + } } if (0) { @@ -3129,7 +3136,7 @@ static u8 * wpas_populate_assoc_ies( } wpa_ie_len = max_wpa_ie_len; if (wpa_supplicant_set_suites(wpa_s, bss, ssid, - wpa_ie, &wpa_ie_len)) { + wpa_ie, &wpa_ie_len, false)) { wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA " "key management and encryption suites"); os_free(wpa_ie); @@ -3141,7 +3148,7 @@ static u8 * wpas_populate_assoc_ies( /* No PMKSA caching, but otherwise similar to RSN/WPA */ wpa_ie_len = max_wpa_ie_len; if (wpa_supplicant_set_suites(wpa_s, bss, ssid, - wpa_ie, &wpa_ie_len)) { + wpa_ie, &wpa_ie_len, false)) { wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA " "key management and encryption suites"); os_free(wpa_ie); @@ -3161,7 +3168,7 @@ static u8 * wpas_populate_assoc_ies( } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) { wpa_ie_len = max_wpa_ie_len; if (wpa_supplicant_set_suites(wpa_s, NULL, ssid, - wpa_ie, &wpa_ie_len)) { + wpa_ie, &wpa_ie_len, false)) { wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA " "key management and encryption suites (no " "scan results)"); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index da3679706..3e35b9ca8 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1550,7 +1550,8 @@ void wpas_set_mgmt_group_cipher(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_ie_data *ie); int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, struct wpa_ssid *ssid, - u8 *wpa_ie, size_t *wpa_ie_len); + u8 *wpa_ie, size_t *wpa_ie_len, + bool skip_default_rsne); int wpas_restore_permanent_mac_addr(struct wpa_supplicant *wpa_s); void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,