[PATCH 1/3] AP: Add support for PASN comeback flow
Ilan Peer
ilan.peer at intel.com
Wed Mar 17 16:13:27 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 | 82 +++++++++++++++++++++++++++++++++++++++----
5 files changed, 96 insertions(+), 6 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 e3ee8b2a0c..f1b379260a 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -2038,6 +2038,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..d8d52368fb 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;
}
@@ -2891,6 +2893,53 @@ 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. 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);
+
+ 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, 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 +3182,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.17.1
More information about the Hostap
mailing list