From ad93bd79cc2e64fe4fec083c57b54a64f2bf9e4d Mon Sep 17 00:00:00 2001 From: Elias Batek Date: Sat, 25 Jan 2025 19:05:53 +0100 Subject: [PATCH] Replace CryptoAPI with Cryptography API: Next Generation (CNG) --- std/random.d | 55 +++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/std/random.d b/std/random.d index 3f9b52e804b..c1ea545ab40 100644 --- a/std/random.d +++ b/std/random.d @@ -1792,39 +1792,36 @@ version (linux) version (Windows) { - pragma(lib, "advapi32.lib"); // `std.registry` does so, too. + pragma(lib, "Bcrypt.lib"); - private bool wincryptGenRandom(T)(out T result) @trusted + private bool bcryptGenRandom(T)(out T result) @trusted { - import core.sys.windows.windef : DWORD, PBYTE; - import core.sys.windows.wincrypt : - CryptAcquireContext, - CryptGenRandom, - CryptReleaseContext, - CRYPT_VERIFYCONTEXT, - HCRYPTPROV, - MS_STRONG_PROV, - PROV_RSA_FULL; - - HCRYPTPROV wincryptHandle; - - const gotHandle = CryptAcquireContext( - &wincryptHandle, - null, + import core.sys.windows.windef : PUCHAR, ULONG; + import core.sys.windows.ntdef : NTSTATUS, NT_SUCCESS; + import core.sys.windows.bcrypt : + BCryptCloseAlgorithmProvider, + BCryptGenRandom, + BCryptOpenAlgorithmProvider, + BCRYPT_ALG_HANDLE; + + BCRYPT_ALG_HANDLE bcryptHandle; + + const handleStatus = BCryptOpenAlgorithmProvider( + &bcryptHandle, MS_STRONG_PROV.ptr, - PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT, + null, + 0, ); - if (!gotHandle) + if (!NT_SUCCESS(handleStatus)) return false; scope (exit) - if (!CryptReleaseContext(wincryptHandle, 0)) { /* ignore */ } + if (!BCryptCloseAlgorithmProvider(bcryptHandle, 0)) { /* ignore */ } - const gotRandom = CryptGenRandom( - wincryptHandle, - DWORD(T.sizeof), - cast(PBYTE) &result, + const gotRandom = BCryptGenRandom( + bcryptHandle, + cast(PUCHAR) &result, + ULONG(T.sizeof), ); if (!gotRandom) return false; @@ -1894,12 +1891,12 @@ how excellent the source of entropy is. else version (Windows) { uint result; - if (!wincryptGenRandom!uint(result)) + if (!bcryptGenRandom!uint(result)) { version (none) return fallbackSeed(); else - assert(false, "CryptAcquireContext() or CryptGenRandom() failed."); + assert(false, "BCryptOpenAlgorithmProvider() or BCryptGenRandom() failed."); } return result; } @@ -1973,12 +1970,12 @@ if (isUnsigned!UIntType) else version (Windows) { UIntType result; - if (!wincryptGenRandom!UIntType(result)) + if (!bcryptGenRandom!UIntType(result)) { version (none) return fallbackSeed(); else - assert(false, "CryptAcquireContext() or CryptGenRandom() failed."); + assert(false, "BCryptOpenAlgorithmProvider() or BCryptGenRandom() failed."); } return result; }