From a64db5adaf14b72b5eb84d1e097c080815e583aa Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 23 Apr 2025 09:13:04 -0400 Subject: [PATCH] TLS: When possible, enable ML-KEM768. Closes ticket 41041. --- changes/ticket41041 | 10 +++++++++ src/lib/tls/tortls_openssl.c | 42 +++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 changes/ticket41041 diff --git a/changes/ticket41041 b/changes/ticket41041 new file mode 100644 index 0000000000..5fa8323ca5 --- /dev/null +++ b/changes/ticket41041 @@ -0,0 +1,10 @@ + o Minor features (security, TLS): + - When we are running with OpenSSL 3.5.0 or later, + support using the ML-KEM768 for post-quantum key agreement. + Closes ticket 41041. + + o Minor features (performance TLS): + - When running with with OpenSSL 3.0.0 or later, + support using X25519 for TLS key agreement. + (This should slightly improve performance + for TLS session establishment.) diff --git a/src/lib/tls/tortls_openssl.c b/src/lib/tls/tortls_openssl.c index 3d20453c07..e691a40f8a 100644 --- a/src/lib/tls/tortls_openssl.c +++ b/src/lib/tls/tortls_openssl.c @@ -670,11 +670,43 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime, * or a macro. */ #if defined(SSL_CTX_set1_groups_list) || defined(HAVE_SSL_CTX_SET1_GROUPS_LIST) { - const char *list; - list = "P-256:P-224"; - int r = (int) SSL_CTX_set1_groups_list(result->ctx, list); - if (r == 0) - goto error; + // We'd like to say something like: + // "?X25519MLKEM768:P-256:P-224" + // to mean that we prefer X25519MLKEM768 if it is present; + // but we do insist on the presence of P-256 and P-224. + // + // Unfortunately, we support back to OpenSSL 3.0, which did not provide + // any syntax for saying "don't worry if this group isn't supported." + // Instead, we have to make this preference list of preference lists. + static const char *group_lists[] = { + // We do use the ? syntax here, since every version of OpenSSL + // that supports ML-KEM also supports the ? syntax. + // We also use the * and / syntaxes: + // '*' indicates that the client should send these keyshares. + // "/" means that we should consider a set of of groups + // as equivalently secure. + // + // Note that we tell the client to send a P-256 keyshare, since until + // this commit, our servers didn't accept X25519. + "?*X25519MLKEM768 / ?SecP256r1MLKEM768:?X25519 / *P-256:P-224", + "P-256:X25519:P-224", + "P-256:P-224", + }; + bool success = false; + for (unsigned j = 0; j < ARRAY_LENGTH(group_lists); ++j) { + const char *list = group_lists[j]; + int r = (int) SSL_CTX_set1_groups_list(result->ctx, list); + if (r == 1) { + log_info(LD_NET, "Set supported groups to %s", list); + success = true; + break; + } + log_info(LD_NET, "Group list %s wasn't accepted", list); + } + if (! success) { + log_warn(LD_NET, "No lists of TLS groups were supported. " + "Using library defaults"); + } } #else /* !(defined(SSL_CTX_set1_groups_list) || defined(HAVE_SSL_CTX_SE...)) */ if (! is_client) { -- 2.47.2