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";