]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: cfg80211: indicate (Re)Association frame encryption to userspace
authorKavita Kavita <kavita.kavita@oss.qualcomm.com>
Mon, 4 May 2026 12:36:23 +0000 (18:06 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 5 May 2026 10:09:19 +0000 (12:09 +0200)
In SME-in-driver mode, the driver handles the entire (re)association
exchange. Userspace (e.g., wpa_supplicant) currently has no explicit
indication of whether the (re)association exchange was encrypted,
making it difficult to distinguish EPP (Enhanced Privacy Protection,
IEEE 802.11bi) associations from non-EPP associations.

When (Re)Association frame encryption is used, the (Re)Association
Response frame must contain a Key Delivery element as specified in
IEEE P802.11bi/D4.0, Table 9-65. Userspace must process this element
only when the (Re)Association Response frame is actually encrypted.
Processing it unconditionally for unencrypted frames leads to incorrect
behavior. Without an explicit indication from the driver, userspace
cannot determine whether encryption was used and whether the Key
Delivery element is valid.

Add a new flag attribute NL80211_ATTR_ASSOC_ENCRYPTED and a
corresponding field "assoc_encrypted" in cfg80211_connect_resp_params
to indicate that both the (Re)Association Request and Response frames
are transmitted encrypted over the air.

For mac80211-based drivers, extend cfg80211_rx_assoc_resp_data with
the assoc_encrypted field as well, which is then propagated to
cfg80211_connect_resp_params.

Pass the flag to userspace via NL80211_CMD_CONNECT event.

Signed-off-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
Link: https://patch.msgid.link/20260504123624.529218-2-kavita.kavita@oss.qualcomm.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/mlme.c
net/wireless/nl80211.c
net/wireless/sme.c

index 51eded4204cf3b54db0d54728ea9b4e6357ef037..b0a908b2ba734210abe43793a3e3e07f343dc877 100644 (file)
@@ -8305,6 +8305,7 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr);
  *     as the AC bitmap in the QoS info field
  * @req_ies: information elements from the (Re)Association Request frame
  * @req_ies_len: length of req_ies data
+ * @assoc_encrypted: indicate if the (re)association exchange is encrypted.
  * @ap_mld_addr: AP MLD address (in case of MLO)
  * @links: per-link information indexed by link ID, use links[0] for
  *     non-MLO connections
@@ -8319,6 +8320,7 @@ struct cfg80211_rx_assoc_resp_data {
        const u8 *req_ies;
        size_t req_ies_len;
        int uapsd_queues;
+       bool assoc_encrypted;
        const u8 *ap_mld_addr;
        struct {
                u8 addr[ETH_ALEN] __aligned(2);
@@ -8838,6 +8840,9 @@ struct cfg80211_fils_resp_params {
  * @links.status: per-link status code, to report a status code that's not
  *     %WLAN_STATUS_SUCCESS for a given link, it must also be in the
  *     @valid_links bitmap and may have a BSS pointer (which is then released)
+ * @assoc_encrypted: The driver should set this flag to indicate that the
+ *     (Re)Association Request/Response frames are transmitted encrypted over
+ *     the air.
  */
 struct cfg80211_connect_resp_params {
        int status;
@@ -8847,6 +8852,7 @@ struct cfg80211_connect_resp_params {
        size_t resp_ie_len;
        struct cfg80211_fils_resp_params fils;
        enum nl80211_timeout_reason timeout_reason;
+       bool assoc_encrypted;
 
        const u8 *ap_mld_addr;
        u16 valid_links;
index 072b383d7d3ce6773db7429317495dcd4c22150e..e26d65c1b73795361b7814a7bc5248548aaed172 100644 (file)
@@ -3142,6 +3142,13 @@ enum nl80211_commands {
  *     association response etc., since it's abridged in the beacon. Used
  *     for START_AP etc.
  *
+ * @NL80211_ATTR_ASSOC_ENCRYPTED: Flag attribute, used only with the
+ *     %NL80211_CMD_CONNECT event in SME-in-driver mode. The driver should
+ *     set this flag to indicate that both the (Re)Association Request frame
+ *     and the corresponding (Re)Association Response frame are transmitted
+ *     encrypted over the air. Enhanced Privacy Protection (EPP), as defined
+ *     in IEEE P802.11bi/D4.0, mandates this encryption.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3735,6 +3742,8 @@ enum nl80211_attrs {
        NL80211_ATTR_NAN_MAX_CHAN_SWITCH_TIME,
        NL80211_ATTR_NAN_PEER_MAPS,
 
+       NL80211_ATTR_ASSOC_ENCRYPTED,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
index bd72317c4964e25031504b611511d1e7cd70f192..d196b5c086ccc7f200ac93e9fa737ed62803158d 100644 (file)
@@ -38,6 +38,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
                                        u.assoc_resp.variable),
                .status = le16_to_cpu(mgmt->u.assoc_resp.status_code),
                .ap_mld_addr = data->ap_mld_addr,
+               .assoc_encrypted = data->assoc_encrypted,
        };
        unsigned int link_id;
 
index cf236307cca9c5b355747f0b2f02d3bfdbc91a00..b96f2f7f67d2492b6240c1d73cc2186054a446cc 100644 (file)
@@ -20660,7 +20660,9 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
              (cr->fils.pmk &&
               nla_put(msg, NL80211_ATTR_PMK, cr->fils.pmk_len, cr->fils.pmk)) ||
              (cr->fils.pmkid &&
-              nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->fils.pmkid)))))
+              nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->fils.pmkid)))) ||
+           (cr->assoc_encrypted &&
+            nla_put_flag(msg, NL80211_ATTR_ASSOC_ENCRYPTED)))
                goto nla_put_failure;
 
        if (cr->valid_links) {
index 86e2ccaa678ce589320e3189077b0a019e34cc74..b451df3096dd1eebbc8c91a4f170450e0ef1d6ed 100644 (file)
@@ -1066,6 +1066,7 @@ void cfg80211_connect_done(struct net_device *dev,
        }
        ev->cr.status = params->status;
        ev->cr.timeout_reason = params->timeout_reason;
+       ev->cr.assoc_encrypted = params->assoc_encrypted;
 
        spin_lock_irqsave(&wdev->event_lock, flags);
        list_add_tail(&ev->list, &wdev->event_list);