Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

wifi: mac80211: add support for encryption/decryption of (Re)Association frames

Currently, mac80211 does not encrypt or decrypt (Re)Association frames
(Request and Response) because temporal keys are not yet available at
that stage.

With extensions from IEEE P802.11bi, e.g. EPPKE, temporal keys can be
established before association. This enables the encryption and
decryption of (Re)Association Request/Response frames.

Add support to unset the IEEE80211_TX_INTFL_DONT_ENCRYPT flag when
the peer is marked as an Enhanced Privacy Protection (EPP) peer and
encryption keys are available for the connection in non-AP STA mode,
allowing secure transmission of (Re)Association Request frames.

Drop unprotected (Re)Association Request/Response frames received from
an EPP peer.

Co-developed-by: Sai Pratyusha Magam <quic_smagam@quicinc.com>
Signed-off-by: Sai Pratyusha Magam <quic_smagam@quicinc.com>
Signed-off-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
Link: https://patch.msgid.link/20260114111900.2196941-9-kavita.kavita@oss.qualcomm.com
[remove useless parentheses]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Kavita Kavita and committed by
Johannes Berg
3d2515fd 0e7e5099

+34 -4
+8
net/mac80211/ieee80211_i.h
··· 2393 2393 struct sk_buff *skb, int tid, int link_id, 2394 2394 enum nl80211_band band); 2395 2395 2396 + static inline bool ieee80211_require_encrypted_assoc(__le16 fc, 2397 + struct sta_info *sta) 2398 + { 2399 + return (sta && sta->sta.epp_peer && 2400 + (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc) || 2401 + ieee80211_is_assoc_resp(fc) || ieee80211_is_reassoc_resp(fc))); 2402 + } 2403 + 2396 2404 /* sta_out needs to be checked for ERR_PTR() before using */ 2397 2405 int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata, 2398 2406 struct sk_buff *skb,
+11 -1
net/mac80211/mlme.c
··· 2155 2155 struct ieee80211_prep_tx_info info = {}; 2156 2156 unsigned int link_id, n_links = 0; 2157 2157 u16 present_elems[PRESENT_ELEMS_MAX] = {}; 2158 + struct sta_info *sta; 2159 + bool assoc_encrypt; 2158 2160 void *capab_pos; 2159 2161 size_t size; 2160 2162 int ret; ··· 2337 2335 info.link_id = assoc_data->assoc_link_id; 2338 2336 drv_mgd_prepare_tx(local, sdata, &info); 2339 2337 2340 - IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 2338 + sta = sta_info_get_bss(sdata, sdata->vif.cfg.ap_addr); 2339 + 2340 + assoc_encrypt = sta && sta->sta.epp_peer && 2341 + wiphy_dereference(sdata->local->hw.wiphy, 2342 + sta->ptk[sta->ptk_idx]); 2343 + 2344 + if (!assoc_encrypt) 2345 + IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 2346 + 2341 2347 if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) 2342 2348 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS | 2343 2349 IEEE80211_TX_INTFL_MLME_CONN_TX;
+8
net/mac80211/rx.c
··· 2609 2609 (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC))) 2610 2610 return RX_DROP_U_UNPROT_ROBUST_ACTION; 2611 2611 2612 + /* 2613 + * Drop unprotected (Re)Association Request/Response frame received from 2614 + * an EPP Peer. 2615 + */ 2616 + if (!ieee80211_has_protected(fc) && 2617 + ieee80211_require_encrypted_assoc(fc, rx->sta)) 2618 + return RX_DROP_U_UNPROT_UCAST_MGMT; 2619 + 2612 2620 return RX_CONTINUE; 2613 2621 } 2614 2622 EXPORT_SYMBOL_IF_MAC80211_KUNIT(ieee80211_drop_unencrypted_mgmt);
+3 -1
net/mac80211/tx.c
··· 640 640 if (!ieee80211_is_data_present(hdr->frame_control) && 641 641 !ieee80211_use_mfp(hdr->frame_control, tx->sta, 642 642 tx->skb) && 643 - !ieee80211_is_group_privacy_action(tx->skb)) 643 + !ieee80211_is_group_privacy_action(tx->skb) && 644 + !ieee80211_require_encrypted_assoc(hdr->frame_control, 645 + tx->sta)) 644 646 tx->key = NULL; 645 647 else 646 648 skip_hw = (tx->key->conf.flags &
+4 -2
net/mac80211/wpa.c
··· 527 527 hdrlen = ieee80211_hdrlen(hdr->frame_control); 528 528 529 529 if (!ieee80211_is_data(hdr->frame_control) && 530 - !ieee80211_is_robust_mgmt_frame(skb)) 530 + !ieee80211_is_robust_mgmt_frame(skb) && 531 + !ieee80211_require_encrypted_assoc(hdr->frame_control, rx->sta)) 531 532 return RX_CONTINUE; 532 533 533 534 if (status->flag & RX_FLAG_DECRYPTED) { ··· 724 723 hdrlen = ieee80211_hdrlen(hdr->frame_control); 725 724 726 725 if (!ieee80211_is_data(hdr->frame_control) && 727 - !ieee80211_is_robust_mgmt_frame(skb)) 726 + !ieee80211_is_robust_mgmt_frame(skb) && 727 + !ieee80211_require_encrypted_assoc(hdr->frame_control, rx->sta)) 728 728 return RX_CONTINUE; 729 729 730 730 if (status->flag & RX_FLAG_DECRYPTED) {