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.
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
Changes in v2 use reverse xmas tree ordering in tls_set_sw_offload and do_tls_setsockopt_conf turn the alt_crypto_info into an else if selftests: add rekey_fail test
Vadim suggested simplifying tls_set_sw_offload by copying the new crypto_info in the context in do_tls_setsockopt_conf, and then detecting the rekey in tls_set_sw_offload based on whether the iv was already set, but I don't think we can have a common error path (otherwise we'd free the aead etc on rekey failure). I decided instead to reorganize tls_set_sw_offload so that the context is unmodified until we know the rekey cannot fail. Some fields will be touched during the rekey, but they will be set to the same value they had before the rekey (prot->rec_seq_size, etc).
Apoorv suggested to name the struct tls_crypto_info_keys "tls13" rather than "tls12". Since we're using the same crypto_info data for TLS1.3 as for 1.2, even if the tests only run for TLS1.3, I'd rather keep the "tls12" name, in case we end up adding a "tls13_crypto_info_aes_gcm_128" type in the future.
Kuniyuki and Apoorv also suggested preventing rekeys on RX when we haven't received a matching KeyUpdate message, but I'd rather let userspace handle this and have a symmetric API between TX and RX on the kernel side. It's a bit of a foot-gun, but we can't really stop a broken userspace from rolling back the rec_seq on an existing crypto_info either, and that seems like a worse possible breakage.
Sabrina Dubroca (5): tls: remove tls_context argument from tls_set_sw_offload tls: block decryption when a rekey is pending tls: implement rekey for TLS1.3 selftests: tls: add key_generation argument to tls_crypto_info_init selftests: tls: add rekey tests
include/net/tls.h | 4 + net/tls/tls.h | 3 +- net/tls/tls_device.c | 2 +- net/tls/tls_main.c | 37 +++- net/tls/tls_sw.c | 189 +++++++++++++---- tools/testing/selftests/net/tls.c | 336 +++++++++++++++++++++++++++++- 6 files changed, 511 insertions(+), 60 deletions(-)