From 24574712d19f1a5117936beeaa1ed9773199d4f3 Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Wed, 21 Oct 2020 19:29:37 +0200 Subject: [PATCH] Use RtlGenRandom() directly on the Windows platform. --- frontend/src/main.c | 2 +- libslunkcrypt/src/internal.c | 67 ++++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/frontend/src/main.c b/frontend/src/main.c index 764ebee..e61c46d 100644 --- a/frontend/src/main.c +++ b/frontend/src/main.c @@ -512,7 +512,7 @@ static int run_test_case(const char *const message) goto clean_up; } - if (strncmp(message, text_temp, length) != 0) + if (memcmp(message, text_temp, length * sizeof(char)) != 0) { FPUTS(T("\n\nWhoops: Decrypted message does *not* match the original message!\n\n"), stderr); goto clean_up; diff --git a/libslunkcrypt/src/internal.c b/libslunkcrypt/src/internal.c index c141395..acc949c 100644 --- a/libslunkcrypt/src/internal.c +++ b/libslunkcrypt/src/internal.c @@ -3,58 +3,75 @@ /* This work has been released under the CC0 1.0 Universal license! */ /******************************************************************************/ -#ifdef _WIN32 -#define _WIN32_WINNT 0x0600 -#define _CRT_RAND_S 1 -#define WIN32_LEAN_AND_MEAN 1 -#endif - #include #ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN 1 #include +typedef BOOLEAN(WINAPI *genrandom_t)(void*, ULONG); +static volatile LONG g_random_init = 0L; +static HMODULE g_advapi32 = NULL; +static genrandom_t g_genrandom = NULL; #else #include #include #include -#if (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)) || (defined(__FreeBSD__) && (__FreeBSD__ >= 12)) +#if (defined(__GLIBC__) && __GLIBC_PREREQ(2,25)) || (defined(__FreeBSD__) && (__FreeBSD__ >= 12)) #include +#else +static const char *const DEV_RANDOM[] = { "/dev/urandom", "/dev/arandom", "/dev/random", NULL }; #endif #endif +#ifdef _WIN32 +static genrandom_t init_genrandom() +{ + LONG state; + while ((state = InterlockedCompareExchange(&g_random_init, -1L, 0L)) != 0L) + { + if (state > 0L) + { + return g_genrandom; + } + Sleep(0U); + } + if (g_advapi32 || (g_advapi32 = LoadLibrary(L"advapi32.dll"))) + { + if ((g_genrandom = (genrandom_t)GetProcAddress(g_advapi32, "SystemFunction036"))) + { + InterlockedExchange(&g_random_init, 1L); + return g_genrandom; + } + } + InterlockedExchange(&g_random_init, 0L); + return NULL; +} +#endif + int slunkcrypt_random_bytes(uint8_t* const buffer, const size_t length) { #ifdef _WIN32 - size_t pos = 0U; - while (pos < length) + if ((length <= ((size_t)ULONG_MAX))) { - const size_t bytes_left = length - pos; - const size_t bytes_copy = (bytes_left < sizeof(uint32_t)) ? bytes_left : sizeof(uint32_t); - uint32_t temp; - if (rand_s(&temp) != 0) + const genrandom_t genrandom = init_genrandom(); + if (genrandom) { - return -1; - } - for (size_t i = 0; i < bytes_copy; ++i) - { - buffer[pos++] = (uint8_t)(temp & 0xFF); - temp >>= 8; + return genrandom(buffer, (ULONG)length) ? 0 : (-1); } } - return 0; + return -1; #else -#if (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)) || (defined(__FreeBSD__) && (__FreeBSD__ >= 12)) +#if (defined(__GLIBC__) && __GLIBC_PREREQ(2,25)) || (defined(__FreeBSD__) && (__FreeBSD__ >= 12)) if (getrandom(buffer, length, 0U) >= length) { return 0; } return -1; #else - static const char* const PATH[] = { "/dev/urandom", "/dev/arandom", "/dev/random" }; int result = -1; - for (size_t i = 0; (i < 3U) && (result < 0); ++i) + for (size_t i = 0U; DEV_RANDOM[i] && (result != 0); ++i) { - const int fd = open(PATH[i], O_RDONLY); + const int fd = open(DEV_RANDOM[i], O_RDONLY); if (fd >= 0) { if (read(fd, buffer, length) >= length) @@ -76,7 +93,7 @@ void slunkcrypt_bzero(void* const ptr, const size_t length) #if defined(_WIN32) && defined(SecureZeroMemory) SecureZeroMemory(ptr, length); #else -#if (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)) || (defined(__FreeBSD__) && (__FreeBSD__ >= 11)) +#if (defined(__GLIBC__) && __GLIBC_PREREQ(2,25)) || (defined(__FreeBSD__) && (__FreeBSD__ >= 11)) explicit_bzero(ptr, length); #else volatile uint8_t *buffer = (volatile uint8_t*)ptr;