MLD STA: Allow auth frames without ML IE for failure status codes

In some cases like unknown-group rejection, AP MLD can't parse the
received Authentication frame to the point of the Multi-Link element if
the group used by the peer is unknown to the AP MLD.

In such cases, AP MLD not including Multi-Link element in rejection
Authentication frames can be considered as standard compliant since AP
MLD doesn't know whether the received Authentication frame has
Multi-Link element or not.

To avoid connection issues in such cases, don't reject Authentication
frames without Multi-Link element when status code is other than
WLAN_STATUS_SUCCESS, WLAN_STATUS_SAE_HASH_TO_ELEMENT,
WLAN_STATUS_SAE_PK, and WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ.

Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
This commit is contained in:
Veerendranath Jakkam 2023-05-09 19:23:21 +05:30 committed by Jouni Malinen
parent 57386a647a
commit 199b44213c

View file

@ -547,6 +547,7 @@ static void wpas_sme_ml_auth(struct wpa_supplicant *wpa_s,
{ {
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
const u8 *mld_addr; const u8 *mld_addr;
u16 status_code = data->auth.status_code;
if (!wpa_s->valid_links) if (!wpa_s->valid_links)
return; return;
@ -560,7 +561,14 @@ static void wpas_sme_ml_auth(struct wpa_supplicant *wpa_s,
if (!elems.basic_mle || !elems.basic_mle_len) { if (!elems.basic_mle || !elems.basic_mle_len) {
wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication"); wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication");
if (status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ ||
status_code == WLAN_STATUS_SUCCESS ||
status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
status_code == WLAN_STATUS_SAE_PK)
goto out; goto out;
/* Accept missing Multi-Link element in failed authentication
* cases. */
return;
} }
mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len); mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
@ -1614,7 +1622,8 @@ static int sme_check_sae_rejected_groups(struct wpa_supplicant *wpa_s,
static int sme_external_ml_auth(struct wpa_supplicant *wpa_s, static int sme_external_ml_auth(struct wpa_supplicant *wpa_s,
const u8 *data, size_t len, int ie_offset) const u8 *data, size_t len, int ie_offset,
u16 status_code)
{ {
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
const u8 *mld_addr; const u8 *mld_addr;
@ -1627,7 +1636,14 @@ static int sme_external_ml_auth(struct wpa_supplicant *wpa_s,
if (!elems.basic_mle || !elems.basic_mle_len) { if (!elems.basic_mle || !elems.basic_mle_len) {
wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication"); wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication");
if (status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ ||
status_code == WLAN_STATUS_SUCCESS ||
status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
status_code == WLAN_STATUS_SAE_PK)
return -1; return -1;
/* Accept missing Multi-Link element in failed authentication
* cases. */
return 0;
} }
mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len); mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
@ -1733,7 +1749,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
wpa_s->current_ssid, 2); wpa_s->current_ssid, 2);
} else { } else {
if (wpa_s->sme.ext_ml_auth && if (wpa_s->sme.ext_ml_auth &&
sme_external_ml_auth(wpa_s, data, len, *ie_offset)) sme_external_ml_auth(wpa_s, data, len, *ie_offset,
status_code))
return -1; return -1;
sme_external_auth_send_sae_commit( sme_external_auth_send_sae_commit(
@ -1760,7 +1777,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
wpa_s->current_ssid, 1); wpa_s->current_ssid, 1);
} else { } else {
if (wpa_s->sme.ext_ml_auth && if (wpa_s->sme.ext_ml_auth &&
sme_external_ml_auth(wpa_s, data, len, *ie_offset)) sme_external_ml_auth(wpa_s, data, len, *ie_offset,
status_code))
return -1; return -1;
sme_external_auth_send_sae_commit( sme_external_auth_send_sae_commit(
@ -1859,7 +1877,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
wpa_s->current_ssid, 0); wpa_s->current_ssid, 0);
} else { } else {
if (wpa_s->sme.ext_ml_auth && if (wpa_s->sme.ext_ml_auth &&
sme_external_ml_auth(wpa_s, data, len, *ie_offset)) sme_external_ml_auth(wpa_s, data, len, *ie_offset,
status_code))
return -1; return -1;
sme_external_auth_send_sae_confirm(wpa_s, sa); sme_external_auth_send_sae_confirm(wpa_s, sa);
@ -1875,7 +1894,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
ie_offset) < 0) ie_offset) < 0)
return -1; return -1;
if (external && wpa_s->sme.ext_ml_auth && if (external && wpa_s->sme.ext_ml_auth &&
sme_external_ml_auth(wpa_s, data, len, *ie_offset)) sme_external_ml_auth(wpa_s, data, len, *ie_offset,
status_code))
return -1; return -1;
wpa_s->sme.sae.state = SAE_ACCEPTED; wpa_s->sme.sae.state = SAE_ACCEPTED;