AP: Rename SAE anti clogging variables and functions

PASN authentication mandates support for comeback flow, which
among others can be used for anti-clogging purposes.

As the SAE support for anti clogging can also be used for PASN,
start modifying the source code so the anti clogging support
can be used for both SAE and PASN.

As a start, rename some variables/functions etc. so that they would not
be SAE specific. The configuration variable is also renamed, but the old
version remains available for backwards compatibility.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
Ilan Peer 2021-03-15 14:57:05 +02:00 committed by Jouni Malinen
parent b42b6c4d53
commit 6fe0d56e88
6 changed files with 48 additions and 41 deletions

View file

@ -4276,8 +4276,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "assocresp_elements") == 0) { } else if (os_strcmp(buf, "assocresp_elements") == 0) {
if (parse_wpabuf_hex(line, buf, &bss->assocresp_elements, pos)) if (parse_wpabuf_hex(line, buf, &bss->assocresp_elements, pos))
return 1; return 1;
} else if (os_strcmp(buf, "sae_anti_clogging_threshold") == 0) { } else if (os_strcmp(buf, "sae_anti_clogging_threshold") == 0 ||
bss->sae_anti_clogging_threshold = atoi(pos); os_strcmp(buf, "anti_clogging_threshold") == 0) {
bss->anti_clogging_threshold = atoi(pos);
} else if (os_strcmp(buf, "sae_sync") == 0) { } else if (os_strcmp(buf, "sae_sync") == 0) {
bss->sae_sync = atoi(pos); bss->sae_sync = atoi(pos);
} else if (os_strcmp(buf, "sae_groups") == 0) { } else if (os_strcmp(buf, "sae_groups") == 0) {

View file

@ -1886,7 +1886,8 @@ own_ip_addr=127.0.0.1
# SAE threshold for anti-clogging mechanism (dot11RSNASAEAntiCloggingThreshold) # SAE threshold for anti-clogging mechanism (dot11RSNASAEAntiCloggingThreshold)
# This parameter defines how many open SAE instances can be in progress at the # This parameter defines how many open SAE instances can be in progress at the
# same time before the anti-clogging mechanism is taken into use. # same time before the anti-clogging mechanism is taken into use.
#sae_anti_clogging_threshold=5 #sae_anti_clogging_threshold=5 (deprecated)
#anti_clogging_threshold=5
# Maximum number of SAE synchronization errors (dot11RSNASAESync) # Maximum number of SAE synchronization errors (dot11RSNASAESync)
# The offending SAE peer will be disconnected if more than this many # The offending SAE peer will be disconnected if more than this many

View file

@ -121,7 +121,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
bss->radius_das_time_window = 300; bss->radius_das_time_window = 300;
bss->sae_anti_clogging_threshold = 5; bss->anti_clogging_threshold = 5;
bss->sae_sync = 5; bss->sae_sync = 5;
bss->gas_frag_limit = 1400; bss->gas_frag_limit = 1400;

View file

@ -655,7 +655,7 @@ struct hostapd_bss_config {
struct wpabuf *vendor_elements; struct wpabuf *vendor_elements;
struct wpabuf *assocresp_elements; struct wpabuf *assocresp_elements;
unsigned int sae_anti_clogging_threshold; unsigned int anti_clogging_threshold;
unsigned int sae_sync; unsigned int sae_sync;
int sae_require_mfp; int sae_require_mfp;
int sae_confirm_immediate; int sae_confirm_immediate;

View file

@ -326,10 +326,10 @@ struct hostapd_data {
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
/** Key used for generating SAE anti-clogging tokens */ /** Key used for generating SAE anti-clogging tokens */
u8 sae_token_key[8]; u8 comeback_key[8];
struct os_reltime last_sae_token_key_update; struct os_reltime last_comeback_key_update;
u16 sae_token_idx; u16 comeback_idx;
u16 sae_pending_token_idx[256]; u16 comeback_pending_idx[256];
int dot11RSNASAERetransPeriod; /* msec */ int dot11RSNASAERetransPeriod; /* msec */
struct dl_list sae_commit_queue; /* struct hostapd_sae_commit_queue */ struct dl_list sae_commit_queue; /* struct hostapd_sae_commit_queue */
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */

View file

@ -688,12 +688,12 @@ static int auth_sae_send_confirm(struct hostapd_data *hapd,
} }
static int use_sae_anti_clogging(struct hostapd_data *hapd) static int use_anti_clogging(struct hostapd_data *hapd)
{ {
struct sta_info *sta; struct sta_info *sta;
unsigned int open = 0; unsigned int open = 0;
if (hapd->conf->sae_anti_clogging_threshold == 0) if (hapd->conf->anti_clogging_threshold == 0)
return 1; return 1;
for (sta = hapd->sta_list; sta; sta = sta->next) { for (sta = hapd->sta_list; sta; sta = sta->next) {
@ -703,7 +703,7 @@ static int use_sae_anti_clogging(struct hostapd_data *hapd)
sta->sae->state != SAE_CONFIRMED) sta->sae->state != SAE_CONFIRMED)
continue; continue;
open++; open++;
if (open >= hapd->conf->sae_anti_clogging_threshold) if (open >= hapd->conf->anti_clogging_threshold)
return 1; return 1;
} }
@ -711,18 +711,19 @@ static int use_sae_anti_clogging(struct hostapd_data *hapd)
* there are enough pending commit messages in the processing queue to * there are enough pending commit messages in the processing queue to
* potentially result in too many open sessions. */ * potentially result in too many open sessions. */
if (open + dl_list_len(&hapd->sae_commit_queue) >= if (open + dl_list_len(&hapd->sae_commit_queue) >=
hapd->conf->sae_anti_clogging_threshold) hapd->conf->anti_clogging_threshold)
return 1; return 1;
return 0; return 0;
} }
static int sae_token_hash(struct hostapd_data *hapd, const u8 *addr, u8 *idx) static int comeback_token_hash(struct hostapd_data *hapd, const u8 *addr,
u8 *idx)
{ {
u8 hash[SHA256_MAC_LEN]; u8 hash[SHA256_MAC_LEN];
if (hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key), if (hmac_sha256(hapd->comeback_key, sizeof(hapd->comeback_key),
addr, ETH_ALEN, hash) < 0) addr, ETH_ALEN, hash) < 0)
return -1; return -1;
*idx = hash[0]; *idx = hash[0];
@ -730,7 +731,7 @@ static int sae_token_hash(struct hostapd_data *hapd, const u8 *addr, u8 *idx)
} }
static int check_sae_token(struct hostapd_data *hapd, const u8 *addr, static int check_comeback_token(struct hostapd_data *hapd, const u8 *addr,
const u8 *token, size_t token_len) const u8 *token, size_t token_len)
{ {
u8 mac[SHA256_MAC_LEN]; u8 mac[SHA256_MAC_LEN];
@ -739,11 +740,13 @@ static int check_sae_token(struct hostapd_data *hapd, const u8 *addr,
u16 token_idx; u16 token_idx;
u8 idx; u8 idx;
if (token_len != SHA256_MAC_LEN || sae_token_hash(hapd, addr, &idx) < 0) if (token_len != SHA256_MAC_LEN ||
comeback_token_hash(hapd, addr, &idx) < 0)
return -1; return -1;
token_idx = hapd->sae_pending_token_idx[idx]; token_idx = hapd->comeback_pending_idx[idx];
if (token_idx == 0 || token_idx != WPA_GET_BE16(token)) { if (token_idx == 0 || token_idx != WPA_GET_BE16(token)) {
wpa_printf(MSG_DEBUG, "SAE: Invalid anti-clogging token from " wpa_printf(MSG_DEBUG,
"Comeback: Invalid anti-clogging token from "
MACSTR " - token_idx 0x%04x, expected 0x%04x", MACSTR " - token_idx 0x%04x, expected 0x%04x",
MAC2STR(addr), WPA_GET_BE16(token), token_idx); MAC2STR(addr), WPA_GET_BE16(token), token_idx);
return -1; return -1;
@ -753,12 +756,12 @@ static int check_sae_token(struct hostapd_data *hapd, const u8 *addr,
len[0] = ETH_ALEN; len[0] = ETH_ALEN;
addrs[1] = token; addrs[1] = token;
len[1] = 2; len[1] = 2;
if (hmac_sha256_vector(hapd->sae_token_key, sizeof(hapd->sae_token_key), if (hmac_sha256_vector(hapd->comeback_key, sizeof(hapd->comeback_key),
2, addrs, len, mac) < 0 || 2, addrs, len, mac) < 0 ||
os_memcmp_const(token + 2, &mac[2], SHA256_MAC_LEN - 2) != 0) os_memcmp_const(token + 2, &mac[2], SHA256_MAC_LEN - 2) != 0)
return -1; return -1;
hapd->sae_pending_token_idx[idx] = 0; /* invalidate used token */ hapd->comeback_pending_idx[idx] = 0; /* invalidate used token */
return 0; return 0;
} }
@ -777,18 +780,18 @@ static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
u16 token_idx; u16 token_idx;
os_get_reltime(&now); os_get_reltime(&now);
if (!os_reltime_initialized(&hapd->last_sae_token_key_update) || if (!os_reltime_initialized(&hapd->last_comeback_key_update) ||
os_reltime_expired(&now, &hapd->last_sae_token_key_update, 60) || os_reltime_expired(&now, &hapd->last_comeback_key_update, 60) ||
hapd->sae_token_idx == 0xffff) { hapd->comeback_idx == 0xffff) {
if (random_get_bytes(hapd->sae_token_key, if (random_get_bytes(hapd->comeback_key,
sizeof(hapd->sae_token_key)) < 0) sizeof(hapd->comeback_key)) < 0)
return NULL; return NULL;
wpa_hexdump(MSG_DEBUG, "SAE: Updated token key", wpa_hexdump(MSG_DEBUG, "Comeback: Updated token key",
hapd->sae_token_key, sizeof(hapd->sae_token_key)); hapd->comeback_key, sizeof(hapd->comeback_key));
hapd->last_sae_token_key_update = now; hapd->last_comeback_key_update = now;
hapd->sae_token_idx = 0; hapd->comeback_idx = 0;
os_memset(hapd->sae_pending_token_idx, 0, os_memset(hapd->comeback_pending_idx, 0,
sizeof(hapd->sae_pending_token_idx)); sizeof(hapd->comeback_pending_idx));
} }
buf = wpabuf_alloc(sizeof(le16) + 3 + SHA256_MAC_LEN); buf = wpabuf_alloc(sizeof(le16) + 3 + SHA256_MAC_LEN);
@ -804,15 +807,16 @@ static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
wpabuf_put_u8(buf, WLAN_EID_EXT_ANTI_CLOGGING_TOKEN); wpabuf_put_u8(buf, WLAN_EID_EXT_ANTI_CLOGGING_TOKEN);
} }
if (sae_token_hash(hapd, addr, &p_idx) < 0) { if (comeback_token_hash(hapd, addr, &p_idx) < 0) {
wpabuf_free(buf); wpabuf_free(buf);
return NULL; return NULL;
} }
token_idx = hapd->sae_pending_token_idx[p_idx];
token_idx = hapd->comeback_pending_idx[p_idx];
if (!token_idx) { if (!token_idx) {
hapd->sae_token_idx++; hapd->comeback_idx++;
token_idx = hapd->sae_token_idx; token_idx = hapd->comeback_idx;
hapd->sae_pending_token_idx[p_idx] = token_idx; hapd->comeback_pending_idx[p_idx] = token_idx;
} }
WPA_PUT_BE16(idx, token_idx); WPA_PUT_BE16(idx, token_idx);
token = wpabuf_put(buf, SHA256_MAC_LEN); token = wpabuf_put(buf, SHA256_MAC_LEN);
@ -820,7 +824,7 @@ static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
len[0] = ETH_ALEN; len[0] = ETH_ALEN;
addrs[1] = idx; addrs[1] = idx;
len[1] = sizeof(idx); len[1] = sizeof(idx);
if (hmac_sha256_vector(hapd->sae_token_key, sizeof(hapd->sae_token_key), if (hmac_sha256_vector(hapd->comeback_key, sizeof(hapd->comeback_key),
2, addrs, len, token) < 0) { 2, addrs, len, token) < 0) {
wpabuf_free(buf); wpabuf_free(buf);
return NULL; return NULL;
@ -1452,7 +1456,8 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
goto remove_sta; goto remove_sta;
} }
if (token && check_sae_token(hapd, sta->addr, token, token_len) if (token &&
check_comeback_token(hapd, sta->addr, token, token_len)
< 0) { < 0) {
wpa_printf(MSG_DEBUG, "SAE: Drop commit message with " wpa_printf(MSG_DEBUG, "SAE: Drop commit message with "
"incorrect token from " MACSTR, "incorrect token from " MACSTR,
@ -1469,7 +1474,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
goto reply; goto reply;
} }
if (!token && use_sae_anti_clogging(hapd) && !allow_reuse) { if (!token && use_anti_clogging(hapd) && !allow_reuse) {
int h2e = 0; int h2e = 0;
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,