From: Zbigniew Jędrzejewski-Szmek Date: Sun, 25 Jun 2017 21:32:53 +0000 (-0400) Subject: basic/random-util: use most of the pseudorandom bytes from rand() X-Git-Tag: v234~58^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a06b1a5d9d6a05404ea6ace739d39e6256968c3;p=thirdparty%2Fsystemd.git basic/random-util: use most of the pseudorandom bytes from rand() The only implementation that we care about — glibc — provides us with 31 bits of entropy. Let's use 24 bits of that, instead of throwing all but 8 away. --- diff --git a/src/basic/random-util.c b/src/basic/random-util.c index b216be579d2..b2ca2cc8e31 100644 --- a/src/basic/random-util.c +++ b/src/basic/random-util.c @@ -121,19 +121,44 @@ void initialize_srand(void) { srand_called = true; } -void random_bytes(void *p, size_t n) { +/* INT_MAX gives us only 31 bits, so use 24 out of that. */ +#if RAND_MAX >= INT_MAX +# define RAND_STEP 3 +#else +/* SHORT_INT_MAX or lower gives at most 15 bits, we just just 8 out of that. */ +# define RAND_STEP 1 +#endif + +void pseudorandom_bytes(void *p, size_t n) { uint8_t *q; + + initialize_srand(); + + for (q = p; q < (uint8_t*) p + n; q += RAND_STEP) { + unsigned rr; + + rr = (unsigned) rand(); + +#if RAND_STEP >= 3 + if (q - (uint8_t*) p + 2 < n) + q[2] = rr >> 16; +#endif +#if RAND_STEP >= 2 + if (q - (uint8_t*) p + 1 < n) + q[1] = rr >> 8; +#endif + q[0] = rr; + } +} + +void random_bytes(void *p, size_t n) { int r; r = dev_urandom(p, n); if (r >= 0) return; - /* If some idiot made /dev/urandom unavailable to us, he'll - * get a PRNG instead. */ - - initialize_srand(); - - for (q = p; q < (uint8_t*) p + n; q ++) - *q = rand(); + /* If some idiot made /dev/urandom unavailable to us, or the + * kernel has no entropy, use a PRNG instead. */ + return pseudorandom_bytes(p, n); } diff --git a/src/basic/random-util.h b/src/basic/random-util.h index 3cee4c50140..294ef4d4e50 100644 --- a/src/basic/random-util.h +++ b/src/basic/random-util.h @@ -23,6 +23,7 @@ #include int dev_urandom(void *p, size_t n); +void pseudorandom_bytes(void *p, size_t n); void random_bytes(void *p, size_t n); void initialize_srand(void);