瀏覽代碼

Merge pull request #103415 from bruvzg/iv_pools

Use single RNG instance for `FileAccessEncrypted` IV generation.
Rémi Verschelde 4 月之前
父節點
當前提交
65161977e9
共有 3 個文件被更改,包括 26 次插入4 次删除
  1. 18 4
      core/io/file_access_encrypted.cpp
  2. 5 0
      core/io/file_access_encrypted.h
  3. 3 0
      core/register_core_types.cpp

+ 18 - 4
core/io/file_access_encrypted.cpp

@@ -30,9 +30,17 @@
 
 
 #include "file_access_encrypted.h"
 #include "file_access_encrypted.h"
 
 
-#include "core/crypto/crypto_core.h"
 #include "core/variant/variant.h"
 #include "core/variant/variant.h"
 
 
+CryptoCore::RandomGenerator *FileAccessEncrypted::_fae_static_rng = nullptr;
+
+void FileAccessEncrypted::deinitialize() {
+	if (_fae_static_rng) {
+		memdelete(_fae_static_rng);
+		_fae_static_rng = nullptr;
+	}
+}
+
 Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic, const Vector<uint8_t> &p_iv) {
 Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic, const Vector<uint8_t> &p_iv) {
 	ERR_FAIL_COND_V_MSG(file.is_valid(), ERR_ALREADY_IN_USE, vformat("Can't open file while another file from path '%s' is open.", file->get_path_absolute()));
 	ERR_FAIL_COND_V_MSG(file.is_valid(), ERR_ALREADY_IN_USE, vformat("Can't open file while another file from path '%s' is open.", file->get_path_absolute()));
 	ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
 	ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
@@ -48,9 +56,15 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u
 		key = p_key;
 		key = p_key;
 		if (p_iv.is_empty()) {
 		if (p_iv.is_empty()) {
 			iv.resize(16);
 			iv.resize(16);
-			CryptoCore::RandomGenerator rng;
-			ERR_FAIL_COND_V_MSG(rng.init(), FAILED, "Failed to initialize random number generator.");
-			Error err = rng.get_random_bytes(iv.ptrw(), 16);
+			if (unlikely(!_fae_static_rng)) {
+				_fae_static_rng = memnew(CryptoCore::RandomGenerator);
+				if (_fae_static_rng->init() != OK) {
+					memdelete(_fae_static_rng);
+					_fae_static_rng = nullptr;
+					ERR_FAIL_V_MSG(FAILED, "Failed to initialize random number generator.");
+				}
+			}
+			Error err = _fae_static_rng->get_random_bytes(iv.ptrw(), 16);
 			ERR_FAIL_COND_V(err != OK, err);
 			ERR_FAIL_COND_V(err != OK, err);
 		} else {
 		} else {
 			ERR_FAIL_COND_V(p_iv.size() != 16, ERR_INVALID_PARAMETER);
 			ERR_FAIL_COND_V(p_iv.size() != 16, ERR_INVALID_PARAMETER);

+ 5 - 0
core/io/file_access_encrypted.h

@@ -30,6 +30,7 @@
 
 
 #pragma once
 #pragma once
 
 
+#include "core/crypto/crypto_core.h"
 #include "core/io/file_access.h"
 #include "core/io/file_access.h"
 
 
 #define ENCRYPTED_HEADER_MAGIC 0x43454447
 #define ENCRYPTED_HEADER_MAGIC 0x43454447
@@ -56,6 +57,8 @@ private:
 
 
 	void _close();
 	void _close();
 
 
+	static CryptoCore::RandomGenerator *_fae_static_rng;
+
 public:
 public:
 	Error open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true, const Vector<uint8_t> &p_iv = Vector<uint8_t>());
 	Error open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true, const Vector<uint8_t> &p_iv = Vector<uint8_t>());
 	Error open_and_parse_password(Ref<FileAccess> p_base, const String &p_key, Mode p_mode);
 	Error open_and_parse_password(Ref<FileAccess> p_base, const String &p_key, Mode p_mode);
@@ -98,6 +101,8 @@ public:
 
 
 	virtual void close() override;
 	virtual void close() override;
 
 
+	static void deinitialize();
+
 	FileAccessEncrypted() {}
 	FileAccessEncrypted() {}
 	~FileAccessEncrypted();
 	~FileAccessEncrypted();
 };
 };

+ 3 - 0
core/register_core_types.cpp

@@ -45,6 +45,7 @@
 #include "core/io/config_file.h"
 #include "core/io/config_file.h"
 #include "core/io/dir_access.h"
 #include "core/io/dir_access.h"
 #include "core/io/dtls_server.h"
 #include "core/io/dtls_server.h"
+#include "core/io/file_access_encrypted.h"
 #include "core/io/http_client.h"
 #include "core/io/http_client.h"
 #include "core/io/image_loader.h"
 #include "core/io/image_loader.h"
 #include "core/io/json.h"
 #include "core/io/json.h"
@@ -455,5 +456,7 @@ void unregister_core_types() {
 	CoreStringNames::free();
 	CoreStringNames::free();
 	StringName::cleanup();
 	StringName::cleanup();
 
 
+	FileAccessEncrypted::deinitialize();
+
 	OS::get_singleton()->benchmark_end_measure("Core", "Unregister Types");
 	OS::get_singleton()->benchmark_end_measure("Core", "Unregister Types");
 }
 }