Configuring supported TLS groups in OpenSSL

The configuration of supported groups in TLS servers is important to limit the resource consumption of the TLS handshakes performed by the server. This blog post should give system administrators a few useful hints on how to configure the OpenSSL library and two of the most used open source HTTP servers which use the OpenSSL library for supporting the HTTPS protocol.

UPDATE: The post was updated to mention the new CVE-2022-40735 vulnerability.

The CVE-2002-20001 (a.k.a DHEat attack) vulnerability inherent to the support of the Diffie-Hellman (DH) and Elliptic Curve Diffie-Hellman (ECDH) key exchanges in TLS and other protocols provides a way for an attacker to cause high CPU usage on servers with relatively low effort on the client side.

The recent CVE-2022-40735 vulnerability also emphasises the importance of limiting private key sizes for DH performance.

A general solution to the problem is to limit the CPU cycles spent by the server on connections from the same originating client.

However such a solution is not always available. In that case the only other option is to limit the supported Diffie-Hellman groups so the amount of CPU cycles spent on a single TLS handshake is limited.

A general recommendation is to limit the groups to those that meet the required security level and that all the potential TLS clients support.

Nowadays contemporary TLS clients support ECDH groups so it is fairly safe for the server to disable the classic finite field DH (FFDH) groups completely. Otherwise, if DH support is required, keep support for DH groups up to 3072-bit group size (ffdhe2048, ffdhe3072) as it should limit the CPU resource consumption. The group ffdhe2048 offers 112 bits of security, while ffdhe3072 offers the same security strength (128 bits) as prime256v1 or X25519.

Larger ECDH groups, such as secp521r1, may require as many CPU cycles as the smallest DH groups, so it is prudent to enable only those that are necessary for the required security level. For backward compatibility reasons you may require the prime256v1 curve to be enabled. However, X25519 provides the same security strength as prime256v1, is also supported by the major clients and has better performance in most cases, so it may be worth preferring X25519 over prime256v1.

OpenSSL version differences

Among the currently supported OpenSSL library versions there is a major difference among the supported groups in the TLS protocol version 1.3.

There is no support for the finite field DH groups in TLS 1.3 in the OpenSSL 1.1.1 releases. Thus the finite field DH key exchange can be negotiated only in TLS 1.2.

The support for finite field DH groups in TLS 1.3 was added in the OpenSSL 3.0.0 release. By default all the finite field DH groups specified in TLS 1.3 are enabled in OpenSSL 3.0 releases. Thus following the recommendations in this article when these releases are deployed is even more important than before.

OpenSSL configuration

The OpenSSL library configuration file openssl.cnf provides a simple way to configure the supported groups for all the client and server connections and it is available since the OpenSSL 1.1.1 release.

The system default can be later overridden by the configuration of individual applications, but otherwise it provides the default configuration the OpenSSL library will apply to all TLS connections.

To find where the openssl.cnf file is placed you can run:

# openssl version -d
OPENSSLDIR: "/etc/pki/tls"

Unless the configuration file already contains the openssl_conf value we have to add somewhere at the beginning:

openssl_conf = openssl_init

In the openssl_init section or the section named in the existing openssl_conf value we will add ssl_conf value unless it is there already.

[openssl_init]
ssl_conf = ssl_module

In the ssl_module section or the section named in the existing ssl_conf value we will add system_default value unless it is there already.

[ssl_module]
system_default = tls_system_default

Finally, in the tls_system_default section or the section named in the existing system_default value we can specify the supported groups.

[tls_system_default]
Groups = x25519:prime256v1:x448:secp521r1:secp384r1:ffdhe2048:ffdhe3072

The above configuration keeps support for the 2048 and 3072 bit finite field DH groups to allow connecting clients that do not support elliptic curve groups. Such configuration should be compatible with any reasonable client or server.

Please note that the above configuration is applicable only to OpenSSL 3.0 as finite field DH groups are not available in OpenSSL 1.1.1.

To keep only the least CPU intensive groups with the security level of at least 128 bits you can use:

[tls_system_default]
Groups = x25519:prime256v1
SSLCipherSuite = DEFAULT:!kDHE

The SSLCipherSuite setting is needed to disable the support for the finite field DH key exchange in TLS 1.2.

If the 256 bit security level needs to be supported we can add the x448 and secp521r1 groups. The secp384r1 group computations are usually slower due to missing optimizations thus there is no reason to add it.

Apache HTTP server configuration

Instead of configuring the system defaults for the OpenSSL library we can configure the individual TLS server applications.

The most restricted and efficient configuration of the Apache HTTP server would look like this:

SSLOpenSSLConfCmd Groups x25519:secp256r1
SSLCipherSuite DEFAULT:!kDHE

NGINX HTTP server configuration

Similarly to the above the most restricted configuration for NGINX would look like this:

ssl_ciphers DEFAULT:!kDHE;
ssl_ecdh_curve x25519:secp256r1;