From 6545754337e202d8fb4d80c2953a7031666cbd9f Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sat, 17 Aug 2019 21:19:04 -0400 Subject: [PATCH] Check size_t to DWORD and ULONG conversions DWORD and ULONG are 32-bit. The conversion from size_t could fail, and the RNG would return a truncated result. I think it is low risk, but the test for the conversion test is cheap. --- osrng.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/osrng.cpp b/osrng.cpp index 2e846b45..50821471 100644 --- a/osrng.cpp +++ b/osrng.cpp @@ -157,10 +157,27 @@ void NonblockingRng::GenerateBlock(byte *output, size_t size) const MicrosoftCryptoProvider &hProvider = Singleton().Ref(); # endif # if defined(USE_MS_CRYPTOAPI) - if (!CryptGenRandom(hProvider.GetProviderHandle(), (DWORD)size, output)) + DWORD dwSize; + CRYPTOPP_ASSERT(SafeConvert(size, dwSize)); + if (!SafeConvert(size, dwSize)) + { + SetLastError(ERROR_INCORRECT_SIZE); + throw OS_RNG_Err("GenerateBlock size"); + } + BOOL ret = CryptGenRandom(hProvider.GetProviderHandle(), dwSize, output); + CRYPTOPP_ASSERT(ret != FALSE); + if (ret == FALSE) throw OS_RNG_Err("CryptGenRandom"); # elif defined(USE_MS_CNGAPI) - NTSTATUS ret = BCryptGenRandom(hProvider.GetProviderHandle(), output, (ULONG)size, 0); + ULONG ulSize; + CRYPTOPP_ASSERT(SafeConvert(size, ulSize)); + if (!SafeConvert(size, ulSize)) + { + SetLastError(ERROR_INCORRECT_SIZE); + throw OS_RNG_Err("GenerateBlock size"); + } + NTSTATUS ret = BCryptGenRandom(hProvider.GetProviderHandle(), output, ulSize, 0); + CRYPTOPP_ASSERT(BCRYPT_SUCCESS(ret)); if (!(BCRYPT_SUCCESS(ret))) { // Hack... OS_RNG_Err calls GetLastError()