vendor/libsodium/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c in rbnacl-libsodium-0.4.5 vs vendor/libsodium/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c in rbnacl-libsodium-0.5.0
- old
+ new
@@ -1,8 +1,9 @@
#include <sys/types.h>
#ifndef _WIN32
+# include <sys/stat.h>
# include <sys/time.h>
#endif
#include <assert.h>
#include <errno.h>
@@ -10,11 +11,10 @@
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#ifndef _WIN32
-# include <poll.h>
# include <unistd.h>
#endif
#include "randombytes.h"
#include "randombytes_sysrandom.h"
@@ -23,10 +23,43 @@
#ifdef _WIN32
# include <windows.h>
# include <wincrypt.h>
#endif
+#ifdef __OpenBSD__
+
+uint32_t
+randombytes_sysrandom(void)
+{
+ return arc4random();
+}
+
+void
+randombytes_sysrandom_stir(void)
+{
+}
+
+uint32_t
+randombytes_sysrandom_uniform(const uint32_t upper_bound)
+{
+ return arc4random_uniform(upper_bound);
+}
+
+void
+randombytes_sysrandom_buf(void * const buf, const size_t size)
+{
+ return arc4random_buf(buf, size);
+}
+
+int
+randombytes_sysrandom_close(void)
+{
+ return 0;
+}
+
+#else /* __OpenBSD__ */
+
typedef struct SysRandom_ {
#ifdef _WIN32
HCRYPTPROV hcrypt_prov;
#endif
int random_data_source_fd;
@@ -43,10 +76,11 @@
safe_read(const int fd, void * const buf_, size_t count)
{
unsigned char *buf = (unsigned char *) buf_;
ssize_t readnb;
+ assert(count > (size_t) 0U);
do {
while ((readnb = read(fd, buf, count)) < (ssize_t) 0 &&
errno == EINTR);
if (readnb < (ssize_t) 0) {
return readnb;
@@ -64,44 +98,53 @@
#ifndef _WIN32
static int
randombytes_sysrandom_random_dev_open(void)
{
- static const char * const devices[] = {
+ struct stat st;
+ static const char *devices[] = {
# ifndef USE_BLOCKING_RANDOM
- "/dev/arandom", "/dev/urandom",
+ "/dev/urandom",
# endif
"/dev/random", NULL
};
- const char * const *device = devices;
+ const char ** device = devices;
+ int fd;
do {
- if (access(*device, F_OK | R_OK) == 0) {
- return open(*device, O_RDONLY);
+ if (access(*device, F_OK | R_OK) == 0 &&
+ (fd = open(*device, O_RDONLY)) != -1) {
+ if (fstat(fd, &st) == 0 && S_ISCHR(st.st_mode)) {
+ return fd;
+ }
+ (void) close(fd);
}
device++;
} while (*device != NULL);
return -1;
}
static void
randombytes_sysrandom_init(void)
{
+ const int errno_save = errno;
+
if ((stream.random_data_source_fd =
randombytes_sysrandom_random_dev_open()) == -1) {
abort();
}
+ errno = errno_save;
}
#else /* _WIN32 */
static void
randombytes_sysrandom_init(void)
{
- if (! CryptAcquireContext(&stream.hcrypt_prov, NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+ if (! CryptAcquireContextW(&stream.hcrypt_prov, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
abort();
}
}
#endif
@@ -164,13 +207,16 @@
#ifndef _WIN32
if (safe_read(stream.random_data_source_fd, buf, size) != (ssize_t) size) {
abort();
}
#else
- if (! CryptGenRandom(stream.hcrypt_prov, size, (BYTE *) buf)) {
+ if (size > 0xffffffff) {
abort();
}
+ if (! CryptGenRandom(stream.hcrypt_prov, (DWORD) size, (BYTE *) buf)) {
+ abort();
+ }
#endif
}
/*
* randombytes_sysrandom_uniform() derives from OpenBSD's arc4random_uniform()
@@ -193,9 +239,11 @@
break;
}
}
return r % upper_bound;
}
+
+#endif
const char *
randombytes_sysrandom_implementation_name(void)
{
return "sysrandom";