From: Jouni Malinen Date: Wed, 30 Oct 2024 09:33:44 +0000 (+0200) Subject: SAE: Reject unexpected password identifier in commit message parser X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8a33510550cb29da62df00b87623c7cf6ae133aa;p=thirdparty%2Fhostap.git SAE: Reject unexpected password identifier in commit message parser While the list of possible SAE password identifiers might not be available at the time of parsing a SAE commit message, an AP knows whether any password identifiers have been enabled (since it has to advertise that in the Beacon frames). When parsing a commit message on an AP with no password identifiers in use, the parser can already reject the unexpected case of an SAE password identifier. Check for this specific case and reject the SAE commit based on unknown password identifier if the received value cannot be for an enabled password. This prevents some cases where an active attacker might have been able to cause DoS by binding an STA entry in hostapd to a specific SAE password identifier even when that identifier is not in use. Signed-off-by: Jouni Malinen --- diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 8206932f3..98609c013 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1375,6 +1375,8 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, resp = -1; goto remove_sta; } + if (!hostapd_sae_pw_id_in_use(hapd->conf)) + sta->sae->no_pw_id = 1; sae_set_state(sta, SAE_NOTHING, "Init"); sta->sae->sync = 0; } diff --git a/src/common/sae.c b/src/common/sae.c index 73964e8b1..c93d3a6d2 100644 --- a/src/common/sae.c +++ b/src/common/sae.c @@ -121,12 +121,16 @@ void sae_clear_temp_data(struct sae_data *sae) void sae_clear_data(struct sae_data *sae) { + unsigned int no_pw_id; + if (sae == NULL) return; sae_clear_temp_data(sae); crypto_bignum_deinit(sae->peer_commit_scalar, 0); crypto_bignum_deinit(sae->peer_commit_scalar_accepted, 0); + no_pw_id = sae->no_pw_id; os_memset(sae, 0, sizeof(*sae)); + sae->no_pw_id = no_pw_id; } @@ -2070,6 +2074,12 @@ static int sae_parse_password_identifier(struct sae_data *sae, epos++; /* skip ext ID */ len--; + if (sae->no_pw_id) { + wpa_printf(MSG_DEBUG, + "SAE: Password Identifier included, but none has been enabled"); + return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER; + } + if (sae->tmp->pw_id && (len != os_strlen(sae->tmp->pw_id) || os_memcmp(sae->tmp->pw_id, epos, len) != 0)) { diff --git a/src/common/sae.h b/src/common/sae.h index c3ca4d41b..3a83c3be5 100644 --- a/src/common/sae.h +++ b/src/common/sae.h @@ -120,6 +120,7 @@ struct sae_data { u16 rc; /* protocol instance variable: Rc (received send-confirm) */ unsigned int h2e:1; unsigned int pk:1; + unsigned int no_pw_id:1; struct sae_temporary_data *tmp; };