diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 1f5f96be6..7095edbe5 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -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) diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index aaa84f603..d92686139 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -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;