From c752eb55d9e9992bc38e7790128953427aa0a89f Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sun, 15 May 2016 17:18:50 +0200 Subject: [PATCH] On ancient Linux kernels, block on /dev/random before using /dev/urandom --- .../salsa20/randombytes_salsa20_random.c | 33 +++++++++++++++++++ .../sysrandom/randombytes_sysrandom.c | 33 +++++++++++++++++++ 2 files changed, 66 insertions(+) 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) {