[PATCH v2 1/3] AP: Add support for PASN comeback flow

Ilan Peer ilan.peer at intel.com
Sun Mar 21 11:55:08 GMT 2021


Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 hostapd/config_file.c |  2 +
 hostapd/hostapd.conf  |  7 ++++
 src/ap/ap_config.c    |  5 +++
 src/ap/ap_config.h    |  6 +++
 src/ap/ieee802_11.c   | 88 +++++++++++++++++++++++++++++++++++++++----
 5 files changed, 101 insertions(+), 7 deletions(-)

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index fd9bc0e9fc..d73a737821 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -4675,6 +4675,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 				   line, pos);
 			return 1;
 		}
+	} else if (os_strcmp(buf, "pasn_comeback_after") == 0) {
+		bss->pasn_comeback_after = atoi(pos);
 #endif /* CONFIG_PASN */
 	} else {
 		wpa_printf(MSG_ERROR,
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index d19db5a154..bb532763b5 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -2051,6 +2051,13 @@ own_ip_addr=127.0.0.1
 # http://www.iana.org/assignments/ipsec-registry/ipsec-registry.xml#ipsec-registry-10
 #pasn_groups=19 20 21
 
+# PASN comeback after.
+# In case the AP is temporally unable to handle a PASN authentication exchange,
+# this value would indicate to the peer after how many TUs it can try comeback
+# and try the PASN exchange again.
+# (default: 10 TUs)
+# pasn_comeback_after=10
+
 ##### IEEE 802.11r configuration ##############################################
 
 # Mobility Domain identifier (dot11FTMobilityDomainID, MDID)
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 452386b7e5..7b6249bbe5 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -165,6 +165,11 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
 #ifdef CONFIG_TESTING_OPTIONS
 	bss->sae_commit_status = -1;
 #endif /* CONFIG_TESTING_OPTIONS */
+
+#ifdef CONFIG_PASN
+	/* comeback after 10 TUs */
+	bss->pasn_comeback_after = 10;
+#endif /* CONFIG_PASN */
 }
 
 
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 8aeb03107a..26bdaf1317 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -880,6 +880,12 @@ struct hostapd_bss_config {
 #endif /* CONFIG_TESTING_OPTIONS */
 
 	int *pasn_groups;
+
+	/*
+	 * The time in TUs after which the non-AP STA is requested to retry the
+	 * PASN authentication
+	 */
+	u16 pasn_comeback_after;
 #endif /* CONFIG_PASN */
 
 	unsigned int unsol_bcast_probe_resp_interval;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 72d102f44e..e31e4710da 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -702,13 +702,15 @@ static int use_anti_clogging(struct hostapd_data *hapd)
 
 	for (sta = hapd->sta_list; sta; sta = sta->next) {
 #ifdef CONFIG_SAE
-		if (!sta->sae)
-			continue;
-		if (sta->sae->state != SAE_COMMITTED &&
-		    sta->sae->state != SAE_CONFIRMED)
-			continue;
-		open++;
+		if (sta->sae &&
+		    (sta->sae->state == SAE_COMMITTED ||
+		     sta->sae->state == SAE_CONFIRMED))
+			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;
 	}
@@ -806,7 +808,8 @@ static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
 	if (buf == NULL)
 		return NULL;
 
-	wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
+	if (group)
+		wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
 
 	if (h2e) {
 		/* Encapsulate Anti-clogging Token field in a container IE */
@@ -2891,6 +2894,57 @@ 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, u16 group)
+{
+	struct wpabuf *buf, *comeback;
+	int ret;
+
+	wpa_printf(MSG_DEBUG,
+		   "PASN: Building comeback frame 2. Comeback after=%u",
+		   hapd->conf->pasn_comeback_after);
+
+	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);
+
+	/*
+	 * Do not include the group as part of the token since it is not going
+	 * to be used
+	 */
+	comeback = auth_build_token_req(hapd, 0, 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, group,
+				  WPA_PASN_WRAPPED_DATA_NO,
+				  NULL, 0, comeback,
+				  hapd->conf->pasn_comeback_after);
+
+	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,
@@ -3133,6 +3187,26 @@ 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");
+
+		ret = check_comeback_token(hapd, sta->addr,
+					   pasn_params.comeback,
+					   pasn_params.comeback_len);
+
+		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, pasn_params.group);
+		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.17.1




More information about the Hostap mailing list