You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Merge pull request #57887 from Faless/crypto/4.x_os_get_entropy
This commit is contained in:
@@ -31,6 +31,8 @@ if not has_module:
|
|||||||
"aes.c",
|
"aes.c",
|
||||||
"base64.c",
|
"base64.c",
|
||||||
"constant_time.c",
|
"constant_time.c",
|
||||||
|
"ctr_drbg.c",
|
||||||
|
"entropy.c",
|
||||||
"md5.c",
|
"md5.c",
|
||||||
"sha1.c",
|
"sha1.c",
|
||||||
"sha256.c",
|
"sha256.c",
|
||||||
|
|||||||
@@ -30,12 +30,55 @@
|
|||||||
|
|
||||||
#include "crypto_core.h"
|
#include "crypto_core.h"
|
||||||
|
|
||||||
|
#include "core/os/os.h"
|
||||||
|
|
||||||
#include <mbedtls/aes.h>
|
#include <mbedtls/aes.h>
|
||||||
#include <mbedtls/base64.h>
|
#include <mbedtls/base64.h>
|
||||||
|
#include <mbedtls/ctr_drbg.h>
|
||||||
|
#include <mbedtls/entropy.h>
|
||||||
#include <mbedtls/md5.h>
|
#include <mbedtls/md5.h>
|
||||||
#include <mbedtls/sha1.h>
|
#include <mbedtls/sha1.h>
|
||||||
#include <mbedtls/sha256.h>
|
#include <mbedtls/sha256.h>
|
||||||
|
|
||||||
|
// RandomGenerator
|
||||||
|
CryptoCore::RandomGenerator::RandomGenerator() {
|
||||||
|
entropy = memalloc(sizeof(mbedtls_entropy_context));
|
||||||
|
mbedtls_entropy_init((mbedtls_entropy_context *)entropy);
|
||||||
|
mbedtls_entropy_add_source((mbedtls_entropy_context *)entropy, &CryptoCore::RandomGenerator::_entropy_poll, nullptr, 256, MBEDTLS_ENTROPY_SOURCE_STRONG);
|
||||||
|
ctx = memalloc(sizeof(mbedtls_ctr_drbg_context));
|
||||||
|
mbedtls_ctr_drbg_init((mbedtls_ctr_drbg_context *)ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoCore::RandomGenerator::~RandomGenerator() {
|
||||||
|
mbedtls_ctr_drbg_free((mbedtls_ctr_drbg_context *)ctx);
|
||||||
|
memfree(ctx);
|
||||||
|
mbedtls_entropy_free((mbedtls_entropy_context *)entropy);
|
||||||
|
memfree(entropy);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CryptoCore::RandomGenerator::_entropy_poll(void *p_data, unsigned char *r_buffer, size_t p_len, size_t *r_len) {
|
||||||
|
*r_len = 0;
|
||||||
|
Error err = OS::get_singleton()->get_entropy(r_buffer, p_len);
|
||||||
|
ERR_FAIL_COND_V(err, MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
|
||||||
|
*r_len = p_len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error CryptoCore::RandomGenerator::init() {
|
||||||
|
int ret = mbedtls_ctr_drbg_seed((mbedtls_ctr_drbg_context *)ctx, mbedtls_entropy_func, (mbedtls_entropy_context *)entropy, nullptr, 0);
|
||||||
|
if (ret) {
|
||||||
|
ERR_FAIL_COND_V_MSG(ret, FAILED, " failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret));
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error CryptoCore::RandomGenerator::get_random_bytes(uint8_t *r_buffer, size_t p_bytes) {
|
||||||
|
ERR_FAIL_COND_V(!ctx, ERR_UNCONFIGURED);
|
||||||
|
int ret = mbedtls_ctr_drbg_random((mbedtls_ctr_drbg_context *)ctx, r_buffer, p_bytes);
|
||||||
|
ERR_FAIL_COND_V_MSG(ret, FAILED, " failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret));
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
// MD5
|
// MD5
|
||||||
CryptoCore::MD5Context::MD5Context() {
|
CryptoCore::MD5Context::MD5Context() {
|
||||||
ctx = memalloc(sizeof(mbedtls_md5_context));
|
ctx = memalloc(sizeof(mbedtls_md5_context));
|
||||||
|
|||||||
@@ -35,9 +35,24 @@
|
|||||||
|
|
||||||
class CryptoCore {
|
class CryptoCore {
|
||||||
public:
|
public:
|
||||||
|
class RandomGenerator {
|
||||||
|
private:
|
||||||
|
void *entropy = nullptr;
|
||||||
|
void *ctx = nullptr;
|
||||||
|
|
||||||
|
static int _entropy_poll(void *p_data, unsigned char *r_buffer, size_t p_len, size_t *r_len);
|
||||||
|
|
||||||
|
public:
|
||||||
|
RandomGenerator();
|
||||||
|
~RandomGenerator();
|
||||||
|
|
||||||
|
Error init();
|
||||||
|
Error get_random_bytes(uint8_t *r_buffer, size_t p_bytes);
|
||||||
|
};
|
||||||
|
|
||||||
class MD5Context {
|
class MD5Context {
|
||||||
private:
|
private:
|
||||||
void *ctx = nullptr; // To include, or not to include...
|
void *ctx = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MD5Context();
|
MD5Context();
|
||||||
@@ -50,7 +65,7 @@ public:
|
|||||||
|
|
||||||
class SHA1Context {
|
class SHA1Context {
|
||||||
private:
|
private:
|
||||||
void *ctx = nullptr; // To include, or not to include...
|
void *ctx = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHA1Context();
|
SHA1Context();
|
||||||
@@ -63,7 +78,7 @@ public:
|
|||||||
|
|
||||||
class SHA256Context {
|
class SHA256Context {
|
||||||
private:
|
private:
|
||||||
void *ctx = nullptr; // To include, or not to include...
|
void *ctx = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHA256Context();
|
SHA256Context();
|
||||||
@@ -76,7 +91,7 @@ public:
|
|||||||
|
|
||||||
class AESContext {
|
class AESContext {
|
||||||
private:
|
private:
|
||||||
void *ctx = nullptr; // To include, or not to include...
|
void *ctx = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AESContext();
|
AESContext();
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#include "resource_uid.h"
|
#include "resource_uid.h"
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
#include "core/crypto/crypto.h"
|
#include "core/crypto/crypto_core.h"
|
||||||
#include "core/io/dir_access.h"
|
#include "core/io/dir_access.h"
|
||||||
#include "core/io/file_access.h"
|
#include "core/io/file_access.h"
|
||||||
|
|
||||||
@@ -82,20 +82,14 @@ ResourceUID::ID ResourceUID::text_to_id(const String &p_text) const {
|
|||||||
return ID(uid & 0x7FFFFFFFFFFFFFFF);
|
return ID(uid & 0x7FFFFFFFFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceUID::ID ResourceUID::create_id() const {
|
ResourceUID::ID ResourceUID::create_id() {
|
||||||
mutex.lock();
|
|
||||||
if (crypto.is_null()) {
|
|
||||||
crypto = Ref<Crypto>(Crypto::create());
|
|
||||||
}
|
|
||||||
mutex.unlock();
|
|
||||||
while (true) {
|
while (true) {
|
||||||
PackedByteArray bytes = crypto->generate_random_bytes(8);
|
ID id = INVALID_ID;
|
||||||
ERR_FAIL_COND_V(bytes.size() != 8, INVALID_ID);
|
MutexLock lock(mutex);
|
||||||
const uint64_t *ptr64 = (const uint64_t *)bytes.ptr();
|
Error err = ((CryptoCore::RandomGenerator *)crypto)->get_random_bytes((uint8_t *)&id, sizeof(id));
|
||||||
ID id = int64_t((*ptr64) & 0x7FFFFFFFFFFFFFFF);
|
ERR_FAIL_COND_V(err != OK, INVALID_ID);
|
||||||
mutex.lock();
|
id &= 0x7FFFFFFFFFFFFFFF;
|
||||||
bool exists = unique_ids.has(id);
|
bool exists = unique_ids.has(id);
|
||||||
mutex.unlock();
|
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -261,6 +255,9 @@ ResourceUID *ResourceUID::singleton = nullptr;
|
|||||||
ResourceUID::ResourceUID() {
|
ResourceUID::ResourceUID() {
|
||||||
ERR_FAIL_COND(singleton != nullptr);
|
ERR_FAIL_COND(singleton != nullptr);
|
||||||
singleton = this;
|
singleton = this;
|
||||||
|
crypto = memnew(CryptoCore::RandomGenerator);
|
||||||
|
((CryptoCore::RandomGenerator *)crypto)->init();
|
||||||
}
|
}
|
||||||
ResourceUID::~ResourceUID() {
|
ResourceUID::~ResourceUID() {
|
||||||
|
memdelete((CryptoCore::RandomGenerator *)crypto);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
#include "core/string/string_name.h"
|
#include "core/string/string_name.h"
|
||||||
#include "core/templates/ordered_hash_map.h"
|
#include "core/templates/ordered_hash_map.h"
|
||||||
|
|
||||||
class Crypto;
|
|
||||||
class ResourceUID : public Object {
|
class ResourceUID : public Object {
|
||||||
GDCLASS(ResourceUID, Object)
|
GDCLASS(ResourceUID, Object)
|
||||||
public:
|
public:
|
||||||
@@ -47,7 +46,7 @@ public:
|
|||||||
static String get_cache_file();
|
static String get_cache_file();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable Ref<Crypto> crypto;
|
void *crypto; // CryptoCore::RandomGenerator (avoid including crypto_core.h)
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
struct Cache {
|
struct Cache {
|
||||||
CharString cs;
|
CharString cs;
|
||||||
@@ -67,7 +66,7 @@ public:
|
|||||||
String id_to_text(ID p_id) const;
|
String id_to_text(ID p_id) const;
|
||||||
ID text_to_id(const String &p_text) const;
|
ID text_to_id(const String &p_text) const;
|
||||||
|
|
||||||
ID create_id() const;
|
ID create_id();
|
||||||
bool has_id(ID p_id) const;
|
bool has_id(ID p_id) const;
|
||||||
void add_id(ID p_id, const String &p_path);
|
void add_id(ID p_id, const String &p_path);
|
||||||
void set_id(ID p_id, const String &p_path);
|
void set_id(ID p_id, const String &p_path);
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ public:
|
|||||||
|
|
||||||
virtual String get_stdin_string(bool p_block = true) = 0;
|
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 PackedStringArray get_connected_midi_inputs();
|
||||||
virtual void open_midi_inputs();
|
virtual void open_midi_inputs();
|
||||||
virtual void close_midi_inputs();
|
virtual void close_midi_inputs();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<description>
|
<description>
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="create_id" qualifiers="const">
|
<method name="create_id">
|
||||||
<return type="int" />
|
<return type="int" />
|
||||||
<description>
|
<description>
|
||||||
</description>
|
</description>
|
||||||
|
|||||||
@@ -65,6 +65,21 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.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)
|
/// Clock Setup function (used by get_ticks_usec)
|
||||||
static uint64_t _clock_start = 0;
|
static uint64_t _clock_start = 0;
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
@@ -150,6 +165,31 @@ String OS_Unix::get_stdin_string(bool p_block) {
|
|||||||
return "";
|
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 {
|
String OS_Unix::get_name() const {
|
||||||
return "Unix";
|
return "Unix";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ protected:
|
|||||||
|
|
||||||
virtual void initialize_core();
|
virtual void initialize_core();
|
||||||
virtual int unix_initialize_audio(int p_audio_driver);
|
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;
|
virtual void finalize_core() override;
|
||||||
|
|
||||||
@@ -54,15 +53,7 @@ public:
|
|||||||
|
|
||||||
virtual String get_stdin_string(bool p_block) override;
|
virtual String get_stdin_string(bool p_block) override;
|
||||||
|
|
||||||
//virtual void set_mouse_show(bool p_show);
|
virtual Error get_entropy(uint8_t *r_buffer, int p_bytes) override; // Should return cryptographycally-safe random bytes.
|
||||||
//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 open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) 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 close_dynamic_library(void *p_library_handle) override;
|
||||||
|
|||||||
@@ -1359,9 +1359,12 @@ Error CodeSign::_codesign_file(bool p_use_hardened_runtime, bool p_force, const
|
|||||||
|
|
||||||
// Generate common signature structures.
|
// Generate common signature structures.
|
||||||
if (id.is_empty()) {
|
if (id.is_empty()) {
|
||||||
Ref<Crypto> crypto = Ref<Crypto>(Crypto::create());
|
CryptoCore::RandomGenerator rng;
|
||||||
PackedByteArray uuid = crypto->generate_random_bytes(16);
|
ERR_FAIL_COND_V_MSG(rng.init(), FAILED, "Failed to initialize random number generator.");
|
||||||
id = (String("a-55554944") /*a-UUID*/ + String::hex_encode_buffer(uuid.ptr(), 16));
|
uint8_t uuid[16];
|
||||||
|
Error err = rng.get_random_bytes(uuid, 16);
|
||||||
|
ERR_FAIL_COND_V_MSG(err, err, "Failed to generate UUID.");
|
||||||
|
id = (String("a-55554944") /*a-UUID*/ + String::hex_encode_buffer(uuid, 16));
|
||||||
}
|
}
|
||||||
CharString uuid_str = id.utf8();
|
CharString uuid_str = id.utf8();
|
||||||
print_verbose(vformat("CodeSign: Used bundle ID: %s", id));
|
print_verbose(vformat("CodeSign: Used bundle ID: %s", id));
|
||||||
|
|||||||
@@ -41,7 +41,6 @@
|
|||||||
#ifndef CODESIGN_H
|
#ifndef CODESIGN_H
|
||||||
#define CODESIGN_H
|
#define CODESIGN_H
|
||||||
|
|
||||||
#include "core/crypto/crypto.h"
|
|
||||||
#include "core/crypto/crypto_core.h"
|
#include "core/crypto/crypto_core.h"
|
||||||
#include "core/io/dir_access.h"
|
#include "core/io/dir_access.h"
|
||||||
#include "core/io/file_access.h"
|
#include "core/io/file_access.h"
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include "windows_terminal_logger.h"
|
#include "windows_terminal_logger.h"
|
||||||
|
|
||||||
#include <avrt.h>
|
#include <avrt.h>
|
||||||
|
#include <bcrypt.h>
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include <knownfolders.h>
|
#include <knownfolders.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
@@ -192,6 +193,12 @@ void OS_Windows::finalize_core() {
|
|||||||
NetSocketPosix::cleanup();
|
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) {
|
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("/", "\\");
|
String path = p_path.replace("/", "\\");
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,8 @@ protected:
|
|||||||
public:
|
public:
|
||||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
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 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 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;
|
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override;
|
||||||
|
|||||||
@@ -7,7 +7,12 @@
|
|||||||
|
|
||||||
#define MBEDTLS_AES_C
|
#define MBEDTLS_AES_C
|
||||||
#define MBEDTLS_BASE64_C
|
#define MBEDTLS_BASE64_C
|
||||||
|
#define MBEDTLS_CTR_DRBG_C
|
||||||
|
#define MBEDTLS_ENTROPY_C
|
||||||
#define MBEDTLS_MD5_C
|
#define MBEDTLS_MD5_C
|
||||||
#define MBEDTLS_SHA1_C
|
#define MBEDTLS_SHA1_C
|
||||||
#define MBEDTLS_SHA256_C
|
#define MBEDTLS_SHA256_C
|
||||||
#define MBEDTLS_PLATFORM_ZEROIZE_ALT
|
#define MBEDTLS_PLATFORM_ZEROIZE_ALT
|
||||||
|
#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user