]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Use H2E whenever Password Identifier is used
authorJouni Malinen <jouni@codeaurora.org>
Mon, 20 Jan 2020 19:15:04 +0000 (21:15 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 21 Jan 2020 11:13:56 +0000 (13:13 +0200)
IEEE P802.11-REVmd was modified to require H2E to be used whenever
Password Identifier is used with SAE.

See this document for more details of the approved changes:
https://mentor.ieee.org/802.11/dcn/19/11-19-2154-02-000m-sae-anti-clogging-token.docx

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
hostapd/hostapd.conf
src/ap/ap_config.c
src/ap/ieee802_11.c
src/ap/ieee802_11_shared.c
src/ap/wpa_auth_glue.c
wpa_supplicant/events.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant.conf

index d76a6c7f1f4acfb1c71099646cac343b9be39702..1688321108df655d558e3c4d937a61aaf6d94029 100644 (file)
@@ -1784,11 +1784,13 @@ own_ip_addr=127.0.0.1
 #sae_confirm_immediate=0
 
 # SAE mechanism for PWE derivation
-# 0 = hunting-and-pecking loop only (default)
-# 1 = hash-to-element only
+# 0 = hunting-and-pecking loop only (default without password identifier)
+# 1 = hash-to-element only (default with password identifier)
 # 2 = both hunting-and-pecking loop and hash-to-element enabled
 # Note: The default value is likely to change from 0 to 2 once the new
 # hash-to-element mechanism has received more interoperability testing.
+# When using SAE password identifier, the hash-to-element mechanism is used
+# regardless of the sae_pwe parameter value.
 #sae_pwe=0
 
 # FILS Cache Identifier (16-bit value in hexdump format)
index cc041441c53e261e4597d92a2e13c06a7b919ee7..799d8f4da02f895b6685d2b7f53c180596d40fc3 100644 (file)
@@ -441,7 +441,8 @@ int hostapd_setup_sae_pt(struct hostapd_bss_config *conf)
        struct hostapd_ssid *ssid = &conf->ssid;
        struct sae_password_entry *pw;
 
-       if (conf->sae_pwe == 0 || !wpa_key_mgmt_sae(conf->wpa_key_mgmt))
+       if ((conf->sae_pwe == 0 && !hostapd_sae_pw_id_in_use(conf)) ||
+           !wpa_key_mgmt_sae(conf->wpa_key_mgmt))
                return 0; /* PT not needed */
 
        sae_deinit_pt(ssid->pt);
index cd61077944a9624c5a59c82ca53dad5e3d5b6353..5ff65b901138827104bf99ada04aaaedd3fedc32 100644 (file)
@@ -88,6 +88,7 @@ u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
 {
        u8 *pos = eid;
        int i, num, count;
+       int h2e_required;
 
        if (hapd->iface->current_rates == NULL)
                return eid;
@@ -98,8 +99,10 @@ u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
                num++;
        if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
                num++;
-       if (hapd->conf->sae_pwe == 1 &&
-           wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt))
+       h2e_required = (hapd->conf->sae_pwe == 1 ||
+                       hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
+               wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
+       if (h2e_required)
                num++;
        if (num > 8) {
                /* rest of the rates are encoded in Extended supported
@@ -127,9 +130,7 @@ u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
                *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
        }
 
-       if (hapd->conf->sae_pwe == 1 &&
-           wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
-           count < 8) {
+       if (h2e_required && count < 8) {
                count++;
                *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
        }
@@ -142,6 +143,7 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
 {
        u8 *pos = eid;
        int i, num, count;
+       int h2e_required;
 
        if (hapd->iface->current_rates == NULL)
                return eid;
@@ -151,8 +153,10 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
                num++;
        if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
                num++;
-       if (hapd->conf->sae_pwe == 1 &&
-           wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt))
+       h2e_required = (hapd->conf->sae_pwe == 1 ||
+                       hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
+               wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
+       if (h2e_required)
                num++;
        if (num <= 8)
                return eid;
@@ -183,8 +187,7 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
                        *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
        }
 
-       if (hapd->conf->sae_pwe == 1 &&
-           wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt)) {
+       if (h2e_required) {
                count++;
                if (count > 8)
                        *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
@@ -453,7 +456,9 @@ static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
                use_pt = sta->sae->tmp->h2e;
        }
 
-       if (status_code == WLAN_STATUS_SUCCESS)
+       if (rx_id)
+               use_pt = 1;
+       else if (status_code == WLAN_STATUS_SUCCESS)
                use_pt = 0;
        else if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT)
                use_pt = 1;
@@ -1060,11 +1065,20 @@ static void sae_pick_next_group(struct hostapd_data *hapd, struct sta_info *sta)
 
 static int sae_status_success(struct hostapd_data *hapd, u16 status_code)
 {
-       return (hapd->conf->sae_pwe == 0 &&
+       int sae_pwe = hapd->conf->sae_pwe;
+       int id_in_use;
+
+       id_in_use = hostapd_sae_pw_id_in_use(hapd->conf);
+       if (id_in_use == 2)
+               sae_pwe = 1;
+       else if (id_in_use == 1 && sae_pwe == 0)
+               sae_pwe = 2;
+
+       return (sae_pwe == 0 &&
                status_code == WLAN_STATUS_SUCCESS) ||
-               (hapd->conf->sae_pwe == 1 &&
+               (sae_pwe == 1 &&
                 status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT) ||
-               (hapd->conf->sae_pwe == 2 &&
+               (sae_pwe == 2 &&
                 (status_code == WLAN_STATUS_SUCCESS ||
                  status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT));
 }
index ab81d083ef73cf2b88ffaf11af0415947896fe1c..5b14694eab8357b7ed545c200a905f4e8b0d4cfc 100644 (file)
@@ -1014,7 +1014,8 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
 
        if (!(hapd->conf->wpa & WPA_PROTO_RSN) ||
            !wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) ||
-           (hapd->conf->sae_pwe != 1 && hapd->conf->sae_pwe != 2) ||
+           (hapd->conf->sae_pwe != 1 && hapd->conf->sae_pwe != 2 &&
+            !hostapd_sae_pw_id_in_use(hapd->conf)) ||
            len < 3)
                return pos;
 
index e643046368a38346114e04f035dcefa054d9bfa9..4927744ef39608688e735f33e8a6ba3ba47754e6 100644 (file)
@@ -37,6 +37,8 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
                                  struct hostapd_config *iconf,
                                  struct wpa_auth_config *wconf)
 {
+       int sae_pw_id;
+
        os_memset(wconf, 0, sizeof(*wconf));
        wconf->wpa = conf->wpa;
        wconf->wpa_key_mgmt = conf->wpa_key_mgmt;
@@ -155,6 +157,11 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
                  FILS_CACHE_ID_LEN);
 #endif /* CONFIG_FILS */
        wconf->sae_pwe = conf->sae_pwe;
+       sae_pw_id = hostapd_sae_pw_id_in_use(conf);
+       if (sae_pw_id == 2)
+               wconf->sae_pwe = 1;
+       else if (sae_pw_id == 1 && wconf->sae_pwe == 0)
+               wconf->sae_pwe = 2;
 }
 
 
index 8f5b21a9fa2b2d3becfa95ebc5ea3ffabb96f5ca..12e22e84e0ff9e910aa4d64de7347a1875ae796a 100644 (file)
@@ -854,6 +854,7 @@ static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
                        if (flagged && ((rate_ie[j] & 0x7f) ==
                                        BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY)) {
                                if (wpa_s->conf->sae_pwe == 0 &&
+                                   !ssid->sae_password_id &&
                                    wpa_key_mgmt_sae(ssid->key_mgmt)) {
                                        if (debug_print)
                                                wpa_dbg(wpa_s, MSG_DEBUG,
@@ -1299,7 +1300,7 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
                }
 
 #ifdef CONFIG_SAE
-               if (wpa_s->conf->sae_pwe == 1 &&
+               if ((wpa_s->conf->sae_pwe == 1 || ssid->sae_password_id) &&
                    wpa_key_mgmt_sae(ssid->key_mgmt) &&
                    (!(ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX)) ||
                     ie[1] < 1 ||
index 2d7373e559e2481883792703f88827e3312b1084..51f8d6105b6593d4ff644b075ed387dda734fc14 100644 (file)
@@ -131,7 +131,10 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
                return NULL;
        }
 
-       if (wpa_s->conf->sae_pwe == 1 || wpa_s->conf->sae_pwe == 2) {
+       if (ssid->sae_password_id)
+               use_pt = 1;
+
+       if (use_pt || wpa_s->conf->sae_pwe == 1 || wpa_s->conf->sae_pwe == 2) {
                bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
                if (bss) {
                        const u8 *rsnxe;
@@ -142,7 +145,8 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
                                            BIT(WLAN_RSNX_CAPAB_SAE_H2E));
                }
 
-               if (wpa_s->conf->sae_pwe == 1 && !use_pt) {
+               if ((wpa_s->conf->sae_pwe == 1 || ssid->sae_password_id) &&
+                   !use_pt) {
                        wpa_printf(MSG_DEBUG,
                                   "SAE: Cannot use H2E with the selected AP");
                        return NULL;
index 9f3d6ef600df0250136365dae61bbafa24126a30..8cf148f90afa8983ae8e0509b495268308aeca74 100644 (file)
@@ -1272,7 +1272,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
                              u8 *wpa_ie, size_t *wpa_ie_len)
 {
        struct wpa_ie_data ie;
-       int sel, proto;
+       int sel, proto, sae_pwe;
        const u8 *bss_wpa, *bss_rsn, *bss_rsnx, *bss_osen;
 
        if (bss) {
@@ -1617,7 +1617,10 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 #ifdef CONFIG_OCV
        wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv);
 #endif /* CONFIG_OCV */
-       wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SAE_PWE, wpa_s->conf->sae_pwe);
+       sae_pwe = wpa_s->conf->sae_pwe;
+       if (ssid->sae_password_id)
+               sae_pwe = 1;
+       wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SAE_PWE, sae_pwe);
 
        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");
@@ -1993,7 +1996,7 @@ static void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid)
        if (!password)
                password = ssid->passphrase;
 
-       if (conf->sae_pwe == 0 || !password) {
+       if ((conf->sae_pwe == 0 && !ssid->sae_password_id) || !password) {
                /* PT derivation not needed */
                sae_deinit_pt(ssid->pt);
                ssid->pt = NULL;
index 328f91a97aa91c1352e2bf16cf0322a60445cce6..ec1ec0dbe7802753317bed4853b462eb7843a27f 100644 (file)
@@ -426,11 +426,13 @@ fast_reauth=1
 #sae_groups=19 20 21
 
 # SAE mechanism for PWE derivation
-# 0 = hunting-and-pecking loop only (default)
-# 1 = hash-to-element only
+# 0 = hunting-and-pecking loop only (default without password identifier)
+# 1 = hash-to-element only (default with password identifier)
 # 2 = both hunting-and-pecking loop and hash-to-element enabled
 # Note: The default value is likely to change from 0 to 2 once the new
 # hash-to-element mechanism has received more interoperability testing.
+# When using SAE password identifier, the hash-to-element mechanism is used
+# regardless of the sae_pwe parameter value.
 #sae_pwe=0
 
 # Default value for DTIM period (if not overridden in network block)