[*] Wanna drop threaten to drop older APIs from the Windows Runtime? Alright, we're being pushed towards Windows XP support by accident.

This commit is contained in:
Reece Wilson 2023-07-09 11:26:17 +01:00
parent 8c5a706dc6
commit 14d60ee2d0
3 changed files with 99 additions and 38 deletions

View File

@ -24,6 +24,8 @@ namespace Aurora
ADD_LOAD_LIB(KernelBase); ADD_LOAD_LIB(KernelBase);
ADD_LOAD_LIB(Sync); ADD_LOAD_LIB(Sync);
ADD_LOAD_LIB(WS2); ADD_LOAD_LIB(WS2);
ADD_LOAD_LIB(AdvancedApi);
ADD_LOAD_LIB(BCrypt);
#define ADD_GET_PROC(name, proc) \ #define ADD_GET_PROC(name, proc) \
if (h ## name) \ if (h ## name) \
@ -75,6 +77,12 @@ namespace Aurora
ADD_GET_PROC(WS2, GetAddrInfoExCancel) ADD_GET_PROC(WS2, GetAddrInfoExCancel)
ADD_GET_PROC(AdvancedApi, CryptAcquireContextW)
ADD_GET_PROC(AdvancedApi, CryptReleaseContext)
ADD_GET_PROC(AdvancedApi, CryptGenRandom)
ADD_GET_PROC(BCrypt, BCryptGenRandom)
#else #else
pWaitOnAddress = WaitOnAddress; pWaitOnAddress = WaitOnAddress;
pWakeByAddressSingle = WakeByAddressSingle; pWakeByAddressSingle = WakeByAddressSingle;

View File

@ -16,6 +16,8 @@ namespace Aurora
static const wchar_t *kKernel32DllName { L"Kernel32.dll" }; static const wchar_t *kKernel32DllName { L"Kernel32.dll" };
static const wchar_t *kKernelBaseDllName { L"KernelBase.dll" }; static const wchar_t *kKernelBaseDllName { L"KernelBase.dll" };
static const wchar_t *kWS2DllName { L"Ws2_32.dll" }; static const wchar_t *kWS2DllName { L"Ws2_32.dll" };
static const wchar_t *kAdvancedApiDllName { L"Advapi32.dll" };
static const wchar_t *kBCryptDllName { L"bcrypt.dll" };
struct WIN32_MEMORY_RANGE_ENTRY2 struct WIN32_MEMORY_RANGE_ENTRY2
{ {
@ -162,6 +164,32 @@ namespace Aurora
ULONG Flags ULONG Flags
); );
inline NTSTATUS(__stdcall *pBCryptGenRandom)(
PVOID hAlgorithm,
PUCHAR pbBuffer,
ULONG cbBuffer,
ULONG dwFlags
);
inline BOOL(__stdcall *pCryptGenRandom)(
ULONG_PTR hProv,
DWORD dwLen,
BYTE *pbBuffer
);
inline BOOL(__stdcall *pCryptAcquireContextW)(
ULONG_PTR * hProv,
LPCWSTR szContainer,
LPCWSTR szProvider,
DWORD dwProvType,
DWORD dwFlags
);
inline BOOL(__stdcall *pCryptReleaseContext)(
ULONG_PTR hProvz,
DWORD dwFlags
);
inline bool gUseNativeWaitMutex {}; inline bool gUseNativeWaitMutex {};
inline bool gUseNativeWaitCondvar {}; inline bool gUseNativeWaitCondvar {};
inline bool gUseNativeWaitSemapahore {}; inline bool gUseNativeWaitSemapahore {};

View File

@ -12,9 +12,21 @@
#include "AuRNGEntropy.hpp" #include "AuRNGEntropy.hpp"
#if defined(AURORA_PLATFORM_WIN32) #if defined(AURORA_PLATFORM_WIN32)
#include <bcrypt.h>
#if !defined(BCRYPT_RNG_ALG_HANDLE)
#define BCRYPT_RNG_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000081)
#endif
#define USE_OLD_NTCRYPT
#endif
#if defined(AURORA_IS_MODERNNT_DERIVED)
#include <bcrypt.h>
#endif
#if defined(USE_OLD_NTCRYPT)
#include <wincrypt.h> #include <wincrypt.h>
#include <bcrypt.h>
#include <bcrypt.h>
#endif #endif
#if defined(AURORA_IS_POSIX_DERIVED) #if defined(AURORA_IS_POSIX_DERIVED)
@ -62,54 +74,57 @@ namespace Aurora::RNG
void EntropyInit() void EntropyInit()
{ {
#if defined(USE_OLD_NTCRYPT) #if defined(USE_OLD_NTCRYPT)
if (!CryptAcquireContext(&gCryptoProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, if (pBCryptGenRandom)
{
return;
}
if (pCryptAcquireContextW)
{
if (!pCryptAcquireContextW(&gCryptoProv, NULL,
MS_DEF_PROV_W, PROV_RSA_FULL,
(CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))) (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)))
{ {
if (!CryptAcquireContext(&gCryptoProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, if (!pCryptAcquireContextW(&gCryptoProv, NULL,
MS_DEF_PROV_W, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
{ {
gCryptoProv = 0; gCryptoProv = 0;
} }
} }
}
#endif #endif
} }
static AuUInt32 RngWin32(AuUInt8 *pBuf, AuUInt32 uLen) static AuUInt32 RngWin32(AuUInt8 *pBuf, AuUInt32 uLen)
{ {
#if defined(USE_OLD_NTCRYPT) if (pBCryptGenRandom)
if (!gCryptoProv)
{ {
return 0;
}
if (!::CryptGenRandom(gCryptoProv, uLen, pBuf))
{
return 0;
}
return uLen;
#else
#if !defined(AURORA_DONT_PREFER_WIN32_USERLAND_AES_RNG) #if !defined(AURORA_DONT_PREFER_WIN32_USERLAND_AES_RNG)
#if !defined(BCRYPT_RNG_ALG_HANDLE)
#define BCRYPT_RNG_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000081)
#endif
if (AuSwInfo::IsWindows10OrGreater() && if (AuSwInfo::IsWindows10OrGreater() &&
::BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, reinterpret_cast<PUCHAR>(pBuf), uLen, 0) == 0) pBCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, reinterpret_cast<PUCHAR>(pBuf), uLen, 0) == 0)
{ {
return uLen; return uLen;
} }
#endif #endif
if (::BCryptGenRandom(NULL, reinterpret_cast<PUCHAR>(pBuf), uLen, BCRYPT_USE_SYSTEM_PREFERRED_RNG) == 0) if (pBCryptGenRandom(NULL, reinterpret_cast<PUCHAR>(pBuf), uLen, BCRYPT_USE_SYSTEM_PREFERRED_RNG) == 0)
{ {
return uLen; return uLen;
} }
}
#if defined(USE_OLD_NTCRYPT)
if (gCryptoProv)
{
if (pCryptGenRandom(gCryptoProv, uLen, pBuf))
{
return uLen;
}
}
#endif
return 0; return 0;
#endif
} }
#else #else
@ -137,7 +152,7 @@ namespace Aurora::RNG
do do
{ {
t1 = clock(); t1 = clock();
while (t1 == clock()) // spin within the resolution of 1 C clock() tick while (t1 == clock()) // spin within the resolution of 1 posix clock() tick (this is usually 1,000,000 == CLOCKS_PER_SEC per posix, but it can be 1k)
{ {
a ^= 1; // flip a ^= 1; // flip
} }
@ -157,6 +172,8 @@ namespace Aurora::RNG
bits = 8; bits = 8;
} }
// TODO: Is that whitening algorithm enough or should we work towards a continuous hash stream?
return l; return l;
} }
@ -192,7 +209,15 @@ namespace Aurora::RNG
::close(gDevURand); ::close(gDevURand);
} }
#elif defined(AURORA_IS_MODERNNT_DERIVED) && defined(USE_OLD_NTCRYPT) #elif defined(AURORA_IS_MODERNNT_DERIVED) && defined(USE_OLD_NTCRYPT)
CryptReleaseContext(gCryptoProv, 0); if (pBCryptGenRandom)
{
return;
}
if (pCryptReleaseContext)
{
pCryptReleaseContext(gCryptoProv, 0);
}
#endif #endif
} }
} }