diff --git a/configure.ac b/configure.ac index 214a7d421d..7e8d56fa9a 100644 --- a/configure.ac +++ b/configure.ac @@ -324,6 +324,8 @@ DOVECOT_FDATASYNC DOVECOT_LIBCAP DOVECOT_LIBWRAP +DOVECOT_ARC4RANDOM + AC_DEFINE(PACKAGE_WEBPAGE, "http://www.dovecot.org/", [Support URL]) dnl * after -lsocket and -lnsl tests, inet_aton() may be in them diff --git a/m4/arc4random.m4 b/m4/arc4random.m4 new file mode 100644 index 0000000000..a4540c6ec1 --- /dev/null +++ b/m4/arc4random.m4 @@ -0,0 +1,11 @@ +AC_DEFUN([DOVECOT_ARC4RANDOM], [ + AC_CHECK_FUNC([arc4random], [ + AC_DEFINE([HAVE_ARC4RANDOM], [1], [Define this if you arc4random()]) + ], [ + AC_CHECK_LIB([bsd], [arc4random], [ + LIBS="$LIBS -lbsd" + AC_DEFINE([HAVE_ARC4RANDOM], [1], [Define this if you arc4random()]) + AC_DEFINE([HAVE_LIBBSD], [1], [Define this if you have libbsd]) + ]) + ]) +]) diff --git a/src/lib/rand.c b/src/lib/rand.c index bdcf6795de..1c338e2b3f 100644 --- a/src/lib/rand.c +++ b/src/lib/rand.c @@ -31,3 +31,14 @@ void rand_set_seed(unsigned int s) srand(seed); } + +#ifdef HAVE_ARC4RANDOM +#ifdef HAVE_LIBBSD +#include +#endif + +/* this returns [0,RAND_MAX), to keep it compatible with rand() */ +int arc4random_rand(void) { + return (int)(arc4random() % ((unsigned)RAND_MAX + 1)); +} +#endif diff --git a/src/lib/rand.h b/src/lib/rand.h index 4382af687b..b0de58f514 100644 --- a/src/lib/rand.h +++ b/src/lib/rand.h @@ -16,4 +16,11 @@ unsigned int rand_get_last_seed(void); /* Actually seed the prng (could add char* for name of function?) */ void rand_set_seed(unsigned int s); +#ifdef HAVE_ARC4RANDOM + +int arc4random_rand(void); +#define rand arc4random_rand + +#endif + #endif diff --git a/src/lib/randgen.c b/src/lib/randgen.c index d3e321e05f..ff73cb4868 100644 --- a/src/lib/randgen.c +++ b/src/lib/randgen.c @@ -61,6 +61,18 @@ void random_deinit(void) i_close_fd(&urandom_fd); } +#ifdef HAVE_ARC4RANDOM +#ifdef HAVE_LIBBSD +#include +#endif + +void random_fill_weak(void *buf, size_t size) +{ + arc4random_buf(buf, size); +} + +#else + void random_fill_weak(void *buf, size_t size) { unsigned char *cbuf = buf; @@ -68,3 +80,5 @@ void random_fill_weak(void *buf, size_t size) for (; size > 0; size--) *cbuf++ = (unsigned char)rand(); } + +#endif