diff options
Diffstat (limited to 'net/tls/tls_main.c')
-rw-r--r-- | net/tls/tls_main.c | 92 |
1 files changed, 67 insertions, 25 deletions
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index d824d548447e..6f5c1146da4a 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c | |||
@@ -52,20 +52,23 @@ enum { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | enum { | 54 | enum { |
55 | TLS_BASE_TX, | 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 | { |
66 | int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4; | 69 | int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4; |
67 | 70 | ||
68 | sk->sk_prot = &tls_prots[ip_ver][ctx->tx_conf]; | 71 | sk->sk_prot = &tls_prots[ip_ver][ctx->conf]; |
69 | } | 72 | } |
70 | 73 | ||
71 | int wait_on_pending_writer(struct sock *sk, long *timeo) | 74 | int wait_on_pending_writer(struct sock *sk, long *timeo) |
@@ -238,7 +241,7 @@ static void tls_sk_proto_close(struct sock *sk, long timeout) | |||
238 | lock_sock(sk); | 241 | lock_sock(sk); |
239 | sk_proto_close = ctx->sk_proto_close; | 242 | sk_proto_close = ctx->sk_proto_close; |
240 | 243 | ||
241 | if (ctx->tx_conf == TLS_BASE_TX) { | 244 | if (ctx->conf == TLS_BASE) { |
242 | kfree(ctx); | 245 | kfree(ctx); |
243 | goto skip_tx_cleanup; | 246 | goto skip_tx_cleanup; |
244 | } | 247 | } |
@@ -259,11 +262,16 @@ static void tls_sk_proto_close(struct sock *sk, long timeout) | |||
259 | } | 262 | } |
260 | } | 263 | } |
261 | 264 | ||
262 | kfree(ctx->rec_seq); | 265 | kfree(ctx->tx.rec_seq); |
263 | kfree(ctx->iv); | 266 | kfree(ctx->tx.iv); |
267 | kfree(ctx->rx.rec_seq); | ||
268 | kfree(ctx->rx.iv); | ||
264 | 269 | ||
265 | if (ctx->tx_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); |
@@ -319,9 +327,9 @@ static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval, | |||
319 | } | 327 | } |
320 | lock_sock(sk); | 328 | lock_sock(sk); |
321 | memcpy(crypto_info_aes_gcm_128->iv, | 329 | memcpy(crypto_info_aes_gcm_128->iv, |
322 | ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, | 330 | ctx->tx.iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, |
323 | TLS_CIPHER_AES_GCM_128_IV_SIZE); | 331 | TLS_CIPHER_AES_GCM_128_IV_SIZE); |
324 | memcpy(crypto_info_aes_gcm_128->rec_seq, ctx->rec_seq, | 332 | memcpy(crypto_info_aes_gcm_128->rec_seq, ctx->tx.rec_seq, |
325 | TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); | 333 | TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); |
326 | release_sock(sk); | 334 | release_sock(sk); |
327 | if (copy_to_user(optval, | 335 | if (copy_to_user(optval, |
@@ -365,20 +373,24 @@ 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); |
373 | int rc = 0; | 381 | int rc = 0; |
374 | int tx_conf; | 382 | int conf; |
375 | 383 | ||
376 | if (!optval || (optlen < sizeof(*crypto_info))) { | 384 | if (!optval || (optlen < sizeof(*crypto_info))) { |
377 | rc = -EINVAL; | 385 | rc = -EINVAL; |
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 | tx_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->tx_conf = tx_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: |
@@ -465,14 +495,22 @@ static int tls_setsockopt(struct sock *sk, int level, int optname, | |||
465 | 495 | ||
466 | static void build_protos(struct proto *prot, struct proto *base) | 496 | static void build_protos(struct proto *prot, struct proto *base) |
467 | { | 497 | { |
468 | prot[TLS_BASE_TX] = *base; | 498 | prot[TLS_BASE] = *base; |
469 | prot[TLS_BASE_TX].setsockopt = tls_setsockopt; | 499 | prot[TLS_BASE].setsockopt = tls_setsockopt; |
470 | prot[TLS_BASE_TX].getsockopt = tls_getsockopt; | 500 | prot[TLS_BASE].getsockopt = tls_getsockopt; |
471 | prot[TLS_BASE_TX].close = tls_sk_proto_close; | 501 | prot[TLS_BASE].close = tls_sk_proto_close; |
472 | 502 | ||
473 | prot[TLS_SW_TX] = prot[TLS_BASE_TX]; | 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) |
@@ -513,7 +551,7 @@ static int tls_init(struct sock *sk) | |||
513 | mutex_unlock(&tcpv6_prot_mutex); | 551 | mutex_unlock(&tcpv6_prot_mutex); |
514 | } | 552 | } |
515 | 553 | ||
516 | ctx->tx_conf = TLS_BASE_TX; | 554 | ctx->conf = TLS_BASE; |
517 | update_sk_prot(sk, ctx); | 555 | update_sk_prot(sk, ctx); |
518 | out: | 556 | out: |
519 | return rc; | 557 | return rc; |
@@ -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; |