Do not request more than 256 bytes of random data from getentropy() at once.

This commit is contained in:
LoRd_MuldeR 2021-04-21 13:52:49 +02:00
parent b63dfd1a44
commit 7f643ad566
Signed by: mulder
GPG Key ID: 2B5913365F57E03F
2 changed files with 28 additions and 14 deletions

View File

@ -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*/
}
}
return offset;
} }
#endif #else
#endif
return 0U; return 0U;
#endif
#endif
} }
// ========================================================================== // ==========================================================================