From fadf7d944d9b956155e32c53dd106127c85b9644 Mon Sep 17 00:00:00 2001 From: "Radames S. Cruz Moreno" Date: Fri, 24 Jul 2020 18:06:50 -0700 Subject: [PATCH 1/2] Use RtlGenRandom if BCryptGenRandom fails In some circumstances BCryptGenRandom can fail (for example, when running within a Google Chrome sandboxed process). If this ever happens, use RtlGenRandom instead to generate a cryptographically secure random number. --- random/random.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/random/random.c b/random/random.c index fc547fe..ea41dd2 100644 --- a/random/random.c +++ b/random/random.c @@ -18,6 +18,14 @@ static int lock = -1; #endif +#if defined(__WINDOWS__) + +#define RTL_GENRANDOM "SystemFunction036" + +NTSTATUS last_bcrypt_error = 0; + +#endif + static __inline void delay(unsigned int count) { @@ -29,8 +37,31 @@ int random_bytes(unsigned char* random_array, unsigned int nbytes) { // Generation of "nbytes" of random values #if defined(__WINDOWS__) - if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, random_array, nbytes, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { - return false; + if (BCRYPT_SUCCESS(last_bcrypt_error)) + { + NTSTATUS status = BCryptGenRandom( + NULL, random_array, nbytes, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + + if (BCRYPT_SUCCESS(status)) + { + return true; + } + + last_bcrypt_error = status; + } + + HMODULE hAdvApi = LoadLibraryA("ADVAPI32.DLL"); + if (hAdvApi) + { + BOOLEAN(APIENTRY * RtlGenRandom) + (void*, ULONG) = (BOOLEAN(APIENTRY*)(void*, ULONG))GetProcAddress(hAdvApi, RTL_GENRANDOM); + + if (!RtlGenRandom || !RtlGenRandom(random_array, nbytes)) + { + return false; + } + + FreeLibrary(hAdvApi); } #elif defined(__LINUX__) From ae63d036ea9290cd8073243e55f00f5f9b4931da Mon Sep 17 00:00:00 2001 From: "Radames S. Cruz Moreno" Date: Thu, 30 Jul 2020 13:14:58 -0700 Subject: [PATCH 2/2] Return false if unable to load advapi32.dll. Correctly free advapi32.dll when failing to do GetProcAddress. --- random/random.c | 78 +++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/random/random.c b/random/random.c index ea41dd2..593d14e 100644 --- a/random/random.c +++ b/random/random.c @@ -10,12 +10,12 @@ #include #include #if defined(__WINDOWS__) - #include - #include + #include + #include #elif defined(__LINUX__) - #include - #include - static int lock = -1; + #include + #include + static int lock = -1; #endif #if defined(__WINDOWS__) @@ -37,44 +37,52 @@ int random_bytes(unsigned char* random_array, unsigned int nbytes) { // Generation of "nbytes" of random values #if defined(__WINDOWS__) - if (BCRYPT_SUCCESS(last_bcrypt_error)) - { - NTSTATUS status = BCryptGenRandom( - NULL, random_array, nbytes, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + if (BCRYPT_SUCCESS(last_bcrypt_error)) + { + NTSTATUS status = BCryptGenRandom( + NULL, random_array, nbytes, BCRYPT_USE_SYSTEM_PREFERRED_RNG); - if (BCRYPT_SUCCESS(status)) - { - return true; - } + if (BCRYPT_SUCCESS(status)) + { + return true; + } - last_bcrypt_error = status; - } + last_bcrypt_error = status; + } - HMODULE hAdvApi = LoadLibraryA("ADVAPI32.DLL"); - if (hAdvApi) - { - BOOLEAN(APIENTRY * RtlGenRandom) - (void*, ULONG) = (BOOLEAN(APIENTRY*)(void*, ULONG))GetProcAddress(hAdvApi, RTL_GENRANDOM); + HMODULE hAdvApi = LoadLibraryA("ADVAPI32.DLL"); + if (!hAdvApi) + { + return false; + } - if (!RtlGenRandom || !RtlGenRandom(random_array, nbytes)) - { - return false; - } + BOOLEAN(APIENTRY * RtlGenRandom) + (void*, ULONG) = (BOOLEAN(APIENTRY*)(void*, ULONG))GetProcAddress(hAdvApi, RTL_GENRANDOM); - FreeLibrary(hAdvApi); - } + BOOLEAN genrand_result = FALSE; + if (RtlGenRandom) + { + genrand_result = RtlGenRandom(random_array, nbytes); + } + + FreeLibrary(hAdvApi); + + if (!genrand_result) + { + return false; + } #elif defined(__LINUX__) int r, n = nbytes, count = 0; - - if (lock == -1) { - do { - lock = open("/dev/urandom", O_RDONLY); - if (lock == -1) { - delay(0xFFFFF); - } - } while (lock == -1); - } + + if (lock == -1) { + do { + lock = open("/dev/urandom", O_RDONLY); + if (lock == -1) { + delay(0xFFFFF); + } + } while (lock == -1); + } while (n > 0) { do {