diff options
author | heinrich5991 <heinrich5991@gmail.com> | 2015-06-21 17:47:37 +0200 |
---|---|---|
committer | heinrich5991 <heinrich5991@gmail.com> | 2018-10-12 22:09:04 +0200 |
commit | 4389728d64318639e493b9d5c9dc52a9ab52d9c4 (patch) | |
tree | d7f9d79d6882d655d4889403e52a48455a67699e | |
parent | 6866069ce68b0afcfd224b4064a7619a4462fca7 (diff) |
Add platform-independent secure random number generator
(cherry picked from commit 903878f4a2fe63cd7df2fa998129f517faf9ee2a)
-rw-r--r-- | bam.lua | 1 | ||||
-rw-r--r-- | src/base/system.c | 64 | ||||
-rw-r--r-- | src/base/system.h | 21 | ||||
-rw-r--r-- | src/engine/client/client.cpp | 6 | ||||
-rw-r--r-- | src/engine/server/server.cpp | 6 |
5 files changed, 98 insertions, 0 deletions
@@ -188,6 +188,7 @@ function build(settings) settings.link.libs:Add("ws2_32") settings.link.libs:Add("ole32") settings.link.libs:Add("shell32") + settings.link.libs:Add("advapi32") end -- compile zlib if needed diff --git a/src/base/system.c b/src/base/system.c index ca6400756..c5765e68a 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -40,6 +40,7 @@ #include <fcntl.h> #include <direct.h> #include <errno.h> + #include <wincrypt.h> #else #error NOT IMPLEMENTED #endif @@ -2029,6 +2030,69 @@ unsigned str_quickhash(const char *str) 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, unsigned 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) } diff --git a/src/base/system.h b/src/base/system.h index ec208096b..c4fb1a4c5 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -1294,6 +1294,27 @@ int str_utf8_encode(char *ptr, int chr); */ 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, unsigned length); + #ifdef __cplusplus } #endif diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index d8cd41557..d64c39c39 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2303,6 +2303,12 @@ int main(int argc, const char **argv) // ignore_convention } #endif + if(secure_random_init() != 0) + { + dbg_msg("secure", "could not initialize secure RNG"); + return -1; + } + CClient *pClient = CreateClient(); IKernel *pKernel = IKernel::Create(); pKernel->RegisterInterface(pClient); diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 6c459257f..14778e8f5 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1664,6 +1664,12 @@ int main(int argc, const char **argv) // ignore_convention } #endif + if(secure_random_init() != 0) + { + dbg_msg("secure", "could not initialize secure RNG"); + return -1; + } + CServer *pServer = CreateServer(); IKernel *pKernel = IKernel::Create(); |