aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/rng/system_rng
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-01-15 19:42:30 -0500
committerJack Lloyd <[email protected]>2016-07-17 10:43:34 -0400
commit8a1aead31c9ae9caa405c6951de8aa51d6a4b751 (patch)
treeac0c166c8b98a4c25b69c91aa4d5c2d0bc5bda42 /src/lib/rng/system_rng
parentcd1e2d3bff92a2d91343541e2cf83287dce87c6f (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.cpp76
-rw-r--r--src/lib/rng/system_rng/system_rng.h23
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 {}
};
}