* [PATCH wireless-next v3 1/2] wifi: cfg80211: indicate (Re)Association frame encryption to userspace
2026-05-04 12:36 [PATCH wireless-next v3 0/2] wifi: cfg80211/mac80211: indicate (Re)Association frame encryption in SME-in-driver mode Kavita Kavita
@ 2026-05-04 12:36 ` Kavita Kavita
2026-05-04 12:36 ` [PATCH wireless-next v3 2/2] wifi: mac80211: set assoc_encrypted for EPP associations Kavita Kavita
1 sibling, 0 replies; 5+ messages in thread
From: Kavita Kavita @ 2026-05-04 12:36 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, kavita.kavita
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>
---
include/net/cfg80211.h | 6 ++++++
include/uapi/linux/nl80211.h | 9 +++++++++
net/wireless/mlme.c | 1 +
net/wireless/nl80211.c | 4 +++-
net/wireless/sme.c | 1 +
5 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a40ab36b8edb..5e1ca0fb614e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -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;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 072b383d7d3c..e26d65c1b737 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -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,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index bd72317c4964..d196b5c086cc 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -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;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cf236307cca9..b96f2f7f67d2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -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) {
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 86e2ccaa678c..b451df3096dd 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -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);
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH wireless-next v3 2/2] wifi: mac80211: set assoc_encrypted for EPP associations
2026-05-04 12:36 [PATCH wireless-next v3 0/2] wifi: cfg80211/mac80211: indicate (Re)Association frame encryption in SME-in-driver mode Kavita Kavita
2026-05-04 12:36 ` [PATCH wireless-next v3 1/2] wifi: cfg80211: indicate (Re)Association frame encryption to userspace Kavita Kavita
@ 2026-05-04 12:36 ` Kavita Kavita
2026-05-04 14:15 ` Johannes Berg
1 sibling, 1 reply; 5+ messages in thread
From: Kavita Kavita @ 2026-05-04 12:36 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, kavita.kavita
Populate the assoc_encrypted field in cfg80211_rx_assoc_resp_data
for mac80211-based drivers to indicate that the entire (re)association
exchange was encrypted.
When epp_peer is set, mac80211 enforces that unprotected
(Re)Association Request/Response frames are dropped. This ensures that
by the time the (Re)Association Response is processed, the entire
exchange was transmitted encrypted over the air.
Add support to populate assoc_encrypted based on epp_peer flag.
Signed-off-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
---
net/mac80211/mlme.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 00b4beff0e43..a1246af09dc5 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -6652,6 +6652,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
.type = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_TYPE,
};
struct ieee802_11_elems *elems;
+ struct sta_info *sta;
int ac;
const u8 *elem_start;
unsigned int elem_len;
@@ -6847,6 +6848,14 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
resp.ap_mld_addr = ap_mld_addr;
}
+ /*
+ * If epp_peer set, unprotected (Re)Association Request/Response frames
+ * are dropped, which ensures that the (re)association exchange is
+ * encrypted over the air.
+ */
+ sta = sta_info_get_bss(sdata, sdata->vif.cfg.ap_addr);
+ resp.assoc_encrypted = sta && sta->sta.epp_peer;
+
ieee80211_destroy_assoc_data(sdata,
status_code == WLAN_STATUS_SUCCESS ?
ASSOC_SUCCESS :
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread