summaryrefslogtreecommitdiff
path: root/drivers/unix
diff options
context:
space:
mode:
authorFabio Alessandrelli <fabio.alessandrelli@gmail.com>2022-02-07 17:33:55 +0100
committerFabio Alessandrelli <fabio.alessandrelli@gmail.com>2022-02-14 10:45:50 +0100
commit6b5634b96aa90ab2db7357b353fc8f96ad4878c5 (patch)
tree79683c4d2e538e5702a74a5b431a0913777ee0ed /drivers/unix
parent8317753c24f6a05d4fdc8541fecf1cd2ec189b41 (diff)
[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.
Diffstat (limited to 'drivers/unix')
-rw-r--r--drivers/unix/os_unix.cpp40
-rw-r--r--drivers/unix/os_unix.h11
2 files changed, 41 insertions, 10 deletions
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 <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";
}
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<VideoMode> *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;