aboutsummaryrefslogtreecommitdiffstats
path: root/net/tls/tls_main.c
diff options
context:
space:
mode:
authorDave Watson <davejwatson@fb.com>2018-03-22 13:10:35 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-23 12:25:54 -0400
commitc46234ebb4d1eee5e09819f49169e51cfc6eb909 (patch)
tree6f1fbbe3cd74ec939633db5a9e2d6b80ffffaf16 /net/tls/tls_main.c
parent583715853a25b4f2720b847e4fb8e37727299152 (diff)
tls: RX path for ktls
Add rx path for tls software implementation. recvmsg, splice_read, and poll implemented. An additional sockopt TLS_RX is added, with the same interface as TLS_TX. Either TLX_RX or TLX_TX may be provided separately, or together (with two different setsockopt calls with appropriate keys). Control messages are passed via CMSG in a similar way to transmit. If no cmsg buffer is passed, then only application data records will be passed to userspace, and EIO is returned for other types of alerts. EBADMSG is passed for decryption errors, and EMSGSIZE is passed for framing too big, and EBADMSG for framing too small (matching openssl semantics). EINVAL is returned for TLS versions that do not match the original setsockopt call. All are unrecoverable. strparser is used to parse TLS framing. Decryption is done directly in to userspace buffers if they are large enough to support it, otherwise sk_cow_data is called (similar to ipsec), and buffers are decrypted in place and copied. splice_read always decrypts in place, since no buffers are provided to decrypt in to. sk_poll is overridden, and only returns POLLIN if a full TLS message is received. Otherwise we wait for strparser to finish reading a full frame. Actual decryption is only done during recvmsg or splice_read calls. Signed-off-by: Dave Watson <davejwatson@fb.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tls/tls_main.c')
-rw-r--r--net/tls/tls_main.c62
1 files changed, 52 insertions, 10 deletions
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index c405beeda765..6f5c1146da4a 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -54,12 +54,15 @@ enum {
54enum { 54enum {
55 TLS_BASE, 55 TLS_BASE,
56 TLS_SW_TX, 56 TLS_SW_TX,
57 TLS_SW_RX,
58 TLS_SW_RXTX,
57 TLS_NUM_CONFIG, 59 TLS_NUM_CONFIG,
58}; 60};
59 61
60static struct proto *saved_tcpv6_prot; 62static struct proto *saved_tcpv6_prot;
61static DEFINE_MUTEX(tcpv6_prot_mutex); 63static DEFINE_MUTEX(tcpv6_prot_mutex);
62static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG]; 64static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG];
65static struct proto_ops tls_sw_proto_ops;
63 66
64static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx) 67static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx)
65{ 68{
@@ -261,9 +264,14 @@ static void tls_sk_proto_close(struct sock *sk, long timeout)
261 264
262 kfree(ctx->tx.rec_seq); 265 kfree(ctx->tx.rec_seq);
263 kfree(ctx->tx.iv); 266 kfree(ctx->tx.iv);
267 kfree(ctx->rx.rec_seq);
268 kfree(ctx->rx.iv);
264 269
265 if (ctx->conf == TLS_SW_TX) 270 if (ctx->conf == TLS_SW_TX ||
266 tls_sw_free_tx_resources(sk); 271 ctx->conf == TLS_SW_RX ||
272 ctx->conf == TLS_SW_RXTX) {
273 tls_sw_free_resources(sk);
274 }
267 275
268skip_tx_cleanup: 276skip_tx_cleanup:
269 release_sock(sk); 277 release_sock(sk);
@@ -365,8 +373,8 @@ static int tls_getsockopt(struct sock *sk, int level, int optname,
365 return do_tls_getsockopt(sk, optname, optval, optlen); 373 return do_tls_getsockopt(sk, optname, optval, optlen);
366} 374}
367 375
368static int do_tls_setsockopt_tx(struct sock *sk, char __user *optval, 376static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
369 unsigned int optlen) 377 unsigned int optlen, int tx)
370{ 378{
371 struct tls_crypto_info *crypto_info; 379 struct tls_crypto_info *crypto_info;
372 struct tls_context *ctx = tls_get_ctx(sk); 380 struct tls_context *ctx = tls_get_ctx(sk);
@@ -378,7 +386,11 @@ static int do_tls_setsockopt_tx(struct sock *sk, char __user *optval,
378 goto out; 386 goto out;
379 } 387 }
380 388
381 crypto_info = &ctx->crypto_send; 389 if (tx)
390 crypto_info = &ctx->crypto_send;
391 else
392 crypto_info = &ctx->crypto_recv;
393
382 /* Currently we don't support set crypto info more than one time */ 394 /* Currently we don't support set crypto info more than one time */
383 if (TLS_CRYPTO_INFO_READY(crypto_info)) { 395 if (TLS_CRYPTO_INFO_READY(crypto_info)) {
384 rc = -EBUSY; 396 rc = -EBUSY;
@@ -417,15 +429,31 @@ static int do_tls_setsockopt_tx(struct sock *sk, char __user *optval,
417 } 429 }
418 430
419 /* currently SW is default, we will have ethtool in future */ 431 /* currently SW is default, we will have ethtool in future */
420 rc = tls_set_sw_offload(sk, ctx); 432 if (tx) {
421 conf = TLS_SW_TX; 433 rc = tls_set_sw_offload(sk, ctx, 1);
434 if (ctx->conf == TLS_SW_RX)
435 conf = TLS_SW_RXTX;
436 else
437 conf = TLS_SW_TX;
438 } else {
439 rc = tls_set_sw_offload(sk, ctx, 0);
440 if (ctx->conf == TLS_SW_TX)
441 conf = TLS_SW_RXTX;
442 else
443 conf = TLS_SW_RX;
444 }
445
422 if (rc) 446 if (rc)
423 goto err_crypto_info; 447 goto err_crypto_info;
424 448
425 ctx->conf = conf; 449 ctx->conf = conf;
426 update_sk_prot(sk, ctx); 450 update_sk_prot(sk, ctx);
427 ctx->sk_write_space = sk->sk_write_space; 451 if (tx) {
428 sk->sk_write_space = tls_write_space; 452 ctx->sk_write_space = sk->sk_write_space;
453 sk->sk_write_space = tls_write_space;
454 } else {
455 sk->sk_socket->ops = &tls_sw_proto_ops;
456 }
429 goto out; 457 goto out;
430 458
431err_crypto_info: 459err_crypto_info:
@@ -441,8 +469,10 @@ static int do_tls_setsockopt(struct sock *sk, int optname,
441 469
442 switch (optname) { 470 switch (optname) {
443 case TLS_TX: 471 case TLS_TX:
472 case TLS_RX:
444 lock_sock(sk); 473 lock_sock(sk);
445 rc = do_tls_setsockopt_tx(sk, optval, optlen); 474 rc = do_tls_setsockopt_conf(sk, optval, optlen,
475 optname == TLS_TX);
446 release_sock(sk); 476 release_sock(sk);
447 break; 477 break;
448 default: 478 default:
@@ -473,6 +503,14 @@ static void build_protos(struct proto *prot, struct proto *base)
473 prot[TLS_SW_TX] = prot[TLS_BASE]; 503 prot[TLS_SW_TX] = prot[TLS_BASE];
474 prot[TLS_SW_TX].sendmsg = tls_sw_sendmsg; 504 prot[TLS_SW_TX].sendmsg = tls_sw_sendmsg;
475 prot[TLS_SW_TX].sendpage = tls_sw_sendpage; 505 prot[TLS_SW_TX].sendpage = tls_sw_sendpage;
506
507 prot[TLS_SW_RX] = prot[TLS_BASE];
508 prot[TLS_SW_RX].recvmsg = tls_sw_recvmsg;
509 prot[TLS_SW_RX].close = tls_sk_proto_close;
510
511 prot[TLS_SW_RXTX] = prot[TLS_SW_TX];
512 prot[TLS_SW_RXTX].recvmsg = tls_sw_recvmsg;
513 prot[TLS_SW_RXTX].close = tls_sk_proto_close;
476} 514}
477 515
478static int tls_init(struct sock *sk) 516static int tls_init(struct sock *sk)
@@ -531,6 +569,10 @@ static int __init tls_register(void)
531{ 569{
532 build_protos(tls_prots[TLSV4], &tcp_prot); 570 build_protos(tls_prots[TLSV4], &tcp_prot);
533 571
572 tls_sw_proto_ops = inet_stream_ops;
573 tls_sw_proto_ops.poll = tls_sw_poll;
574 tls_sw_proto_ops.splice_read = tls_sw_splice_read;
575
534 tcp_register_ulp(&tcp_tls_ulp_ops); 576 tcp_register_ulp(&tcp_tls_ulp_ops);
535 577
536 return 0; 578 return 0;