The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@kernel.org>
To: linux-crypto@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Eric Biggers <ebiggers@kernel.org>
Subject: [PATCH 24/33] wifi: mac80211: Use AES-GCM library for GMAC suite
Date: Mon,  6 Jul 2026 22:34:54 -0700	[thread overview]
Message-ID: <20260707053503.209874-25-ebiggers@kernel.org> (raw)
In-Reply-To: <20260707053503.209874-1-ebiggers@kernel.org>

Now that there's a library API for AES-GCM (of which AES-GMAC is a
special case), for implementing the GMAC cipher suite use it instead of
a "gcm(aes)" crypto_aead.  This significantly simplifies the code and
eliminates per-skb heap allocations.

As a bonus, ieee80211_crypto_aes_gmac_decrypt() no longer needs to
allocate 'mic' on the heap, since it no longer needs to be representable
as a scatterlist for crypto_aead.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 net/mac80211/Kconfig    |  1 +
 net/mac80211/aes_gmac.c | 85 ++++++++---------------------------------
 net/mac80211/aes_gmac.h | 10 ++---
 net/mac80211/key.c      | 11 ++----
 net/mac80211/key.h      |  3 +-
 net/mac80211/wpa.c      | 12 ++----
 6 files changed, 29 insertions(+), 93 deletions(-)

diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 8fe97e63ff39..32808c5de0fb 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -5,6 +5,7 @@ config MAC80211
 	select CRYPTO
 	select CRYPTO_LIB_AES_CBC_MACS
 	select CRYPTO_LIB_AES_CTR
+	select CRYPTO_LIB_AES_GCM
 	select CRYPTO_LIB_ARC4
 	select CRYPTO_AES
 	select CRYPTO_CCM
diff --git a/net/mac80211/aes_gmac.c b/net/mac80211/aes_gmac.c
index 811a83d8d525..722d8983bb5c 100644
--- a/net/mac80211/aes_gmac.c
+++ b/net/mac80211/aes_gmac.c
@@ -6,89 +6,34 @@
 
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/err.h>
-#include <crypto/aead.h>
-#include <crypto/aes.h>
+#include <crypto/aes-gcm.h>
 
 #include <net/mac80211.h>
-#include "key.h"
 #include "aes_gmac.h"
 
-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
-		       const u8 *data, size_t data_len, u8 *mic)
+int ieee80211_aes_gmac(const struct aes_gcm_key *key, const u8 *aad,
+		       const u8 *nonce, const u8 *data, size_t data_len,
+		       u8 *mic)
 {
-	struct scatterlist sg[5];
-	u8 *zero, *__aad, iv[AES_BLOCK_SIZE];
-	struct aead_request *aead_req;
-	int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
+	static const u8 zero[IEEE80211_GMAC_MIC_LEN];
+	struct aes_gcm_ctx ctx;
 	const __le16 *fc;
-	int ret;
 
 	if (data_len < IEEE80211_GMAC_MIC_LEN)
 		return -EINVAL;
 
-	aead_req = kzalloc(reqsize + IEEE80211_GMAC_MIC_LEN + GMAC_AAD_LEN,
-			   GFP_ATOMIC);
-	if (!aead_req)
-		return -ENOMEM;
-
-	zero = (u8 *)aead_req + reqsize;
-	__aad = zero + IEEE80211_GMAC_MIC_LEN;
-	memcpy(__aad, aad, GMAC_AAD_LEN);
+	aes_gcm_init(&ctx, nonce, key);
+	aes_gcm_auth_update(&ctx, aad, GMAC_AAD_LEN);
 
 	fc = (const __le16 *)aad;
 	if (ieee80211_is_beacon(*fc)) {
 		/* mask Timestamp field to zero */
-		sg_init_table(sg, 5);
-		sg_set_buf(&sg[0], __aad, GMAC_AAD_LEN);
-		sg_set_buf(&sg[1], zero, 8);
-		sg_set_buf(&sg[2], data + 8,
-			   data_len - 8 - IEEE80211_GMAC_MIC_LEN);
-		sg_set_buf(&sg[3], zero, IEEE80211_GMAC_MIC_LEN);
-		sg_set_buf(&sg[4], mic, IEEE80211_GMAC_MIC_LEN);
-	} else {
-		sg_init_table(sg, 4);
-		sg_set_buf(&sg[0], __aad, GMAC_AAD_LEN);
-		sg_set_buf(&sg[1], data, data_len - IEEE80211_GMAC_MIC_LEN);
-		sg_set_buf(&sg[2], zero, IEEE80211_GMAC_MIC_LEN);
-		sg_set_buf(&sg[3], mic, IEEE80211_GMAC_MIC_LEN);
+		aes_gcm_auth_update(&ctx, zero, 8);
+		data += 8;
+		data_len -= 8;
 	}
-
-	memcpy(iv, nonce, GMAC_NONCE_LEN);
-	memset(iv + GMAC_NONCE_LEN, 0, sizeof(iv) - GMAC_NONCE_LEN);
-	iv[AES_BLOCK_SIZE - 1] = 0x01;
-
-	aead_request_set_tfm(aead_req, tfm);
-	aead_request_set_crypt(aead_req, sg, sg, 0, iv);
-	aead_request_set_ad(aead_req, GMAC_AAD_LEN + data_len);
-
-	ret = crypto_aead_encrypt(aead_req);
-	kfree_sensitive(aead_req);
-
-	return ret;
-}
-
-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
-						 size_t key_len)
-{
-	struct crypto_aead *tfm;
-	int err;
-
-	tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
-	if (IS_ERR(tfm))
-		return tfm;
-
-	err = crypto_aead_setkey(tfm, key, key_len);
-	if (!err)
-		err = crypto_aead_setauthsize(tfm, IEEE80211_GMAC_MIC_LEN);
-	if (!err)
-		return tfm;
-
-	crypto_free_aead(tfm);
-	return ERR_PTR(err);
-}
-
-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
-{
-	crypto_free_aead(tfm);
+	aes_gcm_auth_update(&ctx, data, data_len - IEEE80211_GMAC_MIC_LEN);
+	aes_gcm_auth_update(&ctx, zero, IEEE80211_GMAC_MIC_LEN);
+	aes_gcm_encrypt_final(&ctx, mic);
+	return 0;
 }
diff --git a/net/mac80211/aes_gmac.h b/net/mac80211/aes_gmac.h
index 206136b60bca..f31bdfbecf3c 100644
--- a/net/mac80211/aes_gmac.h
+++ b/net/mac80211/aes_gmac.h
@@ -6,15 +6,13 @@
 #ifndef AES_GMAC_H
 #define AES_GMAC_H
 
-#include <linux/crypto.h>
+#include <crypto/aes-gcm.h>
 
 #define GMAC_AAD_LEN	20
 #define GMAC_NONCE_LEN	12
 
-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
-						 size_t key_len);
-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
-		       const u8 *data, size_t data_len, u8 *mic);
-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
+int ieee80211_aes_gmac(const struct aes_gcm_key *key, const u8 *aad,
+		       const u8 *nonce, const u8 *data, size_t data_len,
+		       u8 *mic);
 
 #endif /* AES_GMAC_H */
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index f45e792abede..48404097e4f1 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -711,10 +711,9 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
 		/* Initialize AES key state here as an optimization so that
 		 * it does not need to be initialized for every packet.
 		 */
-		key->u.aes_gmac.tfm =
-			ieee80211_aes_gmac_key_setup(key_data, key_len);
-		if (IS_ERR(key->u.aes_gmac.tfm)) {
-			err = PTR_ERR(key->u.aes_gmac.tfm);
+		err = aes_gcm_preparekey(&key->u.aes_gmac.key, key_data,
+					 key_len, IEEE80211_GMAC_MIC_LEN);
+		if (err) {
 			kfree(key);
 			return ERR_PTR(err);
 		}
@@ -752,10 +751,6 @@ static void ieee80211_key_free_common(struct ieee80211_key *key)
 	case WLAN_CIPHER_SUITE_CCMP_256:
 		ieee80211_aes_key_free(key->u.ccmp.tfm);
 		break;
-	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
-	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
-		ieee80211_aes_gmac_key_free(key->u.aes_gmac.tfm);
-		break;
 	case WLAN_CIPHER_SUITE_GCMP:
 	case WLAN_CIPHER_SUITE_GCMP_256:
 		ieee80211_aes_gcm_key_free(key->u.gcmp.tfm);
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 826e4e9387c5..d2dd2a76fa25 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -13,6 +13,7 @@
 #include <linux/crypto.h>
 #include <linux/rcupdate.h>
 #include <crypto/aes-cbc-macs.h>
+#include <crypto/aes-gcm.h>
 #include <crypto/arc4.h>
 #include <net/mac80211.h>
 
@@ -100,7 +101,7 @@ struct ieee80211_key {
 		} aes_cmac;
 		struct {
 			u8 rx_pn[IEEE80211_GMAC_PN_LEN];
-			struct crypto_aead *tfm;
+			struct aes_gcm_key key;
 			u32 replays; /* dot11RSNAStatsCMACReplays */
 			u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
 		} aes_gmac;
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index be3a2e95303c..eb4a98537395 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -1007,7 +1007,7 @@ ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx)
 	bip_ipn_swap(nonce + ETH_ALEN, mmie->sequence_number);
 
 	/* MIC = AES-GMAC(IGTK, AAD || Management Frame Body || MMIE, 128) */
-	if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
+	if (ieee80211_aes_gmac(&key->u.aes_gmac.key, aad, nonce,
 			       skb->data + 24, skb->len - 24, mmie->mic) < 0)
 		return TX_DROP;
 
@@ -1021,7 +1021,8 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_key *key = rx->key;
 	struct ieee80211_mmie_16 *mmie;
-	u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN];
+	u8 aad[GMAC_AAD_LEN], ipn[6], nonce[GMAC_NONCE_LEN];
+	u8 mic[IEEE80211_GMAC_MIC_LEN];
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
 	if (!ieee80211_is_mgmt(hdr->frame_control))
@@ -1052,18 +1053,13 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
 		memcpy(nonce, hdr->addr2, ETH_ALEN);
 		memcpy(nonce + ETH_ALEN, ipn, 6);
 
-		mic = kmalloc(IEEE80211_GMAC_MIC_LEN, GFP_ATOMIC);
-		if (!mic)
-			return RX_DROP_U_OOM;
-		if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
+		if (ieee80211_aes_gmac(&key->u.aes_gmac.key, aad, nonce,
 				       skb->data + 24, skb->len - 24,
 				       mic) < 0 ||
 		    crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
 			key->u.aes_gmac.icverrors++;
-			kfree(mic);
 			return RX_DROP_U_MIC_FAIL;
 		}
-		kfree(mic);
 	}
 
 	memcpy(key->u.aes_gmac.rx_pn, ipn, 6);
-- 
2.54.0


  parent reply	other threads:[~2026-07-07  5:37 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-07  5:34 [PATCH 00/33] Library APIs for AES encryption modes Eric Biggers
2026-07-07  5:34 ` [PATCH 01/33] crypto: xts - Split out __xts_verify_key() helper Eric Biggers
2026-07-07 13:20   ` Thomas Huth
2026-07-07  5:34 ` [PATCH 02/33] lib/crypto: aes: Add ECB support Eric Biggers
2026-07-07 13:59   ` Thomas Huth
2026-07-07 19:22     ` Eric Biggers
2026-07-08  5:29       ` Thomas Huth
2026-07-07  5:34 ` [PATCH 03/33] lib/crypto: aes: Add CBC and CBC-CTS support Eric Biggers
2026-07-07  5:34 ` [PATCH 04/33] lib/crypto: aes: Add CTR and XCTR support Eric Biggers
2026-07-07  5:34 ` [PATCH 05/33] lib/crypto: aes: Add XTS support Eric Biggers
2026-07-07  5:34 ` [PATCH 06/33] lib/crypto: aes: Add GCM support Eric Biggers
2026-07-07  5:34 ` [PATCH 07/33] lib/crypto: aes: Add CCM support Eric Biggers
2026-07-07  5:34 ` [PATCH 08/33] crypto: aes - Add ECB support using library Eric Biggers
2026-07-07  5:34 ` [PATCH 09/33] crypto: aes - Add CBC and CBC-CTS " Eric Biggers
2026-07-07  5:34 ` [PATCH 10/33] crypto: aes - Add CTR and XCTR " Eric Biggers
2026-07-07  5:34 ` [PATCH 11/33] crypto: aes - Add XTS " Eric Biggers
2026-07-07  5:34 ` [PATCH 12/33] crypto: aes - Add GCM " Eric Biggers
2026-07-07  5:34 ` [PATCH 13/33] crypto: aes - Add CCM " Eric Biggers
2026-07-07  5:34 ` [PATCH 14/33] x86/sev: Use new AES-GCM library Eric Biggers
2026-07-07  5:34 ` [PATCH 15/33] lib/crypto: aesgcm: Remove old " Eric Biggers
2026-07-07  5:34 ` [PATCH 16/33] crypto: aes - Remove AES-CBC-MAC support Eric Biggers
2026-07-07  5:34 ` [PATCH 17/33] lib/crypto: aes: Remove aes_cbcmac_* functions Eric Biggers
2026-07-07  5:34 ` [PATCH 18/33] fscrypt: Use aes_ecb_encrypt() for v1 key derivation Eric Biggers
2026-07-07  5:34 ` [PATCH 19/33] KEYS: encrypted: Use AES-CBC library instead of crypto_skcipher Eric Biggers
2026-07-07  5:34 ` [PATCH 20/33] KEYS: trusted: dcp: Use AES-GCM library instead of crypto_aead Eric Biggers
2026-07-07  5:34 ` [PATCH 21/33] libceph: Use AES-CBC library in ceph_aes_crypt() Eric Biggers
2026-07-07  5:34 ` [PATCH 22/33] libceph: Reimplement messenger v2 encryption using AES-GCM library Eric Biggers
2026-07-07  5:34 ` [PATCH 23/33] wifi: mac80211: Use AES-CTR library in fils_aead.c Eric Biggers
2026-07-07  5:34 ` Eric Biggers [this message]
2026-07-07  5:34 ` [PATCH 25/33] wifi: mac80211: Use crypto libraries for GCMP and CCMP suites Eric Biggers
2026-07-07  5:34 ` [PATCH 26/33] macsec: Use AES-GCM library instead of crypto_aead Eric Biggers
2026-07-07  5:34 ` [PATCH 27/33] wifi: ipw2x00: Use AES-CCM library Eric Biggers
2026-07-07  5:34 ` [PATCH 28/33] mac802154: Use AES-CCM and AES-CTR libraries Eric Biggers
2026-07-07  5:34 ` [PATCH 29/33] bpf: crypto: Use AES-CBC and AES-ECB libraries Eric Biggers
2026-07-07 15:01   ` Vadim Fedorenko
2026-07-07 18:20     ` Eric Biggers
2026-07-07 22:50       ` Vadim Fedorenko
2026-07-07 23:16         ` Eric Biggers
2026-07-08 11:47           ` Vadim Fedorenko
2026-07-07  5:35 ` [PATCH 30/33] bpf: crypto: Add AES-GCM support Eric Biggers
2026-07-07 15:02   ` Vadim Fedorenko
2026-07-07  5:35 ` [PATCH 31/33] smb: client: Use AES-GCM and AES-CCM libraries Eric Biggers
2026-07-07  5:35 ` [PATCH 32/33] ksmbd: " Eric Biggers
2026-07-07 10:51   ` Namjae Jeon
2026-07-07  5:35 ` [PATCH 33/33] net: tipc: Use AES-GCM library instead of crypto_aead Eric Biggers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260707053503.209874-25-ebiggers@kernel.org \
    --to=ebiggers@kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox