Fall back to /dev/urandom, if compiled with getrandom() support but that syscall is not available at runtime.

This commit is contained in:
LoRd_MuldeR 2021-04-17 16:05:32 +02:00
parent a656e9de37
commit 2e93d8dc28
Signed by: mulder
GPG Key ID: 2B5913365F57E03F

View File

@ -48,7 +48,7 @@
/* detect explicit_bzero() support */
#undef EXPLICIT_BZERO
#if defined(_WIN32) && defined(SecureZeroMemory)
#if defined(_WIN32) && defined(SecureZeroMemory)
# define EXPLICIT_BZERO SecureZeroMemory
#elif defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
# define EXPLICIT_BZERO explicit_bzero
@ -97,7 +97,7 @@ static CALL_ONCE_TYPE s_random_is_initialized = CALL_ONCE_INIT;
typedef BOOLEAN(WINAPI *rtlgenrandom_t)(void *buffer, ULONG buff_size);
static HMODULE s_advapi32 = NULL;
static rtlgenrandom_t s_rtlgenrandom = NULL;
#elif !defined(SYS_GETRANDOM)
#else
static const char *const DEV_RANDOM[] = { "/dev/urandom", "/dev/arandom", "/dev/random", NULL };
static int s_random_fd = -1;
#endif
@ -112,7 +112,7 @@ static void exit_random_source(void)
FreeLibrary(s_advapi32);
s_advapi32 = NULL;
}
#elif !defined(SYS_GETRANDOM)
#else
if (s_random_fd >= 0)
{
close(s_random_fd);
@ -129,14 +129,22 @@ static void init_random_source(void)
{
s_rtlgenrandom = (rtlgenrandom_t) GetProcAddress(s_advapi32, "SystemFunction036");
}
#elif !defined(SYS_GETRANDOM)
#else
#if defined(SYS_GETRANDOM)
uint8_t temp;
if (getrandom(&temp, 0U, 0U) >= 0)
{
goto init_completed;
}
#endif
for (size_t i = 0U; DEV_RANDOM[i]; ++i)
{
if ((s_random_fd = open(DEV_RANDOM[i], O_RDONLY)) >= 0)
{
break; /*success*/
goto init_completed;
}
}
init_completed: ;
#endif
#if !defined(ATTRIB_DESTRUCTOR)
atexit(exit_random_source);
@ -153,15 +161,19 @@ size_t slunkcrypt_random_bytes(uint8_t* const buffer, const size_t length)
const ULONG buff_size = (ULONG)length;
return s_rtlgenrandom(buffer, buff_size) ? buff_size : 0U;
}
#elif defined(SYS_GETRANDOM)
const ssize_t result = getrandom(buffer, length, 0U);
return (result < 0) ? 0U : ((size_t)result);
#else
if (s_random_fd >= 0)
{
const ssize_t result = read(s_random_fd, buffer, length);
return (result < 0) ? 0U : ((size_t)result);
}
#if defined(SYS_GETRANDOM)
else
{
const ssize_t result = getrandom(buffer, length, 0U);
return (result < 0) ? 0U : ((size_t)result);
}
#endif
#endif
return 0U;
}