From 6b5634b96aa90ab2db7357b353fc8f96ad4878c5 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Mon, 7 Feb 2022 17:33:55 +0100 Subject: [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. --- core/os/os.h | 2 ++ drivers/unix/os_unix.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ drivers/unix/os_unix.h | 11 +---------- platform/windows/os_windows.cpp | 7 +++++++ platform/windows/os_windows.h | 2 ++ 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/core/os/os.h b/core/os/os.h index d3d2a868fa..188900a070 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -132,6 +132,8 @@ public: virtual String get_stdin_string(bool p_block = true) = 0; + virtual Error get_entropy(uint8_t *r_buffer, int p_bytes) = 0; // Should return cryptographically-safe random bytes. + virtual PackedStringArray get_connected_midi_inputs(); virtual void open_midi_inputs(); virtual void close_midi_inputs(); diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 00f84eba8c..7d57926757 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -65,6 +65,21 @@ #include #include +#if defined(OSX_ENABLED) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28) +// Random location for getentropy. Fitting. +#include +#define UNIX_GET_ENTROPY +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__GLIBC_MINOR__) && (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 26)) +// In . +// 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 +#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"; } diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 3f0e8a171c..460ba4b9e1 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -43,7 +43,6 @@ protected: virtual void initialize_core(); virtual int unix_initialize_audio(int p_audio_driver); - //virtual Error initialize(int p_video_driver,int p_audio_driver); virtual void finalize_core() override; @@ -54,15 +53,7 @@ public: virtual String get_stdin_string(bool p_block) override; - //virtual void set_mouse_show(bool p_show); - //virtual void set_mouse_grab(bool p_grab); - //virtual bool is_mouse_grab_enabled() const = 0; - //virtual void get_mouse_position(int &x, int &y) const; - //virtual void set_window_title(const String& p_title); - - //virtual void set_video_mode(const VideoMode& p_video_mode); - //virtual VideoMode get_video_mode() const; - //virtual void get_fullscreen_mode_list(List *p_list) const; + virtual Error get_entropy(uint8_t *r_buffer, int p_bytes) override; // Should return cryptographycally-safe random bytes. virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; virtual Error close_dynamic_library(void *p_library_handle) override; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index d844531071..59f55b5dd2 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -46,6 +46,7 @@ #include "windows_terminal_logger.h" #include +#include #include #include #include @@ -192,6 +193,12 @@ void OS_Windows::finalize_core() { NetSocketPosix::cleanup(); } +Error OS_Windows::get_entropy(uint8_t *r_buffer, int p_bytes) { + NTSTATUS status = BCryptGenRandom(nullptr, r_buffer, p_bytes, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + ERR_FAIL_COND_V(status, FAILED); + return OK; +} + Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { String path = p_path.replace("/", "\\"); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 0a11416b1b..bde663a27b 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -106,6 +106,8 @@ protected: public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; + virtual Error get_entropy(uint8_t *r_buffer, int p_bytes) override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; virtual Error close_dynamic_library(void *p_library_handle) override; virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override; -- cgit v1.2.3