From b9d008de3d171fa7da763616161b462ed8815a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Fri, 27 Oct 2023 10:25:50 +0200 Subject: [PATCH] mbedtls: Backport Windows fix to use bcrypt for entropy We had a slightly older version of it for UWP, as the wincrypt API isn't allowed there. We removed this with UWP in #81416, but since this was enabled inconditionally before, this actually changed behavior for Windows compared to Godot 4.1 and earlier. This change is also needed to properly supported Windows Store. --- thirdparty/README.md | 6 +- thirdparty/mbedtls/library/entropy_poll.c | 32 ++++++----- .../patches/windows-entropy-bcrypt.diff | 56 +++++++++++++++++++ 3 files changed, 76 insertions(+), 18 deletions(-) create mode 100644 thirdparty/mbedtls/patches/windows-entropy-bcrypt.diff diff --git a/thirdparty/README.md b/thirdparty/README.md index a81b5ea0fff..a3989a1f5d6 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -480,7 +480,7 @@ in the MSVC debugger. ## mbedtls - Upstream: https://github.com/Mbed-TLS/mbedtls -- Version: 2.28.4 (aeb97a18913a86f051afab11b2c92c6be0c2eb83, 2023) +- Version: 2.28.5 (47e8cc9db2e469d902b0e3093ae9e482c3d87188, 2023) - License: Apache 2.0 File extracted from upstream release tarball: @@ -490,8 +490,8 @@ File extracted from upstream release tarball: - All `.c` and `.h` from `library/` to `thirdparty/mbedtls/library/` except those starting with `psa_*` - The `LICENSE` file -- Applied the patch in `patches/windows-arm64-hardclock.diff` - Applied the patch in `aesni-no-arm-intrinsics.patch` to fix MSVC ARM build +- Applied the patch `windows-arm64-hardclock.diff` to fix Windows ARM64 build + Applied the patch `windows-entropy-bcrypt.diff` to fix Windows Store support - Added 2 files `godot_core_mbedtls_platform.c` and `godot_core_mbedtls_config.h` providing configuration for light bundling with core - Added the file `godot_module_mbedtls_config.h` to customize the build diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c index 3420616a06c..fec2abc2e43 100644 --- a/thirdparty/mbedtls/library/entropy_poll.c +++ b/thirdparty/mbedtls/library/entropy_poll.c @@ -51,31 +51,33 @@ #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) -#if !defined(_WIN32_WINNT) -#define _WIN32_WINNT 0x0400 -#endif #include -#include +#include +#include int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen) { - HCRYPTPROV provider; ((void) data); *olen = 0; - if (CryptAcquireContext(&provider, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) { - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } + /* + * BCryptGenRandom takes ULONG for size, which is smaller than size_t on + * 64-bit Windows platforms. Extract entropy in chunks of len (dependent + * on ULONG_MAX) size. + */ + while (len != 0) { + unsigned long ulong_bytes = + (len > ULONG_MAX) ? ULONG_MAX : (unsigned long) len; - if (CryptGenRandom(provider, (DWORD) len, output) == FALSE) { - CryptReleaseContext(provider, 0); - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } + if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, ulong_bytes, + BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { + return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + } - CryptReleaseContext(provider, 0); - *olen = len; + *olen += ulong_bytes; + len -= ulong_bytes; + } return 0; } diff --git a/thirdparty/mbedtls/patches/windows-entropy-bcrypt.diff b/thirdparty/mbedtls/patches/windows-entropy-bcrypt.diff new file mode 100644 index 00000000000..2517687be63 --- /dev/null +++ b/thirdparty/mbedtls/patches/windows-entropy-bcrypt.diff @@ -0,0 +1,56 @@ +Backported from: https://github.com/Mbed-TLS/mbedtls/pull/8047 + +diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c +index 3420616a06..fec2abc2e4 100644 +--- a/thirdparty/mbedtls/library/entropy_poll.c ++++ b/thirdparty/mbedtls/library/entropy_poll.c +@@ -51,32 +51,34 @@ + + #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +-#if !defined(_WIN32_WINNT) +-#define _WIN32_WINNT 0x0400 +-#endif + #include +-#include ++#include ++#include + + int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, + size_t *olen) + { +- HCRYPTPROV provider; + ((void) data); + *olen = 0; + +- if (CryptAcquireContext(&provider, NULL, NULL, +- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) { +- return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; +- } ++ /* ++ * BCryptGenRandom takes ULONG for size, which is smaller than size_t on ++ * 64-bit Windows platforms. Extract entropy in chunks of len (dependent ++ * on ULONG_MAX) size. ++ */ ++ while (len != 0) { ++ unsigned long ulong_bytes = ++ (len > ULONG_MAX) ? ULONG_MAX : (unsigned long) len; ++ ++ if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, ulong_bytes, ++ BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { ++ return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; ++ } + +- if (CryptGenRandom(provider, (DWORD) len, output) == FALSE) { +- CryptReleaseContext(provider, 0); +- return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; ++ *olen += ulong_bytes; ++ len -= ulong_bytes; + } + +- CryptReleaseContext(provider, 0); +- *olen = len; +- + return 0; + } + #else /* _WIN32 && !EFIX64 && !EFI32 */