summaryrefslogtreecommitdiffstats
path: root/contrib/unbound/util/random.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/unbound/util/random.c')
-rw-r--r--contrib/unbound/util/random.c150
1 files changed, 20 insertions, 130 deletions
diff --git a/contrib/unbound/util/random.c b/contrib/unbound/util/random.c
index 8a24ff0..71f0ba5 100644
--- a/contrib/unbound/util/random.c
+++ b/contrib/unbound/util/random.c
@@ -61,11 +61,8 @@
#include "util/random.h"
#include "util/log.h"
#include <time.h>
-#ifdef HAVE_SSL
-#include <openssl/rand.h>
-#include <openssl/rc4.h>
-#include <openssl/err.h>
-#elif defined(HAVE_NSS)
+
+#ifdef HAVE_NSS
/* nspr4 */
#include "prerror.h"
/* nss3 */
@@ -79,147 +76,41 @@
*/
#define MAX_VALUE 0x7fffffff
-#ifdef HAVE_SSL
-/**
- * Struct with per-thread random state.
- * Keeps SSL types away from the header file.
- */
-struct ub_randstate {
- /** key used for arc4random generation */
- RC4_KEY rc4;
- /** keeps track of key usage */
- int rc4_ready;
-};
-
-/** Size of key to use (must be multiple of 8) */
-#define SEED_SIZE 24
-
-/** Number of bytes to reseed after */
-#define REKEY_BYTES (1 << 24)
-
-/* (re)setup system seed */
+#ifndef HAVE_NSS
void
-ub_systemseed(unsigned int seed)
+ub_systemseed(unsigned int ATTR_UNUSED(seed))
{
- /* RAND_ is threadsafe, by the way */
- if(!RAND_status()) {
- /* try to seed it */
- unsigned char buf[256];
- unsigned int v = seed;
- size_t i;
- for(i=0; i<256/sizeof(seed); i++) {
- memmove(buf+i*sizeof(seed), &v, sizeof(seed));
- v = v*seed + (unsigned int)i;
- }
- RAND_seed(buf, 256);
- if(!RAND_status()) {
- log_err("Random generator has no entropy "
- "(error %ld)", ERR_get_error());
- } else {
- verbose(VERB_OPS, "openssl has no entropy, "
- "seeding with time and pid");
- }
- }
-}
-
-/** reseed random generator */
-static void
-ub_arc4random_stir(struct ub_randstate* s, struct ub_randstate* from)
-{
- /* not as unsigned char, but longerint so that it is
- aligned properly on alignment sensitive platforms */
- uint64_t rand_buf[SEED_SIZE/sizeof(uint64_t)];
- int i;
-
- memset(&s->rc4, 0, sizeof(s->rc4));
- memset(rand_buf, 0xc, sizeof(rand_buf));
- if (from) {
- uint8_t* rbuf = (uint8_t*)rand_buf;
- for(i=0; i<SEED_SIZE; i++)
- rbuf[i] = (uint8_t)ub_random(from);
- } else {
- if(!RAND_status())
- ub_systemseed((unsigned)getpid()^(unsigned)time(NULL));
- if (RAND_bytes((unsigned char*)rand_buf,
- (int)sizeof(rand_buf)) <= 0) {
- /* very unlikely that this happens, since we seeded
- * above, if it does; complain and keep going */
- log_err("Couldn't obtain random bytes (error %ld)",
- ERR_get_error());
- s->rc4_ready = 256;
- return;
- }
- }
-#ifdef HAVE_FIPS_MODE
- if(FIPS_mode()) {
- /* RC4 is not allowed, get some trustworthy randomness */
- /* double certainty here, this routine should not be
- * called in FIPS_mode */
- memset(rand_buf, 0, sizeof(rand_buf));
- s->rc4_ready = REKEY_BYTES;
- return;
- }
-#endif /* FIPS_MODE */
- RC4_set_key(&s->rc4, SEED_SIZE, (unsigned char*)rand_buf);
-
- /*
- * Discard early keystream, as per recommendations in:
- * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
- */
- for(i = 0; i <= 256; i += sizeof(rand_buf))
- RC4(&s->rc4, sizeof(rand_buf), (unsigned char*)rand_buf,
- (unsigned char*)rand_buf);
-
- memset(rand_buf, 0, sizeof(rand_buf));
-
- s->rc4_ready = REKEY_BYTES;
+ /* arc4random_uniform does not need seeds, it gets kernel entropy */
}
struct ub_randstate*
-ub_initstate(unsigned int seed, struct ub_randstate* from)
+ub_initstate(unsigned int ATTR_UNUSED(seed),
+ struct ub_randstate* ATTR_UNUSED(from))
{
- struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s));
+ struct ub_randstate* s = (struct ub_randstate*)malloc(1);
if(!s) {
log_err("malloc failure in random init");
return NULL;
}
- ub_systemseed(seed);
-#ifdef HAVE_FIPS_MODE
- if(!FIPS_mode())
-#endif
- ub_arc4random_stir(s, from);
return s;
}
long int
-ub_random(struct ub_randstate* s)
+ub_random(struct ub_randstate* ATTR_UNUSED(s))
{
- unsigned int r = 0;
-#ifdef HAVE_FIPS_MODE
- if(FIPS_mode()) {
- /* RC4 is not allowed, get some trustworthy randomness */
- /* we use pseudo bytes: it tries to return secure randomness
- * but returns 'something' if that fails. We need something
- * else if it fails, because we cannot block here */
- if(RAND_pseudo_bytes((unsigned char*)&r, (int)sizeof(r))
- == -1) {
- log_err("FIPSmode, no arc4random but RAND failed "
- "(error %ld)", ERR_get_error());
- }
- return (long int)((r) % (((unsigned)MAX_VALUE + 1)));
- }
-#endif /* FIPS_MODE */
- if (s->rc4_ready <= 0) {
- ub_arc4random_stir(s, NULL);
- }
+ /* This relies on MAX_VALUE being 0x7fffffff. */
+ return (long)arc4random() & MAX_VALUE;
+}
- RC4(&s->rc4, sizeof(r),
- (unsigned char *)&r, (unsigned char *)&r);
- s->rc4_ready -= sizeof(r);
- return (long int)((r) % (((unsigned)MAX_VALUE + 1)));
+long int
+ub_random_max(struct ub_randstate* state, long int x)
+{
+ (void)state;
+ /* on OpenBSD, this does not need _seed(), or _stir() calls */
+ return (long)arc4random_uniform((uint32_t)x);
}
-#elif defined(HAVE_NSS)
+#else
/* not much to remember for NSS since we use its pk11_random, placeholder */
struct ub_randstate {
@@ -253,8 +144,6 @@ long int ub_random(struct ub_randstate* ATTR_UNUSED(state))
return x & MAX_VALUE;
}
-#endif /* HAVE_SSL or HAVE_NSS */
-
long int
ub_random_max(struct ub_randstate* state, long int x)
{
@@ -266,6 +155,7 @@ ub_random_max(struct ub_randstate* state, long int x)
v = ub_random(state);
return (v % x);
}
+#endif /* HAVE_NSS */
void
ub_randfree(struct ub_randstate* s)
OpenPOWER on IntegriCloud