-
-
Notifications
You must be signed in to change notification settings - Fork 21.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update builtin mbedtls to 3.5.1, keeping compatiblity with mbedtls 2.x #82282
Conversation
I did a quick comparison with the artifacts from this PR and from https://github.com/godotengine/godot/actions/runs/6292543678 merged yesterday. The current
So there's +20/30 kB for Linux editor/templates, but -40 kB for the Web template and the Windows editor. So it's pretty much an insignificant difference. |
202da6f
to
05e1efd
Compare
@Faless isn't confident bumping the mbedtls version right now. Also, mbedTLS 3.5 just came out, so we should do the switch soon after the release to have an entire release cycle to ensure Godot Engine networking works. Switching to mbedTLS 3.x means more maintenance burden and potentially more instability. The plan is to merge the mbedtls update after the Godot Engine 4.2 release is out. |
Sounds like a good plan 👍 |
fd0ba0b
to
d791a54
Compare
@Faless The window for 4.3 is running down, what is the revised plan for this? I don't see a mbedtls upgrade being essential if the webrtc isn't desired in the core, and that was the reason for the upgrade. So the mbedlts upgrade is salvageable for someone? Good reasons to salvage:
|
@fire You asked about being salvageable. I was able to rebase to latest master with no issue, so I think this PR should still be fine. What are the next steps? |
=============================================================================== | ||
|
||
|
||
GNU GENERAL PUBLIC LICENSE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't include the text of the GPL, this will freak people out. The upstream Apache-licensed source tarball usually has the edited version of the LICENSE with only Apache (basically the file we already had).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to test a build against a distro mbedtls 2.x to confirm it's working, but I support moving to mbedtls 3 as our bundled version.
Reserving merge for approval by @Faless.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work 🏆 .
This looks overall good, see my suggestion about seeding rngs on-the-fly when parsing private keys.
Also, I noticed that building with module_mbedtls_enabled=no
is giving some weird linking error:
$ scons module_mbedtls_enabled=no
scons: Reading SConscript files ...
Automatically detected platform: linuxbsd
Auto-detected 8 CPU cores available for build parallelism. Using 7 cores by default. You can override it with the -j argument.
Using linker program: gold
Building for platform "linuxbsd", architecture "x86_64", target "editor".
NOTE: Developer build, with debug optimization level and debug symbols (unless overridden).
Checking for C header file mntent.h... (cached) yes
scons: done reading SConscript files.
scons: Building targets ...
[ 96%] Linking Program bin/godot.linuxbsd.editor.dev.x86_64 ...
[100%] progress_finish(["progress_finish"], [])
[100%] thirdparty/mbedtls/library/common.h:221: error: undefined reference to 'mbedtls_get_unaligned_uint64'
thirdparty/mbedtls/library/common.h:221: error: undefined reference to 'mbedtls_get_unaligned_uint64'
thirdparty/mbedtls/library/common.h:222: error: undefined reference to 'mbedtls_put_unaligned_uint64'
thirdparty/mbedtls/library/aes.c:650: error: undefined reference to 'mbedtls_get_unaligned_uint32'
thirdparty/mbedtls/library/aes.c:930: error: undefined reference to 'mbedtls_get_unaligned_uint32'
thirdparty/mbedtls/library/aes.c:931: error: undefined reference to 'mbedtls_get_unaligned_uint32'
thirdparty/mbedtls/library/aes.c:932: error: undefined reference to 'mbedtls_get_unaligned_uint32'
thirdparty/mbedtls/library/aes.c:966: error: undefined reference to 'mbedtls_put_unaligned_uint32'
thirdparty/mbedtls/library/aes.c:967: error: undefined reference to 'mbedtls_put_unaligned_uint32'
thirdparty/mbedtls/library/aes.c:968: error: undefined reference to 'mbedtls_put_unaligned_uint32'
thirdparty/mbedtls/library/aes.c:969: error: undefined reference to 'mbedtls_put_unaligned_uint32'
thirdparty/mbedtls/library/aes.c:1206: error: undefined reference to 'mbedtls_get_unaligned_uint64'
thirdparty/mbedtls/library/aes.c:1207: error: undefined reference to 'mbedtls_get_unaligned_uint64'
thirdparty/mbedtls/library/aes.c:1212: error: undefined reference to 'mbedtls_put_unaligned_uint64'
thirdparty/mbedtls/library/aes.c:1213: error: undefined reference to 'mbedtls_put_unaligned_uint64'
thirdparty/mbedtls/library/aes.c:1271: error: undefined reference to 'mbedtls_xor'
thirdparty/mbedtls/library/aes.c:1278: error: undefined reference to 'mbedtls_xor'
thirdparty/mbedtls/library/aes.c:1304: error: undefined reference to 'mbedtls_xor'
thirdparty/mbedtls/library/aes.c:1308: error: undefined reference to 'mbedtls_xor'
thirdparty/mbedtls/library/constant_time.c:213: error: undefined reference to 'mbedtls_put_unaligned_uint64'
collect2: error: ld returned 1 exit status
scons: *** [bin/godot.linuxbsd.editor.dev.x86_64] Error 1
scons: building terminated because of errors.
[Time elapsed: 00:00:28.522]
#if MBEDTLS_VERSION_MAJOR >= 3 | ||
static mbedtls_entropy_context rng_entropy; | ||
static mbedtls_ctr_drbg_context rng_drbg; | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit worried about this.
mbedTLS doesn't guarantee thread safety in some circumstances (e.g. the threading module can be disabled).
In similar cases (e.g. Crytpo/TLSContext), we always use per-instance rngs.
In this case, given the type of resource in question (CryptoKey) I suggest we instead create it on the fly when parsing.
diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp
index 4bb29d3b00..fbf48ea1e0 100644
--- a/modules/mbedtls/crypto_mbedtls.cpp
+++ b/modules/mbedtls/crypto_mbedtls.cpp
@@ -49,11 +49,6 @@
#define PEM_END_CRT "-----END CERTIFICATE-----\n"
#define PEM_MIN_SIZE 54
-#if MBEDTLS_VERSION_MAJOR >= 3
-static mbedtls_entropy_context rng_entropy;
-static mbedtls_ctr_drbg_context rng_drbg;
-#endif
-
CryptoKey *CryptoKeyMbedTLS::create() {
return memnew(CryptoKeyMbedTLS);
}
@@ -74,11 +69,7 @@ Error CryptoKeyMbedTLS::load(String p_path, bool p_public_only) {
if (p_public_only) {
ret = mbedtls_pk_parse_public_key(&pkey, out.ptr(), out.size());
} else {
-#if MBEDTLS_VERSION_MAJOR >= 3
- ret = mbedtls_pk_parse_key(&pkey, out.ptr(), out.size(), nullptr, 0, mbedtls_ctr_drbg_random, &rng_drbg);
-#else
- ret = mbedtls_pk_parse_key(&pkey, out.ptr(), out.size(), nullptr, 0);
-#endif
+ ret = _parse_key(out.ptr(), out.size());
}
// We MUST zeroize the memory for safety!
mbedtls_platform_zeroize(out.ptrw(), out.size());
@@ -117,11 +108,7 @@ Error CryptoKeyMbedTLS::load_from_string(String p_string_key, bool p_public_only
if (p_public_only) {
ret = mbedtls_pk_parse_public_key(&pkey, (unsigned char *)p_string_key.utf8().get_data(), p_string_key.utf8().size());
} else {
-#if MBEDTLS_VERSION_MAJOR >= 3
- ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)p_string_key.utf8().get_data(), p_string_key.utf8().size(), nullptr, 0, mbedtls_ctr_drbg_random, &rng_drbg);
-#else
- ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)p_string_key.utf8().get_data(), p_string_key.utf8().size(), nullptr, 0);
-#endif
+ ret = _parse_key((unsigned char *)p_string_key.utf8().get_data(), p_string_key.utf8().size());
}
ERR_FAIL_COND_V_MSG(ret, FAILED, "Error parsing key '" + itos(ret) + "'.");
@@ -147,6 +134,25 @@ String CryptoKeyMbedTLS::save_to_string(bool p_public_only) {
return s;
}
+int CryptoKeyMbedTLS::_parse_key(const uint8_t *p_buf, int p_size) {
+#if MBEDTLS_VERSION_MAJOR >= 3
+ mbedtls_entropy_context rng_entropy;
+ mbedtls_ctr_drbg_context rng_drbg;
+
+ mbedtls_ctr_drbg_init(&rng_drbg);
+ mbedtls_entropy_init(&rng_entropy);
+ int ret = mbedtls_ctr_drbg_seed(&rng_drbg, mbedtls_entropy_func, &rng_entropy, nullptr, 0);
+ ERR_FAIL_COND_V_MSG(ret != 0, ret, vformat("mbedtls_ctr_drbg_seed returned -0x%x\n", (unsigned int)-ret));
+
+ ret = mbedtls_pk_parse_key(&pkey, p_buf, p_size, nullptr, 0, mbedtls_ctr_drbg_random, &rng_drbg);
+ mbedtls_ctr_drbg_free(&rng_drbg);
+ mbedtls_entropy_free(&rng_entropy);
+ return ret;
+#else
+ return mbedtls_pk_parse_key(&pkey, p_buf, p_size, nullptr, 0);
+#endif
+}
+
X509Certificate *X509CertificateMbedTLS::create() {
return memnew(X509CertificateMbedTLS);
}
@@ -314,17 +320,6 @@ void CryptoMbedTLS::initialize_crypto() {
Crypto::_create = create;
Crypto::_load_default_certificates = load_default_certificates;
-
-#if MBEDTLS_VERSION_MAJOR >= 3
- mbedtls_ctr_drbg_init(&rng_drbg);
- mbedtls_entropy_init(&rng_entropy);
- const char *pers = "godot personalize";
- int ret = mbedtls_ctr_drbg_seed(&rng_drbg, mbedtls_entropy_func, &rng_entropy, (const unsigned char *)pers, strlen(pers));
- if (ret != 0) {
- ERR_PRINT(vformat("mbedtls_ctr_drbg_seed returned -0x%x\n", (unsigned int)-ret));
- }
-#endif
-
X509CertificateMbedTLS::make_default();
CryptoKeyMbedTLS::make_default();
HMACContextMbedTLS::make_default();
@@ -340,10 +335,6 @@ void CryptoMbedTLS::finalize_crypto() {
X509CertificateMbedTLS::finalize();
CryptoKeyMbedTLS::finalize();
HMACContextMbedTLS::finalize();
-#if MBEDTLS_VERSION_MAJOR >= 3
- mbedtls_ctr_drbg_free(&rng_drbg);
- mbedtls_entropy_free(&rng_entropy);
-#endif
}
CryptoMbedTLS::CryptoMbedTLS() {
diff --git a/modules/mbedtls/crypto_mbedtls.h b/modules/mbedtls/crypto_mbedtls.h
index 0168e1f663..18f0dadb9d 100644
--- a/modules/mbedtls/crypto_mbedtls.h
+++ b/modules/mbedtls/crypto_mbedtls.h
@@ -46,6 +46,8 @@ private:
int locks = 0;
bool public_only = true;
+ int _parse_key(const uint8_t *p_buf, int p_size);
+
public:
static CryptoKey *create();
static void make_default() { CryptoKey::_create = create; }
I did some work on mbedtls 3.6 upgrade in the webrtc branch but it's relatively hard to work with. Needs help. https://github.com/V-Sekai/godot/tree/vsk-libdatachannel-4.3 |
Superseded by #90482. |
Needed for libdatachannel support. Code compatibility was fairly straightforward. The only complexity was that a PRNG was required for parsing keys in CryptoKeyMbedTLS. Otherwise only a couple ifdefs were needed to keep compatibility with both mbedtls 3.x and 2.x.
In a non-rigorous test including both this and the libdatachannel integration, binary size was 1.1MB larger. I determined this size change was entirely due to libdatachannel.
I would like to break this down to see how much of this is from the mbedtls upgrade. Maybe we can compare github actions for a more accurate answer on binary size.