diff --git a/Source/AuProcAddresses.NT.cpp b/Source/AuProcAddresses.NT.cpp index 9b7c7dfd..e8180bb5 100644 --- a/Source/AuProcAddresses.NT.cpp +++ b/Source/AuProcAddresses.NT.cpp @@ -24,6 +24,8 @@ namespace Aurora ADD_LOAD_LIB(KernelBase); ADD_LOAD_LIB(Sync); ADD_LOAD_LIB(WS2); + ADD_LOAD_LIB(AdvancedApi); + ADD_LOAD_LIB(BCrypt); #define ADD_GET_PROC(name, proc) \ if (h ## name) \ @@ -72,9 +74,15 @@ namespace Aurora ADD_GET_PROC(Sync, WaitOnAddress) ADD_GET_PROC(Sync, WakeByAddressSingle) ADD_GET_PROC(Sync, WakeByAddressAll) - + 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 pWaitOnAddress = WaitOnAddress; pWakeByAddressSingle = WakeByAddressSingle; diff --git a/Source/AuProcAddresses.NT.hpp b/Source/AuProcAddresses.NT.hpp index 58adcedb..9199ffeb 100644 --- a/Source/AuProcAddresses.NT.hpp +++ b/Source/AuProcAddresses.NT.hpp @@ -11,11 +11,13 @@ namespace Aurora { void InitNTAddresses(); - static const wchar_t *kSyncDllName { L"API-MS-Win-Core-Synch-l1-2-0.dll" }; - static const wchar_t *kNtDllName { L"NTDLL.dll" }; - static const wchar_t *kKernel32DllName { L"Kernel32.dll" }; - static const wchar_t *kKernelBaseDllName { L"KernelBase.dll" }; - static const wchar_t *kWS2DllName { L"Ws2_32.dll" }; + static const wchar_t *kSyncDllName { L"API-MS-Win-Core-Synch-l1-2-0.dll" }; + static const wchar_t *kNtDllName { L"NTDLL.dll" }; + static const wchar_t *kKernel32DllName { L"Kernel32.dll" }; + static const wchar_t *kKernelBaseDllName { L"KernelBase.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 { @@ -162,6 +164,32 @@ namespace Aurora 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 gUseNativeWaitCondvar {}; inline bool gUseNativeWaitSemapahore {}; diff --git a/Source/RNG/AuRNGEntropy.cpp b/Source/RNG/AuRNGEntropy.cpp index 8dd369ce..96890e1b 100644 --- a/Source/RNG/AuRNGEntropy.cpp +++ b/Source/RNG/AuRNGEntropy.cpp @@ -12,9 +12,21 @@ #include "AuRNGEntropy.hpp" #if defined(AURORA_PLATFORM_WIN32) + #include + + #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 +#endif + +#if defined(USE_OLD_NTCRYPT) #include - #include - #include #endif #if defined(AURORA_IS_POSIX_DERIVED) @@ -62,13 +74,23 @@ namespace Aurora::RNG void EntropyInit() { #if defined(USE_OLD_NTCRYPT) - if (!CryptAcquireContext(&gCryptoProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, - (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))) + if (pBCryptGenRandom) { - if (!CryptAcquireContext(&gCryptoProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) + return; + } + + if (pCryptAcquireContextW) + { + if (!pCryptAcquireContextW(&gCryptoProv, NULL, + MS_DEF_PROV_W, PROV_RSA_FULL, + (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))) { - gCryptoProv = 0; + if (!pCryptAcquireContextW(&gCryptoProv, NULL, + MS_DEF_PROV_W, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) + { + gCryptoProv = 0; + } } } #endif @@ -76,40 +98,33 @@ namespace Aurora::RNG static AuUInt32 RngWin32(AuUInt8 *pBuf, AuUInt32 uLen) { - #if defined(USE_OLD_NTCRYPT) - if (!gCryptoProv) + if (pBCryptGenRandom) { - return 0; - } - - if (!::CryptGenRandom(gCryptoProv, uLen, pBuf)) - { - return 0; - } - - return uLen; - #else - #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() && - ::BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, reinterpret_cast(pBuf), uLen, 0) == 0) + pBCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, reinterpret_cast(pBuf), uLen, 0) == 0) { return uLen; } #endif - if (::BCryptGenRandom(NULL, reinterpret_cast(pBuf), uLen, BCRYPT_USE_SYSTEM_PREFERRED_RNG) == 0) - { - return uLen; + if (pBCryptGenRandom(NULL, reinterpret_cast(pBuf), uLen, BCRYPT_USE_SYSTEM_PREFERRED_RNG) == 0) + { + return uLen; + } } - return 0; + #if defined(USE_OLD_NTCRYPT) + if (gCryptoProv) + { + if (pCryptGenRandom(gCryptoProv, uLen, pBuf)) + { + return uLen; + } + } #endif + + return 0; } #else @@ -137,7 +152,7 @@ namespace Aurora::RNG do { 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 } @@ -157,6 +172,8 @@ namespace Aurora::RNG bits = 8; } + // TODO: Is that whitening algorithm enough or should we work towards a continuous hash stream? + return l; } @@ -192,7 +209,15 @@ namespace Aurora::RNG ::close(gDevURand); } #elif defined(AURORA_IS_MODERNNT_DERIVED) && defined(USE_OLD_NTCRYPT) - CryptReleaseContext(gCryptoProv, 0); + if (pBCryptGenRandom) + { + return; + } + + if (pCryptReleaseContext) + { + pCryptReleaseContext(gCryptoProv, 0); + } #endif } } \ No newline at end of file