From 0f61f6921b2e4395d1e354ad356137e44d6a7e11 Mon Sep 17 00:00:00 2001 From: Eric Haszlakiewicz Date: Wed, 13 Jan 2021 01:57:25 +0000 Subject: Iesue #692: use arc4random() if it's available (in libc on BSD systems, and libbsd on Linux). --- CMakeLists.txt | 11 +++++++++++ cmake/config.h.in | 6 ++++++ random_seed.c | 13 +++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 892aebb..30b4f2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,6 +170,17 @@ check_symbol_exists(vasprintf "stdio.h" HAVE_VASPRINTF) check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF) check_symbol_exists(vprintf "stdio.h" HAVE_VPRINTF) +check_symbol_exists(arc4random "stdlib.h" HAVE_ARC4RANDOM) +if (NOT HAVE_ARC4RANDOM) + check_include_file(bsd/stdlib.h HAVE_BSD_STDLIB_H) + if (HAVE_BSD_STDLIB_H) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-lbsd") + link_libraries(bsd) + unset(HAVE_ARC4RANDOM CACHE) + check_symbol_exists(arc4random "bsd/stdlib.h" HAVE_ARC4RANDOM) + endif() +endif() + if (HAVE_FCNTL_H) check_symbol_exists(open "fcntl.h" HAVE_OPEN) endif() diff --git a/cmake/config.h.in b/cmake/config.h.in index 9e097cb..be0202a 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -74,6 +74,12 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_XLOCALE_H +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_BSD_STDLIB_H + +/* Define to 1 if you have `arc4random' */ +#cmakedefine HAVE_ARC4RANDOM + /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #cmakedefine HAVE_DOPRNT diff --git a/random_seed.c b/random_seed.c index ff5338f..f3ee740 100644 --- a/random_seed.c +++ b/random_seed.c @@ -13,6 +13,10 @@ #include "config.h" #include "strerror_override.h" #include +#include +#ifdef HAVE_BSD_STDLIB_H +#include +#endif #define DEBUG_SEED(s) @@ -168,7 +172,8 @@ static int get_getrandom_seed(int *seed) ssize_t ret; - do { + do + { ret = getrandom(seed, sizeof(*seed), GRND_NONBLOCK); } while ((ret == -1) && (errno == EINTR)); @@ -273,7 +278,7 @@ static int get_cryptgenrandom_seed(int *seed) } else { - BOOL ret = CryptGenRandom(hProvider, sizeof(*seed), (BYTE*)seed); + BOOL ret = CryptGenRandom(hProvider, sizeof(*seed), (BYTE *)seed); CryptReleaseContext(hProvider, 0); if (!ret) { @@ -310,6 +315,10 @@ int json_c_get_random_seed(void) if (has_rdrand()) return get_rdrand_seed(); #endif +#ifdef HAVE_ARC4RANDOM + /* arc4random never fails, so use it if it's available */ + return arc4random(); +#endif #ifdef HAVE_GETRANDOM if (get_getrandom_seed(&seed) == 0) return seed; -- cgit v1.2.1