Index: libgcrypt-1.8.0/random/rndlinux.c =================================================================== --- libgcrypt-1.8.0.orig/random/rndlinux.c 2017-07-21 17:45:39.193291437 +0200 +++ libgcrypt-1.8.0/random/rndlinux.c 2017-07-21 17:48:44.539152641 +0200 @@ -40,7 +40,9 @@ #include "g10lib.h" #include "rand-internal.h" -static int open_device (const char *name, int retry); +#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed" + +static int open_device (const char *name, int retry, int fatal); static int @@ -63,7 +65,7 @@ set_cloexec_flag (int fd) * a fatal error but retries until it is able to reopen the device. */ static int -open_device (const char *name, int retry) +open_device (const char *name, int retry, int fatal) { int fd; @@ -71,6 +73,8 @@ open_device (const char *name, int retry _gcry_random_progress ("open_dev_random", 'X', 1, 0); again: fd = open (name, O_RDONLY); + if (fd == -1 && !fatal) + return fd; if (fd == -1 && retry) { struct timeval tv; @@ -115,6 +119,7 @@ _gcry_rndlinux_gather_random (void (*add { static int fd_urandom = -1; static int fd_random = -1; + static int fd_configured = -1; static int only_urandom = -1; static unsigned char ever_opened; int fd; @@ -150,6 +155,11 @@ _gcry_rndlinux_gather_random (void (*add close (fd_urandom); fd_urandom = -1; } + if (fd_configured != -1) + { + close (fd_configured); + fd_configured = -1; + } return 0; } @@ -190,11 +200,21 @@ _gcry_rndlinux_gather_random (void (*add that we always require the device to be existent but want a more graceful behaviour if the rarely needed close operation has been used and the device needs to be re-opened later. */ + + if (level == -1) + { + if (fd_configured == -1) + fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0, 0 ); + fd = fd_configured; + if (fd == -1) + return -1; + } + if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom) { if (fd_random == -1) { - fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1)); + fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1); ever_opened |= 1; } fd = fd_random; @@ -203,7 +223,7 @@ _gcry_rndlinux_gather_random (void (*add { if (fd_urandom == -1) { - fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); + fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2), 1); ever_opened |= 2; } fd = fd_urandom;