Make sure that the requested number of random bytes is fully read, even if a single read() invocation returned fewer than "count" bytes.
This commit is contained in:
parent
956e79ecc6
commit
c63c3bffe6
@ -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 */
|
||||
|
@ -28,6 +28,7 @@ static INLINE size_t MIN_SIZE(const size_t a, const size_t b) { return (a > b) ?
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <Windows.h>
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <pthread.h>
|
||||
@ -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*/
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user