[Dovecot] [PATCH] OpenSSL RNG initialization

Vilmos Nebehaj vili at huwico.hu
Fri Mar 17 18:28:26 EET 2006


Hi,

dovecot tries to use OpenSSL's PRNG to generate random numbers if
there is no /dev/urandom found. Unfortunately, it is flawed in its  
present
form, since the PRNG is not seeded before RAND_bytes() is called in
src/lib/randgen.c (on systems which have /dev/urandom, OpenSSL
automatically seeds its PRNG from the urandom device).

Here's a patch to address this issue: it tries to seed the PRNG if there
is no /dev/urandom present (which is likely the case if dovecot uses
OpenSSL's RAND API). It can also be fetched from
http://innoidea.com/~vili/dovecot_rng_init.diff

-Vilmos Nebehaj


Index: configure.in
===================================================================
RCS file: /home/cvs/dovecot/configure.in,v
retrieving revision 1.266
diff -u -r1.266 configure.in
--- configure.in	28 Feb 2006 08:36:41 -0000	1.266
+++ configure.in	10 Mar 2006 17:15:01 -0000
@@ -358,7 +358,8 @@
AC_CHECK_FUNCS(fcntl flock lockf inet_aton sigaction getpagesize  
madvise \
                 strcasecmp stricmp vsnprintf vsyslog writev pread \
	       setrlimit setproctitle seteuid setreuid setegid setresgid \
-	       strtoull strtouq setpriority quotactl getmntent kqueue kevent)
+	       strtoull strtouq setpriority quotactl getmntent kqueue kevent \
+           getrusage)
dnl * I/O loop function
have_ioloop=no
Index: src/lib/lib.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib/lib.h,v
retrieving revision 1.20
diff -u -r1.20 lib.h
--- src/lib/lib.h	25 Sep 2005 10:44:04 -0000	1.20
+++ src/lib/lib.h	10 Mar 2006 17:15:02 -0000
@@ -20,6 +20,13 @@
#  include <stdint.h> /* C99 int types, we mostly need uintmax_t */
#endif
+#ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include <sys/resource.h>
+#endif
+
#include "compat.h"
#include "macros.h"
#include "failures.h"
Index: src/lib/randgen.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/randgen.c,v
retrieving revision 1.13
diff -u -r1.13 randgen.c
--- src/lib/randgen.c	6 Jan 2005 19:08:19 -0000	1.13
+++ src/lib/randgen.c	10 Mar 2006 17:15:03 -0000
@@ -81,6 +81,42 @@
	return buf;
}
+static void random_init_rng(void)
+{
+	int counter = 0;
+	struct timeval tv;
+#ifdef HAVE_GETRUSAGE
+	struct rusage ru;
+#endif
+
+	/*
+	 * If the RNG is already seeded, we can return
+	 * immediately.
+	 */
+	if (RAND_status() == 1)
+		return;
+
+	/*
+	 * Else, try to seed it. Unfortunately we don't have
+	 * /dev/urandom, so we can only use weak random sources.
+	 */
+	while (RAND_status() != 1) {
+		if (gettimeofday(&tv, NULL) < 0)
+			i_fatal("gettimeofday() failed: %m");
+		RAND_add((const void *)&tv, sizeof(tv),
+				(double)sizeof(tv) / 2);
+#ifdef HAVE_GETRUSAGE
+		if (getrusage(RUSAGE_SELF, &ru) < 0)
+			i_fatal("getrusage() failed: %m");
+		RAND_add((const void *)&ru, sizeof(ru),
+				(double)sizeof(ru) / 2);
+#endif
+
+		if (counter++ > 100)
+			i_fatal("could not get enough entropy");
+	}
+}
+
void random_fill(void *buf, size_t size)
{
	if (RAND_bytes(buf, size) != 1)
@@ -91,6 +127,8 @@
{
	unsigned int seed;
+	random_init_rng();
+
	random_fill(&seed, sizeof(seed));
	srand(seed);
}



More information about the dovecot mailing list