/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "randgen.h"
#include <unistd.h>
#include <fcntl.h>
#ifdef DEBUG
/* For reproducing tests, fall back onto using a simple deterministic PRNG */
/* Marsaglia's 1999 KISS, de-macro-ified, and with the fixed KISS11 SHR3,
which is clearly what was intended given the "cycle length 2^123" claim. */
static bool kiss_in_use;
static unsigned int kiss_seed;
static void
{
kiss_in_use = TRUE;
}
static unsigned int
kiss_rand(void)
{
}
{
if (!kiss_in_use)
return -1; /* not using a deterministic PRNG, seed is irrelevant */
return 0;
}
#endif
#if defined(HAVE_GETRANDOM) && HAVE_DECL_GETRANDOM != 0
# define USE_GETRANDOM
#elif defined(HAVE_ARC4RANDOM)
# if defined(HAVE_LIBBSD)
# endif
# define USE_ARC4RANDOM
#else
# define USE_RANDOM_DEV
#endif
static int init_refcount = 0;
#if defined(USE_GETRANDOM) || defined(USE_RANDOM_DEV)
static void random_open_urandom(void)
{
if (urandom_fd == -1) {
"currently we require it");
} else {
}
}
}
{
# if defined(USE_GETRANDOM)
if (getrandom_present) {
/* It gets complicated here... While the libc (and its
headers) indicated that getrandom() was available when
we were compiled, the kernel disagreed just now at
}
}
/* this is here to avoid clang complain,
because getrandom_present will be always FALSE
if USE_GETRANDOM is not defined */
if (!getrandom_present)
# endif
if (ret == 0) {
if (getrandom_present) {
i_fatal("getrandom() failed: %m");
} else {
}
}
}
return ret;
}
#endif
{
i_assert(init_refcount > 0);
#ifdef DEBUG
if (kiss_in_use) {
return;
}
#endif
#if defined(USE_ARC4RANDOM)
#else
if (ret > -1)
}
#endif /* defined(USE_ARC4RANDOM) */
}
void random_init(void)
{
/* static analyzer seems to require this */
unsigned int seed = 0;
const char *env_seed;
if (init_refcount++ > 0)
return;
#ifdef DEBUG
/* getrandom_present = FALSE; not needed, only used in random_read() */
goto normal_exit;
}
#else
i_warning("DOVECOT_SRAND is not available in non-debug builds");
#endif /* DEBUG */
#if defined(USE_RANDOM_DEV)
#endif
/* DO NOT REMOVE THIS - It is also
needed to make sure getrandom really works.
*/
#ifdef DEBUG
i_fatal("DOVECOT_SRAND not a number or 'kiss'");
}
#endif
}
void random_deinit(void)
{
if (--init_refcount > 0)
return;
}