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.
pull/877/head
Jeffrey Walton 2019-08-17 21:19:04 -04:00
parent d49c1a1605
commit 6545754337
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
1 changed files with 19 additions and 2 deletions

View File

@ -157,10 +157,27 @@ void NonblockingRng::GenerateBlock(byte *output, size_t size)
const MicrosoftCryptoProvider &hProvider = Singleton<MicrosoftCryptoProvider>().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()