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 33/33] net: tipc: Use AES-GCM library instead of crypto_aead
Date: Mon, 6 Jul 2026 22:35:03 -0700 [thread overview]
Message-ID: <20260707053503.209874-34-ebiggers@kernel.org> (raw)
In-Reply-To: <20260707053503.209874-1-ebiggers@kernel.org>
Now that there's a library API for AES-GCM, use it instead of a
"gcm(aes)" crypto_aead. This significantly simplifies the code.
Notably, per-skb dynamic memory allocations and conversions to
scatterlists are eliminated. For encryption the skb is linear, so just
call the one-shot function aes_gcm_encrypt(). For decryption, just
iterate through the skb's data and decrypt it directly.
There was also an unnecessary copy of the key being made (in a
crypto_aead object) for every CPU. That is removed as well. The
library en/decryption functions treat struct aes_gcm_key as read-only,
so it can be used by an unlimited number of threads with no contention.
Asynchronous en/decryption operations are no longer supported, as that
execution model for symmetric crypto has been found to be harmful. It
generated endless bugs and didn't actually improve performance.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
net/tipc/Kconfig | 4 +-
net/tipc/crypto.c | 467 ++++++++--------------------------------------
net/tipc/msg.h | 3 -
net/tipc/sysctl.c | 6 +
4 files changed, 85 insertions(+), 395 deletions(-)
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index 18f62135e47b..39fa54b04bb9 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -38,9 +38,7 @@ config TIPC_MEDIA_UDP
config TIPC_CRYPTO
bool "TIPC encryption support"
depends on TIPC
- select CRYPTO
- select CRYPTO_AES
- select CRYPTO_GCM
+ select CRYPTO_LIB_AES_GCM
default y
help
Saying Y here will enable support for TIPC encryption.
diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c
index 16f1ed1f6b1b..e0040309a788 100644
--- a/net/tipc/crypto.c
+++ b/net/tipc/crypto.c
@@ -34,8 +34,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <crypto/aead.h>
-#include <crypto/aes.h>
+#include <crypto/aes-gcm.h>
#include <crypto/rng.h>
#include "crypto.h"
#include "msg.h"
@@ -69,9 +68,9 @@ enum {
enum {
STAT_OK,
STAT_NOK,
- STAT_ASYNC,
- STAT_ASYNC_OK,
- STAT_ASYNC_NOK,
+ STAT_ASYNC, /* no longer used */
+ STAT_ASYNC_OK, /* no longer used */
+ STAT_ASYNC_NOK, /* no longer used */
STAT_BADKEYS, /* tx only */
STAT_BADMSGS = STAT_BADKEYS, /* rx only */
STAT_NOKEYS,
@@ -121,19 +120,9 @@ struct tipc_key {
};
};
-/**
- * struct tipc_tfm - TIPC TFM structure to form a list of TFMs
- * @tfm: cipher handle/key
- * @list: linked list of TFMs
- */
-struct tipc_tfm {
- struct crypto_aead *tfm;
- struct list_head list;
-};
-
/**
* struct tipc_aead - TIPC AEAD key structure
- * @tfm_entry: per-cpu pointer to one entry in TFM list
+ * @gcm_key: the AES-GCM key
* @crypto: TIPC crypto owns this key
* @cloned: reference to the source key in case cloning
* @users: the number of the key users (TX/RX)
@@ -149,7 +138,7 @@ struct tipc_tfm {
*/
struct tipc_aead {
#define TIPC_AEAD_HINT_LEN (5)
- struct tipc_tfm * __percpu *tfm_entry;
+ struct aes_gcm_key gcm_key;
struct tipc_crypto *crypto;
struct tipc_aead *cloned;
atomic_t users;
@@ -235,19 +224,6 @@ struct tipc_crypto {
} ____cacheline_aligned;
-/* struct tipc_crypto_tx_ctx - TX context for callbacks */
-struct tipc_crypto_tx_ctx {
- struct tipc_aead *aead;
- struct tipc_bearer *bearer;
- struct tipc_media_addr dst;
-};
-
-/* struct tipc_crypto_rx_ctx - RX context for callbacks */
-struct tipc_crypto_rx_ctx {
- struct tipc_aead *aead;
- struct tipc_bearer *bearer;
-};
-
static struct tipc_aead *tipc_aead_get(struct tipc_aead __rcu *aead);
static inline void tipc_aead_put(struct tipc_aead *aead);
static void tipc_aead_free(struct rcu_head *rp);
@@ -255,22 +231,15 @@ static int tipc_aead_users(struct tipc_aead __rcu *aead);
static void tipc_aead_users_inc(struct tipc_aead __rcu *aead, int lim);
static void tipc_aead_users_dec(struct tipc_aead __rcu *aead, int lim);
static void tipc_aead_users_set(struct tipc_aead __rcu *aead, int val);
-static struct crypto_aead *tipc_aead_tfm_next(struct tipc_aead *aead);
static int tipc_aead_init(struct tipc_aead **aead, struct tipc_aead_key *ukey,
u8 mode);
static int tipc_aead_clone(struct tipc_aead **dst, struct tipc_aead *src);
-static void *tipc_aead_mem_alloc(struct crypto_aead *tfm,
- unsigned int crypto_ctx_size,
- u8 **iv, struct aead_request **req,
- struct scatterlist **sg, int nsg);
static int tipc_aead_encrypt(struct tipc_aead *aead, struct sk_buff *skb,
struct tipc_bearer *b,
struct tipc_media_addr *dst,
struct tipc_node *__dnode);
-static void tipc_aead_encrypt_done(void *data, int err);
static int tipc_aead_decrypt(struct net *net, struct tipc_aead *aead,
struct sk_buff *skb, struct tipc_bearer *b);
-static void tipc_aead_decrypt_done(void *data, int err);
static inline int tipc_ehdr_size(struct tipc_ehdr *ehdr);
static int tipc_ehdr_build(struct net *net, struct tipc_aead *aead,
u8 tx_key, struct sk_buff *skb,
@@ -335,12 +304,6 @@ int tipc_aead_key_validate(struct tipc_aead_key *ukey, struct genl_info *info)
{
int keylen;
- /* Check if algorithm exists */
- if (unlikely(!crypto_has_alg(ukey->alg_name, 0, 0))) {
- GENL_SET_ERR_MSG(info, "unable to load the algorithm (module existed?)");
- return -ENODEV;
- }
-
/* Currently, we only support the "gcm(aes)" cipher algorithm */
if (strcmp(ukey->alg_name, "gcm(aes)")) {
GENL_SET_ERR_MSG(info, "not supported yet the algorithm");
@@ -391,30 +354,15 @@ static inline void tipc_aead_put(struct tipc_aead *aead)
}
/**
- * tipc_aead_free - Release AEAD key incl. all the TFMs in the list
+ * tipc_aead_free - Release AEAD key
* @rp: rcu head pointer
*/
static void tipc_aead_free(struct rcu_head *rp)
{
struct tipc_aead *aead = container_of(rp, struct tipc_aead, rcu);
- struct tipc_tfm *tfm_entry, *head, *tmp;
- if (aead->cloned) {
+ if (aead->cloned)
tipc_aead_put(aead->cloned);
- } else {
- head = *get_cpu_ptr(aead->tfm_entry);
- put_cpu_ptr(aead->tfm_entry);
- list_for_each_entry_safe(tfm_entry, tmp, &head->list, list) {
- crypto_free_aead(tfm_entry->tfm);
- list_del(&tfm_entry->list);
- kfree(tfm_entry);
- }
- /* Free the head */
- crypto_free_aead(head->tfm);
- list_del(&head->list);
- kfree(head);
- }
- free_percpu(aead->tfm_entry);
kfree_sensitive(aead->key);
kfree_sensitive(aead);
}
@@ -472,44 +420,21 @@ static void tipc_aead_users_set(struct tipc_aead __rcu *aead, int val)
rcu_read_unlock();
}
-/**
- * tipc_aead_tfm_next - Move TFM entry to the next one in list and return it
- * @aead: the AEAD key pointer
- */
-static struct crypto_aead *tipc_aead_tfm_next(struct tipc_aead *aead)
-{
- struct tipc_tfm **tfm_entry;
- struct crypto_aead *tfm;
-
- tfm_entry = get_cpu_ptr(aead->tfm_entry);
- *tfm_entry = list_next_entry(*tfm_entry, list);
- tfm = (*tfm_entry)->tfm;
- put_cpu_ptr(tfm_entry);
-
- return tfm;
-}
-
/**
* tipc_aead_init - Initiate TIPC AEAD
* @aead: returned new TIPC AEAD key handle pointer
* @ukey: pointer to user key data
* @mode: the key mode
*
- * Allocate a (list of) new cipher transformation (TFM) with the specific user
- * key data if valid. The number of the allocated TFMs can be set via the sysfs
- * "net/tipc/max_tfms" first.
- * Also, all the other AEAD data are also initialized.
+ * Allocate a new AEAD key container and prepare the AES-GCM key.
*
* Return: 0 if the initiation is successful, otherwise: < 0
*/
static int tipc_aead_init(struct tipc_aead **aead, struct tipc_aead_key *ukey,
u8 mode)
{
- struct tipc_tfm *tfm_entry, *head;
- struct crypto_aead *tfm;
struct tipc_aead *tmp;
- int keylen, err, cpu;
- int tfm_cnt = 0;
+ int keylen, err;
if (unlikely(*aead))
return -EEXIST;
@@ -522,59 +447,9 @@ static int tipc_aead_init(struct tipc_aead **aead, struct tipc_aead_key *ukey,
/* The key consists of two parts: [AES-KEY][SALT] */
keylen = ukey->keylen - TIPC_AES_GCM_SALT_SIZE;
- /* Allocate per-cpu TFM entry pointer */
- tmp->tfm_entry = alloc_percpu(struct tipc_tfm *);
- if (!tmp->tfm_entry) {
- kfree_sensitive(tmp);
- return -ENOMEM;
- }
-
- /* Make a list of TFMs with the user key data */
- do {
- tfm = crypto_alloc_aead(ukey->alg_name, 0, 0);
- if (IS_ERR(tfm)) {
- err = PTR_ERR(tfm);
- break;
- }
-
- if (unlikely(!tfm_cnt &&
- crypto_aead_ivsize(tfm) != TIPC_AES_GCM_IV_SIZE)) {
- crypto_free_aead(tfm);
- err = -ENOTSUPP;
- break;
- }
-
- err = crypto_aead_setauthsize(tfm, TIPC_AES_GCM_TAG_SIZE);
- err |= crypto_aead_setkey(tfm, ukey->key, keylen);
- if (unlikely(err)) {
- crypto_free_aead(tfm);
- break;
- }
-
- tfm_entry = kmalloc_obj(*tfm_entry);
- if (unlikely(!tfm_entry)) {
- crypto_free_aead(tfm);
- err = -ENOMEM;
- break;
- }
- INIT_LIST_HEAD(&tfm_entry->list);
- tfm_entry->tfm = tfm;
-
- /* First entry? */
- if (!tfm_cnt) {
- head = tfm_entry;
- for_each_possible_cpu(cpu) {
- *per_cpu_ptr(tmp->tfm_entry, cpu) = head;
- }
- } else {
- list_add_tail(&tfm_entry->list, &head->list);
- }
-
- } while (++tfm_cnt < sysctl_tipc_max_tfms);
-
- /* Not any TFM is allocated? */
- if (!tfm_cnt) {
- free_percpu(tmp->tfm_entry);
+ err = aes_gcm_preparekey(&tmp->gcm_key, ukey->key, keylen,
+ TIPC_AES_GCM_TAG_SIZE);
+ if (unlikely(err)) {
kfree_sensitive(tmp);
return err;
}
@@ -606,10 +481,8 @@ static int tipc_aead_init(struct tipc_aead **aead, struct tipc_aead_key *ukey,
* @dst: dest key for the cloning
* @src: source key to clone from
*
- * Make a "copy" of the source AEAD key data to the dest, the TFMs list is
- * common for the keys.
- * A reference to the source is hold in the "cloned" pointer for the later
- * freeing purposes.
+ * Make a "copy" of the source AEAD key data to the dest. A reference to the
+ * source is held in the "cloned" pointer for later freeing purposes.
*
* Note: this must be done in cluster-key mode only!
* Return: 0 in case of success, otherwise < 0
@@ -617,7 +490,6 @@ static int tipc_aead_init(struct tipc_aead **aead, struct tipc_aead_key *ukey,
static int tipc_aead_clone(struct tipc_aead **dst, struct tipc_aead *src)
{
struct tipc_aead *aead;
- int cpu;
if (!src)
return -ENOKEY;
@@ -632,16 +504,7 @@ static int tipc_aead_clone(struct tipc_aead **dst, struct tipc_aead *src)
if (unlikely(!aead))
return -ENOMEM;
- aead->tfm_entry = alloc_percpu_gfp(struct tipc_tfm *, GFP_ATOMIC);
- if (unlikely(!aead->tfm_entry)) {
- kfree_sensitive(aead);
- return -ENOMEM;
- }
-
- for_each_possible_cpu(cpu) {
- *per_cpu_ptr(aead->tfm_entry, cpu) =
- *per_cpu_ptr(src->tfm_entry, cpu);
- }
+ aead->gcm_key = src->gcm_key;
memcpy(aead->hint, src->hint, sizeof(src->hint));
aead->mode = src->mode;
@@ -658,53 +521,54 @@ static int tipc_aead_clone(struct tipc_aead **dst, struct tipc_aead *src)
return 0;
}
+static void tipc_decrypt_chunk(struct aes_gcm_ctx *ctx, u8 *data, size_t avail,
+ size_t *assoc_len, size_t *crypt_len)
+{
+ size_t n;
+
+ if (*assoc_len && avail) {
+ /* Associated data */
+ n = min(avail, *assoc_len);
+ aes_gcm_auth_update(ctx, data, n);
+ data += n;
+ avail -= n;
+ *assoc_len -= n;
+ }
+
+ if (*crypt_len && avail) {
+ /* En/decrypted data */
+ n = min(avail, *crypt_len);
+ aes_gcm_decrypt_update(ctx, data, data, n);
+ *crypt_len -= n;
+ }
+}
+
/**
- * tipc_aead_mem_alloc - Allocate memory for AEAD request operations
- * @tfm: cipher handle to be registered with the request
- * @crypto_ctx_size: size of crypto context for callback
- * @iv: returned pointer to IV data
- * @req: returned pointer to AEAD request data
- * @sg: returned pointer to SG lists
- * @nsg: number of SG lists to be allocated
+ * tipc_decrypt_skb() - Decrypt an skb in-place using AES-GCM
+ * @ctx: An AES-GCM context
+ * @skb: The socket buffer to process
+ * @assoc_len: Length of associated data
+ * @crypt_len: Length of payload data to encrypt or decrypt
*
- * Allocate memory to store the crypto context data, AEAD request, IV and SG
- * lists, the memory layout is as follows:
- * crypto_ctx || iv || aead_req || sg[]
+ * Updates the given AES-GCM context with @assoc_len bytes of associated data
+ * from the skb, then decrypts @crypt_len bytes in-place. Context
+ * initialization and finalization are handled by the caller.
*
- * Return: the pointer to the memory areas in case of success, otherwise NULL
+ * The data (both associated and en/decrypted) is taken from the linear head and
+ * frag_list. It is assumed that the @skb was processed by skb_cow_data(),
+ * meaning it has no page fragments (nr_frags == 0) and is writable.
*/
-static void *tipc_aead_mem_alloc(struct crypto_aead *tfm,
- unsigned int crypto_ctx_size,
- u8 **iv, struct aead_request **req,
- struct scatterlist **sg, int nsg)
+static void tipc_decrypt_skb(struct aes_gcm_ctx *ctx, struct sk_buff *skb,
+ size_t assoc_len, size_t crypt_len)
{
- unsigned int iv_size, req_size;
- unsigned int len;
- u8 *mem;
-
- iv_size = crypto_aead_ivsize(tfm);
- req_size = sizeof(**req) + crypto_aead_reqsize(tfm);
-
- len = crypto_ctx_size;
- len += iv_size;
- len += crypto_aead_alignmask(tfm) & ~(crypto_tfm_ctx_alignment() - 1);
- len = ALIGN(len, crypto_tfm_ctx_alignment());
- len += req_size;
- len = ALIGN(len, __alignof__(struct scatterlist));
- len += nsg * sizeof(**sg);
-
- mem = kmalloc(len, GFP_ATOMIC);
- if (!mem)
- return NULL;
-
- *iv = (u8 *)PTR_ALIGN(mem + crypto_ctx_size,
- crypto_aead_alignmask(tfm) + 1);
- *req = (struct aead_request *)PTR_ALIGN(*iv + iv_size,
- crypto_tfm_ctx_alignment());
- *sg = (struct scatterlist *)PTR_ALIGN((u8 *)*req + req_size,
- __alignof__(struct scatterlist));
-
- return (void *)mem;
+ struct sk_buff *frag_iter;
+
+ WARN_ON_ONCE(skb_shinfo(skb)->nr_frags);
+ tipc_decrypt_chunk(ctx, skb->data, skb_headlen(skb), &assoc_len,
+ &crypt_len);
+ skb_walk_frags(skb, frag_iter)
+ tipc_decrypt_chunk(ctx, frag_iter->data, frag_iter->len,
+ &assoc_len, &crypt_len);
}
/**
@@ -717,7 +581,6 @@ static void *tipc_aead_mem_alloc(struct crypto_aead *tfm,
*
* Return:
* * 0 : if the encryption has completed
- * * -EINPROGRESS/-EBUSY : if a callback will be performed
* * < 0 : the encryption has failed
*/
static int tipc_aead_encrypt(struct tipc_aead *aead, struct sk_buff *skb,
@@ -725,16 +588,11 @@ static int tipc_aead_encrypt(struct tipc_aead *aead, struct sk_buff *skb,
struct tipc_media_addr *dst,
struct tipc_node *__dnode)
{
- struct crypto_aead *tfm = tipc_aead_tfm_next(aead);
- struct tipc_crypto_tx_ctx *tx_ctx;
- struct aead_request *req;
struct sk_buff *trailer;
- struct scatterlist *sg;
struct tipc_ehdr *ehdr;
- int ehsz, len, tailen, nsg, rc;
- void *ctx;
+ int ehsz, len, tailen, nsg;
u32 salt;
- u8 *iv;
+ u8 iv[TIPC_AES_GCM_IV_SIZE];
/* Make sure message len at least 4-byte aligned */
len = ALIGN(skb->len, 4);
@@ -760,20 +618,6 @@ static int tipc_aead_encrypt(struct tipc_aead *aead, struct sk_buff *skb,
pskb_put(skb, trailer, tailen);
- /* Allocate memory for the AEAD operation */
- ctx = tipc_aead_mem_alloc(tfm, sizeof(*tx_ctx), &iv, &req, &sg, nsg);
- if (unlikely(!ctx))
- return -ENOMEM;
- TIPC_SKB_CB(skb)->crypto_ctx = ctx;
-
- /* Map skb to the sg lists */
- sg_init_table(sg, nsg);
- rc = skb_to_sgvec(skb, sg, 0, skb->len);
- if (unlikely(rc < 0)) {
- pr_err("TX: skb_to_sgvec() returned %d, nsg %d!\n", rc, nsg);
- goto exit;
- }
-
/* Prepare IV: [SALT (4 octets)][SEQNO (8 octets)]
* In case we're in cluster-key mode, SALT is varied by xor-ing with
* the source address (or w0 of id), otherwise with the dest address
@@ -788,78 +632,12 @@ static int tipc_aead_encrypt(struct tipc_aead *aead, struct sk_buff *skb,
memcpy(iv, &salt, 4);
memcpy(iv + 4, (u8 *)&ehdr->seqno, 8);
- /* Prepare request */
ehsz = tipc_ehdr_size(ehdr);
- aead_request_set_tfm(req, tfm);
- aead_request_set_ad(req, ehsz);
- aead_request_set_crypt(req, sg, sg, len - ehsz, iv);
-
- /* Set callback function & data */
- aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
- tipc_aead_encrypt_done, skb);
- tx_ctx = (struct tipc_crypto_tx_ctx *)ctx;
- tx_ctx->aead = aead;
- tx_ctx->bearer = b;
- memcpy(&tx_ctx->dst, dst, sizeof(*dst));
-
- /* Hold bearer */
- if (unlikely(!tipc_bearer_hold(b))) {
- rc = -ENODEV;
- goto exit;
- }
-
- /* Get net to avoid freed tipc_crypto when delete namespace */
- if (!maybe_get_net(aead->crypto->net)) {
- tipc_bearer_put(b);
- rc = -ENODEV;
- goto exit;
- }
-
- /* Now, do encrypt */
- rc = crypto_aead_encrypt(req);
- if (rc == -EINPROGRESS || rc == -EBUSY)
- return rc;
-
- tipc_bearer_put(b);
- put_net(aead->crypto->net);
-
-exit:
- kfree(ctx);
- TIPC_SKB_CB(skb)->crypto_ctx = NULL;
- return rc;
-}
-static void tipc_aead_encrypt_done(void *data, int err)
-{
- struct sk_buff *skb = data;
- struct tipc_crypto_tx_ctx *tx_ctx = TIPC_SKB_CB(skb)->crypto_ctx;
- struct tipc_bearer *b = tx_ctx->bearer;
- struct tipc_aead *aead = tx_ctx->aead;
- struct tipc_crypto *tx = aead->crypto;
- struct net *net = tx->net;
-
- switch (err) {
- case 0:
- this_cpu_inc(tx->stats->stat[STAT_ASYNC_OK]);
- rcu_read_lock();
- if (likely(test_bit(0, &b->up)))
- b->media->send_msg(net, skb, b, &tx_ctx->dst);
- else
- kfree_skb(skb);
- rcu_read_unlock();
- break;
- case -EINPROGRESS:
- return;
- default:
- this_cpu_inc(tx->stats->stat[STAT_ASYNC_NOK]);
- kfree_skb(skb);
- break;
- }
-
- kfree(tx_ctx);
- tipc_bearer_put(b);
- tipc_aead_put(aead);
- put_net(net);
+ /* Encrypt the skb in-place. */
+ aes_gcm_encrypt(skb->data + ehsz, skb->data + len, skb->data + ehsz,
+ len - ehsz, skb->data, ehsz, iv, &aead->gcm_key);
+ return 0;
}
/**
@@ -871,22 +649,18 @@ static void tipc_aead_encrypt_done(void *data, int err)
*
* Return:
* * 0 : if the decryption has completed
- * * -EINPROGRESS/-EBUSY : if a callback will be performed
* * < 0 : the decryption has failed
*/
static int tipc_aead_decrypt(struct net *net, struct tipc_aead *aead,
struct sk_buff *skb, struct tipc_bearer *b)
{
- struct tipc_crypto_rx_ctx *rx_ctx;
- struct aead_request *req;
- struct crypto_aead *tfm;
+ struct aes_gcm_ctx ctx;
struct sk_buff *unused;
- struct scatterlist *sg;
struct tipc_ehdr *ehdr;
- int ehsz, nsg, rc;
- void *ctx;
+ int ehsz, nsg, rc, crypt_len;
u32 salt;
- u8 *iv;
+ u8 iv[TIPC_AES_GCM_IV_SIZE];
+ u8 authtag[TIPC_AES_GCM_TAG_SIZE];
if (unlikely(!aead))
return -ENOKEY;
@@ -897,21 +671,6 @@ static int tipc_aead_decrypt(struct net *net, struct tipc_aead *aead,
return nsg;
}
- /* Allocate memory for the AEAD operation */
- tfm = tipc_aead_tfm_next(aead);
- ctx = tipc_aead_mem_alloc(tfm, sizeof(*rx_ctx), &iv, &req, &sg, nsg);
- if (unlikely(!ctx))
- return -ENOMEM;
- TIPC_SKB_CB(skb)->crypto_ctx = ctx;
-
- /* Map skb to the sg lists */
- sg_init_table(sg, nsg);
- rc = skb_to_sgvec(skb, sg, 0, skb->len);
- if (unlikely(rc < 0)) {
- pr_err("RX: skb_to_sgvec() returned %d, nsg %d\n", rc, nsg);
- goto exit;
- }
-
/* Reconstruct IV: */
ehdr = (struct tipc_ehdr *)skb->data;
salt = aead->salt;
@@ -922,77 +681,19 @@ static int tipc_aead_decrypt(struct net *net, struct tipc_aead *aead,
memcpy(iv, &salt, 4);
memcpy(iv + 4, (u8 *)&ehdr->seqno, 8);
- /* Prepare request */
ehsz = tipc_ehdr_size(ehdr);
- aead_request_set_tfm(req, tfm);
- aead_request_set_ad(req, ehsz);
- aead_request_set_crypt(req, sg, sg, skb->len - ehsz, iv);
-
- /* Set callback function & data */
- aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
- tipc_aead_decrypt_done, skb);
- rx_ctx = (struct tipc_crypto_rx_ctx *)ctx;
- rx_ctx->aead = aead;
- rx_ctx->bearer = b;
-
- /* Hold bearer */
- if (unlikely(!tipc_bearer_hold(b))) {
- rc = -ENODEV;
- goto exit;
- }
+ crypt_len = skb->len - ehsz - aead->authsize;
+ if (unlikely(crypt_len < 0))
+ return -EBADMSG;
- /* Get net to avoid freed tipc_crypto when delete namespace */
- if (!maybe_get_net(net)) {
- tipc_bearer_put(b);
- rc = -ENODEV;
- goto exit;
- }
-
- /* Now, do decrypt */
- rc = crypto_aead_decrypt(req);
- if (rc == -EINPROGRESS || rc == -EBUSY)
+ rc = skb_copy_bits(skb, skb->len - aead->authsize, authtag,
+ aead->authsize);
+ if (unlikely(rc < 0))
return rc;
- tipc_bearer_put(b);
- put_net(net);
-
-exit:
- kfree(ctx);
- TIPC_SKB_CB(skb)->crypto_ctx = NULL;
- return rc;
-}
-
-static void tipc_aead_decrypt_done(void *data, int err)
-{
- struct sk_buff *skb = data;
- struct tipc_crypto_rx_ctx *rx_ctx = TIPC_SKB_CB(skb)->crypto_ctx;
- struct tipc_bearer *b = rx_ctx->bearer;
- struct tipc_aead *aead = rx_ctx->aead;
- struct tipc_crypto_stats __percpu *stats = aead->crypto->stats;
- struct net *net = aead->crypto->net;
-
- switch (err) {
- case 0:
- this_cpu_inc(stats->stat[STAT_ASYNC_OK]);
- break;
- case -EINPROGRESS:
- return;
- default:
- this_cpu_inc(stats->stat[STAT_ASYNC_NOK]);
- break;
- }
-
- kfree(rx_ctx);
- tipc_crypto_rcv_complete(net, aead, b, &skb, err);
- if (likely(skb)) {
- if (likely(test_bit(0, &b->up)))
- tipc_rcv(net, skb, b);
- else
- kfree_skb(skb);
- }
-
- tipc_bearer_put(b);
- put_net(net);
+ aes_gcm_init(&ctx, iv, &aead->gcm_key);
+ tipc_decrypt_skb(&ctx, skb, ehsz, crypt_len);
+ return aes_gcm_decrypt_final(&ctx, authtag);
}
static inline int tipc_ehdr_size(struct tipc_ehdr *ehdr)
@@ -1680,7 +1381,6 @@ static inline void tipc_crypto_clone_msg(struct net *net, struct sk_buff *_skb,
*
* Return:
* * 0 : the encryption has succeeded (or no encryption)
- * * -EINPROGRESS/-EBUSY : the encryption is ongoing, a callback will be made
* * -ENOKEK : the encryption has failed due to no key
* * -EKEYREVOKED : the encryption has failed due to key revoked
* * -ENOMEM : the encryption has failed due to no memory
@@ -1769,11 +1469,6 @@ int tipc_crypto_xmit(struct net *net, struct sk_buff **skb,
case 0:
this_cpu_inc(stats->stat[STAT_OK]);
break;
- case -EINPROGRESS:
- case -EBUSY:
- this_cpu_inc(stats->stat[STAT_ASYNC]);
- *skb = NULL;
- return rc;
default:
this_cpu_inc(stats->stat[STAT_NOK]);
if (rc == -ENOKEY)
@@ -1805,7 +1500,6 @@ int tipc_crypto_xmit(struct net *net, struct sk_buff **skb,
*
* Return:
* * 0 : the decryption has successfully completed
- * * -EINPROGRESS/-EBUSY : the decryption is ongoing, a callback will be made
* * -ENOKEY : the decryption has failed due to no key
* * -EBADMSG : the decryption has failed due to bad message
* * -ENOMEM : the decryption has failed due to no memory
@@ -1859,11 +1553,6 @@ int tipc_crypto_rcv(struct net *net, struct tipc_crypto *rx,
case 0:
this_cpu_inc(stats->stat[STAT_OK]);
break;
- case -EINPROGRESS:
- case -EBUSY:
- this_cpu_inc(stats->stat[STAT_ASYNC]);
- *skb = NULL;
- return rc;
default:
this_cpu_inc(stats->stat[STAT_NOK]);
if (rc == -ENOKEY) {
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index c5eec16213d7..c7f0105148bb 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -138,9 +138,6 @@ struct tipc_skb_cb {
u8 flags;
};
u8 reserved;
-#ifdef CONFIG_TIPC_CRYPTO
- void *crypto_ctx;
-#endif
} __packed;
#define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0]))
diff --git a/net/tipc/sysctl.c b/net/tipc/sysctl.c
index 30d2e06e3d8c..3e8d9def5674 100644
--- a/net/tipc/sysctl.c
+++ b/net/tipc/sysctl.c
@@ -67,6 +67,12 @@ static struct ctl_table tipc_table[] = {
},
#ifdef CONFIG_TIPC_CRYPTO
{
+ /*
+ * This sysctl no longer has any effect on the way that TIPC
+ * uses the crypto subsystem. However, a special value can
+ * still be written to this to trigger debug commands. See
+ * tipc_crypto_do_cmd().
+ */
.procname = "max_tfms",
.data = &sysctl_tipc_max_tfms,
.maxlen = sizeof(sysctl_tipc_max_tfms),
--
2.54.0
prev parent reply other threads:[~2026-07-07 5:37 UTC|newest]
Thread overview: 54+ 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-09 13:06 ` Thomas Huth
2026-07-13 23:37 ` Eric Biggers
2026-07-07 5:34 ` [PATCH 04/33] lib/crypto: aes: Add CTR and XCTR support Eric Biggers
2026-07-13 8:39 ` Thomas Huth
2026-07-13 23:54 ` Eric Biggers
2026-07-14 4:53 ` Thomas Huth
2026-07-07 5:34 ` [PATCH 05/33] lib/crypto: aes: Add XTS support Eric Biggers
2026-07-13 12:15 ` Thomas Huth
2026-07-14 0:23 ` 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 ` [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-09 15:47 ` Eric Biggers
2026-07-09 16:46 ` 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 ` Eric Biggers [this message]
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-34-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.