]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: ath12k: Use michael_mic() from cfg80211
authorEric Biggers <ebiggers@kernel.org>
Wed, 8 Apr 2026 03:06:49 +0000 (20:06 -0700)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 8 Apr 2026 06:55:15 +0000 (08:55 +0200)
Just use the michael_mic() function from cfg80211 instead of a local
implementation of it using the crypto_shash API.

Note: when the kernel is booted with fips=1,
crypto_alloc_shash("michael_mic", 0, 0) always returned
ERR_PTR(-ENOENT), because Michael MIC is not a "FIPS allowed" algorithm.
For now, just preserve that behavior exactly, to ensure that TKIP is not
allowed to be used in FIPS mode.  This logic actually seems to disable
the entire driver in FIPS mode and not just TKIP, but that was the
existing behavior.  Supporting this driver in FIPS mode, if anyone
actually needs it there, should be a separate commit.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Link: https://patch.msgid.link/20260408030651.80336-5-ebiggers@kernel.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/ath/ath12k/Kconfig
drivers/net/wireless/ath/ath12k/dp.c
drivers/net/wireless/ath/ath12k/dp_peer.h
drivers/net/wireless/ath/ath12k/dp_rx.c
drivers/net/wireless/ath/ath12k/dp_rx.h
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c

index 1ea1af1b8f6c5425c38663977f1d60fe3acb5437..d39c075758bdafb9208779273c37dc5ab363743d 100644 (file)
@@ -2,7 +2,6 @@
 config ATH12K
        tristate "Qualcomm Technologies Wi-Fi 7 support (ath12k)"
        depends on MAC80211 && HAS_DMA && PCI
-       select CRYPTO_MICHAEL_MIC
        select QCOM_QMI_HELPERS
        select MHI_BUS
        select QRTR
index 1c82d927d27b27e19cc5a8a454679fcb341ddec5..90802ed1aa59f9cc86ccf3ef0f50543b6ccd9d82 100644 (file)
@@ -4,7 +4,6 @@
  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 
-#include <crypto/hash.h>
 #include "core.h"
 #include "dp_tx.h"
 #include "hif.h"
@@ -41,7 +40,6 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr)
        }
 
        ath12k_dp_rx_peer_tid_cleanup(ar, peer);
-       crypto_free_shash(peer->dp_peer->tfm_mmic);
        peer->dp_peer->dp_setup_done = false;
        spin_unlock_bh(&dp->dp_lock);
 }
index 20294ff0951310ddd7d9b3ba699e51ccf95f13cb..113b8040010fa3e1d3b6c2cec850a459ce47be96 100644 (file)
@@ -139,7 +139,6 @@ struct ath12k_dp_peer {
        u16 sec_type;
 
        /* Info used in MMIC verification of * RX fragments */
-       struct crypto_shash *tfm_mmic;
        struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
        struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS];
        struct ath12k_reoq_buf reoq_bufs[IEEE80211_NUM_TIDS + 1];
index 59088ab407d05bef0aed8fa041e20abf86e3bc43..250459facff367a1625efda73fee046f17c3c914 100644 (file)
@@ -4,10 +4,10 @@
  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 
+#include <linux/fips.h>
 #include <linux/ieee80211.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
-#include <crypto/hash.h>
 #include "core.h"
 #include "debug.h"
 #include "hw.h"
@@ -1433,29 +1433,27 @@ static void ath12k_dp_rx_frag_timer(struct timer_list *timer)
 int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id)
 {
        struct ath12k_base *ab = ar->ab;
-       struct crypto_shash *tfm;
        struct ath12k_dp_link_peer *peer;
        struct ath12k_dp_rx_tid *rx_tid;
        int i;
        struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
 
-       tfm = crypto_alloc_shash("michael_mic", 0, 0);
-       if (IS_ERR(tfm))
-               return PTR_ERR(tfm);
+       if (fips_enabled) {
+               ath12k_warn(ab, "This driver is disabled due to FIPS\n");
+               return -ENOENT;
+       }
 
        spin_lock_bh(&dp->dp_lock);
 
        peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac);
        if (!peer || !peer->dp_peer) {
                spin_unlock_bh(&dp->dp_lock);
-               crypto_free_shash(tfm);
                ath12k_warn(ab, "failed to find the peer to set up fragment info\n");
                return -ENOENT;
        }
 
        if (!peer->primary_link) {
                spin_unlock_bh(&dp->dp_lock);
-               crypto_free_shash(tfm);
                return 0;
        }
 
@@ -1466,55 +1464,12 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev
                skb_queue_head_init(&rx_tid->rx_frags);
        }
 
-       peer->dp_peer->tfm_mmic = tfm;
        peer->dp_peer->dp_setup_done = true;
        spin_unlock_bh(&dp->dp_lock);
 
        return 0;
 }
 
-int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,
-                              struct ieee80211_hdr *hdr, u8 *data,
-                              size_t data_len, u8 *mic)
-{
-       SHASH_DESC_ON_STACK(desc, tfm);
-       u8 mic_hdr[16] = {};
-       u8 tid = 0;
-       int ret;
-
-       if (!tfm)
-               return -EINVAL;
-
-       desc->tfm = tfm;
-
-       ret = crypto_shash_setkey(tfm, key, 8);
-       if (ret)
-               goto out;
-
-       ret = crypto_shash_init(desc);
-       if (ret)
-               goto out;
-
-       /* TKIP MIC header */
-       memcpy(mic_hdr, ieee80211_get_DA(hdr), ETH_ALEN);
-       memcpy(mic_hdr + ETH_ALEN, ieee80211_get_SA(hdr), ETH_ALEN);
-       if (ieee80211_is_data_qos(hdr->frame_control))
-               tid = ieee80211_get_tid(hdr);
-       mic_hdr[12] = tid;
-
-       ret = crypto_shash_update(desc, mic_hdr, 16);
-       if (ret)
-               goto out;
-       ret = crypto_shash_update(desc, data, data_len);
-       if (ret)
-               goto out;
-       ret = crypto_shash_final(desc, mic);
-out:
-       shash_desc_zero(desc);
-       return ret;
-}
-EXPORT_SYMBOL(ath12k_dp_rx_h_michael_mic);
-
 void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu,
                                 enum hal_encrypt_type enctype, u32 flags)
 {
index bd62af0c80d46d02a8e17b7468fc12a60f2100d2..55a31e669b3b062ad8659257c0d5f51d0d65ed26 100644 (file)
@@ -6,7 +6,6 @@
 #ifndef ATH12K_DP_RX_H
 #define ATH12K_DP_RX_H
 
-#include <crypto/hash.h>
 #include "core.h"
 #include "debug.h"
 
@@ -204,9 +203,6 @@ void ath12k_dp_rx_h_sort_frags(struct ath12k_hal *hal,
                               struct sk_buff *cur_frag);
 void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu,
                                 enum hal_encrypt_type enctype, u32 flags);
-int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,
-                              struct ieee80211_hdr *hdr, u8 *data,
-                              size_t data_len, u8 *mic);
 int ath12k_dp_rx_ampdu_start(struct ath12k *ar,
                             struct ieee80211_ampdu_params *params,
                             u8 link_id);
index e6a934d74e85d813419647e128ee4b95bfed03f6..945680b3ebdfce69e301de20ce62a7105f4bcb2d 100644 (file)
@@ -983,7 +983,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev,
        struct ieee80211_key_conf *key_conf;
        struct ieee80211_hdr *hdr;
        u8 mic[IEEE80211_CCMP_MIC_LEN];
-       int head_len, tail_len, ret;
+       int head_len, tail_len;
        size_t data_len;
        u32 hdr_len, hal_rx_desc_sz = hal->hal_desc_sz;
        u8 *key, *data;
@@ -1011,9 +1011,8 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev,
        data_len = msdu->len - head_len - tail_len;
        key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
 
-       ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data,
-                                        data_len, mic);
-       if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN))
+       michael_mic(key, hdr, data, data_len, mic);
+       if (memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN))
                goto mic_fail;
 
        return 0;