[*] Remove OS randomness in favour of Aurora Runtimes LibTomCrypt helper. I'm sick of seeing warnings on deinit/process shutdown.
This commit is contained in:
parent
928a568c95
commit
74d629643a
120
src/random.c
120
src/random.c
@ -161,132 +161,22 @@ To initialize a fresh random context we rely on the OS:
|
|||||||
If we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR.
|
If we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR.
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#if defined(_WIN32)
|
unsigned long rng_get_bytes(unsigned char* out, unsigned long outlen, void (*callback)(void));
|
||||||
|
|
||||||
#if !defined(MI_USE_RTLGENRANDOM)
|
|
||||||
// We prefer BCryptGenRandom over RtlGenRandom
|
|
||||||
#pragma comment (lib,"bcrypt.lib")
|
|
||||||
#include <bcrypt.h>
|
|
||||||
static bool os_random_buf(void* buf, size_t buf_len) {
|
static bool os_random_buf(void* buf, size_t buf_len) {
|
||||||
return (BCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0);
|
rng_get_bytes(buf, buf_len, 0);
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Use (unofficial) RtlGenRandom
|
|
||||||
#pragma comment (lib,"advapi32.lib")
|
|
||||||
#define RtlGenRandom SystemFunction036
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
static bool os_random_buf(void* buf, size_t buf_len) {
|
|
||||||
return (RtlGenRandom(buf, (ULONG)buf_len) != 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(ANDROID) || defined(XP_DARWIN) || defined(__APPLE__) || defined(__DragonFly__) || \
|
|
||||||
defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
|
|
||||||
defined(__sun) || defined(__wasi__)
|
|
||||||
#include <stdlib.h>
|
|
||||||
static bool os_random_buf(void* buf, size_t buf_len) {
|
|
||||||
arc4random_buf(buf, buf_len);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#elif defined(__linux__)
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
static bool os_random_buf(void* buf, size_t buf_len) {
|
|
||||||
// Modern Linux provides `getrandom` but different distributions either use `sys/random.h` or `linux/random.h`
|
|
||||||
// and for the latter the actual `getrandom` call is not always defined.
|
|
||||||
// (see <https://stackoverflow.com/questions/45237324/why-doesnt-getrandom-compile>)
|
|
||||||
// We therefore use a syscall directly and fall back dynamically to /dev/urandom when needed.
|
|
||||||
#ifdef SYS_getrandom
|
|
||||||
#ifndef GRND_NONBLOCK
|
|
||||||
#define GRND_NONBLOCK (1)
|
|
||||||
#endif
|
|
||||||
static _Atomic(uintptr_t) no_getrandom; // = 0
|
|
||||||
if (mi_atomic_load_acquire(&no_getrandom)==0) {
|
|
||||||
ssize_t ret = syscall(SYS_getrandom, buf, buf_len, GRND_NONBLOCK);
|
|
||||||
if (ret >= 0) return (buf_len == (size_t)ret);
|
|
||||||
if (ret != ENOSYS) return false;
|
|
||||||
mi_atomic_store_release(&no_getrandom, 1UL); // don't call again, and fall back to /dev/urandom
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
int flags = O_RDONLY;
|
|
||||||
#if defined(O_CLOEXEC)
|
|
||||||
flags |= O_CLOEXEC;
|
|
||||||
#endif
|
|
||||||
int fd = open("/dev/urandom", flags, 0);
|
|
||||||
if (fd < 0) return false;
|
|
||||||
size_t count = 0;
|
|
||||||
while(count < buf_len) {
|
|
||||||
ssize_t ret = read(fd, (char*)buf + count, buf_len - count);
|
|
||||||
if (ret<=0) {
|
|
||||||
if (errno!=EAGAIN && errno!=EINTR) break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
count += ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
return (count==buf_len);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static bool os_random_buf(void* buf, size_t buf_len) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#include <Windows.h>
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
#include <mach/mach_time.h>
|
|
||||||
#else
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uintptr_t _os_random_weak(uintptr_t extra_seed) {
|
uintptr_t _os_random_weak(uintptr_t extra_seed) {
|
||||||
uintptr_t x = (uintptr_t)&_os_random_weak ^ extra_seed; // ASLR makes the address random
|
uintptr_t x = extra_seed;
|
||||||
|
rng_get_bytes(&x, sizeof(x), 0);
|
||||||
#if defined(_WIN32)
|
|
||||||
LARGE_INTEGER pcount;
|
|
||||||
QueryPerformanceCounter(&pcount);
|
|
||||||
x ^= (uintptr_t)(pcount.QuadPart);
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
x ^= (uintptr_t)mach_absolute_time();
|
|
||||||
#else
|
|
||||||
struct timespec time;
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
|
||||||
x ^= (uintptr_t)time.tv_sec;
|
|
||||||
x ^= (uintptr_t)time.tv_nsec;
|
|
||||||
#endif
|
|
||||||
// and do a few randomization steps
|
|
||||||
uintptr_t max = ((x ^ (x >> 17)) & 0x0F) + 1;
|
|
||||||
for (uintptr_t i = 0; i < max; i++) {
|
|
||||||
x = _mi_random_shuffle(x);
|
|
||||||
}
|
|
||||||
mi_assert_internal(x != 0);
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mi_random_init(mi_random_ctx_t* ctx) {
|
void _mi_random_init(mi_random_ctx_t* ctx) {
|
||||||
uint8_t key[32];
|
uint8_t key[32];
|
||||||
if (!os_random_buf(key, sizeof(key))) {
|
(void)os_random_buf(key, sizeof(key));
|
||||||
// if we fail to get random data from the OS, we fall back to a
|
|
||||||
// weak random source based on the current time
|
|
||||||
_mi_warning_message("unable to use secure randomness\n");
|
|
||||||
uintptr_t x = _os_random_weak(0);
|
|
||||||
for (size_t i = 0; i < 8; i++) { // key is eight 32-bit words.
|
|
||||||
x = _mi_random_shuffle(x);
|
|
||||||
((uint32_t*)key)[i] = (uint32_t)x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chacha_init(ctx, key, (uintptr_t)ctx /*nonce*/ );
|
chacha_init(ctx, key, (uintptr_t)ctx /*nonce*/ );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user