]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Support cross AKM roaming between SAE AKMs in external auth case
authorVeerendranath Jakkam <quic_vjakkam@quicinc.com>
Sun, 27 Nov 2022 22:06:16 +0000 (03:36 +0530)
committerJouni Malinen <j@w1.fi>
Thu, 15 Dec 2022 16:36:26 +0000 (18:36 +0200)
Add support to handle external authentication request with a different
SAE AKM suite compared to the current connection AKM suite. This is
needed to support cross AKM roaming between SAE and SAE-EXT-KEY AKM
suites.

Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant_i.h

index 1f5f96be643ed3d5d8b6bda2941e12d5caba20d3..7095edbe5d9f382a37f5849656fd3e6e24955f77 100644 (file)
@@ -54,7 +54,7 @@ static int index_within_array(const int *array, int idx)
 }
 
 
-static int sme_set_sae_group(struct wpa_supplicant *wpa_s)
+static int sme_set_sae_group(struct wpa_supplicant *wpa_s, bool external)
 {
        int *groups = wpa_s->conf->sae_groups;
        int default_groups[] = { 19, 20, 21, 0 };
@@ -73,7 +73,8 @@ static int sme_set_sae_group(struct wpa_supplicant *wpa_s)
                if (sae_set_group(&wpa_s->sme.sae, group) == 0) {
                        wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d",
                                wpa_s->sme.sae.group);
-                       wpa_s->sme.sae.akmp = wpa_s->key_mgmt;
+                       wpa_s->sme.sae.akmp = external ?
+                               wpa_s->sme.ext_auth_key_mgmt : wpa_s->key_mgmt;
                        return 0;
                }
                wpa_s->sme.sae_group_index++;
@@ -96,6 +97,8 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
        int use_pt = 0;
        bool use_pk = false;
        u8 rsnxe_capa = 0;
+       int key_mgmt = external ? wpa_s->sme.ext_auth_key_mgmt :
+               wpa_s->key_mgmt;
 
        if (ret_use_pt)
                *ret_use_pt = 0;
@@ -166,7 +169,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
                use_pk = wpa_s->sme.sae.pk;
                goto reuse_data;
        }
-       if (sme_set_sae_group(wpa_s) < 0) {
+       if (sme_set_sae_group(wpa_s, external) < 0) {
                wpa_printf(MSG_DEBUG, "SAE: Failed to select group");
                goto fail;
        }
@@ -189,7 +192,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
        if (ssid->sae_password_id &&
            wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
                use_pt = 1;
-       if (wpa_key_mgmt_sae_ext_key(wpa_s->key_mgmt) &&
+       if (wpa_key_mgmt_sae_ext_key(key_mgmt) &&
            wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
                use_pt = 1;
 #ifdef CONFIG_SAE_PK
@@ -216,7 +219,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
 
                if ((wpa_s->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT ||
                     ssid->sae_password_id ||
-                    wpa_key_mgmt_sae_ext_key(wpa_s->key_mgmt)) &&
+                    wpa_key_mgmt_sae_ext_key(key_mgmt)) &&
                    wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK &&
                    !use_pt) {
                        wpa_printf(MSG_DEBUG,
@@ -1233,7 +1236,7 @@ static void sme_external_auth_send_sae_confirm(struct wpa_supplicant *wpa_s,
 }
 
 
-static bool is_sae_key_mgmt_suite(u32 suite)
+static bool is_sae_key_mgmt_suite(struct wpa_supplicant *wpa_s, u32 suite)
 {
        /* suite is supposed to be the selector value in host byte order with
         * the OUI in three most significant octets. However, the initial
@@ -1241,20 +1244,33 @@ static bool is_sae_key_mgmt_suite(u32 suite)
         * that followed the expected byte order. Keep a workaround here to
         * match that initial implementation so that already deployed use cases
         * remain functional. */
-       if (RSN_SELECTOR_GET(&suite) == RSN_AUTH_KEY_MGMT_SAE)
+       if (RSN_SELECTOR_GET(&suite) == RSN_AUTH_KEY_MGMT_SAE) {
+               /* Old drivers which follow initial implementation send SAE AKM
+                * for both SAE and FT-SAE connections. In that case, determine
+                * the actual AKM from wpa_s->key_mgmt. */
+               wpa_s->sme.ext_auth_key_mgmt = wpa_s->key_mgmt;
                return true;
+       }
+
+       if (suite == RSN_AUTH_KEY_MGMT_SAE)
+               wpa_s->sme.ext_auth_key_mgmt = WPA_KEY_MGMT_SAE;
+       else if (suite == RSN_AUTH_KEY_MGMT_FT_SAE)
+               wpa_s->sme.ext_auth_key_mgmt = WPA_KEY_MGMT_FT_SAE;
+       else if (suite == RSN_AUTH_KEY_MGMT_SAE_EXT_KEY)
+               wpa_s->sme.ext_auth_key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY;
+       else if (suite == RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY)
+               wpa_s->sme.ext_auth_key_mgmt = WPA_KEY_MGMT_FT_SAE_EXT_KEY;
+       else
+               return false;
 
-       return suite == RSN_AUTH_KEY_MGMT_SAE ||
-               suite == RSN_AUTH_KEY_MGMT_FT_SAE ||
-               suite == RSN_AUTH_KEY_MGMT_SAE_EXT_KEY ||
-               suite == RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY;
+       return true;
 }
 
 
 void sme_external_auth_trigger(struct wpa_supplicant *wpa_s,
                               union wpa_event_data *data)
 {
-       if (!is_sae_key_mgmt_suite(data->external_auth.key_mgmt_suite))
+       if (!is_sae_key_mgmt_suite(wpa_s, data->external_auth.key_mgmt_suite))
                return;
 
        if (data->external_auth.action == EXT_AUTH_START) {
@@ -1420,7 +1436,7 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
                int_array_add_unique(&wpa_s->sme.sae_rejected_groups,
                                     wpa_s->sme.sae.group);
                wpa_s->sme.sae_group_index++;
-               if (sme_set_sae_group(wpa_s) < 0)
+               if (sme_set_sae_group(wpa_s, external) < 0)
                        return -1; /* no other groups enabled */
                wpa_dbg(wpa_s, MSG_DEBUG, "SME: Try next enabled SAE group");
                if (!external)
index aaa84f6037f367e33a1f2c18fb0c5a754ac047a5..d92686139abbecd70f82a8721e95418f06fd780f 100644 (file)
@@ -981,6 +981,7 @@ struct wpa_supplicant {
                struct wpa_ssid *ext_auth_wpa_ssid;
                u8 ext_auth_ssid[SSID_MAX_LEN];
                size_t ext_auth_ssid_len;
+               int ext_auth_key_mgmt;
                int *sae_rejected_groups;
 #endif /* CONFIG_SAE */
        } sme;