diff options
author | Jack Lloyd <[email protected]> | 2017-09-02 18:34:37 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-09-02 18:34:37 -0400 |
commit | 87f19427dbc3662636a84e56b7c7a8a49f1246df (patch) | |
tree | 267749bedfa5e4ee9490d3d50a83e08c50c097ea /src/lib/entropy | |
parent | e2036b0dba7084728b209fc3901398e8d46b72b9 (diff) |
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.
Diffstat (limited to 'src/lib/entropy')
-rw-r--r-- | src/lib/entropy/cryptoapi_rng/es_capi.cpp | 95 | ||||
-rw-r--r-- | src/lib/entropy/cryptoapi_rng/es_capi.h | 44 | ||||
-rw-r--r-- | src/lib/entropy/cryptoapi_rng/info.txt | 20 | ||||
-rw-r--r-- | src/lib/entropy/entropy_srcs.cpp | 69 |
4 files changed, 45 insertions, 183 deletions
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 <botan/internal/es_capi.h> -#include <botan/parsing.h> -#define NOMINMAX 1 -#define _WINSOCKAPI_ // stop windows.h including winsock.h -#include <windows.h> -#include <wincrypt.h> - -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<DWORD>(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<DWORD>(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<uint8_t> 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<CSP_Handle>(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 <botan/entropy_src.h> -#include <vector> - -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<std::unique_ptr<CSP_Handle>> 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 @@ -<defines> -ENTROPY_SRC_CAPI -> 20131128 -</defines> - -<header:internal> -es_capi.h -</header:internal> - -# We'll just assume CAPI is there; this is OK except for 3.x, early -# versions of 95, and maybe NT 3.5 -<os> -windows -cygwin -mingw -</os> - -<libs> -windows -> advapi32.lib -mingw -> advapi32 -</libs> 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 <botan/entropy_src.h> #include <botan/rng.h> +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include <botan/system_rng.h> +#endif + #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) #include <botan/internal/rdrand.h> #endif @@ -20,10 +24,6 @@ #include <botan/internal/dev_random.h> #endif -#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI) - #include <botan/internal/es_capi.h> -#endif - #if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) #include <botan/internal/es_win32.h> #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> 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<Entropy_Source>(new System_RNG_EntropySource); + } +#endif + #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) + if(name == "rdrand") + { return std::unique_ptr<Entropy_Source>(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<Entropy_Source>(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<Entropy_Source>(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<Entropy_Source>(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<Entropy_Source>(new Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES)); -#endif } - - if(name == "win32_cryptoapi") - { -#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI) - return std::unique_ptr<Entropy_Source>(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<Entropy_Source>(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<Entropy_Source>(new Win32_EntropySource); -#endif } +#endif return std::unique_ptr<Entropy_Source>(); } |