The behaviour of OpenSSL, as a library, is documented in the man page for SSL_CTX_set_tmp_dh_callback(). Basically, the library itself contains no pre-generated DH parameters and will refuse to do any "DHE" handshake until such parameters have been provided. The caller (the application which uses OpenSSL for running an SSL server) may provide DH parameters preemptively (either "attached" to the structure containing the server's certificate, or with an explicit SSL_CTX_set_tp_dh()
call), or through a callback function which will be invoked for each relevant handshake. The callback method gives the application the opportunity to modulate the DH parameters, in particular their size, based on the cipher suite and other parameters currently being negotiated (this was important for proper support of the old "export" cipher suites, but is much less relevant nowadays).
OpenSSL, as a piece of C code, also comes with command-line applications. E.g. you can run a SSL server with openssl s_server
. Inspection of the apps/s_server.c
source file shows that, unless overridden with explicit DH parameters (the -dhparam
option, or appended in the server's certificate file), default parameters are used, with a 512-bit modulus (!). The provenance of this modulus is unspecified; but it cannot be considered to be really strong since a 530-bit discrete logarithm has been solved at least once.
Note that the apps/
directory also contains files named dh512.pem
, dh1024.pem
, dh2048.pem
and dh4096.pem
, which are DH parameters of 512, 1024, 2048 and 4096 bits, respectively. These apparently come from SKIP, an old protocol for IPsec-related key management, for which I found an old draft, which indeed contains the 1024-bit and 2048-bit modulus that OpenSSL source code contains as the dh1024.pem
and dh2048.pem
files. Interestingly (or not), the 512-bit modulus used by apps/s_server.c
is NOT the same as the one in dh512.pem
.
Since the parameters are caller-provided, let's see what happens in mod_ssl
, the usual SSL engine for Apache. Let's make the story short: the modulus and generator are hardcoded; they are in the source code, in modules/ssl/ssl_engine_dh.c
. There is a 512-bit modulus, and a 1024-bit modulus. The 512-bit modulus will be used if the server's public key has length 512 bits; the 1024-bit modulus will be used in every other case. So, in practice, it is always the 1024-bit modulus. The source code makes no mention as to how these parameters were generated; they are different from the ones which come with OpenSSL's source code. Apparently the whole World uses that 1024-bit modulus of unknown provenance (at least, the half of the World which relies on Apache+mod_ssl).
We may note that future versions of Apache, starting with the development version 2.5.0-dev as of 2013/09/29, will switch to hardcoded DH parameters of 2048, 3072 and 4096 bits, copied from RFC 3526. These DH parameters are supposed to be efficient (e.g. they use g = 2 as generator, and their 64 most significant and least significant bits are all ones, which may help in some implementations of Montgomery multiplication) and to be "obviously safe". Using DH parameters of more than 1024 bits is known to break poor SSL client implementations, in particular the one which comes with Java up to (and including) Java 7 (Java's SSL implementation is generally fine, but for DHE support it has a 1024-bit limit, which is kinda stupid since Java has a BigInteger
class which is completely up to the task of DHing at larger sizes).
One must say that generating DH parameters needs not be that slow. OpenSSL insists on creating so-called "safe primes", where the "safe" is more marketing than science. A "safe prime" is a prime p such that (p-1)/2 is also a prime. This allows the use of any integer in the 2..p-2 range to be used as generator g, in particular g = 2, which yields a slight performance advantage. On the other hand, producing a safe prime is challenging: roughly speaking, when dealing with 1024-bit integers, only 1/1000th of them are prime, and only 1/1000th of these primes are "safe primes", hence a search loop which tries a million potential values.
Cryptographically speaking, one could also use as DH parameters the same kind of parameters used by DSA: p is prime such that p-1 is a multiple of a much smaller prime q, and g is an integer of order q. These can be generated in much less than 1 second, and will be fine for DH.