From 87f19427dbc3662636a84e56b7c7a8a49f1246df Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 2 Sep 2017 18:34:37 -0400 Subject: Refactor RNGs to support Windows Phone This OS has its own crypto API and does not support CryptGenRandom. Splits System_RNG_Impl into distinct declarations one per implementation type. Easier to read now that we are up to 4 distinct versions. Removes the CryptoAPI entropy source, and replaces it with an entropy source that calls the system RNG. This is nominally a bit less flexible in that the entropy source allowed polling multiple providers (though we didn't actually make use of that). Plus side is it works on all systems. Currently the dev_random entropy source is still there because we do actually use it to poll both /dev/random and /dev/urandom, and it might be useful (on certain systems) to also poll a HW RNG, which are often assigned their own device node. This could debatably also be removed in favor of just reading the system RNG. --- src/lib/entropy/cryptoapi_rng/es_capi.cpp | 95 ------------------------------- src/lib/entropy/cryptoapi_rng/es_capi.h | 44 -------------- src/lib/entropy/cryptoapi_rng/info.txt | 20 ------- src/lib/entropy/entropy_srcs.cpp | 69 ++++++++++++++-------- 4 files changed, 45 insertions(+), 183 deletions(-) delete mode 100644 src/lib/entropy/cryptoapi_rng/es_capi.cpp delete mode 100644 src/lib/entropy/cryptoapi_rng/es_capi.h delete mode 100644 src/lib/entropy/cryptoapi_rng/info.txt (limited to 'src/lib/entropy') diff --git a/src/lib/entropy/cryptoapi_rng/es_capi.cpp b/src/lib/entropy/cryptoapi_rng/es_capi.cpp deleted file mode 100644 index 58503c66d..000000000 --- a/src/lib/entropy/cryptoapi_rng/es_capi.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* -* Win32 CryptoAPI EntropySource -* (C) 1999-2009,2016 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include -#define NOMINMAX 1 -#define _WINSOCKAPI_ // stop windows.h including winsock.h -#include -#include - -namespace Botan { - -namespace { - -class CSP_Handle_Impl : public Win32_CAPI_EntropySource::CSP_Handle - { - public: - explicit CSP_Handle_Impl(uint64_t capi_provider) - { - m_valid = ::CryptAcquireContext(&m_handle, - nullptr, - nullptr, - static_cast(capi_provider), - CRYPT_VERIFYCONTEXT); - } - - ~CSP_Handle_Impl() - { - if(m_valid) - ::CryptReleaseContext(m_handle, 0); - } - - size_t gen_random(uint8_t out[], size_t n) const - { - if(m_valid && ::CryptGenRandom(m_handle, static_cast(n), out)) - return n; - return 0; - } - - private: - bool m_valid; - HCRYPTPROV m_handle; - }; - -} - -/* -* Gather Entropy from Win32 CAPI -*/ -size_t Win32_CAPI_EntropySource::poll(RandomNumberGenerator& rng) - { - secure_vector buf(BOTAN_SYSTEM_RNG_POLL_REQUEST); - size_t bits = 0; - - for(size_t i = 0; i != m_csp_provs.size(); ++i) - { - size_t got = m_csp_provs[i]->gen_random(buf.data(), buf.size()); - - if(got > 0) - { - rng.add_entropy(buf.data(), got); - bits += got * 8; - } - } - - return bits; - } - -/* -* Win32_Capi_Entropysource Constructor -*/ -Win32_CAPI_EntropySource::Win32_CAPI_EntropySource(const std::string& provs) - { - for(std::string prov_name : split_on(provs, ':')) - { - DWORD prov_type; - - if(prov_name == "RSA_FULL") - prov_type = PROV_RSA_FULL; - else if(prov_name == "INTEL_SEC") - prov_type = PROV_INTEL_SEC; - else if(prov_name == "RNG") - prov_type = PROV_RNG; - else - continue; - - m_csp_provs.push_back(std::unique_ptr(new CSP_Handle_Impl(prov_type))); - } - } - -} diff --git a/src/lib/entropy/cryptoapi_rng/es_capi.h b/src/lib/entropy/cryptoapi_rng/es_capi.h deleted file mode 100644 index 8439e62fa..000000000 --- a/src/lib/entropy/cryptoapi_rng/es_capi.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* Win32 CAPI EntropySource -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_ENTROPY_SRC_WIN32_CAPI_H__ -#define BOTAN_ENTROPY_SRC_WIN32_CAPI_H__ - -#include -#include - -namespace Botan { - -/** -* Win32 CAPI Entropy Source -*/ -class Win32_CAPI_EntropySource final : public Entropy_Source - { - public: - std::string name() const override { return "win32_cryptoapi"; } - - size_t poll(RandomNumberGenerator& rng) override; - - /** - * Win32_Capi_Entropysource Constructor - * @param provs list of providers, separated by ':' - */ - explicit Win32_CAPI_EntropySource(const std::string& provs = ""); - - class CSP_Handle - { - public: - virtual ~CSP_Handle() {} - virtual size_t gen_random(uint8_t out[], size_t n) const = 0; - }; - private: - std::vector> m_csp_provs; - }; - -} - -#endif diff --git a/src/lib/entropy/cryptoapi_rng/info.txt b/src/lib/entropy/cryptoapi_rng/info.txt deleted file mode 100644 index 21b42f2a0..000000000 --- a/src/lib/entropy/cryptoapi_rng/info.txt +++ /dev/null @@ -1,20 +0,0 @@ - -ENTROPY_SRC_CAPI -> 20131128 - - - -es_capi.h - - -# We'll just assume CAPI is there; this is OK except for 3.x, early -# versions of 95, and maybe NT 3.5 - -windows -cygwin -mingw - - - -windows -> advapi32.lib -mingw -> advapi32 - diff --git a/src/lib/entropy/entropy_srcs.cpp b/src/lib/entropy/entropy_srcs.cpp index d9d5cfe4b..76546c5da 100644 --- a/src/lib/entropy/entropy_srcs.cpp +++ b/src/lib/entropy/entropy_srcs.cpp @@ -8,6 +8,10 @@ #include #include +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include +#endif + #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) #include #endif @@ -20,10 +24,6 @@ #include #endif -#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI) - #include -#endif - #if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) #include #endif @@ -42,65 +42,86 @@ namespace Botan { +#if defined(BOTAN_HAS_SYSTEM_RNG) + +namespace { + +class System_RNG_EntropySource : public Entropy_Source + { + public: + size_t poll(RandomNumberGenerator& rng) override + { + const size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS; + rng.reseed_from_rng(system_rng(), poll_bits); + return poll_bits; + } + + std::string name() const override { return system_rng().name(); } + }; + +} + +#endif + std::unique_ptr Entropy_Source::create(const std::string& name) { - if(name == "rdrand") +#if defined(BOTAN_HAS_SYSTEM_RNG) + if(name == "system_rng" || name == "win32_cryptoapi") { + return std::unique_ptr(new System_RNG_EntropySource); + } +#endif + #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) + if(name == "rdrand") + { return std::unique_ptr(new Intel_Rdrand); -#endif } +#endif +#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED) if(name == "rdseed") { -#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED) return std::unique_ptr(new Intel_Rdseed); -#endif } +#endif +#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) if(name == "darwin_secrandom") { -#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) return std::unique_ptr(new Darwin_SecRandom); -#endif } +#endif +#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY) if(name == "getentropy") { -#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY) return std::unique_ptr(new Getentropy); -#endif } +#endif +#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) if(name == "dev_random") { -#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) return std::unique_ptr(new Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES)); -#endif } - - if(name == "win32_cryptoapi") - { -#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI) - return std::unique_ptr(new Win32_CAPI_EntropySource("RSA_FULL")); #endif - } +#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER) if(name == "proc_walk") { -#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER) const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH; if(!root_dir.empty()) return std::unique_ptr(new ProcWalking_EntropySource(root_dir)); -#endif } +#endif +#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) if(name == "system_stats") { -#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) return std::unique_ptr(new Win32_EntropySource); -#endif } +#endif return std::unique_ptr(); } -- cgit v1.2.3 From 20985b242640907de77ea45c7e0b679c3e7ed82e Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sun, 3 Sep 2017 08:10:13 -0400 Subject: Define macro so windows.h doesn't include winsock.h Ugh Windows headers y u so nasty. --- src/lib/entropy/win32_stats/es_win32.cpp | 2 ++ src/lib/rng/system_rng/system_rng.cpp | 1 + src/lib/utils/dyn_load/dyn_load.cpp | 1 + 3 files changed, 4 insertions(+) (limited to 'src/lib/entropy') diff --git a/src/lib/entropy/win32_stats/es_win32.cpp b/src/lib/entropy/win32_stats/es_win32.cpp index 520848615..0e7056550 100644 --- a/src/lib/entropy/win32_stats/es_win32.cpp +++ b/src/lib/entropy/win32_stats/es_win32.cpp @@ -6,7 +6,9 @@ */ #include + #define NOMINMAX 1 +#define _WINSOCKAPI_ // stop windows.h including winsock.h #include #include diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp index cafdaac78..9ee306991 100644 --- a/src/lib/rng/system_rng/system_rng.cpp +++ b/src/lib/rng/system_rng/system_rng.cpp @@ -10,6 +10,7 @@ #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) #define NOMINMAX 1 + #define _WINSOCKAPI_ // stop windows.h including winsock.h #include #include diff --git a/src/lib/utils/dyn_load/dyn_load.cpp b/src/lib/utils/dyn_load/dyn_load.cpp index 1f33dc761..2b24e5f6c 100644 --- a/src/lib/utils/dyn_load/dyn_load.cpp +++ b/src/lib/utils/dyn_load/dyn_load.cpp @@ -13,6 +13,7 @@ #include #elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) #define NOMINMAX 1 + #define _WINSOCKAPI_ // stop windows.h including winsock.h #include #endif -- cgit v1.2.3