diff options
Diffstat (limited to 'net/tls/tls_main.c')
-rw-r--r-- | net/tls/tls_main.c | 62 |
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 { | |||
54 | enum { | 54 | enum { |
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 | ||
60 | static struct proto *saved_tcpv6_prot; | 62 | static struct proto *saved_tcpv6_prot; |
61 | static DEFINE_MUTEX(tcpv6_prot_mutex); | 63 | static DEFINE_MUTEX(tcpv6_prot_mutex); |
62 | static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG]; | 64 | static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG]; |
65 | static struct proto_ops tls_sw_proto_ops; | ||
63 | 66 | ||
64 | static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx) | 67 | static 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 | ||
268 | skip_tx_cleanup: | 276 | skip_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 | ||
368 | static int do_tls_setsockopt_tx(struct sock *sk, char __user *optval, | 376 | static 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 | ||
431 | err_crypto_info: | 459 | err_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 | ||
478 | static int tls_init(struct sock *sk) | 516 | static 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; |