"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "net/tls/tls_main.c" between
linux-5.3-rc3.tar.gz and linux-5.3-rc4.tar.gz

About: The full source of the development Linux kernel 5.3 (release candidate).

tls_main.c  (linux-5.3-rc3):tls_main.c  (linux-5.3-rc4)
skipping to change at line 264 skipping to change at line 264
void tls_ctx_free(struct tls_context *ctx) void tls_ctx_free(struct tls_context *ctx)
{ {
if (!ctx) if (!ctx)
return; return;
memzero_explicit(&ctx->crypto_send, sizeof(ctx->crypto_send)); memzero_explicit(&ctx->crypto_send, sizeof(ctx->crypto_send));
memzero_explicit(&ctx->crypto_recv, sizeof(ctx->crypto_recv)); memzero_explicit(&ctx->crypto_recv, sizeof(ctx->crypto_recv));
kfree(ctx); kfree(ctx);
} }
static void tls_sk_proto_close(struct sock *sk, long timeout) static void tls_sk_proto_cleanup(struct sock *sk,
struct tls_context *ctx, long timeo)
{ {
struct tls_context *ctx = tls_get_ctx(sk);
long timeo = sock_sndtimeo(sk, 0);
void (*sk_proto_close)(struct sock *sk, long timeout);
bool free_ctx = false;
lock_sock(sk);
sk_proto_close = ctx->sk_proto_close;
if (ctx->tx_conf == TLS_HW_RECORD && ctx->rx_conf == TLS_HW_RECORD)
goto skip_tx_cleanup;
if (ctx->tx_conf == TLS_BASE && ctx->rx_conf == TLS_BASE) {
free_ctx = true;
goto skip_tx_cleanup;
}
if (unlikely(sk->sk_write_pending) && if (unlikely(sk->sk_write_pending) &&
!wait_on_pending_writer(sk, &timeo)) !wait_on_pending_writer(sk, &timeo))
tls_handle_open_record(sk, 0); tls_handle_open_record(sk, 0);
/* We need these for tls_sw_fallback handling of other packets */ /* We need these for tls_sw_fallback handling of other packets */
if (ctx->tx_conf == TLS_SW) { if (ctx->tx_conf == TLS_SW) {
kfree(ctx->tx.rec_seq); kfree(ctx->tx.rec_seq);
kfree(ctx->tx.iv); kfree(ctx->tx.iv);
tls_sw_free_resources_tx(sk); tls_sw_release_resources_tx(sk);
#ifdef CONFIG_TLS_DEVICE #ifdef CONFIG_TLS_DEVICE
} else if (ctx->tx_conf == TLS_HW) { } else if (ctx->tx_conf == TLS_HW) {
tls_device_free_resources_tx(sk); tls_device_free_resources_tx(sk);
#endif #endif
} }
if (ctx->rx_conf == TLS_SW) if (ctx->rx_conf == TLS_SW)
tls_sw_free_resources_rx(sk); tls_sw_release_resources_rx(sk);
#ifdef CONFIG_TLS_DEVICE #ifdef CONFIG_TLS_DEVICE
if (ctx->rx_conf == TLS_HW) if (ctx->rx_conf == TLS_HW)
tls_device_offload_cleanup_rx(sk); tls_device_offload_cleanup_rx(sk);
if (ctx->tx_conf != TLS_HW && ctx->rx_conf != TLS_HW) {
#else
{
#endif #endif
tls_ctx_free(ctx); }
ctx = NULL;
} static void tls_sk_proto_close(struct sock *sk, long timeout)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct tls_context *ctx = tls_get_ctx(sk);
long timeo = sock_sndtimeo(sk, 0);
bool free_ctx;
if (ctx->tx_conf == TLS_SW)
tls_sw_cancel_work_tx(ctx);
skip_tx_cleanup: lock_sock(sk);
free_ctx = ctx->tx_conf != TLS_HW && ctx->rx_conf != TLS_HW;
if (ctx->tx_conf != TLS_BASE || ctx->rx_conf != TLS_BASE)
tls_sk_proto_cleanup(sk, ctx, timeo);
write_lock_bh(&sk->sk_callback_lock);
if (free_ctx)
icsk->icsk_ulp_data = NULL;
sk->sk_prot = ctx->sk_proto;
write_unlock_bh(&sk->sk_callback_lock);
release_sock(sk); release_sock(sk);
sk_proto_close(sk, timeout); if (ctx->tx_conf == TLS_SW)
/* free ctx for TLS_HW_RECORD, used by tcp_set_state tls_sw_free_ctx_tx(ctx);
* for sk->sk_prot->unhash [tls_hw_unhash] if (ctx->rx_conf == TLS_SW || ctx->rx_conf == TLS_HW)
*/ tls_sw_strparser_done(ctx);
if (ctx->rx_conf == TLS_SW)
tls_sw_free_ctx_rx(ctx);
ctx->sk_proto_close(sk, timeout);
if (free_ctx) if (free_ctx)
tls_ctx_free(ctx); tls_ctx_free(ctx);
} }
static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval, static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval,
int __user *optlen) int __user *optlen)
{ {
int rc = 0; int rc = 0;
struct tls_context *ctx = tls_get_ctx(sk); struct tls_context *ctx = tls_get_ctx(sk);
struct tls_crypto_info *crypto_info; struct tls_crypto_info *crypto_info;
skipping to change at line 529 skipping to change at line 532
if (tx) { if (tx) {
#ifdef CONFIG_TLS_DEVICE #ifdef CONFIG_TLS_DEVICE
rc = tls_set_device_offload(sk, ctx); rc = tls_set_device_offload(sk, ctx);
conf = TLS_HW; conf = TLS_HW;
if (rc) { if (rc) {
#else #else
{ {
#endif #endif
rc = tls_set_sw_offload(sk, ctx, 1); rc = tls_set_sw_offload(sk, ctx, 1);
if (rc)
goto err_crypto_info;
conf = TLS_SW; conf = TLS_SW;
} }
} else { } else {
#ifdef CONFIG_TLS_DEVICE #ifdef CONFIG_TLS_DEVICE
rc = tls_set_device_offload_rx(sk, ctx); rc = tls_set_device_offload_rx(sk, ctx);
conf = TLS_HW; conf = TLS_HW;
if (rc) { if (rc) {
#else #else
{ {
#endif #endif
rc = tls_set_sw_offload(sk, ctx, 0); rc = tls_set_sw_offload(sk, ctx, 0);
if (rc)
goto err_crypto_info;
conf = TLS_SW; conf = TLS_SW;
} }
tls_sw_strparser_arm(sk, ctx);
} }
if (rc)
goto err_crypto_info;
if (tx) if (tx)
ctx->tx_conf = conf; ctx->tx_conf = conf;
else else
ctx->rx_conf = conf; ctx->rx_conf = conf;
update_sk_prot(sk, ctx); update_sk_prot(sk, ctx);
if (tx) { if (tx) {
ctx->sk_write_space = sk->sk_write_space; ctx->sk_write_space = sk->sk_write_space;
sk->sk_write_space = tls_write_space; sk->sk_write_space = tls_write_space;
} else { } else {
sk->sk_socket->ops = &tls_sw_proto_ops; sk->sk_socket->ops = &tls_sw_proto_ops;
skipping to change at line 610 skipping to change at line 615
struct tls_context *ctx; struct tls_context *ctx;
ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC); ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC);
if (!ctx) if (!ctx)
return NULL; return NULL;
icsk->icsk_ulp_data = ctx; icsk->icsk_ulp_data = ctx;
ctx->setsockopt = sk->sk_prot->setsockopt; ctx->setsockopt = sk->sk_prot->setsockopt;
ctx->getsockopt = sk->sk_prot->getsockopt; ctx->getsockopt = sk->sk_prot->getsockopt;
ctx->sk_proto_close = sk->sk_prot->close; ctx->sk_proto_close = sk->sk_prot->close;
ctx->unhash = sk->sk_prot->unhash;
return ctx; return ctx;
} }
static void tls_build_proto(struct sock *sk) static void tls_build_proto(struct sock *sk)
{ {
int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4; int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
/* Build IPv6 TLS whenever the address of tcpv6 _prot changes */ /* Build IPv6 TLS whenever the address of tcpv6 _prot changes */
if (ip_ver == TLSV6 && if (ip_ver == TLSV6 &&
unlikely(sk->sk_prot != smp_load_acquire(&saved_tcpv6_prot))) { unlikely(sk->sk_prot != smp_load_acquire(&saved_tcpv6_prot))) {
skipping to change at line 767 skipping to change at line 773
prot[TLS_BASE][TLS_HW] = prot[TLS_BASE][TLS_SW]; prot[TLS_BASE][TLS_HW] = prot[TLS_BASE][TLS_SW];
prot[TLS_SW][TLS_HW] = prot[TLS_SW][TLS_SW]; prot[TLS_SW][TLS_HW] = prot[TLS_SW][TLS_SW];
prot[TLS_HW][TLS_HW] = prot[TLS_HW][TLS_SW]; prot[TLS_HW][TLS_HW] = prot[TLS_HW][TLS_SW];
#endif #endif
prot[TLS_HW_RECORD][TLS_HW_RECORD] = *base; prot[TLS_HW_RECORD][TLS_HW_RECORD] = *base;
prot[TLS_HW_RECORD][TLS_HW_RECORD].hash = tls_hw_hash; prot[TLS_HW_RECORD][TLS_HW_RECORD].hash = tls_hw_hash;
prot[TLS_HW_RECORD][TLS_HW_RECORD].unhash = tls_hw_unhash; prot[TLS_HW_RECORD][TLS_HW_RECORD].unhash = tls_hw_unhash;
prot[TLS_HW_RECORD][TLS_HW_RECORD].close = tls_sk_proto_close;
} }
static int tls_init(struct sock *sk) static int tls_init(struct sock *sk)
{ {
struct tls_context *ctx; struct tls_context *ctx;
int rc = 0; int rc = 0;
if (tls_hw_prot(sk)) if (tls_hw_prot(sk))
goto out; return 0;
/* The TLS ulp is currently supported only for TCP sockets /* The TLS ulp is currently supported only for TCP sockets
* in ESTABLISHED state. * in ESTABLISHED state.
* Supporting sockets in LISTEN state will require us * Supporting sockets in LISTEN state will require us
* to modify the accept implementation to clone rather then * to modify the accept implementation to clone rather then
* share the ulp context. * share the ulp context.
*/ */
if (sk->sk_state != TCP_ESTABLISHED) if (sk->sk_state != TCP_ESTABLISHED)
return -ENOTSUPP; return -ENOTSUPP;
tls_build_proto(sk);
/* allocate tls context */ /* allocate tls context */
write_lock_bh(&sk->sk_callback_lock);
ctx = create_ctx(sk); ctx = create_ctx(sk);
if (!ctx) { if (!ctx) {
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
} }
tls_build_proto(sk);
ctx->tx_conf = TLS_BASE; ctx->tx_conf = TLS_BASE;
ctx->rx_conf = TLS_BASE; ctx->rx_conf = TLS_BASE;
ctx->sk_proto = sk->sk_prot;
update_sk_prot(sk, ctx); update_sk_prot(sk, ctx);
out: out:
write_unlock_bh(&sk->sk_callback_lock);
return rc; return rc;
} }
static void tls_update(struct sock *sk, struct proto *p)
{
struct tls_context *ctx;
ctx = tls_get_ctx(sk);
if (likely(ctx)) {
ctx->sk_proto_close = p->close;
ctx->sk_proto = p;
} else {
sk->sk_prot = p;
}
}
void tls_register_device(struct tls_device *device) void tls_register_device(struct tls_device *device)
{ {
spin_lock_bh(&device_spinlock); spin_lock_bh(&device_spinlock);
list_add_tail(&device->dev_list, &device_list); list_add_tail(&device->dev_list, &device_list);
spin_unlock_bh(&device_spinlock); spin_unlock_bh(&device_spinlock);
} }
EXPORT_SYMBOL(tls_register_device); EXPORT_SYMBOL(tls_register_device);
void tls_unregister_device(struct tls_device *device) void tls_unregister_device(struct tls_device *device)
{ {
spin_lock_bh(&device_spinlock); spin_lock_bh(&device_spinlock);
list_del(&device->dev_list); list_del(&device->dev_list);
spin_unlock_bh(&device_spinlock); spin_unlock_bh(&device_spinlock);
} }
EXPORT_SYMBOL(tls_unregister_device); EXPORT_SYMBOL(tls_unregister_device);
static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = { static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = {
.name = "tls", .name = "tls",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.init = tls_init, .init = tls_init,
.update = tls_update,
}; };
static int __init tls_register(void) static int __init tls_register(void)
{ {
tls_sw_proto_ops = inet_stream_ops; tls_sw_proto_ops = inet_stream_ops;
tls_sw_proto_ops.splice_read = tls_sw_splice_read; tls_sw_proto_ops.splice_read = tls_sw_splice_read;
#ifdef CONFIG_TLS_DEVICE #ifdef CONFIG_TLS_DEVICE
tls_device_init(); tls_device_init();
#endif #endif
 End of changes. 22 change blocks. 
37 lines changed or deleted 60 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)