diff -up libgcrypt-1.8.3/random/random.c.getrandom libgcrypt-1.8.3/random/random.c --- libgcrypt-1.8.3/random/random.c.getrandom 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.3/random/random.c 2018-07-10 15:38:34.303855808 +0200 @@ -110,8 +110,8 @@ _gcry_random_read_conf (void) unsigned int result = 0; fp = fopen (fname, "r"); - if (!fp) - return result; + if (!fp) /* We make only_urandom the default. */ + return RANDOM_CONF_ONLY_URANDOM; for (;;) { diff -up libgcrypt-1.8.3/random/random-csprng.c.getrandom libgcrypt-1.8.3/random/random-csprng.c --- libgcrypt-1.8.3/random/random-csprng.c.getrandom 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.3/random/random-csprng.c 2018-06-14 16:31:04.731179208 +0200 @@ -55,6 +55,10 @@ #ifdef __MINGW32__ #include #endif +#if defined(__linux__) && defined(HAVE_SYSCALL) +# include +# include +#endif #include "g10lib.h" #include "random.h" #include "rand-internal.h" @@ -1116,6 +1120,22 @@ getfnc_gather_random (void))(void (*)(co enum random_origins, size_t, int); #if USE_RNDLINUX +#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) + long ret; + char buffer[1]; + + _gcry_pre_syscall (); + ret = syscall (__NR_getrandom, + (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); + _gcry_post_syscall (); + if (ret != -1 || errno != ENOSYS) + { + fnc = _gcry_rndlinux_gather_random; + return fnc; + } + else + /* The syscall is not supported - fallback to /dev/urandom. */ +#endif if ( !access (NAME_OF_DEV_RANDOM, R_OK) && !access (NAME_OF_DEV_URANDOM, R_OK)) { diff -up libgcrypt-1.8.3/random/rndlinux.c.getrandom libgcrypt-1.8.3/random/rndlinux.c --- libgcrypt-1.8.3/random/rndlinux.c.getrandom 2018-06-14 16:31:04.722178971 +0200 +++ libgcrypt-1.8.3/random/rndlinux.c 2018-07-10 15:55:03.301075155 +0200 @@ -35,6 +35,7 @@ #include #if defined(__linux__) && defined(HAVE_SYSCALL) # include +# include #endif #include "types.h" @@ -204,6 +205,18 @@ _gcry_rndlinux_gather_random (void (*add { if (fd_urandom == -1) { +#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) + long ret; + + _gcry_pre_syscall (); + ret = syscall (__NR_getrandom, + (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); + _gcry_post_syscall (); + if (ret > -1 || errno == EAGAIN || errno == EINTR) + fd_urandom = -2; + else + /* The syscall is not supported - fallback to /dev/urandom. */ +#endif fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); ever_opened |= 2; } @@ -230,7 +243,7 @@ _gcry_rndlinux_gather_random (void (*add * syscall and not a new device and thus we are not able to use * select(2) to have a timeout. */ #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) - if (fd == fd_urandom) + if (fd == -2) { long ret; size_t nbytes; @@ -246,9 +259,7 @@ _gcry_rndlinux_gather_random (void (*add _gcry_post_syscall (); } while (ret == -1 && errno == EINTR); - if (ret == -1 && errno == ENOSYS) - ; /* The syscall is not supported - fallback to /dev/urandom. */ - else + if (1) { /* The syscall is supported. Some sanity checks. */ if (ret == -1) log_fatal ("unexpected error from getrandom: %s\n",