Merge pull request #4 from tetsudaiga/FallbackRandomGeneration

Use RtlGenRandom if BCryptGenRandom fails
This commit is contained in:
Patrick Longa 2020-07-30 14:52:44 -07:00 коммит произвёл GitHub
Родитель 5dbd257b0b ae63d036ea
Коммит 5d7e5f8635
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 55 добавлений и 16 удалений

Просмотреть файл

@ -10,12 +10,20 @@
#include <stdlib.h>
#include <stdbool.h>
#if defined(__WINDOWS__)
#include <windows.h>
#include <bcrypt.h>
#include <windows.h>
#include <bcrypt.h>
#elif defined(__LINUX__)
#include <unistd.h>
#include <fcntl.h>
static int lock = -1;
#include <unistd.h>
#include <fcntl.h>
static int lock = -1;
#endif
#if defined(__WINDOWS__)
#define RTL_GENRANDOM "SystemFunction036"
NTSTATUS last_bcrypt_error = 0;
#endif
@ -29,21 +37,52 @@ int random_bytes(unsigned char* random_array, unsigned int nbytes)
{ // Generation of "nbytes" of random values
#if defined(__WINDOWS__)
if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, random_array, nbytes, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) {
if (BCRYPT_SUCCESS(last_bcrypt_error))
{
NTSTATUS status = BCryptGenRandom(
NULL, random_array, nbytes, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (BCRYPT_SUCCESS(status))
{
return true;
}
last_bcrypt_error = status;
}
HMODULE hAdvApi = LoadLibraryA("ADVAPI32.DLL");
if (!hAdvApi)
{
return false;
}
}
BOOLEAN(APIENTRY * RtlGenRandom)
(void*, ULONG) = (BOOLEAN(APIENTRY*)(void*, ULONG))GetProcAddress(hAdvApi, RTL_GENRANDOM);
BOOLEAN genrand_result = FALSE;
if (RtlGenRandom)
{
genrand_result = RtlGenRandom(random_array, nbytes);
}
FreeLibrary(hAdvApi);
if (!genrand_result)
{
return false;
}
#elif defined(__LINUX__)
int r, n = nbytes, count = 0;
if (lock == -1) {
do {
lock = open("/dev/urandom", O_RDONLY);
if (lock == -1) {
delay(0xFFFFF);
}
} while (lock == -1);
}
if (lock == -1) {
do {
lock = open("/dev/urandom", O_RDONLY);
if (lock == -1) {
delay(0xFFFFF);
}
} while (lock == -1);
}
while (n > 0) {
do {