diff options
-rw-r--r-- | misc/unix/rand.c | 132 |
1 files changed, 69 insertions, 63 deletions
diff --git a/misc/unix/rand.c b/misc/unix/rand.c index c0f02eca7..24221c8ca 100644 --- a/misc/unix/rand.c +++ b/misc/unix/rand.c @@ -111,69 +111,7 @@ APR_DECLARE(apr_status_t) apr_os_uuid_get(unsigned char *uuid_data) APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char *buf, apr_size_t length) { -#if defined(USE_GETRANDOM) - - do { - int rc; - - rc = getrandom(buf, length, GRND_NONBLOCK); - if (rc == -1) { - if (errno == EINTR) { - continue; - } - return errno; - } - - buf += rc; - length -= rc; - } while (length > 0); - -#elif defined(HAVE_ARC4RANDOM) - - arc4random_buf(buf, length); - -#elif defined(DEV_RANDOM) - - int fd = -1; - - /* On BSD/OS 4.1, /dev/random gives out 8 bytes at a time, then - * gives EOF, so reading 'length' bytes may require opening the - * device several times. */ - do { - apr_ssize_t rc; - - if (fd == -1) - if ((fd = open(DEV_RANDOM, O_RDONLY)) == -1) - return errno; - - do { - rc = read(fd, buf, length); - } while (rc == -1 && errno == EINTR); - - if (rc < 0) { - int errnum = errno; - close(fd); - return errnum; - } - else if (rc == 0) { - close(fd); - fd = -1; /* force open() again */ - } - else { - buf += rc; - length -= rc; - } - } while (length > 0); - - close(fd); -#elif defined(OS2) - static UCHAR randbyte(); - unsigned int idx; - - for (idx=0; idx<length; idx++) - buf[idx] = randbyte(); - -#elif defined(HAVE_EGD) +#if defined(HAVE_EGD) /* use EGD-compatible socket daemon (such as EGD or PRNGd). * message format: * 0x00 (get entropy level) @@ -269,6 +207,70 @@ APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char *buf, return bad_errno; } +#elif defined(USE_GETRANDOM) + + do { + int rc; + + rc = getrandom(buf, length, GRND_NONBLOCK); + if (rc == -1) { + if (errno == EINTR) { + continue; + } + return errno; + } + + buf += rc; + length -= rc; + } while (length > 0); + +#elif defined(HAVE_ARC4RANDOM) + + arc4random_buf(buf, length); + +#elif defined(DEV_RANDOM) + + int fd = -1; + + /* On BSD/OS 4.1, /dev/random gives out 8 bytes at a time, then + * gives EOF, so reading 'length' bytes may require opening the + * device several times. */ + do { + apr_ssize_t rc; + + if (fd == -1) + if ((fd = open(DEV_RANDOM, O_RDONLY)) == -1) + return errno; + + do { + rc = read(fd, buf, length); + } while (rc == -1 && errno == EINTR); + + if (rc < 0) { + int errnum = errno; + close(fd); + return errnum; + } + else if (rc == 0) { + close(fd); + fd = -1; /* force open() again */ + } + else { + buf += rc; + length -= rc; + } + } while (length > 0); + + close(fd); + +#elif defined(OS2) + + static UCHAR randbyte(); + unsigned int idx; + + for (idx=0; idx<length; idx++) + buf[idx] = randbyte(); + #elif defined(HAVE_TRUERAND) /* use truerand */ extern int randbyte(void); /* from the truerand library */ @@ -280,6 +282,10 @@ APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char *buf, for (idx=0; idx<length; idx++) buf[idx] = (unsigned char) randbyte(); +#else + +#error APR_HAS_RANDOM defined with no implementation + #endif /* DEV_RANDOM */ return APR_SUCCESS; |