SAE: Reuse previously generated PWE on a retry with the same AP

Do not start SAE authentication from scratch when the AP requests
anti-clogging token to be used. Instead, use the previously generated
PWE as-is if the retry is for the same AP and the same group. This saves
unnecessary processing on the station side in case the AP is under heavy
SAE authentiation load.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2019-03-03 16:23:19 +02:00 committed by Jouni Malinen
parent a9af1da0b5
commit fd83089120
2 changed files with 16 additions and 4 deletions

View file

@ -41,6 +41,7 @@ struct sae_temporary_data {
struct wpabuf *anti_clogging_token; struct wpabuf *anti_clogging_token;
char *pw_id; char *pw_id;
int vlan_id; int vlan_id;
u8 bssid[ETH_ALEN];
}; };
enum sae_state { enum sae_state {

View file

@ -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, static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, struct wpa_ssid *ssid,
const u8 *bssid, int external) const u8 *bssid, int external,
int reuse)
{ {
struct wpabuf *buf; struct wpabuf *buf;
size_t len; size_t len;
@ -111,6 +112,12 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
return NULL; 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) { if (sme_set_sae_group(wpa_s) < 0) {
wpa_printf(MSG_DEBUG, "SAE: Failed to select group"); wpa_printf(MSG_DEBUG, "SAE: Failed to select group");
return NULL; 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"); wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
return NULL; 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; len = wpa_s->sme.sae_token ? wpabuf_len(wpa_s->sme.sae_token) : 0;
if (ssid->sae_password_id) if (ssid->sae_password_id)
len += 4 + os_strlen(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 (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE) {
if (start) if (start)
resp = sme_auth_build_sae_commit(wpa_s, ssid, resp = sme_auth_build_sae_commit(wpa_s, ssid,
bss->bssid, 0); bss->bssid, 0,
start == 2);
else else
resp = sme_auth_build_sae_confirm(wpa_s, 0); resp = sme_auth_build_sae_confirm(wpa_s, 0);
if (resp == NULL) { if (resp == NULL) {
@ -914,7 +925,7 @@ static void sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s,
{ {
struct wpabuf *resp, *buf; 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) if (!resp)
return; return;
@ -1065,7 +1076,7 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
len - sizeof(le16)); len - sizeof(le16));
if (!external) if (!external)
sme_send_authentication(wpa_s, wpa_s->current_bss, sme_send_authentication(wpa_s, wpa_s->current_bss,
wpa_s->current_ssid, 1); wpa_s->current_ssid, 2);
else else
sme_external_auth_send_sae_commit( sme_external_auth_send_sae_commit(
wpa_s, wpa_s->sme.ext_auth.bssid, wpa_s, wpa_s->sme.ext_auth.bssid,