ssl-params: slow startup (patch for consideration)

Joseph Tam jtam.home at
Wed Nov 4 01:24:37 UTC 2015

Based on the recent found weaknesses in DH key exchange,

I increased ssl_dh_parameters_length to 2048 bits, and found waited
for 5+ minutes for dovecot to come back online after a restart.
Unless you got a fast machine, the initialization of DH parameters can
exceed your patience.

Regeneration may not be a problem (if ssl_parameters_regenerate=0 or if
Dovecot uses old parameters until regeneration finishes), but for cold
starts, the server can be tied up for a few minutes creating DH parameters
while clients queue up.

I ran "openssl dhparam 2048" and got wildly varying run times of 1m45s,
11m56s, 0.4s, 2m19s, 3h23s.  Most of the time was spent testing primality
of candidate p *and* (p-1)/2 -- so called "safe prime".  If you're
unlucky, this can take a long time.

However, it appears "safe" primes are not what they're cracked up to be
-- they offer some guarantees, but are not safer than non-safe primes.
Creating DH parameters without requiring primality of (p-1)/2 (i.e. what
"openssl dhparam -dsaparam" does) results in much lower run-time bounds.

I cribbed some OpenSSL code to create this (untested) patch.

--- iostream-openssl-params.c~	Tue Nov  3 16:08:38 2015
+++ iostream-openssl-params.c	Tue Nov  3 15:43:39 2015
@@ -6,5 +6,2 @@

-/* 2 or 5. Haven't seen their difference explained anywhere, but 2 is the
-   default.. */
-#define DH_GENERATOR 2

@@ -14,2 +11,3 @@
  	DH *dh;
+	DSA *dsa;
  	unsigned char *p;
@@ -17,3 +15,13 @@

-	dh = DH_generate_parameters(bitsize, DH_GENERATOR, NULL, NULL);
+	dsa = DSA_generate_parameters(bitsize, NULL, 0, NULL, NULL, NULL, NULL);
+	if (dsa == NULL) {
+		*error_r = t_strdup_printf(
+			"DSA_generate_parameters(bits=%d) failed: %s",
+			bitsize, openssl_iostream_error());
+		return -1;
+	}
+	dh = DSA_dup_DH(dsa);
+	DSA_free(dsa);
  	if (dh == NULL) {
@@ -20,4 +28,4 @@
  		*error_r = t_strdup_printf(
-			"DH_generate_parameters(bits=%d, gen=%d) failed: %s",
-			bitsize, DH_GENERATOR, openssl_iostream_error());
+			"DSA_dup_DH() failed: %s",
+			openssl_iostream_error());
  		return -1;

The other way to prevent long startup times is to pre-compute the DH
parameter using "openssl dhparam -out dh2048.pem 2048".  I can contribute
a patch to do this (read file, convert it into ssl-parameters.dat, then
set/behave like ssl_parameters_regenerate=0), but I couldn't figure
out the best place to do this. ssl_params_if_unchanged()?

Joseph Tam <jtam.home at>

More information about the dovecot mailing list