From 1e91b6a1f68baea5ffc90dfaa45bb7d4c37bba55 Mon Sep 17 00:00:00 2001 From: Syrone Wong Date: Sun, 19 Mar 2017 17:06:21 +0800 Subject: [PATCH] On Linux, warn when we are running low on entropy Based on https://github.com/jedisct1/dnscrypt-proxy/commit/a255d2908305739b54dafb01ae0285f6016869ab Signed-off-by: Syrone Wong --- configure.ac | 2 +- src/crypto.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6a3e39c2..610175a7 100755 --- a/configure.ac +++ b/configure.ac @@ -138,7 +138,7 @@ AM_CONDITIONAL(BUILD_REDIRECTOR, test "$os_support" = "linux") AM_CONDITIONAL(BUILD_WINCOMPAT, test "$os_support" = "mingw") dnl Checks for header files. -AC_CHECK_HEADERS([limits.h stdint.h inttypes.h arpa/inet.h fcntl.h langinfo.h locale.h netdb.h netinet/in.h stdlib.h string.h strings.h unistd.h sys/ioctl.h]) +AC_CHECK_HEADERS([limits.h stdint.h inttypes.h arpa/inet.h fcntl.h langinfo.h locale.h netdb.h netinet/in.h stdlib.h string.h strings.h unistd.h sys/ioctl.h linux/random.h]) dnl A special check required for on Darwin. See dnl http://www.gnu.org/software/autoconf/manual/html_node/Header-Portability.html. diff --git a/src/crypto.c b/src/crypto.c index 58e583d0..63ab6ff2 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -24,6 +24,13 @@ #include "config.h" #endif +#if defined(__linux__) && defined(HAVE_LINUX_RANDOM_H) +# include +# include +# include +# include +#endif + #include #include #include @@ -99,11 +106,31 @@ crypto_md5(const unsigned char *d, size_t n, unsigned char *md) return md; } +static void +entropy_check(void) +{ +#if defined(__linux__) && defined(HAVE_LINUX_RANDOM_H) && defined(RNDGETENTCNT) + int fd; + int c; + + if ((fd = open("/dev/random", O_RDONLY)) != -1) { + if (ioctl(fd, RNDGETENTCNT, &c) == 0 && c < 160) { + LOGE("This system doesn't provide enough entropy to quickly generate high-quality random numbers\n" + "Installing the rng-utils/rng-tools or haveged packages may help.\n" + "On virtualized Linux environments, also consider using virtio-rng.\n" + "The service will not start until enough entropy has been collected."); + } + close(fd); + } +#endif +} + crypto_t * crypto_init(const char *password, const char *key, const char *method) { int i, m = -1; + entropy_check(); // Initialize sodium for random generator if (sodium_init() == -1) { FATAL("Failed to initialize sodium");