>From 6184f5030e9fe74f6f3d27e420b09c8371173061 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Wed, 16 Dec 2020 13:01:00 +0200 Subject: [PATCH 3/5] AP: Add support for PASN comeback flow Signed-off-by: Ilan Peer --- src/ap/ieee802_11.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 80a4e5df1695..a492f5177666 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -709,6 +709,10 @@ static int use_anti_clogging(struct hostapd_data *hapd) continue; open++; #endif /* CONFIG_SAE */ +#ifdef CONFIG_PASN + if (sta->pasn && sta->pasn->ecdh) + open++; +#endif /* CONFIG_PASN */ if (open >= hapd->conf->anti_clogging_threshold) return 1; } @@ -2888,6 +2892,50 @@ pasn_derive_keys(struct hostapd_data *hapd, struct sta_info *sta, } +static void handle_auth_pasn_comeback(struct hostapd_data *hapd, + struct sta_info *sta) +{ + struct wpabuf *buf, *comeback; + int ret; + + wpa_printf(MSG_DEBUG, "PASN: Building comeback frame 2"); + + buf = wpabuf_alloc(1500); + if (!buf) + return; + + wpa_pasn_build_auth_header(buf, hapd->own_addr, hapd->own_addr, + sta->addr, 2, + WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY); + + comeback = auth_build_token_req(hapd, sta->pasn->group, sta->addr, 0); + if (!comeback) { + wpa_printf(MSG_DEBUG, + "PASN: Failed sending auth with comeback"); + + wpabuf_free(buf); + return; + } + + wpa_pasn_add_parameter_ie(buf, sta->pasn->group, + WPA_PASN_WRAPPED_DATA_NO, + NULL, comeback, 10); + + wpabuf_free(comeback); + comeback = NULL; + + wpa_printf(MSG_DEBUG, + "PASN: comeback: STA=" MACSTR, MAC2STR(sta->addr)); + + ret = hostapd_drv_send_mlme(hapd, wpabuf_head(buf), wpabuf_len(buf), 0, + NULL, 0, 0); + if (ret) + wpa_printf(MSG_INFO, "PASN: Failed to send comeback frame 2"); + + wpabuf_free(buf); +} + + static int handle_auth_pasn_resp(struct hostapd_data *hapd, struct sta_info *sta, struct rsn_pmksa_cache_entry *pmksa, @@ -3107,6 +3155,27 @@ static void handle_auth_pasn_1(struct hostapd_data *hapd, struct sta_info *sta, goto send_resp; } + if (pasn_params.comeback) { + wpa_printf(MSG_DEBUG, "PASN: Checking peer comeback token"); + + /* The token includes 2 bytes for the group, so skip them */ + ret = check_comeback_token(hapd, sta->addr, + pasn_params.comeback + 2, + pasn_params.comeback_len - 2); + + if (ret) { + wpa_printf(MSG_DEBUG, "PASN: Invalid comeback token"); + status = WLAN_STATUS_UNSPECIFIED_FAILURE; + goto send_resp; + } + } else if (use_anti_clogging(hapd)) { + wpa_printf(MSG_DEBUG, "PASN: Response with comeback"); + + handle_auth_pasn_comeback(hapd, sta); + ap_free_sta(hapd, sta); + return; + } + sta->pasn->ecdh = crypto_ecdh_init(pasn_params.group); if (!sta->pasn->ecdh) { wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH"); -- 2.25.1