diff options
author | Jack Lloyd <[email protected]> | 2016-01-15 19:42:30 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-07-17 10:43:34 -0400 |
commit | 8a1aead31c9ae9caa405c6951de8aa51d6a4b751 (patch) | |
tree | ac0c166c8b98a4c25b69c91aa4d5c2d0bc5bda42 /src/lib/rng/system_rng | |
parent | cd1e2d3bff92a2d91343541e2cf83287dce87c6f (diff) |
Switch to HMAC_DRBG for all RNG generation.
Add support and tests for additional_data param to HMAC_DRBG
Add Stateful_RNG class which has fork detection and periodic reseeding.
AutoSeeded_RNG passes the current pid and time as additional_data
Diffstat (limited to 'src/lib/rng/system_rng')
-rw-r--r-- | src/lib/rng/system_rng/system_rng.cpp | 76 | ||||
-rw-r--r-- | src/lib/rng/system_rng/system_rng.h | 23 |
2 files changed, 65 insertions, 34 deletions
diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp index 81e235a8c..b6440d968 100644 --- a/src/lib/rng/system_rng/system_rng.cpp +++ b/src/lib/rng/system_rng/system_rng.cpp @@ -28,32 +28,23 @@ namespace Botan { namespace { -class System_RNG_Impl : public RandomNumberGenerator +class System_RNG_Impl final : public RandomNumberGenerator { public: System_RNG_Impl(); ~System_RNG_Impl(); - void randomize(byte buf[], size_t len) override; - bool is_seeded() const override { return true; } + void clear() override {} - std::string name() const override { return "system"; } - size_t reseed_with_sources(Entropy_Sources&, - size_t /*poll_bits*/, - std::chrono::milliseconds /*timeout*/) override - { - // We ignore it and assert the PRNG is seeded. - // TODO: could poll and write it to /dev/urandom to help seed it - return 0; - } + void randomize(Botan::byte out[], size_t len) override; - void add_entropy(const byte[], size_t) override - { - } - private: + void add_entropy(const byte in[], size_t length) override; + + std::string name() const override; + private: #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) HCRYPTPROV m_prov; #else @@ -61,6 +52,15 @@ class System_RNG_Impl : public RandomNumberGenerator #endif }; +std::string System_RNG_Impl::name() const + { +#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) + return "cryptoapi"; +#else + return BOTAN_SYSTEM_RNG_DEVICE; +#endif + } + System_RNG_Impl::System_RNG_Impl() { #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) @@ -74,7 +74,7 @@ System_RNG_Impl::System_RNG_Impl() #define O_NOCTTY 0 #endif - m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY | O_NOCTTY); + m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR | O_NOCTTY); if(m_fd < 0) throw Exception("System_RNG failed to open RNG device"); #endif @@ -90,6 +90,48 @@ System_RNG_Impl::~System_RNG_Impl() #endif } +void System_RNG_Impl::add_entropy(const byte input[], size_t len) + { +#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) + /* + There is no explicit ConsumeRandom, but all values provided in + the call are incorporated into the state. + + TODO: figure out a way to avoid this copy. Byte at a time updating + seems worse than the allocation. + + for(size_t i = 0; i != len; ++i) + { + byte b = input[i]; + ::CryptGenRandom(m_prov, 1, &b); + } + */ + + if(len > 0) + { + secure_vector<byte> buf(input, input + len); + ::CryptGenRandom(m_prov, static_cast<DWORD>(buf.size()), buf.data()); + } +#else + while(len) + { + ssize_t got = ::write(m_fd, input, len); + + if(got < 0) + { + if(errno == EINTR) + continue; + + // maybe just ignore failure here and return? + throw Exception("System_RNG write failed error " + std::to_string(errno)); + } + + input += got; + len -= got; + } +#endif + } + void System_RNG_Impl::randomize(byte buf[], size_t len) { #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) diff --git a/src/lib/rng/system_rng/system_rng.h b/src/lib/rng/system_rng/system_rng.h index 6290b8769..a789631d6 100644 --- a/src/lib/rng/system_rng/system_rng.h +++ b/src/lib/rng/system_rng/system_rng.h @@ -22,29 +22,18 @@ BOTAN_DLL RandomNumberGenerator& system_rng(); /* * Instantiatable reference to the system RNG. */ -class BOTAN_DLL System_RNG : public RandomNumberGenerator +class BOTAN_DLL System_RNG final : public RandomNumberGenerator { public: - System_RNG() : m_rng(system_rng()) {} + std::string name() const override { return system_rng().name(); } - void randomize(Botan::byte out[], size_t len) override { m_rng.randomize(out, len); } + void randomize(Botan::byte out[], size_t len) override { system_rng().randomize(out, len); } - bool is_seeded() const override { return m_rng.is_seeded(); } + void add_entropy(const byte in[], size_t length) override { system_rng().add_entropy(in, length); } - void clear() override { m_rng.clear(); } + bool is_seeded() const override { return true; } - std::string name() const override { return m_rng.name(); } - - size_t reseed_with_sources(Entropy_Sources& srcs, - size_t poll_bits, - std::chrono::milliseconds poll_timeout) override - { - return m_rng.reseed_with_sources(srcs, poll_bits, poll_timeout); - } - - void add_entropy(const byte in[], size_t len) override { m_rng.add_entropy(in, len); } - private: - Botan::RandomNumberGenerator& m_rng; + void clear() override {} }; } |