diff --git a/src/common/sae.h b/src/common/sae.h index bb33761f9..3eb6e323a 100644 --- a/src/common/sae.h +++ b/src/common/sae.h @@ -41,6 +41,7 @@ struct sae_temporary_data { struct wpabuf *anti_clogging_token; char *pw_id; int vlan_id; + u8 bssid[ETH_ALEN]; }; enum sae_state { diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index c22ddba13..925cfa055 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -84,7 +84,8 @@ static int sme_set_sae_group(struct wpa_supplicant *wpa_s) static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, - const u8 *bssid, int external) + const u8 *bssid, int external, + int reuse) { struct wpabuf *buf; size_t len; @@ -111,6 +112,12 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, return NULL; } + if (reuse && wpa_s->sme.sae.tmp && + os_memcmp(bssid, wpa_s->sme.sae.tmp->bssid, ETH_ALEN) == 0) { + wpa_printf(MSG_DEBUG, + "SAE: Reuse previously generated PWE on a retry with the same AP"); + goto reuse_data; + } if (sme_set_sae_group(wpa_s) < 0) { wpa_printf(MSG_DEBUG, "SAE: Failed to select group"); return NULL; @@ -123,7 +130,10 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE"); return NULL; } + if (wpa_s->sme.sae.tmp) + os_memcpy(wpa_s->sme.sae.tmp->bssid, bssid, ETH_ALEN); +reuse_data: len = wpa_s->sme.sae_token ? wpabuf_len(wpa_s->sme.sae_token) : 0; if (ssid->sae_password_id) len += 4 + os_strlen(ssid->sae_password_id); @@ -631,7 +641,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE) { if (start) resp = sme_auth_build_sae_commit(wpa_s, ssid, - bss->bssid, 0); + bss->bssid, 0, + start == 2); else resp = sme_auth_build_sae_confirm(wpa_s, 0); if (resp == NULL) { @@ -914,7 +925,7 @@ static void sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s, { struct wpabuf *resp, *buf; - resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1); + resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1, 0); if (!resp) return; @@ -1065,7 +1076,7 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, len - sizeof(le16)); if (!external) sme_send_authentication(wpa_s, wpa_s->current_bss, - wpa_s->current_ssid, 1); + wpa_s->current_ssid, 2); else sme_external_auth_send_sae_commit( wpa_s, wpa_s->sme.ext_auth.bssid,