[PATCH 2/4] SAE: Fix Anti-Clogging Token request frame format

Masashi Honma masashi.honma at gmail.com
Mon Nov 24 21:04:41 EST 2014


This patch 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 <masashi.honma at gmail.com>
---
 src/ap/ieee802_11.c  | 35 ++++++++++++++++++++++++++++-------
 src/common/sae.c     |  3 +--
 src/common/sae.h     |  1 +
 wpa_supplicant/sme.c | 17 +++++++++++++++--
 4 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 3832b4d..b321cd5 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -447,7 +447,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;
@@ -464,10 +464,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);
@@ -628,7 +630,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,
@@ -637,11 +639,29 @@ 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) {
+			pos = mgmt->u.auth.variable;
+			end = ((const u8 *) mgmt) + len;
+			if (pos + 2 > end) {
+				wpa_printf(MSG_ERROR, "SAE: Too short "
+					   "anti-clogging token request");
+				data = auth_build_sae_commit(hapd, sta, 0);
+				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");
+				data = auth_build_sae_commit(hapd, sta, 0);
+				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");
@@ -683,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 359ee5c..91601fa 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 e78bb49..89d74ab 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 7269eb0..9a2a23b 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -555,6 +555,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);
 
@@ -564,8 +566,19 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
 	    wpa_s->current_bss && wpa_s->current_ssid) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE anti-clogging token "
 			"requested");
+		groups = wpa_s->conf->sae_groups;
+		if (groups && groups[0] <= 0)
+			groups = NULL;
+		if (sae_group_allowed(&wpa_s->sme.sae, groups,
+				      WPA_GET_LE16(data)) !=
+				      WLAN_STATUS_SUCCESS) {
+			wpa_dbg(wpa_s, MSG_ERROR, "SME: SAE group of "
+				"anti-clogging request is invalid");
+			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;
@@ -589,7 +602,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 ||
-- 
1.9.1



More information about the HostAP mailing list