]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Use sae_pwe in network profile for STA mode
authorJouni Malinen <quic_jouni@quicinc.com>
Thu, 26 Sep 2024 20:19:54 +0000 (23:19 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 27 Sep 2024 09:44:30 +0000 (12:44 +0300)
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 <quic_jouni@quicinc.com>
wpa_supplicant/ap.c
wpa_supplicant/events.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 69a0e5ee16af866f8513507a36038aafcc92c294..18d78d16b55d27917a67a9c48fda877e46f7a8d0 100644 (file)
@@ -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) {
index 90e1c7b9fbe6f80edeb72232de4b64dffd27a8ab..d09d2612904aa8192f6cfa580244ad21b9aa7a61 100644 (file)
@@ -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)
index 05ca8ddad211d9a87a75169dd6e5c06da1be929b..818ddca83b68c4f9f83fd4811d071c0b498f27b5 100644 (file)
@@ -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;
                }
index 1dabfe07bb91ae29c0a91d503fcb7c41fc6f8547..031268a41ae74d880a5e714ca6f8e0b89a2292d9 100644 (file)
@@ -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, &params);
@@ -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 */
 
 
index 011cdf2dd455ceebbc8d1823cee9e74aa5cebb8c..7349eb924b7d5c5c7ce3ada6c67657c07cc583c8 100644 (file)
@@ -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);