diff options
Diffstat (limited to 'src/lib/entropy/cryptoapi_rng')
-rw-r--r-- | src/lib/entropy/cryptoapi_rng/es_capi.cpp | 93 | ||||
-rw-r--r-- | src/lib/entropy/cryptoapi_rng/es_capi.h | 37 | ||||
-rw-r--r-- | src/lib/entropy/cryptoapi_rng/info.txt | 20 |
3 files changed, 150 insertions, 0 deletions
diff --git a/src/lib/entropy/cryptoapi_rng/es_capi.cpp b/src/lib/entropy/cryptoapi_rng/es_capi.cpp new file mode 100644 index 000000000..a706b4d5c --- /dev/null +++ b/src/lib/entropy/cryptoapi_rng/es_capi.cpp @@ -0,0 +1,93 @@ +/* +* Win32 CryptoAPI EntropySource +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/internal/es_capi.h> +#include <botan/parsing.h> +#include <windows.h> +#include <wincrypt.h> + +namespace Botan { + +namespace { + +class CSP_Handle + { + public: + CSP_Handle(u64bit capi_provider) + { + valid = false; + DWORD prov_type = (DWORD)capi_provider; + + if(CryptAcquireContext(&handle, 0, 0, + prov_type, CRYPT_VERIFYCONTEXT)) + valid = true; + } + + ~CSP_Handle() + { + if(is_valid()) + CryptReleaseContext(handle, 0); + } + + size_t gen_random(byte out[], size_t n) const + { + if(is_valid() && CryptGenRandom(handle, static_cast<DWORD>(n), out)) + return n; + return 0; + } + + bool is_valid() const { return valid; } + + HCRYPTPROV get_handle() const { return handle; } + private: + HCRYPTPROV handle; + bool valid; + }; + +} + +/* +* Gather Entropy from Win32 CAPI +*/ +void Win32_CAPI_EntropySource::poll(Entropy_Accumulator& accum) + { + secure_vector<byte>& io_buffer = accum.get_io_buffer(32); + + for(size_t i = 0; i != prov_types.size(); ++i) + { + CSP_Handle csp(prov_types[i]); + + size_t got = csp.gen_random(&io_buffer[0], io_buffer.size()); + + if(got) + { + accum.add(&io_buffer[0], io_buffer.size(), 6); + break; + } + } + } + +/* +* Win32_Capi_Entropysource Constructor +*/ +Win32_CAPI_EntropySource::Win32_CAPI_EntropySource(const std::string& provs) + { + std::vector<std::string> capi_provs = split_on(provs, ':'); + + for(size_t i = 0; i != capi_provs.size(); ++i) + { + if(capi_provs[i] == "RSA_FULL") prov_types.push_back(PROV_RSA_FULL); + if(capi_provs[i] == "INTEL_SEC") prov_types.push_back(PROV_INTEL_SEC); + if(capi_provs[i] == "FORTEZZA") prov_types.push_back(PROV_FORTEZZA); + if(capi_provs[i] == "RNG") prov_types.push_back(PROV_RNG); + } + + if(prov_types.size() == 0) + prov_types.push_back(PROV_RSA_FULL); + } + +} diff --git a/src/lib/entropy/cryptoapi_rng/es_capi.h b/src/lib/entropy/cryptoapi_rng/es_capi.h new file mode 100644 index 000000000..d75101923 --- /dev/null +++ b/src/lib/entropy/cryptoapi_rng/es_capi.h @@ -0,0 +1,37 @@ +/* +* Win32 CAPI EntropySource +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#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 : public EntropySource + { + public: + std::string name() const { return "Win32 CryptoGenRandom"; } + + void poll(Entropy_Accumulator& accum); + + /** + * Win32_Capi_Entropysource Constructor + * @param provs list of providers, separated by ':' + */ + Win32_CAPI_EntropySource(const std::string& provs = ""); + private: + std::vector<u64bit> prov_types; + }; + +} + +#endif diff --git a/src/lib/entropy/cryptoapi_rng/info.txt b/src/lib/entropy/cryptoapi_rng/info.txt new file mode 100644 index 000000000..d4ee13aea --- /dev/null +++ b/src/lib/entropy/cryptoapi_rng/info.txt @@ -0,0 +1,20 @@ +define ENTROPY_SRC_CAPI 20131128 + +<source> +es_capi.cpp +</source> + +<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 +</os> + +<libs> +windows -> advapi32.lib +</libs> |