* [PATCH net-next v3 0/6] tls: implement key updates for TLS1.3
@ 2023-08-09 12:58 Sabrina Dubroca
2023-08-09 12:58 ` [PATCH net-next v3 4/6] docs: tls: document TLS1.3 key updates Sabrina Dubroca
0 siblings, 1 reply; 2+ messages in thread
From: Sabrina Dubroca @ 2023-08-09 12:58 UTC (permalink / raw)
To: netdev
Cc: Sabrina Dubroca, Vadim Fedorenko, Frantisek Krenzelok,
Jakub Kicinski, Kuniyuki Iwashima, Apoorv Kothari, Boris Pismenny,
John Fastabend, Shuah Khan, linux-kselftest, Gal Pressman,
Marcel Holtmann, Jonathan Corbet, linux-doc
This adds support for receiving KeyUpdate messages (RFC 8446, 4.6.3
[1]). A sender transmits a KeyUpdate message and then changes its TX
key. The receiver should react by updating its RX key before
processing the next message.
This patchset implements key updates by:
1. pausing decryption when a KeyUpdate message is received, to avoid
attempting to use the old key to decrypt a record encrypted with
the new key
2. returning -EKEYEXPIRED to syscalls that cannot receive the
KeyUpdate message, until the rekey has been performed by userspace
3. passing the KeyUpdate message to userspace as a control message
4. allowing updates of the crypto_info via the TLS_TX/TLS_RX
setsockopts
This API has been tested with gnutls to make sure that it allows
userspace libraries to implement key updates [2]. Thanks to Frantisek
Krenzelok <fkrenzel@redhat.com> for providing the implementation in
gnutls and testing the kernel patches.
=======================================================================
Discussions around v2 of this patchset focused on how HW offload would
interact with rekey.
RX
- The existing SW path will handle all records between the KeyUpdate
message signaling the change of key and the new key becoming known
to the kernel -- those will be queued encrypted, and decrypted in
SW as they are read by userspace (once the key is provided, ie same
as this patchset)
- Call ->tls_dev_del + ->tls_dev_add immediately during
setsockopt(TLS_RX)
TX
- After setsockopt(TLS_TX), switch to the existing SW path (not the
current device_fallback) until we're able to re-enable HW offload
- tls_device_sendmsg will call into tls_sw_sendmsg under lock_sock
to avoid changing socket ops during the rekey while another
thread might be waiting on the lock
- We only re-enable HW offload (call ->tls_dev_add to install the new
key in HW) once all records sent with the old key have been
ACKed. At this point, all unacked records are SW-encrypted with the
new key, and the old key is unused by both HW and retransmissions.
- If there are no unacked records when userspace does
setsockopt(TLS_TX), we can (try to) install the new key in HW
immediately.
- If yet another key has been provided via setsockopt(TLS_TX), we
don't install intermediate keys, only the latest.
- TCP notifies ktls of ACKs via the icsk_clean_acked callback. In
case of a rekey, tls_icsk_clean_acked will record when all data
sent with the most recent past key has been sent. The next call
to sendmsg will install the new key in HW.
- We close and push the current SW record before reenabling
offload.
If ->tls_dev_add fails to install the new key in HW, we stay in SW
mode. We can add a counter to keep track of this.
In addition:
Because we can't change socket ops during a rekey, we'll also have to
modify do_tls_setsockopt_conf to check ctx->tx_conf and only call
either tls_set_device_offload or tls_set_sw_offload. RX already uses
the same ops for both TLS_HW and TLS_SW, so we could switch between HW
and SW mode on rekey.
An alternative would be to have a common sendmsg which locks
the socket and then calls the correct implementation. We'll need that
anyway for the offload under rekey case, so that would only add a test
to the SW path's ops (compared to the current code). That should allow
us to simplify build_protos a bit, but might have a performance
impact - we'll need to check it if we want to go that route.
=======================================================================
Note: in a future series, I'll clean up tls_set_sw_offload and
eliminate the per-cipher copy-paste using tls_cipher_size_desc.
[1] https://www.rfc-editor.org/rfc/rfc8446#section-4.6.3
[2] https://gitlab.com/gnutls/gnutls/-/merge_requests/1625
Sabrina Dubroca (6):
tls: remove tls_context argument from tls_set_sw_offload
tls: block decryption when a rekey is pending
tls: implement rekey for TLS1.3
docs: tls: document TLS1.3 key updates
selftests: tls: add key_generation argument to tls_crypto_info_init
selftests: tls: add rekey tests
Documentation/networking/tls.rst | 21 ++
include/net/tls.h | 3 +
net/tls/tls.h | 3 +-
net/tls/tls_device.c | 2 +-
net/tls/tls_main.c | 47 ++-
net/tls/tls_sw.c | 184 +++++++++---
tools/testing/selftests/net/tls.c | 466 +++++++++++++++++++++++++++++-
7 files changed, 661 insertions(+), 65 deletions(-)
--
2.40.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH net-next v3 4/6] docs: tls: document TLS1.3 key updates
2023-08-09 12:58 [PATCH net-next v3 0/6] tls: implement key updates for TLS1.3 Sabrina Dubroca
@ 2023-08-09 12:58 ` Sabrina Dubroca
0 siblings, 0 replies; 2+ messages in thread
From: Sabrina Dubroca @ 2023-08-09 12:58 UTC (permalink / raw)
To: netdev
Cc: Sabrina Dubroca, Vadim Fedorenko, Frantisek Krenzelok,
Jakub Kicinski, Kuniyuki Iwashima, Apoorv Kothari, Boris Pismenny,
John Fastabend, Shuah Khan, linux-kselftest, Gal Pressman,
Marcel Holtmann, Jonathan Corbet, linux-doc
v3: added following Jakub's comment
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
---
Documentation/networking/tls.rst | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/Documentation/networking/tls.rst b/Documentation/networking/tls.rst
index 658ed3a71e1b..ea6a22eafe2b 100644
--- a/Documentation/networking/tls.rst
+++ b/Documentation/networking/tls.rst
@@ -200,6 +200,27 @@ received without a cmsg buffer set.
recv will never return data from mixed types of TLS records.
+TLS 1.3 Key Updates
+-------------------
+
+In TLS 1.3, KeyUpdate handshake messages signal that the sender is
+updating its TX key. Any message sent after a KeyUpdate will be
+encrypted using the new key. The userspace library can pass the new
+key to the kernel using the TLS_TX and TLS_RX socket options, as for
+the initial keys. TLS version and cipher cannot be changed.
+
+To prevent attempting to decrypt incoming records using the wrong key,
+decryption will be paused when a KeyUpdate message is received by the
+kernel, until the new key has been provided using the TLS_RX socket
+option. Any read occurring after the KeyUpdate has been read and
+before the new key is provided will fail with EKEYEXPIRED. Poll()'ing
+the socket will also sleep until the new key is provided. There is no
+pausing on the transmit side.
+
+Userspace should make sure that the crypto_info provided has been set
+properly. In particular, the kernel will not check for key/nonce
+reuse.
+
Integrating in to userspace TLS library
---------------------------------------
--
2.40.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-08-09 12:59 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-09 12:58 [PATCH net-next v3 0/6] tls: implement key updates for TLS1.3 Sabrina Dubroca
2023-08-09 12:58 ` [PATCH net-next v3 4/6] docs: tls: document TLS1.3 key updates Sabrina Dubroca
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).