diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-01-08 15:28:37 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-01-08 17:33:05 -0800 |
| commit | c5b5bd910507520f7974a156a1de9d187f23bc2f (patch) | |
| tree | 9766716c795d88fe902c7196696c1389d76717ba /src/platform/posix/posix_rand.c | |
| parent | 4b166dd8ae417b818a5ba214d8f2e648ac1d5be9 (diff) | |
| download | nng-c5b5bd910507520f7974a156a1de9d187f23bc2f.tar.gz nng-c5b5bd910507520f7974a156a1de9d187f23bc2f.tar.bz2 nng-c5b5bd910507520f7974a156a1de9d187f23bc2f.zip | |
New ISAAC pRNG. This replaces other local hacks for random data.
Platforms must seed the pRNGs by offering an nni_plat_seed_prng()
routine. Implementations for POSIX using various options (including
the /dev/urandom device) are supplied.
Diffstat (limited to 'src/platform/posix/posix_rand.c')
| -rw-r--r-- | src/platform/posix/posix_rand.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/platform/posix/posix_rand.c b/src/platform/posix/posix_rand.c new file mode 100644 index 00000000..65d1c031 --- /dev/null +++ b/src/platform/posix/posix_rand.c @@ -0,0 +1,86 @@ +// +// Copyright 2017 Garrett D'Amore <garrett@damore.org> +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +// POSIX clock stuff. +#include "core/nng_impl.h" + +#ifdef PLATFORM_POSIX_RANDOM + +#include <time.h> +#include <errno.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> +#include <sys/utsname.h> +#include <fcntl.h> + +#ifdef NNG_USE_GETRANDOM +#include <linux/random.h> +#endif + +#ifdef NNG_USE_GETENTROPY +#include <sys/random.h> +#endif + +// This structure represents the very barest minimum that we can use as +// a source of entropy. We mix these into our initial entropy, but really +// really really you want to have more data than this available, especially +// for cryptographic applications. +struct nni_plat_prng_x { + nni_time now; + pid_t pid; + uid_t uid; + struct utsname uts; +}; + +void +nni_plat_seed_prng(void *buf, size_t bufsz) +{ + struct nni_plat_prng_x x; + int i; + +#if defined(NNG_USE_GETRANDOM) + // Latest Linux has a nice API here. + (void) getrandom(buf, bufsz, 0); +#elif defined(NNG_USE_GETENTROPY) + // Modern BSD systems prefer this, but can only generate 256 bytes + (void) getentropy(buf, bufsz > 256 ? 256 : 0); +#elif defined(NNG_USE_ARC4RANDOM) + // This uses BSD style pRNG seeded from the kernel in libc. + (void) arc4random_buf(buf, bufsz); +#elif defined(NNG_USE_DEVURANDOM) + // The historic /dev/urandom device. This is not as a good as + // a system call, since file descriptor attacks are possible, + // and it may need special permissions. We choose /dev/urandom + // over /dev/random to avoid diminishing the system entropy. + int fd; + + if ((fd = open("/dev/urandom", O_RDONLY)) >= 0) { + (void) read(fd, buf, buffz); + (void) close(fd); + } +#endif + + // As a speical extra guard, let's mixin the data from the + // following system calls. This ensures that even on the most + // limited of systems, we have at least *some* level of randomness. + // The mixing is done in a way to avoid diminishing entropy we may + // have already collected. + x.now = nni_clock(); + x.pid = getpid(); + x.uid = getuid(); + uname(&x.uts); + + for (i = 0; (i < bufsz) && (i < sizeof (x)); i++) { + ((uint8_t *) buf)[i] ^= ((uint8_t *) &x)[i]; + } +} + + +#endif // PLATFORM_POSIX_RANDOM |
