From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8A355275BB; Wed, 23 Sep 2026 14:55:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790175351; cv=none; b=Xy8XlM35jeQ2Ab3mfmXjmqKXEYie1PzqV3dlqStnHzlizMumQl9M0ZythzNMAcb+fcAehsNa91BRUzTsYLIZdnK8natr9sYNmu334uatDWveoTxoipykzuCQTow+LAUE4ocQBeZKiWmMs04adSaruVB771Bohs9aWFpHe0Nh3lI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790175351; c=relaxed/simple; bh=/apciHKHxBg/jsweU2747PhXzyqIFWoEyuJorb7Xihc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EDsWbqq2pYLHdr9/MkZLbAfmqrXefowo7Tut4wvjFMWXKn09T2Mesyk7pciqYLwSI0sf6OSxK0A48wQVD/n2tjHq/EEgrmktbfOyJH+UGHf+zWBF37IYTZn5OqNB225jdZ1dK1moSBONfrzjpMaryxMn6CqV+97tVoDmPFZuFFc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=hWhXJiJW; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="hWhXJiJW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E97F1F000FF; Wed, 23 Sep 2026 14:55:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1790175349; bh=omfZayF9oauv6a2tNexl/JBvawL5GqlniHnBkekdkC8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=hWhXJiJWscBC2vUIjEQWxTdxCklOIDMQleVMZZFjgoLkcdtw1JCCVGcXRrn1/g/Gv zat7s0GvZA8le4emdl0f345jzjMZkV/F5pmR+or/+HURpkOS7gBSGPioC7IAA7IZ9A 6PFQRNAHSUpv2YB5KnbIURk8TMwYavJ5fuIQ0RTg= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Eric Biggers , Johannes Berg , Sasha Levin Subject: [PATCH 6.18 388/398] wifi: mac80211, cfg80211: Export michael_mic() and move it to cfg80211 Date: Wed, 23 Sep 2026 16:07:42 +0200 Message-ID: <20260923140653.525633663@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260923140643.441954610@linuxfoundation.org> References: <20260923140643.441954610@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Eric Biggers [ Upstream commit 613c83766884503f0f6bfdc45964c84b5286091c ] Export michael_mic() so that the ath11k and ath12k drivers can call it. In addition, move it from mac80211 to cfg80211 so that the ipw2x00 drivers, which depend on cfg80211 but not mac80211, can also call it. Currently these drivers have their own local implementations of michael_mic() based on crypto_shash, which is redundant and inefficient. By consolidating all the Michael MIC code into cfg80211, we'll be able to remove the duplicate Michael MIC code in the crypto/ directory. Signed-off-by: Eric Biggers Link: https://patch.msgid.link/20260408030651.80336-3-ebiggers@kernel.org Signed-off-by: Johannes Berg Stable-dep-of: 06f42accaf3c ("wifi: libipw: reject TKIP frames without a full MIC") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- include/linux/ieee80211.h | 5 ++ net/mac80211/Makefile | 1 net/mac80211/michael.c | 83 ------------------------------------------- net/mac80211/michael.h | 22 ----------- net/mac80211/wpa.c | 1 net/wireless/Makefile | 2 - net/wireless/michael-mic.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 92 insertions(+), 108 deletions(-) delete mode 100644 net/mac80211/michael.h rename net/{mac80211/michael.c => wireless/michael-mic.c} (96%) --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -2249,6 +2249,11 @@ enum ieee80211_radio_measurement_actionc #define PMK_MAX_LEN 64 #define SAE_PASSWORD_MAX_LEN 128 +#define MICHAEL_MIC_LEN 8 + +void michael_mic(const u8 *key, struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, u8 *mic); + /* Public action codes (IEEE Std 802.11-2016, 9.6.8.1, Table 9-307) */ enum ieee80211_pub_actioncode { WLAN_PUB_ACTION_20_40_BSS_COEX = 0, --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -18,7 +18,6 @@ mac80211-y := \ iface.o \ link.o \ rate.o \ - michael.o \ tkip.o \ aes_cmac.o \ aes_gmac.o \ --- a/net/mac80211/michael.c +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Michael MIC implementation - optimized for TKIP MIC operations - * Copyright 2002-2003, Instant802 Networks, Inc. - */ -#include -#include -#include -#include - -#include "michael.h" - -static void michael_block(struct michael_mic_ctx *mctx, u32 val) -{ - mctx->l ^= val; - mctx->r ^= rol32(mctx->l, 17); - mctx->l += mctx->r; - mctx->r ^= ((mctx->l & 0xff00ff00) >> 8) | - ((mctx->l & 0x00ff00ff) << 8); - mctx->l += mctx->r; - mctx->r ^= rol32(mctx->l, 3); - mctx->l += mctx->r; - mctx->r ^= ror32(mctx->l, 2); - mctx->l += mctx->r; -} - -static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key, - struct ieee80211_hdr *hdr) -{ - u8 *da, *sa, tid; - - da = ieee80211_get_DA(hdr); - sa = ieee80211_get_SA(hdr); - if (ieee80211_is_data_qos(hdr->frame_control)) - tid = ieee80211_get_tid(hdr); - else - tid = 0; - - mctx->l = get_unaligned_le32(key); - mctx->r = get_unaligned_le32(key + 4); - - /* - * A pseudo header (DA, SA, Priority, 0, 0, 0) is used in Michael MIC - * calculation, but it is _not_ transmitted - */ - michael_block(mctx, get_unaligned_le32(da)); - michael_block(mctx, get_unaligned_le16(&da[4]) | - (get_unaligned_le16(sa) << 16)); - michael_block(mctx, get_unaligned_le32(&sa[2])); - michael_block(mctx, tid); -} - -void michael_mic(const u8 *key, struct ieee80211_hdr *hdr, - const u8 *data, size_t data_len, u8 *mic) -{ - u32 val; - size_t block, blocks, left; - struct michael_mic_ctx mctx; - - michael_mic_hdr(&mctx, key, hdr); - - /* Real data */ - blocks = data_len / 4; - left = data_len % 4; - - for (block = 0; block < blocks; block++) - michael_block(&mctx, get_unaligned_le32(&data[block * 4])); - - /* Partial block of 0..3 bytes and padding: 0x5a + 4..7 zeros to make - * total length a multiple of 4. */ - val = 0x5a; - while (left > 0) { - val <<= 8; - left--; - val |= data[blocks * 4 + left]; - } - - michael_block(&mctx, val); - michael_block(&mctx, 0); - - put_unaligned_le32(mctx.l, mic); - put_unaligned_le32(mctx.r, mic + 4); -} --- a/net/mac80211/michael.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Michael MIC implementation - optimized for TKIP MIC operations - * Copyright 2002-2003, Instant802 Networks, Inc. - */ - -#ifndef MICHAEL_H -#define MICHAEL_H - -#include -#include - -#define MICHAEL_MIC_LEN 8 - -struct michael_mic_ctx { - u32 l, r; -}; - -void michael_mic(const u8 *key, struct ieee80211_hdr *hdr, - const u8 *data, size_t data_len, u8 *mic); - -#endif /* MICHAEL_H */ --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -18,7 +18,6 @@ #include #include "ieee80211_i.h" -#include "michael.h" #include "tkip.h" #include "aes_ccm.h" #include "aes_cmac.h" --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -8,7 +8,7 @@ obj-$(CONFIG_WEXT_PRIV) += wext-priv.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o -cfg80211-y += pmsr.o +cfg80211-y += michael-mic.o pmsr.o cfg80211-$(CONFIG_OF) += of.o cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o --- /dev/null +++ b/net/wireless/michael-mic.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Michael MIC implementation - optimized for TKIP MIC operations + * Copyright 2002-2003, Instant802 Networks, Inc. + */ +#include +#include +#include +#include + +struct michael_mic_ctx { + u32 l, r; +}; + +static void michael_block(struct michael_mic_ctx *mctx, u32 val) +{ + mctx->l ^= val; + mctx->r ^= rol32(mctx->l, 17); + mctx->l += mctx->r; + mctx->r ^= ((mctx->l & 0xff00ff00) >> 8) | + ((mctx->l & 0x00ff00ff) << 8); + mctx->l += mctx->r; + mctx->r ^= rol32(mctx->l, 3); + mctx->l += mctx->r; + mctx->r ^= ror32(mctx->l, 2); + mctx->l += mctx->r; +} + +static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key, + struct ieee80211_hdr *hdr) +{ + u8 *da, *sa, tid; + + da = ieee80211_get_DA(hdr); + sa = ieee80211_get_SA(hdr); + if (ieee80211_is_data_qos(hdr->frame_control)) + tid = ieee80211_get_tid(hdr); + else + tid = 0; + + mctx->l = get_unaligned_le32(key); + mctx->r = get_unaligned_le32(key + 4); + + /* + * A pseudo header (DA, SA, Priority, 0, 0, 0) is used in Michael MIC + * calculation, but it is _not_ transmitted + */ + michael_block(mctx, get_unaligned_le32(da)); + michael_block(mctx, get_unaligned_le16(&da[4]) | + (get_unaligned_le16(sa) << 16)); + michael_block(mctx, get_unaligned_le32(&sa[2])); + michael_block(mctx, tid); +} + +void michael_mic(const u8 *key, struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, u8 *mic) +{ + u32 val; + size_t block, blocks, left; + struct michael_mic_ctx mctx; + + michael_mic_hdr(&mctx, key, hdr); + + /* Real data */ + blocks = data_len / 4; + left = data_len % 4; + + for (block = 0; block < blocks; block++) + michael_block(&mctx, get_unaligned_le32(&data[block * 4])); + + /* Partial block of 0..3 bytes and padding: 0x5a + 4..7 zeros to make + * total length a multiple of 4. */ + val = 0x5a; + while (left > 0) { + val <<= 8; + left--; + val |= data[blocks * 4 + left]; + } + + michael_block(&mctx, val); + michael_block(&mctx, 0); + + put_unaligned_le32(mctx.l, mic); + put_unaligned_le32(mctx.r, mic + 4); +} +EXPORT_SYMBOL_GPL(michael_mic);