diff options
Diffstat (limited to 'src/lib/rng/system_rng/system_rng.cpp')
-rw-r--r-- | src/lib/rng/system_rng/system_rng.cpp | 91 |
1 files changed, 19 insertions, 72 deletions
diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp index cec3deab1..32dabbe9f 100644 --- a/src/lib/rng/system_rng/system_rng.cpp +++ b/src/lib/rng/system_rng/system_rng.cpp @@ -1,25 +1,22 @@ /* * System RNG -* (C) 2014,2015,2017 Jack Lloyd +* (C) 2014,2015,2017,2018 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include <botan/system_rng.h> -#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) - #define NOMINMAX 1 - #define _WINSOCKAPI_ // stop windows.h including winsock.h - #include <windows.h> - #include <wincrypt.h> - -#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG) - #include <bcrypt.h> +#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM) + #include <botan/dyn_load.h> + #define NOMINMAX 1 + #define _WINSOCKAPI_ // stop windows.h including winsock.h + #include <windows.h> #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM) #include <stdlib.h> -#else +#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM) #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -31,82 +28,32 @@ namespace Botan { namespace { -#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) +#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM) class System_RNG_Impl final : public RandomNumberGenerator { public: - System_RNG_Impl() - { - if(!CryptAcquireContext(&m_prov, nullptr, nullptr, - BOTAN_SYSTEM_RNG_CRYPTOAPI_PROV_TYPE, CRYPT_VERIFYCONTEXT)) - throw Exception("System_RNG failed to acquire crypto provider"); - } - - ~System_RNG_Impl() + System_RNG_Impl() : m_advapi("advapi32.dll") { - ::CryptReleaseContext(m_prov, 0); + // This throws if the function is not found + m_rtlgenrandom = m_advapi.resolve<RtlGenRandom_f>("SystemFunction036"); } void randomize(uint8_t buf[], size_t len) override { - ::CryptGenRandom(m_prov, static_cast<DWORD>(len), buf); - } - - void add_entropy(const uint8_t in[], size_t length) override - { - /* - There is no explicit ConsumeRandom, but all values provided in - the call are incorporated into the state. - */ - std::vector<uint8_t> buf(in, in + length); - ::CryptGenRandom(m_prov, static_cast<DWORD>(buf.size()), buf.data()); + if(m_rtlgenrandom(buf, len) == false) + throw Exception("RtlGenRandom failed"); } + void add_entropy(const uint8_t[], size_t) override { /* ignored */ } bool is_seeded() const override { return true; } void clear() override { /* not possible */ } - std::string name() const override { return "cryptoapi"; } + std::string name() const override { return "RtlGenRandom"; } private: - HCRYPTPROV m_prov; - }; + typedef BOOL (*RtlGenRandom_f)(PVOID, ULONG); -#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG) - -class System_RNG_Impl final : public RandomNumberGenerator - { - public: - System_RNG_Impl() - { - NTSTATUS ret = ::BCryptOpenAlgorithmProvider(&m_prov, - BCRYPT_RNG_ALGORITHM, - MS_PRIMITIVE_PROVIDER, 0); - if(ret != STATUS_SUCCESS) - throw Exception("System_RNG failed to acquire crypto provider"); - } - - ~System_RNG_Impl() - { - ::BCryptCloseAlgorithmProvider(m_prov, 0); - } - - void randomize(uint8_t buf[], size_t len) override - { - ::BCryptGenRandom(m_prov, static_cast<PUCHAR>(buf), static_cast<ULONG>(len), 0); - } - - void add_entropy(const uint8_t in[], size_t length) override - { - /* - There is a flag BCRYPT_RNG_USE_ENTROPY_IN_BUFFER to provide - entropy inputs, but it is ignored in Windows 8 and later. - */ - } - - bool is_seeded() const override { return true; } - void clear() override { /* not possible */ } - std::string name() const override { return "crypto_ng"; } - private: - BCRYPT_ALG_HANDLE m_handle; + Dynamically_Loaded_Library m_advapi; + RtlGenRandom_f m_rtlgenrandom; }; #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM) @@ -127,7 +74,7 @@ class System_RNG_Impl final : public RandomNumberGenerator std::string name() const override { return "arc4random"; } }; -#else +#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM) // Read a random device |