Separate cipher context initialization from key material finalization to support staged setup for hardware offload fallback paths. Signed-off-by: Rishikesh Jethwani --- 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 2f86baeb71fc..56eba13261d4 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 1321bf9b59b0..cd26873e9063 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -1233,7 +1233,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; @@ -1247,6 +1247,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 5fe07f110fe8..424e0a11bcf4 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -2775,20 +2775,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; @@ -2809,12 +2808,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; } @@ -2830,10 +2827,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); @@ -2877,19 +2871,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: @@ -2908,3 +2889,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