diff options
-rw-r--r-- | src/lib/rng/system_rng/system_rng.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp index afffb69cc..cdf85ef29 100644 --- a/src/lib/rng/system_rng/system_rng.cpp +++ b/src/lib/rng/system_rng/system_rng.cpp @@ -7,6 +7,15 @@ #include <botan/system_rng.h> +#if defined(BOTAN_TARGET_OS_IS_WINDOWS) + +#include <windows.h> +#include <wincrypt.h> +#undef min +#undef max + +#else + #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -14,6 +23,8 @@ #include <string.h> #include <errno.h> +#endif + namespace Botan { namespace { @@ -33,23 +44,43 @@ class System_RNG : public RandomNumberGenerator void reseed(size_t) {} void add_entropy(const byte[], size_t) {} private: + +#if defined(BOTAN_TARGET_OS_IS_WINDOWS) + HCRYPTPROV m_prov; +#else int m_fd; +#endif }; System_RNG::System_RNG() { +#if defined(BOTAN_TARGET_OS_IS_WINDOWS) + + if(!CryptAcquireContext(&m_prov, 0, 0, RSA_FULL, CRYPT_VERIFYCONTEXT)) + throw std::runtime_error("System_RNG failed to acquire crypto provider"); + +#else + m_fd = ::open("/dev/urandom", O_RDONLY); if(m_fd < 0) throw std::runtime_error("System_RNG failed to open /dev/urandom"); +#endif } System_RNG::~System_RNG() { +#if defined(BOTAN_TARGET_OS_IS_WINDOWS) + ::CryptReleaseContext(m_prov, 0); +#else ::close(m_fd); +#endif } void System_RNG::randomize(byte buf[], size_t len) { +#if defined(BOTAN_TARGET_OS_IS_WINDOWS) + ::CryptGenRandom(m_prov, static_cast<DWORD>(len), buf)) +#else while(len) { ssize_t got = ::read(m_fd, buf, len); @@ -66,6 +97,7 @@ void System_RNG::randomize(byte buf[], size_t len) buf += got; len -= got; } +#endif } } |