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