15

I recently generated some custom Diffie-Hellman parameters which are basically just long (in the below case 4096 bit) primes. Those are then used in the key exchange process.

I used the following command:

openssl dhparam -rand – 4096

Now I really wonder what OpenSSL actually does if I do not generate these parameters on my own.

As the generation took roughly 2 hours it cannot be something that is generated on the fly - at least not of equal strength? So I wonder, is there a standard configuration or what does OpenSSL actually do in this case? (I couldn't find much clear and helpful information yet)

I also wonder how much the increased security actually is comparing the standard with self generated primes, what is the difference in length of the primes.

Thanks


Update 15.06.2015

Looks like it makes sense to generate your own DH params:

Bruno Rohée
  • 5,221
  • 28
  • 39
binaryanomaly
  • 1,291
  • 3
  • 13
  • 21

1 Answers1

20

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.

Tom Leek
  • 168,808
  • 28
  • 337
  • 475
  • Nginx obviously also uses predefined 1024-bit parameters to feed openssl, as I was able to find in the source in `ngx_event_openssl.c` and here in the forum: http://forum.nginx.org/read.php?2,245335,245368 – binaryanomaly Apr 20 '14 at 15:28
  • 1
    Interesting is also the following sentence in the OpenSSL Documentation: `The risk in reusing DH parameters is that an attacker may specialize on a very often used DH group. Applications should therefore generate their own DH parameters during the installation process using the openssl dhparam(1) application.` Which means that if an institution specializes on the out of the box implementation apache and nginx should probably considered insecure with the standard parameters. I think this is not so well known and understood? – binaryanomaly Apr 20 '14 at 19:47
  • 1
    The warning in the documentation is only theoretical. When you try to break discrete logarithm modulo a prime _p_, the first attempt is very expensive, but subsequent breaks _modulo the same prime_ are much cheaper (you can reuse big parts of the inner attack results). This is the "specialization" they are talking about. However, a 1024-bit modulus appears to be quite beyond the technologically feasible (current record is 530 bits) so even that "first attempt" is out of reach. – Tom Leek Apr 21 '14 at 11:21
  • OpenSSL also contains copies of the RFC 2409/3526 parameters in `crypto/bn/bn_const.c`. Apache dev [seems to be using them](https://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_init.c?view=markup&pathrev=1598107#l50) rather than making *another* copy. – Matt Nordhoff Jun 02 '14 at 08:32
  • 1
    https://weakdh.org/imperfect-forward-secrecy.pdf – Michael Hampton May 20 '15 at 06:24
  • As the very same bear later said in https://security.stackexchange.com/questions/95178/ and https://security.stackexchange.com/questions/42415/ OpenSSL _does_ have an option to generate DSA-style (smaller q) parameters for DH. – dave_thompson_085 May 24 '22 at 01:15