]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Derive H2E PT in STA before connection
authorJouni Malinen <jouni@codeaurora.org>
Fri, 6 Sep 2019 12:40:39 +0000 (15:40 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 15 Oct 2019 12:39:22 +0000 (15:39 +0300)
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
wpa_supplicant/config.c
wpa_supplicant/config_ssid.h
wpa_supplicant/wpa_supplicant.c

index ab668759ec35ea79b9db3f79f1226d48b24c7ca1..33b35056b046725eb609a00893afafb4f68a5b35 100644 (file)
@@ -12,6 +12,7 @@
 #include "utils/uuid.h"
 #include "utils/ip_addr.h"
 #include "common/ieee802_1x_defs.h"
+#include "common/sae.h"
 #include "crypto/sha1.h"
 #include "rsn_supp/wpa.h"
 #include "eap_peer/eap.h"
@@ -2765,6 +2766,9 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
                dl_list_del(&psk->list);
                bin_clear_free(psk, sizeof(*psk));
        }
+#ifdef CONFIG_SAE
+       sae_deinit_pt(ssid->pt);
+#endif /* CONFIG_SAE */
        bin_clear_free(ssid, sizeof(*ssid));
 }
 
@@ -3104,6 +3108,15 @@ int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
                        }
                        ret = -1;
                }
+#ifdef CONFIG_SAE
+               if (os_strcmp(var, "ssid") == 0 ||
+                   os_strcmp(var, "psk") == 0 ||
+                   os_strcmp(var, "sae_password") == 0 ||
+                   os_strcmp(var, "sae_password_id") == 0) {
+                       sae_deinit_pt(ssid->pt);
+                       ssid->pt = NULL;
+               }
+#endif /* CONFIG_SAE */
                break;
        }
        if (i == NUM_SSID_FIELDS) {
index df5e9a2c5848b199019ce531c50a2bdc4c657ac6..98db1fe1a45c639592b27a2294d6025bf39988d2 100644 (file)
@@ -213,6 +213,8 @@ struct wpa_ssid {
         */
        char *sae_password_id;
 
+       struct sae_pt *pt;
+
        /**
         * ext_psk - PSK/passphrase name in external storage
         *
index ca8e1cc0b2c93e6eead3d05aa135b3bcf52026f8..39f69be6352c702d94b3d2a54b8d3545014c1a21 100644 (file)
@@ -1932,6 +1932,36 @@ int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
 }
 
 
+static void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid)
+{
+#ifdef CONFIG_SAE
+       int *groups = conf->sae_groups;
+       int default_groups[] = { 19, 20, 21, 0 };
+       const char *password;
+
+       if (!groups || groups[0] <= 0)
+               groups = default_groups;
+
+       password = ssid->sae_password;
+       if (!password)
+               password = ssid->passphrase;
+
+       if (conf->sae_pwe == 0 || !password) {
+               /* PT derivation not needed */
+               sae_deinit_pt(ssid->pt);
+               ssid->pt = NULL;
+               return;
+       }
+
+       if (ssid->pt)
+               return; /* PT already derived */
+       ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
+                                (const u8 *) password, os_strlen(password),
+                                ssid->sae_password_id);
+#endif /* CONFIG_SAE */
+}
+
+
 static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
 
 /**
@@ -1978,6 +2008,10 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
                } else if (wpa_s->current_bss && wpa_s->current_bss != bss) {
                        os_get_reltime(&wpa_s->roam_start);
                }
+       } else {
+#ifdef CONFIG_SAE
+               wpa_s_setup_sae_pt(wpa_s->conf, ssid);
+#endif /* CONFIG_SAE */
        }
 
        if (rand_style > 0 && !wpa_s->reassoc_same_ess) {
@@ -3984,8 +4018,10 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
        wpa_s->disconnected = 0;
        wpa_s->reassociate = 1;
        wpa_s->last_owe_group = 0;
-       if (ssid)
+       if (ssid) {
                ssid->owe_transition_bss_select_count = 0;
+               wpa_s_setup_sae_pt(wpa_s->conf, ssid);
+       }
 
        if (wpa_s->connect_without_scan ||
            wpa_supplicant_fast_associate(wpa_s) != 1) {