[PATCH v16 05/10] tls: split tls_set_sw_offload into init and finalize stages
From: Rishikesh Jethwani <hidden>
Date: 2026-08-07 18:40:30
Subsystem:
networking [general], networking [tls], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, John Fastabend, Sabrina Dubroca, Linus Torvalds
Separate cipher context initialization from key material finalization to support staged setup for hardware offload fallback paths. Signed-off-by: Rishikesh Jethwani <redacted> --- net/tls/tls.h | 4 +++ net/tls/tls_device.c | 3 +- net/tls/tls_sw.c | 77 +++++++++++++++++++++++++++++++------------- 3 files changed, 61 insertions(+), 23 deletions(-)
diff --git a/net/tls/tls.h b/net/tls/tls.h
index 60a37bdaaa25..5a6ee1ea00f8 100644
--- a/net/tls/tls.h
+++ b/net/tls/tls.h@@ -147,6 +147,10 @@ void tls_strp_abort_strp(struct tls_strparser *strp, int err); int init_prot_info(struct tls_prot_info *prot, const struct tls_crypto_info *crypto_info, const struct tls_cipher_desc *cipher_desc); +int tls_sw_ctx_init(struct sock *sk, int tx, + struct tls_crypto_info *new_crypto_info); +void tls_sw_ctx_finalize(struct sock *sk, int tx, + struct tls_crypto_info *new_crypto_info); int tls_set_sw_offload(struct sock *sk, int tx, struct tls_crypto_info *new_crypto_info); void tls_update_rx_zc_capable(struct tls_context *tls_ctx);
diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
index bbb1aa733500..cf67e1f6c5f4 100644
--- a/net/tls/tls_device.c
+++ b/net/tls/tls_device.c@@ -1235,7 +1235,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx) context->resync_nh_reset = 1; ctx->priv_ctx_rx = context; - rc = tls_set_sw_offload(sk, 0, NULL); + rc = tls_sw_ctx_init(sk, 0, NULL); if (rc) goto release_ctx;
@@ -1249,6 +1249,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx) goto free_sw_resources; tls_device_attach(ctx, sk, netdev); + tls_sw_ctx_finalize(sk, 0, NULL); up_read(&device_offload_lock); dev_put(netdev);
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 62d46736e24b..63c83247f9a3 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c@@ -2517,20 +2517,19 @@ static void tls_finish_key_update(struct sock *sk, struct tls_context *tls_ctx) ctx->saved_data_ready(sk); } -int tls_set_sw_offload(struct sock *sk, int tx, - struct tls_crypto_info *new_crypto_info) +int tls_sw_ctx_init(struct sock *sk, int tx, + struct tls_crypto_info *new_crypto_info) { struct tls_crypto_info *crypto_info, *src_crypto_info; struct tls_sw_context_tx *sw_ctx_tx = NULL; struct tls_sw_context_rx *sw_ctx_rx = NULL; const struct tls_cipher_desc *cipher_desc; - char *iv, *rec_seq, *key, *salt; - struct cipher_context *cctx; struct tls_prot_info *prot; struct crypto_aead **aead; struct tls_context *ctx; struct crypto_tfm *tfm; int rc = 0; + char *key; ctx = tls_get_ctx(sk); prot = &ctx->prot_info;
@@ -2551,12 +2550,10 @@ int tls_set_sw_offload(struct sock *sk, int tx, if (tx) { sw_ctx_tx = ctx->priv_ctx_tx; crypto_info = &ctx->crypto_send.info; - cctx = &ctx->tx; aead = &sw_ctx_tx->aead_send; } else { sw_ctx_rx = ctx->priv_ctx_rx; crypto_info = &ctx->crypto_recv.info; - cctx = &ctx->rx; aead = &sw_ctx_rx->aead_recv; }
@@ -2572,10 +2569,7 @@ int tls_set_sw_offload(struct sock *sk, int tx, if (rc) goto free_priv; - iv = crypto_info_iv(src_crypto_info, cipher_desc); key = crypto_info_key(src_crypto_info, cipher_desc); - salt = crypto_info_salt(src_crypto_info, cipher_desc); - rec_seq = crypto_info_rec_seq(src_crypto_info, cipher_desc); if (!*aead) { *aead = crypto_alloc_aead(cipher_desc->cipher_name, 0, 0);
@@ -2619,19 +2613,6 @@ int tls_set_sw_offload(struct sock *sk, int tx, goto free_aead; } - memcpy(cctx->iv, salt, cipher_desc->salt); - memcpy(cctx->iv + cipher_desc->salt, iv, cipher_desc->iv); - memcpy(cctx->rec_seq, rec_seq, cipher_desc->rec_seq); - - if (new_crypto_info) { - unsafe_memcpy(crypto_info, new_crypto_info, - cipher_desc->crypto_info, - /* size was checked in do_tls_setsockopt_conf */); - memzero_explicit(new_crypto_info, cipher_desc->crypto_info); - if (!tx) - tls_finish_key_update(sk, ctx); - } - goto out; free_aead:
@@ -2650,3 +2631,55 @@ int tls_set_sw_offload(struct sock *sk, int tx, out: return rc; } + +void tls_sw_ctx_finalize(struct sock *sk, int tx, + struct tls_crypto_info *new_crypto_info) +{ + struct tls_crypto_info *crypto_info, *src_crypto_info; + const struct tls_cipher_desc *cipher_desc; + struct tls_context *ctx = tls_get_ctx(sk); + struct cipher_context *cctx; + char *iv, *salt, *rec_seq; + + if (tx) { + crypto_info = &ctx->crypto_send.info; + cctx = &ctx->tx; + } else { + crypto_info = &ctx->crypto_recv.info; + cctx = &ctx->rx; + } + + src_crypto_info = new_crypto_info ?: crypto_info; + cipher_desc = get_cipher_desc(src_crypto_info->cipher_type); + + iv = crypto_info_iv(src_crypto_info, cipher_desc); + salt = crypto_info_salt(src_crypto_info, cipher_desc); + rec_seq = crypto_info_rec_seq(src_crypto_info, cipher_desc); + + memcpy(cctx->iv, salt, cipher_desc->salt); + memcpy(cctx->iv + cipher_desc->salt, iv, cipher_desc->iv); + memcpy(cctx->rec_seq, rec_seq, cipher_desc->rec_seq); + + if (new_crypto_info) { + unsafe_memcpy(crypto_info, new_crypto_info, + cipher_desc->crypto_info, + /* size was checked in do_tls_setsockopt_conf */); + memzero_explicit(new_crypto_info, cipher_desc->crypto_info); + + if (!tx) + tls_finish_key_update(sk, ctx); + } +} + +int tls_set_sw_offload(struct sock *sk, int tx, + struct tls_crypto_info *new_crypto_info) +{ + int rc; + + rc = tls_sw_ctx_init(sk, tx, new_crypto_info); + if (rc) + return rc; + + tls_sw_ctx_finalize(sk, tx, new_crypto_info); + return 0; +}
--
2.25.1