diff options
Diffstat (limited to 'core')
| -rw-r--r-- | core/crypto/aes_context.cpp | 116 | ||||
| -rw-r--r-- | core/crypto/aes_context.h | 68 | ||||
| -rw-r--r-- | core/crypto/crypto.cpp | 29 | ||||
| -rw-r--r-- | core/crypto/crypto.h | 13 | ||||
| -rw-r--r-- | core/crypto/crypto_core.cpp | 10 | ||||
| -rw-r--r-- | core/crypto/crypto_core.h | 2 | ||||
| -rw-r--r-- | core/image.cpp | 27 | ||||
| -rw-r--r-- | core/local_vector.h | 8 | ||||
| -rw-r--r-- | core/math/basis.cpp | 2 | ||||
| -rw-r--r-- | core/math/geometry_2d.cpp | 2 | ||||
| -rw-r--r-- | core/math/geometry_3d.cpp | 4 | ||||
| -rw-r--r-- | core/math/geometry_3d.h | 10 | ||||
| -rw-r--r-- | core/register_core_types.cpp | 2 | ||||
| -rw-r--r-- | core/variant_op.cpp | 1 |
14 files changed, 270 insertions, 24 deletions
diff --git a/core/crypto/aes_context.cpp b/core/crypto/aes_context.cpp new file mode 100644 index 0000000000..8ef1f4f1d4 --- /dev/null +++ b/core/crypto/aes_context.cpp @@ -0,0 +1,116 @@ +/*************************************************************************/ +/* aes_context.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "core/crypto/aes_context.h" + +Error AESContext::start(Mode p_mode, PackedByteArray p_key, PackedByteArray p_iv) { + ERR_FAIL_COND_V_MSG(mode != MODE_MAX, ERR_ALREADY_IN_USE, "AESContext already started. Call 'finish' before starting a new one."); + ERR_FAIL_COND_V_MSG(p_mode < 0 || p_mode >= MODE_MAX, ERR_INVALID_PARAMETER, "Invalid mode requested."); + // Key check. + int key_bits = p_key.size() << 3; + ERR_FAIL_COND_V_MSG(key_bits != 128 && key_bits != 256, ERR_INVALID_PARAMETER, "AES key must be either 16 or 32 bytes"); + // Initialization vector. + if (p_mode == MODE_CBC_ENCRYPT || p_mode == MODE_CBC_DECRYPT) { + ERR_FAIL_COND_V_MSG(p_iv.size() != 16, ERR_INVALID_PARAMETER, "The initialization vector (IV) must be exactly 16 bytes."); + iv.resize(0); + iv.append_array(p_iv); + } + // Encryption/decryption key. + if (p_mode == MODE_CBC_ENCRYPT || p_mode == MODE_ECB_ENCRYPT) { + ctx.set_encode_key(p_key.ptr(), key_bits); + } else { + ctx.set_decode_key(p_key.ptr(), key_bits); + } + mode = p_mode; + return OK; +} + +PackedByteArray AESContext::update(PackedByteArray p_src) { + ERR_FAIL_COND_V_MSG(mode < 0 || mode >= MODE_MAX, PackedByteArray(), "AESContext not started. Call 'start' before calling 'update'."); + int len = p_src.size(); + ERR_FAIL_COND_V_MSG(len % 16, PackedByteArray(), "The number of bytes to be encrypted must be multiple of 16. Add padding if needed"); + PackedByteArray out; + out.resize(len); + const uint8_t *src_ptr = p_src.ptr(); + uint8_t *out_ptr = out.ptrw(); + switch (mode) { + case MODE_ECB_ENCRYPT: { + for (int i = 0; i < len; i += 16) { + Error err = ctx.encrypt_ecb(src_ptr + i, out_ptr + i); + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + } + } break; + case MODE_ECB_DECRYPT: { + for (int i = 0; i < len; i += 16) { + Error err = ctx.decrypt_ecb(src_ptr + i, out_ptr + i); + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + } + } break; + case MODE_CBC_ENCRYPT: { + Error err = ctx.encrypt_cbc(len, iv.ptrw(), p_src.ptr(), out.ptrw()); + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + } break; + case MODE_CBC_DECRYPT: { + Error err = ctx.decrypt_cbc(len, iv.ptrw(), p_src.ptr(), out.ptrw()); + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + } break; + default: + ERR_FAIL_V_MSG(PackedByteArray(), "Bug!"); + } + return out; +} + +PackedByteArray AESContext::get_iv_state() { + ERR_FAIL_COND_V_MSG(mode != MODE_CBC_ENCRYPT && mode != MODE_CBC_DECRYPT, PackedByteArray(), "Calling 'get_iv_state' only makes sense when the context is started in CBC mode."); + PackedByteArray out; + out.append_array(iv); + return out; +} + +void AESContext::finish() { + mode = MODE_MAX; + iv.resize(0); +} + +void AESContext::_bind_methods() { + ClassDB::bind_method(D_METHOD("start", "mode", "key", "iv"), &AESContext::start, DEFVAL(PackedByteArray())); + ClassDB::bind_method(D_METHOD("update", "src"), &AESContext::update); + ClassDB::bind_method(D_METHOD("get_iv_state"), &AESContext::get_iv_state); + ClassDB::bind_method(D_METHOD("finish"), &AESContext::finish); + BIND_ENUM_CONSTANT(MODE_ECB_ENCRYPT); + BIND_ENUM_CONSTANT(MODE_ECB_DECRYPT); + BIND_ENUM_CONSTANT(MODE_CBC_ENCRYPT); + BIND_ENUM_CONSTANT(MODE_CBC_DECRYPT); + BIND_ENUM_CONSTANT(MODE_MAX); +} + +AESContext::AESContext() { + mode = MODE_MAX; +} diff --git a/core/crypto/aes_context.h b/core/crypto/aes_context.h new file mode 100644 index 0000000000..006ecee2ad --- /dev/null +++ b/core/crypto/aes_context.h @@ -0,0 +1,68 @@ +/*************************************************************************/ +/* aes_context.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef AES_CONTEXT_H +#define AES_CONTEXT_H + +#include "core/crypto/crypto_core.h" +#include "core/reference.h" + +class AESContext : public Reference { + GDCLASS(AESContext, Reference); + +public: + enum Mode { + MODE_ECB_ENCRYPT, + MODE_ECB_DECRYPT, + MODE_CBC_ENCRYPT, + MODE_CBC_DECRYPT, + MODE_MAX + }; + +private: + Mode mode; + CryptoCore::AESContext ctx; + PackedByteArray iv; + +protected: + static void _bind_methods(); + +public: + Error start(Mode p_mode, PackedByteArray p_key, PackedByteArray p_iv = PackedByteArray()); + PackedByteArray update(PackedByteArray p_src); + PackedByteArray get_iv_state(); + void finish(); + + AESContext(); +}; + +VARIANT_ENUM_CAST(AESContext::Mode); + +#endif // AES_CONTEXT_H diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index a9a7cabee9..29d02e11df 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -45,8 +45,11 @@ CryptoKey *CryptoKey::create() { } void CryptoKey::_bind_methods() { - ClassDB::bind_method(D_METHOD("save", "path"), &CryptoKey::save); - ClassDB::bind_method(D_METHOD("load", "path"), &CryptoKey::load); + ClassDB::bind_method(D_METHOD("save", "path", "public_only"), &CryptoKey::save, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("load", "path", "public_only"), &CryptoKey::load, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("is_public_only"), &CryptoKey::is_public_only); + ClassDB::bind_method(D_METHOD("save_to_string", "public_only"), &CryptoKey::save_to_string, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("load_from_string", "string_key", "public_only"), &CryptoKey::load_from_string, DEFVAL(false)); } X509Certificate *(*X509Certificate::_create)() = nullptr; @@ -83,6 +86,10 @@ void Crypto::_bind_methods() { ClassDB::bind_method(D_METHOD("generate_random_bytes", "size"), &Crypto::generate_random_bytes); ClassDB::bind_method(D_METHOD("generate_rsa", "size"), &Crypto::generate_rsa); ClassDB::bind_method(D_METHOD("generate_self_signed_certificate", "key", "issuer_name", "not_before", "not_after"), &Crypto::generate_self_signed_certificate, DEFVAL("CN=myserver,O=myorganisation,C=IT"), DEFVAL("20140101000000"), DEFVAL("20340101000000")); + ClassDB::bind_method(D_METHOD("sign", "hash_type", "hash", "key"), &Crypto::sign); + ClassDB::bind_method(D_METHOD("verify", "hash_type", "hash", "signature", "key"), &Crypto::verify); + ClassDB::bind_method(D_METHOD("encrypt", "key", "plaintext"), &Crypto::encrypt); + ClassDB::bind_method(D_METHOD("decrypt", "key", "ciphertext"), &Crypto::decrypt); } /// Resource loader/saver @@ -98,9 +105,14 @@ RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_origi } else if (el == "key") { CryptoKey *key = CryptoKey::create(); if (key) { - key->load(p_path); + key->load(p_path, false); } return key; + } else if (el == "pub") { + CryptoKey *key = CryptoKey::create(); + if (key) + key->load(p_path, true); + return key; } return nullptr; } @@ -108,6 +120,7 @@ RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_origi void ResourceFormatLoaderCrypto::get_recognized_extensions(List<String> *p_extensions) const { p_extensions->push_back("crt"); p_extensions->push_back("key"); + p_extensions->push_back("pub"); } bool ResourceFormatLoaderCrypto::handles_type(const String &p_type) const { @@ -118,7 +131,7 @@ String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const String el = p_path.get_extension().to_lower(); if (el == "crt") { return "X509Certificate"; - } else if (el == "key") { + } else if (el == "key" || el == "pub") { return "CryptoKey"; } return ""; @@ -131,7 +144,8 @@ Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resourc if (cert.is_valid()) { err = cert->save(p_path); } else if (key.is_valid()) { - err = key->save(p_path); + String el = p_path.get_extension().to_lower(); + err = key->save(p_path, el == "pub"); } else { ERR_FAIL_V(ERR_INVALID_PARAMETER); } @@ -146,7 +160,10 @@ void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource, p_extensions->push_back("crt"); } if (key) { - p_extensions->push_back("key"); + if (!key->is_public_only()) { + p_extensions->push_back("key"); + } + p_extensions->push_back("pub"); } } diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index 6cc5f46164..916f7798eb 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -31,6 +31,7 @@ #ifndef CRYPTO_H #define CRYPTO_H +#include "core/crypto/hashing_context.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/reference.h" @@ -45,8 +46,11 @@ protected: public: static CryptoKey *create(); - virtual Error load(String p_path) = 0; - virtual Error save(String p_path) = 0; + virtual Error load(String p_path, bool p_public_only = false) = 0; + virtual Error save(String p_path, bool p_public_only = false) = 0; + virtual String save_to_string(bool p_public_only = false) = 0; + virtual Error load_from_string(String p_string_key, bool p_public_only = false) = 0; + virtual bool is_public_only() const = 0; }; class X509Certificate : public Resource { @@ -79,6 +83,11 @@ public: virtual Ref<CryptoKey> generate_rsa(int p_bytes) = 0; virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) = 0; + virtual Vector<uint8_t> sign(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Ref<CryptoKey> p_key) = 0; + virtual bool verify(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Vector<uint8_t> p_signature, Ref<CryptoKey> p_key) = 0; + virtual Vector<uint8_t> encrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_plaintext) = 0; + virtual Vector<uint8_t> decrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_ciphertext) = 0; + Crypto() {} }; diff --git a/core/crypto/crypto_core.cpp b/core/crypto/crypto_core.cpp index ec25ee0d38..b0dc47e655 100644 --- a/core/crypto/crypto_core.cpp +++ b/core/crypto/crypto_core.cpp @@ -145,6 +145,16 @@ Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst return ret ? FAILED : OK; } +Error CryptoCore::AESContext::encrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst) { + int ret = mbedtls_aes_crypt_cbc((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_length, r_iv, p_src, r_dst); + return ret ? FAILED : OK; +} + +Error CryptoCore::AESContext::decrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst) { + int ret = mbedtls_aes_crypt_cbc((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_length, r_iv, p_src, r_dst); + return ret ? FAILED : OK; +} + // CryptoCore String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) { int b64len = p_src_len / 3 * 4 + 4 + 1; diff --git a/core/crypto/crypto_core.h b/core/crypto/crypto_core.h index 36d8ace723..82df9c23a8 100644 --- a/core/crypto/crypto_core.h +++ b/core/crypto/crypto_core.h @@ -86,6 +86,8 @@ public: Error set_decode_key(const uint8_t *p_key, size_t p_bits); Error encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]); Error decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]); + Error encrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst); + Error decrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst); }; static String b64_encode_str(const uint8_t *p_src, int p_src_len); diff --git a/core/image.cpp b/core/image.cpp index 0f15574053..45f10625a9 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -678,34 +678,35 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict enum { FRAC_BITS = 8, FRAC_LEN = (1 << FRAC_BITS), + FRAC_HALF = (FRAC_LEN >> 1), FRAC_MASK = FRAC_LEN - 1 - }; for (uint32_t i = 0; i < p_dst_height; i++) { - uint32_t src_yofs_up_fp = (i * p_src_height * FRAC_LEN / p_dst_height); - uint32_t src_yofs_frac = src_yofs_up_fp & FRAC_MASK; - uint32_t src_yofs_up = src_yofs_up_fp >> FRAC_BITS; - - uint32_t src_yofs_down = (i + 1) * p_src_height / p_dst_height; + // Add 0.5 in order to interpolate based on pixel center + uint32_t src_yofs_up_fp = (i + 0.5) * p_src_height * FRAC_LEN / p_dst_height; + // Calculate nearest src pixel center above current, and truncate to get y index + uint32_t src_yofs_up = src_yofs_up_fp >= FRAC_HALF ? (src_yofs_up_fp - FRAC_HALF) >> FRAC_BITS : 0; + uint32_t src_yofs_down = (src_yofs_up_fp + FRAC_HALF) >> FRAC_BITS; if (src_yofs_down >= p_src_height) { src_yofs_down = p_src_height - 1; } - - //src_yofs_up*=CC; - //src_yofs_down*=CC; + // Calculate distance to pixel center of src_yofs_up + uint32_t src_yofs_frac = src_yofs_up_fp & FRAC_MASK; + src_yofs_frac = src_yofs_frac >= FRAC_HALF ? src_yofs_frac - FRAC_HALF : src_yofs_frac + FRAC_HALF; uint32_t y_ofs_up = src_yofs_up * p_src_width * CC; uint32_t y_ofs_down = src_yofs_down * p_src_width * CC; for (uint32_t j = 0; j < p_dst_width; j++) { - uint32_t src_xofs_left_fp = (j * p_src_width * FRAC_LEN / p_dst_width); - uint32_t src_xofs_frac = src_xofs_left_fp & FRAC_MASK; - uint32_t src_xofs_left = src_xofs_left_fp >> FRAC_BITS; - uint32_t src_xofs_right = (j + 1) * p_src_width / p_dst_width; + uint32_t src_xofs_left_fp = (j + 0.5) * p_src_width * FRAC_LEN / p_dst_width; + uint32_t src_xofs_left = src_xofs_left_fp >= FRAC_HALF ? (src_xofs_left_fp - FRAC_HALF) >> FRAC_BITS : 0; + uint32_t src_xofs_right = (src_xofs_left_fp + FRAC_HALF) >> FRAC_BITS; if (src_xofs_right >= p_src_width) { src_xofs_right = p_src_width - 1; } + uint32_t src_xofs_frac = src_xofs_left_fp & FRAC_MASK; + src_xofs_frac = src_xofs_frac >= FRAC_HALF ? src_xofs_frac - FRAC_HALF : src_xofs_frac + FRAC_HALF; src_xofs_left *= CC; src_xofs_right *= CC; diff --git a/core/local_vector.h b/core/local_vector.h index 7f96b25f8b..d97f3330dc 100644 --- a/core/local_vector.h +++ b/core/local_vector.h @@ -45,6 +45,14 @@ private: T *data = nullptr; public: + T *ptr() { + return data; + } + + const T *ptr() const { + return data; + } + _FORCE_INLINE_ void push_back(T p_elem) { if (unlikely(count == capacity)) { if (capacity == 0) { diff --git a/core/math/basis.cpp b/core/math/basis.cpp index df5199b0f9..dd38e25bb1 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -773,7 +773,7 @@ Basis::operator String() const { mtx += ", "; } - mtx += rtos(elements[i][j]); + mtx += rtos(elements[j][i]); //matrix is stored transposed for performance, so print it transposed } } diff --git a/core/math/geometry_2d.cpp b/core/math/geometry_2d.cpp index 7d8fde8bcc..4636e1c774 100644 --- a/core/math/geometry_2d.cpp +++ b/core/math/geometry_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* geometry.cpp */ +/* geometry_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index 3b30f4b1fe..7807ab19a7 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* geometry.cpp */ +/* geometry_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -993,6 +993,8 @@ Vector<uint32_t> Geometry3D::generate_edf(const Vector<bool> &p_voxels, const Ve } } + memdelete_arr(work_memory); + return ret; } diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 64cd34892e..6bbf518141 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -945,6 +945,16 @@ public: return Color(va6 * v6, vb6 * v6, vc6 * v6, vd6 * v6); #undef STP } + + _FORCE_INLINE_ static Vector3 octahedron_map_decode(const Vector2 &p_uv) { + // https://twitter.com/Stubbesaurus/status/937994790553227264 + Vector2 f = p_uv * 2.0 - Vector2(1.0, 1.0); + Vector3 n = Vector3(f.x, f.y, 1.0f - Math::abs(f.x) - Math::abs(f.y)); + float t = CLAMP(-n.z, 0.0, 1.0); + n.x += n.x >= 0 ? -t : t; + n.y += n.y >= 0 ? -t : t; + return n.normalized(); + } }; #endif // GEOMETRY_3D_H diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index c0f9eea76d..5dac42cacb 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -34,6 +34,7 @@ #include "core/class_db.h" #include "core/compressed_translation.h" #include "core/core_string_names.h" +#include "core/crypto/aes_context.h" #include "core/crypto/crypto.h" #include "core/crypto/hashing_context.h" #include "core/engine.h" @@ -165,6 +166,7 @@ void register_core_types() { // Crypto ClassDB::register_class<HashingContext>(); + ClassDB::register_class<AESContext>(); ClassDB::register_custom_instance_class<X509Certificate>(); ClassDB::register_custom_instance_class<CryptoKey>(); ClassDB::register_custom_instance_class<Crypto>(); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 2c79e2029e..0c9a4a992a 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -1786,6 +1786,7 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const { if (r_valid) { *r_valid = true; } + switch (type) { case VECTOR2: { const Vector2 *v = reinterpret_cast<const Vector2 *>(_data._mem); |