diff options
Diffstat (limited to 'util/libreboot-utils/lib/rand.c')
| -rw-r--r-- | util/libreboot-utils/lib/rand.c | 69 |
1 files changed, 35 insertions, 34 deletions
diff --git a/util/libreboot-utils/lib/rand.c b/util/libreboot-utils/lib/rand.c index 082612d6..bf090b43 100644 --- a/util/libreboot-utils/lib/rand.c +++ b/util/libreboot-utils/lib/rand.c @@ -4,31 +4,30 @@ * Random number generation */ -#ifndef RAND_H -#define RAND_H - +#if defined(USE_ARC4) && \ + ((USE_ARC4) > 0) +#define _DEFAULT_SOURCE 1 /* for arc4random on *linux* */ + /* (not needed on bsd - on bsd, + it is used automatically unless + overridden with USE_URANDOM */ +#elif defined(USE_URANDOM) && \ + ((USE_URANDOM) > 0) +#include <fcntl.h> /* if not arc4random: /dev/urandom */ +#elif defined(__linux__) && \ + !(defined(USE_ARC4) && ((USE_ARC4) > 0)) #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif +#include <sys/syscall.h> +#include <sys/random.h> +#endif #ifdef __OpenBSD__ #include <sys/param.h> #endif #include <sys/types.h> -#ifndef USE_URANDOM -#define USE_URANDOM 0 -#endif - #include <errno.h> -#if defined(USE_URANDOM) && \ - ((USE_URANDOM) > 0) -#include <fcntl.h> /* if not arc4random: /dev/urandom */ -#elif defined(__linux__) -#include <sys/random.h> -#include <sys/syscall.h> -#endif - #include <fcntl.h> #include <limits.h> #include <stddef.h> @@ -139,10 +138,15 @@ rset(void *buf, size_t n) if (n == 0) exitf("rset: zero-byte request"); -#if (defined(__OpenBSD__) || defined(__FreeBSD__) || \ +/* on linux, getrandom is recommended, + but you can pass -DUSE_ARC4=1 to use arc4random. + useful for portability testing from linux. + */ +#if (defined(USE_ARC4) && ((USE_ARC4) > 0)) || \ + ((defined(__OpenBSD__) || defined(__FreeBSD__) || \ defined(__NetBSD__) || defined(__APPLE__) || \ defined(__DragonFly__)) && !(defined(USE_URANDOM) && \ - ((USE_URANDOM) > 0)) + ((USE_URANDOM) > 0))) arc4random_buf(buf, n); #else @@ -152,35 +156,37 @@ retry_rand: { #if defined(USE_URANDOM) && \ ((USE_URANDOM) > 0) - ssize_t rc; + ssize_t rval; int fd = -1; open_file_on_eintr("/dev/urandom", &fd, O_RDONLY, 0400, NULL); while (rw_retry(saved_errno, - rc = read_on_eintr(fd, - (unsigned char *)buf + off, n - off, 0))); + rval = rw(fd, (unsigned char *)buf + off, n - off, 0, IO_READ))); #elif defined(__linux__) - long rc; + long rval; while (sys_retry(saved_errno, - rc = syscall(SYS_getrandom, + rval = syscall(SYS_getrandom, (unsigned char *)buf + off, n - off, 0))); #else #error Unsupported operating system (possibly unsecure randomisation) #endif - if (rc < 0) - goto err; /* syscall fehler */ - - if (rc == 0) - goto err; /* prevent infinite loop on fatal err */ + if (rval < 0 || /* syscall fehler */ + rval == 0) { /* prevent infinite loop on fatal err */ +#if defined(USE_URANDOM) && \ + ((USE_URANDOM) > 0) + xclose(&fd); +#endif + goto err; + } - if ((off += (size_t)rc) < n) + if ((off += (size_t)rval) < n) goto retry_rand; #if defined(USE_URANDOM) && \ ((USE_URANDOM) > 0) - close_on_eintr(&fd); + xclose(&fd); #endif } @@ -188,12 +194,7 @@ retry_rand: { reset_caller_errno(0); return; err: -#if defined(USE_URANDOM) && \ - ((USE_URANDOM) > 0) - close_on_eintr(&fd); -#endif (void) with_fallback_errno(ECANCELED); exitf("Randomisierungsfehler"); exit(EXIT_FAILURE); } -#endif |
