From a959a3b69dd2b341736e736cf4ff76e8d4a69cc2 Mon Sep 17 00:00:00 2001 From: Masashi Honma Date: Tue, 25 Nov 2014 11:04:41 +0900 Subject: [PATCH] SAE: Fix Anti-Clogging Token request frame format This commit inserts Finite Cyclic Group to Anti-Clogging Token request frame because IEEE Std 802.11-2012, Table 8-29 says "Finite Cyclic Group is present if Status is zero or 76". Signed-off-by: Masashi Honma --- src/ap/ieee802_11.c | 33 ++++++++++++++++++++++++++------- src/common/sae.c | 3 +-- src/common/sae.h | 1 + wpa_supplicant/sme.c | 32 ++++++++++++++++++++++++++++---- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 1d0fa5166..1dbd996cd 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -449,7 +449,7 @@ static int check_sae_token(struct hostapd_data *hapd, const u8 *addr, static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd, - const u8 *addr) + int group, const u8 *addr) { struct wpabuf *buf; u8 *token; @@ -466,10 +466,12 @@ static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd, hapd->last_sae_token_key_update = now; } - buf = wpabuf_alloc(SHA256_MAC_LEN); + buf = wpabuf_alloc(sizeof(le16) + SHA256_MAC_LEN); if (buf == NULL) return NULL; + wpabuf_put_le16(buf, group); /* Finite Cyclic Group */ + token = wpabuf_put(buf, SHA256_MAC_LEN); hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key), addr, ETH_ALEN, token); @@ -630,7 +632,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, } if (auth_transaction == 1) { - const u8 *token = NULL; + const u8 *token = NULL, *pos, *end; size_t token_len = 0; hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, @@ -639,11 +641,27 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, if ((hapd->conf->mesh & MESH_ENABLED) && mgmt->u.auth.status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ && sta->sae->tmp) { + pos = mgmt->u.auth.variable; + end = ((const u8 *) mgmt) + len; + if (pos + sizeof(le16) > end) { + wpa_printf(MSG_ERROR, + "SAE: Too short anti-clogging token request"); + resp = WLAN_STATUS_UNSPECIFIED_FAILURE; + goto reply; + } + resp = sae_group_allowed(sta->sae, + hapd->conf->sae_groups, + WPA_GET_LE16(pos)); + if (resp != WLAN_STATUS_SUCCESS) { + wpa_printf(MSG_ERROR, + "SAE: Invalid group in anti-clogging token request"); + goto reply; + } + pos += sizeof(le16); + wpabuf_free(sta->sae->tmp->anti_clogging_token); sta->sae->tmp->anti_clogging_token = - wpabuf_alloc_copy(mgmt->u.auth.variable, - ((const u8 *) mgmt) + len - - mgmt->u.auth.variable); + wpabuf_alloc_copy(pos, end - pos); if (sta->sae->tmp->anti_clogging_token == NULL) { wpa_printf(MSG_ERROR, "SAE: Failed to alloc for anti-clogging token"); @@ -685,7 +703,8 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, wpa_printf(MSG_DEBUG, "SAE: Request anti-clogging token from " MACSTR, MAC2STR(sta->addr)); - data = auth_build_token_req(hapd, sta->addr); + data = auth_build_token_req(hapd, sta->sae->group, + sta->addr); resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ; if (hapd->conf->mesh & MESH_ENABLED) sta->sae->state = SAE_NOTHING; diff --git a/src/common/sae.c b/src/common/sae.c index 6454b4adb..87d49b630 100644 --- a/src/common/sae.c +++ b/src/common/sae.c @@ -686,8 +686,7 @@ void sae_write_commit(struct sae_data *sae, struct wpabuf *buf, } -static u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, - u16 group) +u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group) { if (allowed_groups) { int i; diff --git a/src/common/sae.h b/src/common/sae.h index e78bb495a..89d74ab17 100644 --- a/src/common/sae.h +++ b/src/common/sae.h @@ -61,5 +61,6 @@ u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len, const u8 **token, size_t *token_len, int *allowed_groups); void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf); int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len); +u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group); #endif /* SAE_H */ diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index da8e65e2c..7eb896639 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -611,6 +611,8 @@ void sme_authenticate(struct wpa_supplicant *wpa_s, static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, u16 status_code, const u8 *data, size_t len) { + int *groups; + wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u " "status code %u", auth_transaction, status_code); @@ -618,10 +620,32 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ && wpa_s->sme.sae.state == SAE_COMMITTED && wpa_s->current_bss && wpa_s->current_ssid) { - wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE anti-clogging token " - "requested"); + int default_groups[] = { 19, 20, 21, 25, 26, 0 }; + u16 group; + + groups = wpa_s->conf->sae_groups; + if (!groups || groups[0] <= 0) + groups = default_groups; + + if (len < sizeof(le16)) { + wpa_dbg(wpa_s, MSG_DEBUG, + "SME: Too short SAE anti-clogging token request"); + return -1; + } + group = WPA_GET_LE16(data); + wpa_dbg(wpa_s, MSG_DEBUG, + "SME: SAE anti-clogging token requested (group %u)", + group); + if (sae_group_allowed(&wpa_s->sme.sae, groups, group) != + WLAN_STATUS_SUCCESS) { + wpa_dbg(wpa_s, MSG_ERROR, + "SME: SAE group %u of anti-clogging request is invalid", + group); + return -1; + } wpabuf_free(wpa_s->sme.sae_token); - wpa_s->sme.sae_token = wpabuf_alloc_copy(data, len); + wpa_s->sme.sae_token = wpabuf_alloc_copy(data + sizeof(le16), + len - sizeof(le16)); sme_send_authentication(wpa_s, wpa_s->current_bss, wpa_s->current_ssid, 1); return 0; @@ -645,7 +669,7 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, return -1; if (auth_transaction == 1) { - int *groups = wpa_s->conf->sae_groups; + groups = wpa_s->conf->sae_groups; wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit"); if (wpa_s->current_bss == NULL ||