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 27/33] wifi: ipw2x00: Use AES-CCM library
Date: Mon, 6 Jul 2026 22:34:57 -0700 [thread overview]
Message-ID: <20260707053503.209874-28-ebiggers@kernel.org> (raw)
In-Reply-To: <20260707053503.209874-1-ebiggers@kernel.org>
Now that there's a library API for AES-CCM, use it instead of a
"ccm(aes)" crypto_aead.
This significantly simplifies the code:
- Dynamic memory allocations go away, including ones during Tx and Rx.
- The additional authenticated data is now just constructed on the
stack, as it no longer needs to be representable in a scatterlist.
- The AES-CCM library supports variable-length nonces via the
self-explanatory nonce_len parameter, so for the needed 13-byte nonce
just use that instead of the odd workaround used by "ccm(aes)" where
the nonce was prefixed with a byte containing '14 - nonce_len'.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/net/wireless/intel/ipw2x00/Kconfig | 2 +-
.../intel/ipw2x00/libipw_crypto_ccmp.c | 117 +++++-------------
2 files changed, 29 insertions(+), 90 deletions(-)
diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig
index b508f14542d5..a1073d34f634 100644
--- a/drivers/net/wireless/intel/ipw2x00/Kconfig
+++ b/drivers/net/wireless/intel/ipw2x00/Kconfig
@@ -153,8 +153,8 @@ config LIBIPW
tristate
depends on PCI && CFG80211
select WIRELESS_EXT
- select CRYPTO
select CRYPTO_LIB_ARC4
+ select CRYPTO_LIB_AES_CCM
select CRC32
help
This option enables the hardware independent IEEE 802.11
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c
index 631a4dd86cab..aa6dce7acba1 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c
@@ -19,15 +19,14 @@
#include <asm/string.h>
#include <linux/wireless.h>
#include <linux/ieee80211.h>
-#include <linux/crypto.h>
-#include <crypto/aead.h>
+#include <crypto/aes-ccm.h>
#include "libipw.h"
-#define AES_BLOCK_LEN 16
#define CCMP_HDR_LEN 8
#define CCMP_MIC_LEN 8
#define CCMP_TK_LEN 16
#define CCMP_PN_LEN 6
+#define CCMP_NONCE_LEN 13
struct libipw_ccmp_data {
u8 key[CCMP_TK_LEN];
@@ -42,11 +41,7 @@ struct libipw_ccmp_data {
int key_idx;
- struct crypto_aead *tfm;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 tx_aad[2 * AES_BLOCK_LEN];
- u8 rx_aad[2 * AES_BLOCK_LEN];
+ struct aes_ccm_key ccm_key;
};
static void *libipw_ccmp_init(int key_idx)
@@ -55,37 +50,20 @@ static void *libipw_ccmp_init(int key_idx)
priv = kzalloc_obj(*priv, GFP_ATOMIC);
if (priv == NULL)
- goto fail;
+ return NULL;
priv->key_idx = key_idx;
- priv->tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tfm)) {
- priv->tfm = NULL;
- goto fail;
- }
-
return priv;
-
- fail:
- if (priv) {
- if (priv->tfm)
- crypto_free_aead(priv->tfm);
- kfree(priv);
- }
-
- return NULL;
}
static void libipw_ccmp_deinit(void *priv)
{
- struct libipw_ccmp_data *_priv = priv;
- if (_priv && _priv->tfm)
- crypto_free_aead(_priv->tfm);
- kfree(priv);
+ kfree_sensitive(priv);
}
-static int ccmp_init_iv_and_aad(const struct ieee80211_hdr *hdr,
- const u8 *pn, u8 *iv, u8 *aad)
+static int ccmp_init_nonce_and_aad(const struct ieee80211_hdr *hdr,
+ const u8 *pn, u8 nonce[CCMP_NONCE_LEN],
+ u8 *aad)
{
u8 *pos, qc = 0;
size_t aad_len;
@@ -105,19 +83,11 @@ static int ccmp_init_iv_and_aad(const struct ieee80211_hdr *hdr,
aad_len += 2;
}
- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
- * mode authentication are not allowed to collide, yet both are derived
- * from the same vector. We only set L := 1 here to indicate that the
- * data size can be represented in (L+1) bytes. The CCM layer will take
- * care of storing the data length in the top (L+1) bytes and setting
- * and clearing the other bits as is required to derive the two IVs.
- */
- iv[0] = 0x1;
-
/* Nonce: QC | A2 | PN */
- iv[1] = qc;
- memcpy(iv + 2, hdr->addr2, ETH_ALEN);
- memcpy(iv + 8, pn, CCMP_PN_LEN);
+ nonce[0] = qc;
+ memcpy(nonce + 1, hdr->addr2, ETH_ALEN);
+ memcpy(nonce + 7, pn, CCMP_PN_LEN);
+ static_assert(7 + CCMP_PN_LEN == CCMP_NONCE_LEN);
/* AAD:
* FC with bits 4..6 and 11..13 masked to zero; 14 is always one
@@ -184,12 +154,9 @@ static int libipw_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct libipw_ccmp_data *key = priv;
struct ieee80211_hdr *hdr;
- struct aead_request *req;
- struct scatterlist sg[2];
- u8 *aad = key->tx_aad;
- u8 iv[AES_BLOCK_LEN];
+ u8 aad[2 * AES_BLOCK_SIZE];
+ u8 nonce[CCMP_NONCE_LEN];
int len, data_len, aad_len;
- int ret;
if (skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
return -1;
@@ -199,28 +166,16 @@ static int libipw_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (len < 0)
return -1;
- req = aead_request_alloc(key->tfm, GFP_ATOMIC);
- if (!req)
- return -ENOMEM;
-
hdr = (struct ieee80211_hdr *)skb->data;
- aad_len = ccmp_init_iv_and_aad(hdr, key->tx_pn, iv, aad);
+ aad_len = ccmp_init_nonce_and_aad(hdr, key->tx_pn, nonce, aad);
skb_put(skb, CCMP_MIC_LEN);
- sg_init_table(sg, 2);
- sg_set_buf(&sg[0], aad, aad_len);
- sg_set_buf(&sg[1], skb->data + hdr_len + CCMP_HDR_LEN,
- data_len + CCMP_MIC_LEN);
-
- aead_request_set_callback(req, 0, NULL, NULL);
- aead_request_set_ad(req, aad_len);
- aead_request_set_crypt(req, sg, sg, data_len, iv);
-
- ret = crypto_aead_encrypt(req);
- aead_request_free(req);
-
- return ret;
+ return aes_ccm_encrypt(skb->data + hdr_len + CCMP_HDR_LEN,
+ skb->data + hdr_len + CCMP_HDR_LEN + data_len,
+ skb->data + hdr_len + CCMP_HDR_LEN, data_len,
+ aad, aad_len, nonce, CCMP_NONCE_LEN,
+ &key->ccm_key);
}
/*
@@ -249,10 +204,8 @@ static int libipw_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
struct libipw_ccmp_data *key = priv;
u8 keyidx, *pos;
struct ieee80211_hdr *hdr;
- struct aead_request *req;
- struct scatterlist sg[2];
- u8 *aad = key->rx_aad;
- u8 iv[AES_BLOCK_LEN];
+ u8 aad[2 * AES_BLOCK_SIZE];
+ u8 nonce[CCMP_NONCE_LEN];
u8 pn[6];
int aad_len, ret;
size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN;
@@ -303,23 +256,11 @@ static int libipw_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return -4;
}
- req = aead_request_alloc(key->tfm, GFP_ATOMIC);
- if (!req)
- return -ENOMEM;
-
- aad_len = ccmp_init_iv_and_aad(hdr, pn, iv, aad);
-
- sg_init_table(sg, 2);
- sg_set_buf(&sg[0], aad, aad_len);
- sg_set_buf(&sg[1], pos, data_len);
-
- aead_request_set_callback(req, 0, NULL, NULL);
- aead_request_set_ad(req, aad_len);
- aead_request_set_crypt(req, sg, sg, data_len, iv);
-
- ret = crypto_aead_decrypt(req);
- aead_request_free(req);
+ aad_len = ccmp_init_nonce_and_aad(hdr, pn, nonce, aad);
+ ret = aes_ccm_decrypt(pos, pos, pos + data_len - CCMP_MIC_LEN,
+ data_len - CCMP_MIC_LEN, aad, aad_len, nonce,
+ CCMP_NONCE_LEN, &key->ccm_key);
if (ret) {
net_dbg_ratelimited("CCMP: decrypt failed: STA=%pM (%d)\n",
hdr->addr2, ret);
@@ -341,12 +282,10 @@ static int libipw_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
{
struct libipw_ccmp_data *data = priv;
int keyidx;
- struct crypto_aead *tfm = data->tfm;
keyidx = data->key_idx;
memset(data, 0, sizeof(*data));
data->key_idx = keyidx;
- data->tfm = tfm;
if (len == CCMP_TK_LEN) {
memcpy(data->key, key, CCMP_TK_LEN);
data->key_set = 1;
@@ -358,8 +297,8 @@ static int libipw_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
data->rx_pn[4] = seq[1];
data->rx_pn[5] = seq[0];
}
- if (crypto_aead_setauthsize(data->tfm, CCMP_MIC_LEN) ||
- crypto_aead_setkey(data->tfm, data->key, CCMP_TK_LEN))
+ if (aes_ccm_preparekey(&data->ccm_key, data->key, CCMP_TK_LEN,
+ CCMP_MIC_LEN))
return -1;
} else if (len == 0)
data->key_set = 0;
--
2.54.0
next prev 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 ` [PATCH 24/33] wifi: mac80211: Use AES-GCM library for GMAC suite Eric Biggers
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 ` Eric Biggers [this message]
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-28-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