diff --git a/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c b/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c index 618ec81e..b71ce7e1 100644 --- a/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c +++ b/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c @@ -7,6 +7,7 @@ #endif #ifdef __linux__ # include +# include #endif #include @@ -128,6 +129,33 @@ safe_read(const int fd, void * const buf_, size_t size) #endif #ifndef _WIN32 +# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) +static int +randombytes_block_on_dev_random(void) +{ + struct pollfd pfd; + int fd; + int pret; + + fd = open("/dev/random", O_RDONLY); + if (fd == -1) { + return 0; + } + pfd.fd = fd; + pfd.events = POLLIN; + pfd.revents = 0; + do { + pret = poll(&pfd, 1, -1); + } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); + if (pret != 1) { + (void) close(fd); + errno = EIO; + return -1; + } + return close(fd); +} +# endif + # ifndef HAVE_SAFE_ARC4RANDOM static int randombytes_salsa20_random_random_dev_open(void) @@ -143,6 +171,11 @@ randombytes_salsa20_random_random_dev_open(void) const char ** device = devices; int fd; +# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) + if (randombytes_block_on_dev_random() != 0) { + return -1; + } +# endif do { fd = open(*device, O_RDONLY); if (fd != -1) { diff --git a/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c b/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c index 62b1c760..f9277ae5 100644 --- a/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c +++ b/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c @@ -7,6 +7,7 @@ #endif #ifdef __linux__ # include +# include #endif #include @@ -107,6 +108,33 @@ safe_read(const int fd, void * const buf_, size_t size) #endif #ifndef _WIN32 +# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) +static int +randombytes_block_on_dev_random(void) +{ + struct pollfd pfd; + int fd; + int pret; + + fd = open("/dev/random", O_RDONLY); + if (fd == -1) { + return 0; + } + pfd.fd = fd; + pfd.events = POLLIN; + pfd.revents = 0; + do { + pret = poll(&pfd, 1, -1); + } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); + if (pret != 1) { + (void) close(fd); + errno = EIO; + return -1; + } + return close(fd); +} +# endif + static int randombytes_sysrandom_random_dev_open(void) { @@ -121,6 +149,11 @@ randombytes_sysrandom_random_dev_open(void) const char ** device = devices; int fd; +# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) + if (randombytes_block_on_dev_random() != 0) { + return -1; + } +# endif do { fd = open(*device, O_RDONLY); if (fd != -1) {