PASN: Add support for comeback flow in AP mode
Reuse the SAE anti-clogging token implementation to support similar design with the PASN comeback cookie. Signed-off-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
parent
4871df4bf7
commit
ab623ac750
5 changed files with 97 additions and 7 deletions
|
@ -4675,6 +4675,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
line, pos);
|
line, pos);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
} else if (os_strcmp(buf, "pasn_comeback_after") == 0) {
|
||||||
|
bss->pasn_comeback_after = atoi(pos);
|
||||||
#endif /* CONFIG_PASN */
|
#endif /* CONFIG_PASN */
|
||||||
} else {
|
} else {
|
||||||
wpa_printf(MSG_ERROR,
|
wpa_printf(MSG_ERROR,
|
||||||
|
|
|
@ -2051,6 +2051,13 @@ own_ip_addr=127.0.0.1
|
||||||
# http://www.iana.org/assignments/ipsec-registry/ipsec-registry.xml#ipsec-registry-10
|
# http://www.iana.org/assignments/ipsec-registry/ipsec-registry.xml#ipsec-registry-10
|
||||||
#pasn_groups=19 20 21
|
#pasn_groups=19 20 21
|
||||||
|
|
||||||
|
# PASN comeback after time in TUs
|
||||||
|
# In case the AP is temporarily unable to handle a PASN authentication exchange
|
||||||
|
# due to a too large number of parallel operations, this value indicates to the
|
||||||
|
# peer after how many TUs it can try the PASN exchange again.
|
||||||
|
# (default: 10 TUs)
|
||||||
|
#pasn_comeback_after=10
|
||||||
|
|
||||||
##### IEEE 802.11r configuration ##############################################
|
##### IEEE 802.11r configuration ##############################################
|
||||||
|
|
||||||
# Mobility Domain identifier (dot11FTMobilityDomainID, MDID)
|
# Mobility Domain identifier (dot11FTMobilityDomainID, MDID)
|
||||||
|
|
|
@ -165,6 +165,11 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
bss->sae_commit_status = -1;
|
bss->sae_commit_status = -1;
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
|
#ifdef CONFIG_PASN
|
||||||
|
/* comeback after 10 TUs */
|
||||||
|
bss->pasn_comeback_after = 10;
|
||||||
|
#endif /* CONFIG_PASN */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -880,6 +880,12 @@ struct hostapd_bss_config {
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
int *pasn_groups;
|
int *pasn_groups;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The time in TUs after which the non-AP STA is requested to retry the
|
||||||
|
* PASN authentication in case there are too many parallel operations.
|
||||||
|
*/
|
||||||
|
u16 pasn_comeback_after;
|
||||||
#endif /* CONFIG_PASN */
|
#endif /* CONFIG_PASN */
|
||||||
|
|
||||||
unsigned int unsol_bcast_probe_resp_interval;
|
unsigned int unsol_bcast_probe_resp_interval;
|
||||||
|
|
|
@ -702,13 +702,15 @@ static int use_anti_clogging(struct hostapd_data *hapd)
|
||||||
|
|
||||||
for (sta = hapd->sta_list; sta; sta = sta->next) {
|
for (sta = hapd->sta_list; sta; sta = sta->next) {
|
||||||
#ifdef CONFIG_SAE
|
#ifdef CONFIG_SAE
|
||||||
if (!sta->sae)
|
if (sta->sae &&
|
||||||
continue;
|
(sta->sae->state == SAE_COMMITTED ||
|
||||||
if (sta->sae->state != SAE_COMMITTED &&
|
sta->sae->state == SAE_CONFIRMED))
|
||||||
sta->sae->state != SAE_CONFIRMED)
|
open++;
|
||||||
continue;
|
|
||||||
open++;
|
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
|
#ifdef CONFIG_PASN
|
||||||
|
if (sta->pasn && sta->pasn->ecdh)
|
||||||
|
open++;
|
||||||
|
#endif /* CONFIG_PASN */
|
||||||
if (open >= hapd->conf->anti_clogging_threshold)
|
if (open >= hapd->conf->anti_clogging_threshold)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -806,7 +808,8 @@ static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
|
if (group)
|
||||||
|
wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
|
||||||
|
|
||||||
if (h2e) {
|
if (h2e) {
|
||||||
/* Encapsulate Anti-clogging Token field in a container IE */
|
/* Encapsulate Anti-clogging Token field in a container IE */
|
||||||
|
@ -2891,6 +2894,54 @@ 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 a 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);
|
||||||
|
|
||||||
|
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,
|
static int handle_auth_pasn_resp(struct hostapd_data *hapd,
|
||||||
struct sta_info *sta,
|
struct sta_info *sta,
|
||||||
struct rsn_pmksa_cache_entry *pmksa,
|
struct rsn_pmksa_cache_entry *pmksa,
|
||||||
|
@ -3133,6 +3184,25 @@ static void handle_auth_pasn_1(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
goto send_resp;
|
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: Respond 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);
|
sta->pasn->ecdh = crypto_ecdh_init(pasn_params.group);
|
||||||
if (!sta->pasn->ecdh) {
|
if (!sta->pasn->ecdh) {
|
||||||
wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH");
|
wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH");
|
||||||
|
|
Loading…
Reference in a new issue