SAE: Support cross AKM roaming between SAE AKMs in external auth case

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>
This commit is contained in:
Veerendranath Jakkam 2022-11-28 03:36:16 +05:30 committed by Jouni Malinen
parent a170267076
commit 23e31eb68e
2 changed files with 30 additions and 13 deletions

View 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;
}
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;
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 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)

View 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;