From c63c3bffe6a373bb8c4b7ca0bf646a46444ca4e1 Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Tue, 8 Feb 2022 22:46:33 +0100 Subject: [PATCH] Make sure that the requested number of random bytes is fully read, even if a single read() invocation returned fewer than "count" bytes. --- libslunkcrypt/src/compiler.h | 2 +- libslunkcrypt/src/junk.c | 50 ++++++++++++++++++++++++++---------- libslunkcrypt/src/version.h | 2 +- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/libslunkcrypt/src/compiler.h b/libslunkcrypt/src/compiler.h index ad2e215..49c9093 100644 --- a/libslunkcrypt/src/compiler.h +++ b/libslunkcrypt/src/compiler.h @@ -8,7 +8,7 @@ /* Intel(R) oneAPI DPC++/C++ Compiler */ #if defined(__INTEL_LLVM_COMPILER) && (!defined(__GNUC__)) -# define __GNUC__ 9 +# define __GNUC__ 10 #endif /* Compiler compatibility */ diff --git a/libslunkcrypt/src/junk.c b/libslunkcrypt/src/junk.c index e593eb9..4cb46e6 100644 --- a/libslunkcrypt/src/junk.c +++ b/libslunkcrypt/src/junk.c @@ -28,6 +28,7 @@ static INLINE size_t MIN_SIZE(const size_t a, const size_t b) { return (a > b) ? #ifdef _WIN32 # include +# include #else # include # include @@ -88,12 +89,14 @@ static void win32_call_once(CALL_ONCE_TYPE *const control, void (*init_routine)( // Random bytes // ========================================================================== +#define MAX_COUNT 1048576U + /* Global state */ static CALL_ONCE_TYPE s_random_is_initialized = CALL_ONCE_INIT; #if defined(_WIN32) -typedef BOOLEAN(WINAPI *rtlgenrandom_t)(void *buffer, ULONG length); +typedef BOOLEAN(WINAPI *ptr_genrandom_t)(void *buffer, ULONG length); static HMODULE s_advapi32 = NULL; -static rtlgenrandom_t s_rtlgenrandom = NULL; +static ptr_genrandom_t s_genrandom = NULL; #else static const char *const DEV_RANDOM[] = { "/dev/urandom", "/dev/arandom", "/dev/random", NULL }; static int s_random_fd = -1; @@ -102,8 +105,11 @@ static int s_random_fd = -1; /* De-initialize CSRNG */ static void exit_random_source(void) { -#if defined(_WIN32) - s_rtlgenrandom = NULL; +#ifdef _WIN32 + if (s_genrandom) + { + s_genrandom = NULL; + } if (s_advapi32) { FreeLibrary(s_advapi32); @@ -121,10 +127,10 @@ static void exit_random_source(void) /* Initialize CSRNG */ static void init_random_source(void) { -#if defined(_WIN32) +#ifdef _WIN32 if ((s_advapi32 = LoadLibraryW(L"advapi32.dll"))) { - s_rtlgenrandom = (rtlgenrandom_t) GetProcAddress(s_advapi32, "SystemFunction036"); + s_genrandom = (ptr_genrandom_t) GetProcAddress(s_advapi32, "SystemFunction036"); } #else #if defined(GETENTROPY) @@ -151,27 +157,43 @@ init_completed: ; /* Generate random bytes */ size_t slunkcrypt_random_bytes(uint8_t* const buffer, const size_t length) { + size_t offset; CALL_ONCE(&s_random_is_initialized, init_random_source); -#if defined(_WIN32) - if (s_rtlgenrandom) +#ifdef _WIN32 + if (s_genrandom) { - const ULONG count = (ULONG) MIN_SIZE(length, ULONG_MAX); - return s_rtlgenrandom(buffer, count) ? count : 0U; + ULONG count; + for (offset = 0U; offset < length; offset += count) + { + count = (ULONG) MIN_SIZE(length - offset, MAX_COUNT); + if (!s_genrandom(buffer + offset, count)) + { + break; /*failed*/ + } + } + return offset; } return 0U; #else if (s_random_fd >= 0) { - const ssize_t result = read(s_random_fd, buffer, length); - return (result < 0) ? 0U : ((size_t)result); + ssize_t count; + for (offset = 0; offset < length; offset += (size_t)count) + { + if (!((count = read(s_random_fd, buffer + offset, MIN_SIZE(length - offset, MAX_COUNT))) > 0)) + { + break; /*failed*/ + } + } + return offset; } #if defined(GETENTROPY) else { - size_t offset, count; + size_t count; for (offset = 0U; offset < length; offset += count) { - count = MIN_SIZE(length - offset, 256U); + count = MIN_SIZE(length - offset, 256U); /*the maximum permitted value is 256*/ if (GETENTROPY(buffer + offset, count) < 0) { break; /*failed*/ diff --git a/libslunkcrypt/src/version.h b/libslunkcrypt/src/version.h index 33e8e0c..097c508 100644 --- a/libslunkcrypt/src/version.h +++ b/libslunkcrypt/src/version.h @@ -8,6 +8,6 @@ #define LIB_VERSION_MAJOR 1 #define LIB_VERSION_MINOR 1 -#define LIB_VERSION_PATCH 1 +#define LIB_VERSION_PATCH 2 #endif