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:
parent
a170267076
commit
23e31eb68e
2 changed files with 30 additions and 13 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue