Do not request more than 256 bytes of random data from getentropy() at once.
This commit is contained in:
parent
b63dfd1a44
commit
7f643ad566
@ -19,6 +19,9 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* Utils */
|
||||||
|
static INLINE size_t MIN_SIZE(const size_t a, const size_t b) { return (a > b) ? b : a; }
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Platform compatibility
|
// Platform compatibility
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
@ -37,13 +40,13 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* detect getentropy() support */
|
/* detect getentropy() support */
|
||||||
#undef SYSCALL_GETENTROPY
|
#undef GETENTROPY
|
||||||
#if defined(__linux__) && defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
|
#if defined(__linux__) && defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
|
||||||
# define SYSCALL_GETENTROPY getentropy
|
# define GETENTROPY getentropy
|
||||||
#elif defined(__FreeBSD__) && (__FreeBSD__ >= 12)
|
#elif defined(__FreeBSD__) && (__FreeBSD__ >= 12)
|
||||||
# define SYSCALL_GETENTROPY getentropy
|
# define GETENTROPY getentropy
|
||||||
#elif defined(__OpenBSD__) && (__OpenBSD__ >= 1)
|
#elif defined(__OpenBSD__) && (__OpenBSD__ >= 1)
|
||||||
# define SYSCALL_GETENTROPY getentropy
|
# define GETENTROPY getentropy
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* detect explicit_bzero() support */
|
/* detect explicit_bzero() support */
|
||||||
@ -96,7 +99,7 @@ static void win32_call_once(CALL_ONCE_TYPE *const control, void (*init_routine)(
|
|||||||
/* Global state */
|
/* Global state */
|
||||||
static CALL_ONCE_TYPE s_random_is_initialized = CALL_ONCE_INIT;
|
static CALL_ONCE_TYPE s_random_is_initialized = CALL_ONCE_INIT;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
typedef BOOLEAN(WINAPI *rtlgenrandom_t)(void *buffer, ULONG buff_size);
|
typedef BOOLEAN(WINAPI *rtlgenrandom_t)(void *buffer, ULONG length);
|
||||||
static HMODULE s_advapi32 = NULL;
|
static HMODULE s_advapi32 = NULL;
|
||||||
static rtlgenrandom_t s_rtlgenrandom = NULL;
|
static rtlgenrandom_t s_rtlgenrandom = NULL;
|
||||||
#else
|
#else
|
||||||
@ -132,9 +135,9 @@ static void init_random_source(void)
|
|||||||
s_rtlgenrandom = (rtlgenrandom_t) GetProcAddress(s_advapi32, "SystemFunction036");
|
s_rtlgenrandom = (rtlgenrandom_t) GetProcAddress(s_advapi32, "SystemFunction036");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#if defined(SYSCALL_GETENTROPY)
|
#if defined(GETENTROPY)
|
||||||
uint8_t temp;
|
uint8_t temp;
|
||||||
if (SYSCALL_GETENTROPY(&temp, sizeof(uint8_t)) >= 0)
|
if (GETENTROPY(&temp, sizeof(uint8_t)) >= 0)
|
||||||
{
|
{
|
||||||
goto init_completed;
|
goto init_completed;
|
||||||
}
|
}
|
||||||
@ -160,23 +163,34 @@ size_t slunkcrypt_random_bytes(uint8_t* const buffer, const size_t length)
|
|||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (s_rtlgenrandom)
|
if (s_rtlgenrandom)
|
||||||
{
|
{
|
||||||
const ULONG buff_length = (ULONG)length;
|
const ULONG count = (ULONG) MIN_SIZE(length, ULONG_MAX);
|
||||||
return s_rtlgenrandom(buffer, buff_length) ? buff_length : 0U;
|
return s_rtlgenrandom(buffer, count) ? count : 0U;
|
||||||
}
|
}
|
||||||
|
return 0U;
|
||||||
#else
|
#else
|
||||||
if (s_random_fd >= 0)
|
if (s_random_fd >= 0)
|
||||||
{
|
{
|
||||||
const ssize_t result = read(s_random_fd, buffer, length);
|
const ssize_t result = read(s_random_fd, buffer, length);
|
||||||
return (result < 0) ? 0U : ((size_t)result);
|
return (result < 0) ? 0U : ((size_t)result);
|
||||||
}
|
}
|
||||||
#if defined(SYSCALL_GETENTROPY)
|
#if defined(GETENTROPY)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (SYSCALL_GETENTROPY(buffer, length) >= 0) ? length : 0U;
|
size_t offset, count;
|
||||||
|
for (offset = 0U; offset < length; offset += count)
|
||||||
|
{
|
||||||
|
count = MIN_SIZE(length - offset, 256U);
|
||||||
|
if (GETENTROPY(buffer + offset, count) < 0)
|
||||||
|
{
|
||||||
|
break; /*failed*/
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
#endif
|
return offset;
|
||||||
|
}
|
||||||
|
#else
|
||||||
return 0U;
|
return 0U;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
Loading…
Reference in New Issue
Block a user