Add platform-independent secure random number generator

This commit is contained in:
heinrich5991 2015-06-21 17:47:37 +02:00 committed by oy
parent 0f0af75054
commit 903878f4a2
4 changed files with 92 additions and 0 deletions

View file

@ -232,6 +232,7 @@ function GenerateWindowsSettings(settings, conf, target_arch, compiler)
settings.link.libs:Add("ws2_32") settings.link.libs:Add("ws2_32")
settings.link.libs:Add("ole32") settings.link.libs:Add("ole32")
settings.link.libs:Add("shell32") settings.link.libs:Add("shell32")
settings.link.libs:Add("advapi32")
GenerateCommonSettings(settings, conf, target_arch) GenerateCommonSettings(settings, conf, target_arch)

View file

@ -39,6 +39,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <direct.h> #include <direct.h>
#include <errno.h> #include <errno.h>
#include <wincrypt.h>
#else #else
#error NOT IMPLEMENTED #error NOT IMPLEMENTED
#endif #endif
@ -2070,6 +2071,69 @@ unsigned str_quickhash(const char *str)
return hash; return hash;
} }
struct SECURE_RANDOM_DATA
{
int initialized;
#if defined(CONF_FAMILY_WINDOWS)
HCRYPTPROV provider;
#else
IOHANDLE urandom;
#endif
};
static struct SECURE_RANDOM_DATA secure_random_data = { 0 };
int secure_random_init()
{
if(secure_random_data.initialized)
{
return 0;
}
#if defined(CONF_FAMILY_WINDOWS)
if(CryptAcquireContext(&secure_random_data.provider, NULL, NULL, PROV_RSA_FULL, 0))
{
secure_random_data.initialized = 1;
return 0;
}
else
{
return 1;
}
#else
secure_random_data.urandom = io_open("/dev/urandom", IOFLAG_READ);
if(secure_random_data.urandom)
{
secure_random_data.initialized = 1;
return 0;
}
else
{
return 1;
}
#endif
}
void secure_random_fill(void *bytes, size_t length)
{
if(!secure_random_data.initialized)
{
dbg_msg("secure", "called secure_random_fill before secure_random_init");
dbg_break();
}
#if defined(CONF_FAMILY_WINDOWS)
if(!CryptGenRandom(secure_random_data.provider, length, bytes))
{
dbg_msg("secure", "CryptGenRandom failed, last_error=%d", GetLastError());
dbg_break();
}
#else
if(length != io_read(secure_random_data.urandom, bytes, length))
{
dbg_msg("secure", "io_read returned with a short read");
dbg_break();
}
#endif
}
#if defined(__cplusplus) #if defined(__cplusplus)
} }

View file

@ -1321,6 +1321,27 @@ int str_utf8_encode(char *ptr, int chr);
*/ */
int str_utf8_check(const char *str); int str_utf8_check(const char *str);
/*
Function: secure_random_init
Initializes the secure random module.
You *MUST* check the return value of this function.
Returns:
0 - Initialization succeeded.
1 - Initialization failed.
*/
int secure_random_init();
/*
Function: secure_random_fill
Fills the buffer with the specified amount of random bytes.
Parameters:
bytes - Pointer to the start of the buffer.
length - Length of the buffer.
*/
void secure_random_fill(void *bytes, size_t length);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -1679,6 +1679,12 @@ int main(int argc, const char **argv) // ignore_convention
} }
} }
if(secure_random_init() != 0)
{
dbg_msg("secure", "could not initialize secure RNG");
return -1;
}
CServer *pServer = CreateServer(); CServer *pServer = CreateServer();
IKernel *pKernel = IKernel::Create(); IKernel *pKernel = IKernel::Create();