From 978f5845d6d21c37393cbd47bed3b1ee55760318 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Mon, 29 Mar 2021 06:23:56 +0300 Subject: [PATCH 19/25] Support unpredictable random seed on Windows See osdn #41842 Signed-off-by: Marko Lindqvist --- configure.ac | 8 +++++--- utility/randseed.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index dad6c94e28..e91f064293 100644 --- a/configure.ac +++ b/configure.ac @@ -1434,11 +1434,13 @@ AC_CHECK_FUNCS([strerror strstr uname nanosleep usleep]) AC_CHECK_FUNCS([getline _strcoll stricoll _stricoll strcasecoll]) AC_CHECK_FUNCS([backtrace setenv putenv]) -dnl Possible random sources on Unixen +dnl Possible random sources +AC_CHECK_HEADERS([sys/random.h bcrypt.h]) +AC_CHECK_LIB([bcrypt], [BCryptGenRandom], [ + AC_DEFINE([HAVE_BCRYPTGENRANDOM], [1], [BCryptGenRandom() available]) + UTILITY_LIBS="${UTILITY_LIBS} -lbcrypt" ]) AC_CHECK_FUNCS([getentropy clock_gettime]) -AC_CHECK_HEADERS([sys/random.h]) - dnl TODO: Reimplement this check, in a cross-compiling friendly way dnl AC_CHECK_FILES([/dev/urandom]) diff --git a/utility/randseed.c b/utility/randseed.c index 5610b27270..523b3f9f5c 100644 --- a/utility/randseed.c +++ b/utility/randseed.c @@ -19,6 +19,9 @@ #include "fc_prehdrs.h" +#ifdef HAVE_BCRYPT_H +#include +#endif #include #include #include @@ -31,6 +34,9 @@ #ifdef HAVE_UNISTD_H #include #endif +#ifdef FREECIV_MSWINDOWS +#include +#endif /* utility */ #include "fcintl.h" @@ -63,6 +69,27 @@ static bool generate_seed_getentropy(uint32_t *ret) return FALSE; } +/**********************************************************************//** + Read a 32-bit random value using BCryptGenRandom(), if available. + (Windows) + Return FALSE on error, otherwise return TRUE and store seed in *ret. +**************************************************************************/ +static bool generate_seed_bcryptgenrandom(uint32_t *ret) +{ +#ifdef HAVE_BCRYPTGENRANDOM + NTSTATUS Status; + + Status = BCryptGenRandom(NULL, (PUCHAR)ret, sizeof(uint32_t), + BCRYPT_USE_SYSTEM_PREFERRED_RNG); + + if (NT_SUCCESS(Status)) { + return TRUE; + } +#endif /* HAVE_BCRYPTGENRANDOM */ + + return FALSE; +} + /**********************************************************************//** Read a 32-bit random value using /dev/urandom, if available. (Most Unix-like systems) @@ -172,6 +199,10 @@ unsigned int generate_game_seed(void) log_debug("Got random seed from getentropy()"); return seed; } + if (generate_seed_bcryptgenrandom(&seed)) { + log_debug("Got random seed from BCryptGenRandom()"); + return seed; + } if (generate_seed_urandom(&seed)) { log_debug("Got random seed from urandom()"); return seed; -- 2.30.2