From 96d6dfa8e419daceb4c6c15b7d5f661fca056ece Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 8 Mar 2019 16:21:03 +0200 Subject: [PATCH] SAE: Add Finite Cyclic Group field in status code 77 response Copy the Finite Cyclic Group field value from the request to the response Authentication frame if we end up rejecting the request due to unsupported group. IEEE Std 802.11-2016 has conflicting statements about this behavior. Table 9-36 (Presence of fields and elements in Authentication frames) indicates that the Finite Cyclic Group field is only included with status code values 0 (success) and 76 (anti-clogging token request) while SAE protocol description implying that the Finite Cyclic Group field is set to the rejected group (12.4.8.6.3 and 12.4.8.6.4). The standard language needs to cleaned up to describe this unambiguously, but since it looks safe to add the field into the rejection case and since there is desire to have the field present to be able to implement what exactly is stated in 12.4.8.6.4, it looks reasonable to move ahead with the AP mode implementation change. There is no change in wpa_supplicant for now to modify its behavior based on whether this field is present, i.e., wpa_supplicant will continue to work with both the old and new hostapd behavior for SAE group negotiation. Signed-off-by: Jouni Malinen --- src/ap/ieee802_11.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 2ea3eabc3..589d82e90 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -961,14 +961,13 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, struct wpabuf *data = NULL; int *groups = hapd->conf->sae_groups; int default_groups[] = { 19, 0 }; + const u8 *pos, *end; if (!groups) groups = default_groups; #ifdef CONFIG_TESTING_OPTIONS if (hapd->conf->sae_reflection_attack && auth_transaction == 1) { - const u8 *pos, *end; - wpa_printf(MSG_DEBUG, "SAE: TESTING - reflection attack"); pos = mgmt->u.auth.variable; end = ((const u8 *) mgmt) + len; @@ -1011,7 +1010,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, } if (auth_transaction == 1) { - const u8 *token = NULL, *pos, *end; + const u8 *token = NULL; size_t token_len = 0; int allow_reuse = 0; @@ -1211,6 +1210,15 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, reply: if (resp != WLAN_STATUS_SUCCESS) { + pos = mgmt->u.auth.variable; + end = ((const u8 *) mgmt) + len; + + /* Copy the Finite Cyclic Group field from the request if we + * rejected it as unsupported group. */ + if (resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED && + !data && end - pos >= 2) + data = wpabuf_alloc_copy(pos, 2); + send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE, auth_transaction, resp, data ? wpabuf_head(data) : (u8 *) "",