Skip to content

Commit 399b721

Browse files
author
CKI KWF Bot
committed
Merge: tls update
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/766 JIRA: https://issues.redhat.com/browse/RHEL-86020 Upstream commits: 0471b10 ("tls: block decryption when a rekey is pending") 4706959 ("tls: implement rekey for TLS1.3") 510128b ("tls: add counters for rekey") b2e584a ("selftests: tls: add key_generation argument to tls_crypto_info_init") 555f0ed ("selftests: tls: add rekey tests") b341ca5 ("tls: Fix tls_sw_sendmsg error handling") 06cc878 ("tls: skip setting sk_write_space on rekey") 5071a1e ("net: tls: explicitly disallow disconnect") a1328a6 ("selftests: tls: check that disconnect does nothing") Signed-off-by: Sabrina Dubroca <sdubroca@redhat.com> Approved-by: Xin Long <lxin@redhat.com> Approved-by: Florian Westphal <fwestpha@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents dc085f3 + ce7c32e commit 399b721

File tree

8 files changed

+693
-62
lines changed

8 files changed

+693
-62
lines changed

include/net/tls.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ struct tls_rec;
5959

6060
#define TLS_CRYPTO_INFO_READY(info) ((info)->cipher_type)
6161

62+
#define TLS_HANDSHAKE_KEYUPDATE 24 /* rfc8446 B.3: Key update */
63+
6264
#define TLS_AAD_SPACE_SIZE 13
6365

6466
#define TLS_MAX_IV_SIZE 16
@@ -130,6 +132,7 @@ struct tls_sw_context_rx {
130132
u8 async_capable:1;
131133
u8 zc_capable:1;
132134
u8 reader_contended:1;
135+
bool key_update_pending;
133136

134137
struct tls_strparser strp;
135138

include/uapi/linux/snmp.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,11 @@ enum
358358
LINUX_MIB_TLSRXDEVICERESYNC, /* TlsRxDeviceResync */
359359
LINUX_MIB_TLSDECRYPTRETRY, /* TlsDecryptRetry */
360360
LINUX_MIB_TLSRXNOPADVIOL, /* TlsRxNoPadViolation */
361+
LINUX_MIB_TLSRXREKEYOK, /* TlsRxRekeyOk */
362+
LINUX_MIB_TLSRXREKEYERROR, /* TlsRxRekeyError */
363+
LINUX_MIB_TLSTXREKEYOK, /* TlsTxRekeyOk */
364+
LINUX_MIB_TLSTXREKEYERROR, /* TlsTxRekeyError */
365+
LINUX_MIB_TLSRXREKEYRECEIVED, /* TlsRxRekeyReceived */
361366
__LINUX_MIB_TLSMAX
362367
};
363368

net/tls/tls.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ void tls_err_abort(struct sock *sk, int err);
145145
int init_prot_info(struct tls_prot_info *prot,
146146
const struct tls_crypto_info *crypto_info,
147147
const struct tls_cipher_desc *cipher_desc);
148-
int tls_set_sw_offload(struct sock *sk, int tx);
148+
int tls_set_sw_offload(struct sock *sk, int tx,
149+
struct tls_crypto_info *new_crypto_info);
149150
void tls_update_rx_zc_capable(struct tls_context *tls_ctx);
150151
void tls_sw_strparser_arm(struct sock *sk, struct tls_context *ctx);
151152
void tls_sw_strparser_done(struct tls_context *tls_ctx);

net/tls/tls_device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx)
12271227
context->resync_nh_reset = 1;
12281228

12291229
ctx->priv_ctx_rx = context;
1230-
rc = tls_set_sw_offload(sk, 0);
1230+
rc = tls_set_sw_offload(sk, 0, NULL);
12311231
if (rc)
12321232
goto release_ctx;
12331233

net/tls/tls_main.c

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,10 @@ static __poll_t tls_sk_poll(struct file *file, struct socket *sock,
423423
ctx = tls_sw_ctx_rx(tls_ctx);
424424
psock = sk_psock_get(sk);
425425

426-
if (skb_queue_empty_lockless(&ctx->rx_list) &&
427-
!tls_strp_msg_ready(ctx) &&
428-
sk_psock_queue_empty(psock))
426+
if ((skb_queue_empty_lockless(&ctx->rx_list) &&
427+
!tls_strp_msg_ready(ctx) &&
428+
sk_psock_queue_empty(psock)) ||
429+
READ_ONCE(ctx->key_update_pending))
429430
mask &= ~(EPOLLIN | EPOLLRDNORM);
430431

431432
if (psock)
@@ -612,11 +613,13 @@ static int validate_crypto_info(const struct tls_crypto_info *crypto_info,
612613
static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
613614
unsigned int optlen, int tx)
614615
{
615-
struct tls_crypto_info *crypto_info;
616-
struct tls_crypto_info *alt_crypto_info;
616+
struct tls_crypto_info *crypto_info, *alt_crypto_info;
617+
struct tls_crypto_info *old_crypto_info = NULL;
617618
struct tls_context *ctx = tls_get_ctx(sk);
618619
const struct tls_cipher_desc *cipher_desc;
619620
union tls_crypto_context *crypto_ctx;
621+
union tls_crypto_context tmp = {};
622+
bool update = false;
620623
int rc = 0;
621624
int conf;
622625

@@ -633,17 +636,36 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
633636

634637
crypto_info = &crypto_ctx->info;
635638

636-
/* Currently we don't support set crypto info more than one time */
637-
if (TLS_CRYPTO_INFO_READY(crypto_info))
638-
return -EBUSY;
639+
if (TLS_CRYPTO_INFO_READY(crypto_info)) {
640+
/* Currently we only support setting crypto info more
641+
* than one time for TLS 1.3
642+
*/
643+
if (crypto_info->version != TLS_1_3_VERSION) {
644+
TLS_INC_STATS(sock_net(sk), tx ? LINUX_MIB_TLSTXREKEYERROR
645+
: LINUX_MIB_TLSRXREKEYERROR);
646+
return -EBUSY;
647+
}
648+
649+
update = true;
650+
old_crypto_info = crypto_info;
651+
crypto_info = &tmp.info;
652+
crypto_ctx = &tmp;
653+
}
639654

640655
rc = copy_from_sockptr(crypto_info, optval, sizeof(*crypto_info));
641656
if (rc) {
642657
rc = -EFAULT;
643658
goto err_crypto_info;
644659
}
645660

646-
rc = validate_crypto_info(crypto_info, alt_crypto_info);
661+
if (update) {
662+
/* Ensure that TLS version and ciphers are not modified */
663+
if (crypto_info->version != old_crypto_info->version ||
664+
crypto_info->cipher_type != old_crypto_info->cipher_type)
665+
rc = -EINVAL;
666+
} else {
667+
rc = validate_crypto_info(crypto_info, alt_crypto_info);
668+
}
647669
if (rc)
648670
goto err_crypto_info;
649671

@@ -673,11 +695,17 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
673695
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSTXDEVICE);
674696
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSCURRTXDEVICE);
675697
} else {
676-
rc = tls_set_sw_offload(sk, 1);
698+
rc = tls_set_sw_offload(sk, 1,
699+
update ? crypto_info : NULL);
677700
if (rc)
678701
goto err_crypto_info;
679-
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSTXSW);
680-
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSCURRTXSW);
702+
703+
if (update) {
704+
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSTXREKEYOK);
705+
} else {
706+
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSTXSW);
707+
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSCURRTXSW);
708+
}
681709
conf = TLS_SW;
682710
}
683711
} else {
@@ -687,21 +715,32 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
687715
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSRXDEVICE);
688716
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSCURRRXDEVICE);
689717
} else {
690-
rc = tls_set_sw_offload(sk, 0);
718+
rc = tls_set_sw_offload(sk, 0,
719+
update ? crypto_info : NULL);
691720
if (rc)
692721
goto err_crypto_info;
693-
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSRXSW);
694-
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSCURRRXSW);
722+
723+
if (update) {
724+
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSRXREKEYOK);
725+
} else {
726+
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSRXSW);
727+
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSCURRRXSW);
728+
}
695729
conf = TLS_SW;
696730
}
697-
tls_sw_strparser_arm(sk, ctx);
731+
if (!update)
732+
tls_sw_strparser_arm(sk, ctx);
698733
}
699734

700735
if (tx)
701736
ctx->tx_conf = conf;
702737
else
703738
ctx->rx_conf = conf;
704739
update_sk_prot(sk, ctx);
740+
741+
if (update)
742+
return 0;
743+
705744
if (tx) {
706745
ctx->sk_write_space = sk->sk_write_space;
707746
sk->sk_write_space = tls_write_space;
@@ -713,6 +752,10 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
713752
return 0;
714753

715754
err_crypto_info:
755+
if (update) {
756+
TLS_INC_STATS(sock_net(sk), tx ? LINUX_MIB_TLSTXREKEYERROR
757+
: LINUX_MIB_TLSRXREKEYERROR);
758+
}
716759
memzero_explicit(crypto_ctx, sizeof(*crypto_ctx));
717760
return rc;
718761
}
@@ -809,6 +852,11 @@ static int tls_setsockopt(struct sock *sk, int level, int optname,
809852
return do_tls_setsockopt(sk, optname, optval, optlen);
810853
}
811854

855+
static int tls_disconnect(struct sock *sk, int flags)
856+
{
857+
return -EOPNOTSUPP;
858+
}
859+
812860
struct tls_context *tls_ctx_create(struct sock *sk)
813861
{
814862
struct inet_connection_sock *icsk = inet_csk(sk);
@@ -904,6 +952,7 @@ static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG],
904952
prot[TLS_BASE][TLS_BASE] = *base;
905953
prot[TLS_BASE][TLS_BASE].setsockopt = tls_setsockopt;
906954
prot[TLS_BASE][TLS_BASE].getsockopt = tls_getsockopt;
955+
prot[TLS_BASE][TLS_BASE].disconnect = tls_disconnect;
907956
prot[TLS_BASE][TLS_BASE].close = tls_sk_proto_close;
908957

909958
prot[TLS_SW][TLS_BASE] = prot[TLS_BASE][TLS_BASE];

net/tls/tls_proc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ static const struct snmp_mib tls_mib_list[] = {
2222
SNMP_MIB_ITEM("TlsRxDeviceResync", LINUX_MIB_TLSRXDEVICERESYNC),
2323
SNMP_MIB_ITEM("TlsDecryptRetry", LINUX_MIB_TLSDECRYPTRETRY),
2424
SNMP_MIB_ITEM("TlsRxNoPadViolation", LINUX_MIB_TLSRXNOPADVIOL),
25+
SNMP_MIB_ITEM("TlsRxRekeyOk", LINUX_MIB_TLSRXREKEYOK),
26+
SNMP_MIB_ITEM("TlsRxRekeyError", LINUX_MIB_TLSRXREKEYERROR),
27+
SNMP_MIB_ITEM("TlsTxRekeyOk", LINUX_MIB_TLSTXREKEYOK),
28+
SNMP_MIB_ITEM("TlsTxRekeyError", LINUX_MIB_TLSTXREKEYERROR),
29+
SNMP_MIB_ITEM("TlsRxRekeyReceived", LINUX_MIB_TLSRXREKEYRECEIVED),
2530
SNMP_MIB_SENTINEL
2631
};
2732

0 commit comments

Comments
 (0)