]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: mac80211: Check for MLE before appending in Authentication frame
authorKavita Kavita <kavita.kavita@oss.qualcomm.com>
Wed, 14 Jan 2026 11:18:57 +0000 (16:48 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 14 Jan 2026 13:34:16 +0000 (14:34 +0100)
Currently, in MLO connections, userspace constructs most of the
Authentication frame body, excluding the Multi-Link element (MLE),
which mac80211 appends later in ieee80211_send_auth(). At present,
mac80211 always adds the MLE itself, since userspace
(e.g. wpa_supplicant) does not yet include it.

However, for new authentication protocols such as Enhanced Privacy
Protection Key Exchange (EPPKE), as specified in
"IEEE P802.11bi/D3.0 section 12.16.9", the MLE must be included in
userspace so that the Message Integrity Code (MIC) can be computed
correctly over the complete frame body. Table 9-71 specifies that
the MIC is mandatory. If mac80211 appends the MLE again, the
Authentication frame becomes invalid.

Add a check in ieee80211_send_auth() to detect whether the MLE is
already present in the Authentication frame body before appending.
Skip the append if the MLE exists, otherwise add it as before.

Signed-off-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
Link: https://patch.msgid.link/20260114111900.2196941-7-kavita.kavita@oss.qualcomm.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/util.c

index 7d7650c91f4fafe91108233042f4e8599ec3f6f8..4d5680da7aa0f60555feb3d3d5f9f06aee2867ee 100644 (file)
@@ -1142,14 +1142,17 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
                .ml.control = cpu_to_le16(IEEE80211_ML_CONTROL_TYPE_BASIC),
                .basic.len = sizeof(mle.basic),
        };
+       bool add_mle;
        int err;
 
-       memcpy(mle.basic.mld_mac_addr, sdata->vif.addr, ETH_ALEN);
+       add_mle = (multi_link &&
+                  !cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_MULTI_LINK,
+                                          extra, extra_len));
 
        /* 24 + 6 = header + auth_algo + auth_transaction + status_code */
        skb = dev_alloc_skb(local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN +
                            24 + 6 + extra_len + IEEE80211_WEP_ICV_LEN +
-                           multi_link * sizeof(mle));
+                           add_mle * sizeof(mle));
        if (!skb)
                return;
 
@@ -1166,8 +1169,11 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
        mgmt->u.auth.status_code = cpu_to_le16(status);
        if (extra)
                skb_put_data(skb, extra, extra_len);
-       if (multi_link)
+
+       if (add_mle) {
+               memcpy(mle.basic.mld_mac_addr, sdata->vif.addr, ETH_ALEN);
                skb_put_data(skb, &mle, sizeof(mle));
+       }
 
        if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
                mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);