wifi: mac80211: clean up cipher suite handling

Under the previous commit's assumption that FIPS isn't
supported by hardware, we don't need to modify the
cipher suite list, but just need to use the software
one instead of the driver's in this case, so clean up
the code.

Also fix it to exclude TKIP in this case, since that's
also dependent on RC4.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250709233537.cff427e8f8a5.I744d1ea6a37e3ea55ae8bc3e770acee734eff268@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2025-07-09 23:37:57 +03:00
parent 5241526ded
commit 8d313426d5
2 changed files with 15 additions and 52 deletions

View File

@ -1403,8 +1403,6 @@ struct ieee80211_local {
bool rx_mcast_action_reg;
unsigned int filter_flags; /* FIF_* */
bool wiphy_ciphers_allocated;
struct cfg80211_chan_def dflt_chandef;
bool emulate_chanctx;

View File

@ -5,7 +5,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2017 Intel Deutschland GmbH
* Copyright (C) 2018-2024 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*/
#include <net/mac80211.h>
@ -1025,12 +1025,9 @@ EXPORT_SYMBOL(ieee80211_alloc_hw_nm);
static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
{
bool have_wep = !fips_enabled; /* FIPS does not permit the use of RC4 */
bool have_mfp = ieee80211_hw_check(&local->hw, MFP_CAPABLE);
int r = 0, w = 0;
u32 *suites;
static const u32 cipher_suites[] = {
/* keep WEP first, it may be removed below */
/* keep WEP and TKIP first, they may be removed below */
WLAN_CIPHER_SUITE_WEP40,
WLAN_CIPHER_SUITE_WEP104,
WLAN_CIPHER_SUITE_TKIP,
@ -1046,34 +1043,17 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
WLAN_CIPHER_SUITE_BIP_GMAC_256,
};
if (ieee80211_hw_check(&local->hw, SW_CRYPTO_CONTROL) ||
local->hw.wiphy->cipher_suites) {
/* If the driver advertises, or doesn't support SW crypto,
* we only need to remove WEP if necessary.
*/
if (have_wep)
return 0;
if (ieee80211_hw_check(&local->hw, SW_CRYPTO_CONTROL) && fips_enabled) {
dev_err(local->hw.wiphy->dev.parent,
"Drivers with SW_CRYPTO_CONTROL cannot work with FIPS\n");
return -EINVAL;
}
/* well if it has _no_ ciphers ... fine */
if (!local->hw.wiphy->n_cipher_suites)
return 0;
if (WARN_ON(ieee80211_hw_check(&local->hw, SW_CRYPTO_CONTROL) &&
!local->hw.wiphy->cipher_suites))
return -EINVAL;
/* Driver provides cipher suites, but we need to exclude WEP */
suites = kmemdup_array(local->hw.wiphy->cipher_suites,
local->hw.wiphy->n_cipher_suites,
sizeof(u32), GFP_KERNEL);
if (!suites)
return -ENOMEM;
for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
u32 suite = local->hw.wiphy->cipher_suites[r];
if (suite == WLAN_CIPHER_SUITE_WEP40 ||
suite == WLAN_CIPHER_SUITE_WEP104)
continue;
suites[w++] = suite;
}
} else {
if (fips_enabled || !local->hw.wiphy->cipher_suites) {
/* assign the (software supported and perhaps offloaded)
* cipher suites
*/
@ -1083,19 +1063,13 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
if (!have_mfp)
local->hw.wiphy->n_cipher_suites -= 4;
if (!have_wep) {
local->hw.wiphy->cipher_suites += 2;
local->hw.wiphy->n_cipher_suites -= 2;
/* FIPS does not permit the use of RC4 */
if (fips_enabled) {
local->hw.wiphy->cipher_suites += 3;
local->hw.wiphy->n_cipher_suites -= 3;
}
/* not dynamically allocated, so just return */
return 0;
}
local->hw.wiphy->cipher_suites = suites;
local->hw.wiphy->n_cipher_suites = w;
local->wiphy_ciphers_allocated = true;
return 0;
}
@ -1651,10 +1625,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
ieee80211_led_exit(local);
destroy_workqueue(local->workqueue);
fail_workqueue:
if (local->wiphy_ciphers_allocated) {
kfree(local->hw.wiphy->cipher_suites);
local->wiphy_ciphers_allocated = false;
}
kfree(local->int_scan_req);
return result;
}
@ -1725,11 +1695,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
mutex_destroy(&local->iflist_mtx);
if (local->wiphy_ciphers_allocated) {
kfree(local->hw.wiphy->cipher_suites);
local->wiphy_ciphers_allocated = false;
}
idr_for_each(&local->ack_status_frames,
ieee80211_free_ack_frame, NULL);
idr_destroy(&local->ack_status_frames);