From: Jouni Malinen Date: Thu, 26 Sep 2024 20:19:54 +0000 (+0300) Subject: SAE: Use sae_pwe in network profile for STA mode X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5fb90cf3fa96ceea850db82be2e26082debd2f8f;p=thirdparty%2Fhostap.git SAE: Use sae_pwe in network profile for STA mode Commit 891bb1305bbd ("P2P: Enforce SAE-H2E for P2P GO in 6 GHz") introduced a network profile specific sae_pwe to avoid having to change the global sae_pwe parameter. However, this was enabled only for AP/P2P GO mode. Extend that to cover STA mode as well. Signed-off-by: Jouni Malinen --- diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 69a0e5ee1..18d78d16b 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -638,10 +638,7 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, bss->sae_passwords = pw; } - if (ssid->sae_pwe != DEFAULT_SAE_PWE) - bss->sae_pwe = ssid->sae_pwe; - else - bss->sae_pwe = wpa_s->conf->sae_pwe; + bss->sae_pwe = wpas_get_ssid_sae_pwe(wpa_s, ssid); #endif /* CONFIG_SAE */ if (wpa_s->conf->go_interworking) { diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 90e1c7b9f..d09d26129 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1044,7 +1044,7 @@ static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, #ifdef CONFIG_SAE if (flagged && ((rate_ie[j] & 0x7f) == BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY)) { - if (wpa_s->conf->sae_pwe == + if (wpas_get_ssid_sae_pwe(wpa_s, ssid) == SAE_PWE_HUNT_AND_PECK && !ssid->sae_password_id && !is_6ghz_freq(bss->freq) && @@ -1272,6 +1272,7 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, #endif /* CONFIG_MBO */ #ifdef CONFIG_SAE u8 rsnxe_capa = 0; + enum sae_pwe sae_pwe; #endif /* CONFIG_SAE */ const u8 *ie; @@ -1448,9 +1449,10 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, #ifdef CONFIG_SAE /* When using SAE Password Identifier and when operationg on the 6 GHz * band, only H2E is allowed. */ - if ((wpa_s->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT || + sae_pwe = wpas_get_ssid_sae_pwe(wpa_s, ssid); + if ((sae_pwe == SAE_PWE_HASH_TO_ELEMENT || is_6ghz_freq(bss->freq) || ssid->sae_password_id) && - wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK && + sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK && wpa_key_mgmt_sae(ssid->key_mgmt) && !(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) { if (debug_print) diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 05ca8ddad..818ddca83 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -105,6 +105,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, int key_mgmt = external ? wpa_s->sme.ext_auth_key_mgmt : wpa_s->key_mgmt; const u8 *addr = mld_addr ? mld_addr : bssid; + enum sae_pwe sae_pwe; if (ret_use_pt) *ret_use_pt = 0; @@ -198,14 +199,16 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, rsnxe_capa = rsnxe[2]; } + sae_pwe = wpas_get_ssid_sae_pwe(wpa_s, ssid); + if (ssid->sae_password_id && - wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK) + sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK) use_pt = 1; if (wpa_key_mgmt_sae_ext_key(key_mgmt) && - wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK) + sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK) use_pt = 1; if (bss && is_6ghz_freq(bss->freq) && - wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK) + sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK) use_pt = 1; #ifdef CONFIG_SAE_PK if ((rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) && @@ -225,14 +228,14 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_SAE_PK */ - if (use_pt || wpa_s->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT || - wpa_s->conf->sae_pwe == SAE_PWE_BOTH) { + if (use_pt || sae_pwe == SAE_PWE_HASH_TO_ELEMENT || + sae_pwe == SAE_PWE_BOTH) { use_pt = !!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E)); - if ((wpa_s->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT || + if ((sae_pwe == SAE_PWE_HASH_TO_ELEMENT || ssid->sae_password_id || wpa_key_mgmt_sae_ext_key(key_mgmt)) && - wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK && + sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK && !use_pt) { wpa_printf(MSG_DEBUG, "SAE: Cannot use H2E with the selected AP"); @@ -241,7 +244,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, } if (use_pt && !ssid->pt) - wpa_s_setup_sae_pt(wpa_s->conf, ssid, true); + wpa_s_setup_sae_pt(wpa_s, ssid, true); if (use_pt && sae_prepare_commit_pt(&wpa_s->sme.sae, ssid->pt, wpa_s->own_addr, addr, @@ -1449,7 +1452,7 @@ static int sme_handle_external_auth_start(struct wpa_supplicant *wpa_s, os_memcmp(ssid_str, ssid->ssid, ssid_str_len) == 0 && wpa_key_mgmt_sae(ssid->key_mgmt)) { /* Make sure PT is derived */ - wpa_s_setup_sae_pt(wpa_s->conf, ssid, false); + wpa_s_setup_sae_pt(wpa_s, ssid, false); wpa_s->sme.ext_auth_wpa_ssid = ssid; break; } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 1dabfe07b..031268a41 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1574,6 +1574,9 @@ static void wpas_update_allowed_key_mgmt(struct wpa_supplicant *wpa_s, { int akm_count = wpa_s->max_num_akms; u8 capab = 0; +#ifdef CONFIG_SAE + enum sae_pwe sae_pwe; +#endif /* CONFIG_SAE */ if (akm_count < 2) return; @@ -1652,13 +1655,16 @@ static void wpas_update_allowed_key_mgmt(struct wpa_supplicant *wpa_s, return; } - if (wpa_s->conf->sae_pwe != SAE_PWE_HUNT_AND_PECK && - wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK) +#ifdef CONFIG_SAE + sae_pwe = wpas_get_ssid_sae_pwe(wpa_s, ssid); + if (sae_pwe != SAE_PWE_HUNT_AND_PECK && + sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK) capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E); #ifdef CONFIG_SAE_PK if (ssid->sae_pk) capab |= BIT(WLAN_RSNX_CAPAB_SAE_PK); #endif /* CONFIG_SAE_PK */ +#endif /* CONFIG_SAE */ if (!((wpa_s->allowed_key_mgmts & (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_SAE_EXT_KEY)) && capab)) @@ -1697,7 +1703,9 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, { struct wpa_ie_data ie; int sel, proto; +#ifdef CONFIG_SAE enum sae_pwe sae_pwe; +#endif /* CONFIG_SAE */ const u8 *bss_wpa, *bss_rsn, *bss_rsnx, *bss_osen; bool wmm; @@ -2056,7 +2064,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_OCV)) wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv); #endif /* CONFIG_OCV */ - sae_pwe = wpa_s->conf->sae_pwe; +#ifdef CONFIG_SAE + sae_pwe = wpas_get_ssid_sae_pwe(wpa_s, ssid); if ((ssid->sae_password_id || wpa_key_mgmt_sae_ext_key(wpa_s->key_mgmt)) && sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK) @@ -2077,6 +2086,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, (!ssid->sae_password && ssid->passphrase && sae_pk_valid_password(ssid->passphrase)))); #endif /* CONFIG_SAE_PK */ +#endif /* CONFIG_SAE */ if (bss && is_6ghz_freq(bss->freq) && wpas_get_ssid_pmf(wpa_s, ssid) != MGMT_FRAME_PROTECTION_REQUIRED) { wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Force MFPR=1 on 6 GHz"); @@ -2524,13 +2534,15 @@ int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s) } -void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid, +void wpa_s_setup_sae_pt(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, bool force) { #ifdef CONFIG_SAE + struct wpa_config *conf = wpa_s->conf; int *groups = conf->sae_groups; int default_groups[] = { 19, 20, 21, 0 }; const char *password; + enum sae_pwe sae_pwe; if (!groups || groups[0] <= 0) groups = default_groups; @@ -2539,13 +2551,15 @@ void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid, if (!password) password = ssid->passphrase; + sae_pwe = wpas_get_ssid_sae_pwe(wpa_s, ssid); + if (!password || !wpa_key_mgmt_sae(ssid->key_mgmt) || - (conf->sae_pwe == SAE_PWE_HUNT_AND_PECK && !ssid->sae_password_id && + (sae_pwe == SAE_PWE_HUNT_AND_PECK && !ssid->sae_password_id && !wpa_key_mgmt_sae_ext_key(ssid->key_mgmt) && !force && !sae_pk_valid_password(password)) || - conf->sae_pwe == SAE_PWE_FORCE_HUNT_AND_PECK) { + sae_pwe == SAE_PWE_FORCE_HUNT_AND_PECK) { /* PT derivation not needed */ sae_deinit_pt(ssid->pt); ssid->pt = NULL; @@ -2666,7 +2680,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, wpa_s_clear_sae_rejected(wpa_s); #ifdef CONFIG_SAE - wpa_s_setup_sae_pt(wpa_s->conf, ssid, false); + wpa_s_setup_sae_pt(wpa_s, ssid, false); #endif /* CONFIG_SAE */ if (rand_style > WPAS_MAC_ADDR_STYLE_PERMANENT) { @@ -4637,7 +4651,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) params.prev_bssid = prev_bssid; #ifdef CONFIG_SAE - params.sae_pwe = wpa_s->conf->sae_pwe; + params.sae_pwe = wpas_get_ssid_sae_pwe(wpa_s, ssid); #endif /* CONFIG_SAE */ ret = wpa_drv_associate(wpa_s, ¶ms); @@ -5176,7 +5190,7 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s, wpa_s->last_owe_group = 0; if (ssid) { ssid->owe_transition_bss_select_count = 0; - wpa_s_setup_sae_pt(wpa_s->conf, ssid, false); + wpa_s_setup_sae_pt(wpa_s, ssid, false); } if (wpa_s->connect_without_scan || request_new_scan || @@ -8888,6 +8902,16 @@ int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) #ifdef CONFIG_SAE + +enum sae_pwe wpas_get_ssid_sae_pwe(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + if (!ssid || ssid->sae_pwe == DEFAULT_SAE_PWE) + return wpa_s->conf->sae_pwe; + return ssid->sae_pwe; +} + + bool wpas_is_sae_avoided(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, const struct wpa_ie_data *ie) @@ -8897,6 +8921,7 @@ bool wpas_is_sae_avoided(struct wpa_supplicant *wpa_s, (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) || wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION); } + #endif /* CONFIG_SAE */ diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 011cdf2dd..7349eb924 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1906,8 +1906,10 @@ static inline int wpas_mode_to_ieee80211_mode(enum wpas_mode mode) int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); +enum sae_pwe wpas_get_ssid_sae_pwe(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr); -void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid, +void wpa_s_setup_sae_pt(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, bool force); void wpa_s_clear_sae_rejected(struct wpa_supplicant *wpa_s);