[09/14] AP: Add support for PASN comeback flow
diff mbox series

Message ID 20200224091602.15306-10-ilan.peer@intel.com
State Deferred
Headers show
Series
  • Support PASN with SAE, FILS and FT
Related show

Commit Message

Peer, Ilan Feb. 24, 2020, 9:15 a.m. UTC
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
---
 src/ap/ieee802_11.c | 71 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

Patch
diff mbox series

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 4262747679..92bad982a9 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -488,6 +488,11 @@  static int use_anti_clogging(struct hostapd_data *hapd)
 		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;
 	}
@@ -2803,6 +2808,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_NO_WRAPPED_DATA,
+				  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, "send_auth_reply: send failed");
+
+	wpabuf_free(buf);
+}
+
+
 static int handle_auth_pasn_resp(struct hostapd_data *hapd,
 				 struct sta_info *sta,
 				 struct rsn_pmksa_cache_entry *pmksa,
@@ -2995,6 +3044,28 @@  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 init ECDH");