diff options
author | Ronny Chevalier <chevalier.ronny@gmail.com> | 2015-04-10 22:27:10 +0200 |
---|---|---|
committer | Ronny Chevalier <chevalier.ronny@gmail.com> | 2015-04-11 00:11:13 +0200 |
commit | 3df3e884ae1237ef0d4d23b0e80f4ffda95ac135 (patch) | |
tree | 630cb996d0cf23429633e4900826aac56d9271ad /src/shared/util.c | |
parent | 0b452006de98294d1690f045f6ea2f7f6630ec3b (diff) |
shared: add random-util.[ch]
Diffstat (limited to 'src/shared/util.c')
-rw-r--r-- | src/shared/util.c | 96 |
1 files changed, 1 insertions, 95 deletions
diff --git a/src/shared/util.c b/src/shared/util.c index d4753f1ee8..e4c4dd92f1 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -94,6 +94,7 @@ #include "sparse-endian.h" #include "formats-util.h" #include "process-util.h" +#include "random-util.h" /* Put this test here for a lack of better place */ assert_cc(EAGAIN == EWOULDBLOCK); @@ -2387,101 +2388,6 @@ char* dirname_malloc(const char *path) { return dir; } -int dev_urandom(void *p, size_t n) { - static int have_syscall = -1; - - _cleanup_close_ int fd = -1; - int r; - - /* Gathers some randomness from the kernel. This call will - * never block, and will always return some data from the - * kernel, regardless if the random pool is fully initialized - * or not. It thus makes no guarantee for the quality of the - * returned entropy, but is good enough for or usual usecases - * of seeding the hash functions for hashtable */ - - /* Use the getrandom() syscall unless we know we don't have - * it, or when the requested size is too large for it. */ - if (have_syscall != 0 || (size_t) (int) n != n) { - r = getrandom(p, n, GRND_NONBLOCK); - if (r == (int) n) { - have_syscall = true; - return 0; - } - - if (r < 0) { - if (errno == ENOSYS) - /* we lack the syscall, continue with - * reading from /dev/urandom */ - have_syscall = false; - else if (errno == EAGAIN) - /* not enough entropy for now. Let's - * remember to use the syscall the - * next time, again, but also read - * from /dev/urandom for now, which - * doesn't care about the current - * amount of entropy. */ - have_syscall = true; - else - return -errno; - } else - /* too short read? */ - return -ENODATA; - } - - fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); - if (fd < 0) - return errno == ENOENT ? -ENOSYS : -errno; - - return loop_read_exact(fd, p, n, true); -} - -void initialize_srand(void) { - static bool srand_called = false; - unsigned x; -#ifdef HAVE_SYS_AUXV_H - void *auxv; -#endif - - if (srand_called) - return; - - x = 0; - -#ifdef HAVE_SYS_AUXV_H - /* The kernel provides us with a bit of entropy in auxv, so - * let's try to make use of that to seed the pseudo-random - * generator. It's better than nothing... */ - - auxv = (void*) getauxval(AT_RANDOM); - if (auxv) - x ^= *(unsigned*) auxv; -#endif - - x ^= (unsigned) now(CLOCK_REALTIME); - x ^= (unsigned) gettid(); - - srand(x); - srand_called = true; -} - -void random_bytes(void *p, size_t n) { - uint8_t *q; - 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(); -} - void rename_process(const char name[8]) { assert(name); |