[OS/Crypto] Add get_entropy to OS.

Implemented via `BCryptGenRandom` on Windows.
Implemented via `getentropy` syscall when available.
Implemented via `/dev/urandom` device as a fallback.

The `/dev/urandom` fallback can be disabled via the `NO_URANDOM` build
flag.

Note: The HTML5 version relies on emscripten file system urandom
device which itself uses the Crypto API when available or the plain
old not crypto-safe `Math.random()` otherwise.

Restore get_entropy.
This commit is contained in:
Fabio Alessandrelli 2022-02-07 17:33:55 +01:00
parent 8317753c24
commit 6b5634b96a
5 changed files with 52 additions and 10 deletions

View file

@ -65,6 +65,21 @@
#include <time.h>
#include <unistd.h>
#if defined(OSX_ENABLED) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28)
// Random location for getentropy. Fitting.
#include <sys/random.h>
#define UNIX_GET_ENTROPY
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__GLIBC_MINOR__) && (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 26))
// In <unistd.h>.
// One day... (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700)
// https://publications.opengroup.org/standards/unix/c211
#define UNIX_GET_ENTROPY
#endif
#if !defined(UNIX_GET_ENTROPY) && !defined(NO_URANDOM)
#include <fcntl.h>
#endif
/// Clock Setup function (used by get_ticks_usec)
static uint64_t _clock_start = 0;
#if defined(__APPLE__)
@ -150,6 +165,31 @@ String OS_Unix::get_stdin_string(bool p_block) {
return "";
}
Error OS_Unix::get_entropy(uint8_t *r_buffer, int p_bytes) {
#if defined(UNIX_GET_ENTROPY)
int left = p_bytes;
int ofs = 0;
do {
int chunk = MIN(left, 256);
ERR_FAIL_COND_V(getentropy(r_buffer + ofs, chunk), FAILED);
left -= chunk;
ofs += chunk;
} while (left > 0);
#elif !defined(NO_URANDOM)
int r = open("/dev/urandom", O_RDONLY);
ERR_FAIL_COND_V(r < 0, FAILED);
int left = p_bytes;
do {
ssize_t ret = read(r, r_buffer, p_bytes);
ERR_FAIL_COND_V(ret <= 0, FAILED);
left -= ret;
} while (left > 0);
#else
return ERR_UNAVAILABLE;
#endif
return OK;
}
String OS_Unix::get_name() const {
return "Unix";
}