diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/prov/pkcs11/p11_randomgenerator.h | 3 | ||||
-rw-r--r-- | src/lib/prov/tpm/tpm.h | 2 | ||||
-rw-r--r-- | src/lib/rng/auto_rng/auto_rng.h | 2 | ||||
-rw-r--r-- | src/lib/rng/rdrand_rng/rdrand_rng.h | 2 | ||||
-rw-r--r-- | src/lib/rng/rng.cpp | 41 | ||||
-rw-r--r-- | src/lib/rng/rng.h | 17 | ||||
-rw-r--r-- | src/lib/rng/stateful_rng/stateful_rng.h | 2 | ||||
-rw-r--r-- | src/lib/rng/system_rng/system_rng.cpp | 25 | ||||
-rw-r--r-- | src/lib/rng/system_rng/system_rng.h | 2 | ||||
-rw-r--r-- | src/tests/test_newhope.cpp | 2 | ||||
-rw-r--r-- | src/tests/test_rng.h | 8 | ||||
-rw-r--r-- | src/tests/test_runner.cpp | 2 |
12 files changed, 91 insertions, 17 deletions
diff --git a/src/lib/prov/pkcs11/p11_randomgenerator.h b/src/lib/prov/pkcs11/p11_randomgenerator.h index cab9b77c4..82b7d9f48 100644 --- a/src/lib/prov/pkcs11/p11_randomgenerator.h +++ b/src/lib/prov/pkcs11/p11_randomgenerator.h @@ -57,6 +57,9 @@ class BOTAN_PUBLIC_API(2,0) PKCS11_RNG final : public Hardware_RNG /// Calls `C_SeedRandom` to add entropy to the random generation function of the token/middleware void add_entropy(const uint8_t in[], std::size_t length) override; + // C_SeedRandom may suceed + bool accepts_input() const override { return true; } + private: const std::reference_wrapper<Session> m_session; }; diff --git a/src/lib/prov/tpm/tpm.h b/src/lib/prov/tpm/tpm.h index b6e220935..7eaf2140c 100644 --- a/src/lib/prov/tpm/tpm.h +++ b/src/lib/prov/tpm/tpm.h @@ -78,6 +78,8 @@ class BOTAN_PUBLIC_API(2,0) TPM_RNG final : public Hardware_RNG public: TPM_RNG(TPM_Context& ctx) : m_ctx(ctx) {} + bool accepts_input() const override { return true; } + void add_entropy(const uint8_t in[], size_t in_len) override { m_ctx.stir_random(in, in_len); diff --git a/src/lib/rng/auto_rng/auto_rng.h b/src/lib/rng/auto_rng/auto_rng.h index 49663cbea..8cb2c4a12 100644 --- a/src/lib/rng/auto_rng/auto_rng.h +++ b/src/lib/rng/auto_rng/auto_rng.h @@ -27,6 +27,8 @@ class BOTAN_PUBLIC_API(2,0) AutoSeeded_RNG final : public RandomNumberGenerator bool is_seeded() const override; + bool accepts_input() const override { return true; } + /** * Mark state as requiring a reseed on next use */ diff --git a/src/lib/rng/rdrand_rng/rdrand_rng.h b/src/lib/rng/rdrand_rng/rdrand_rng.h index 3f6a33b64..181edcd47 100644 --- a/src/lib/rng/rdrand_rng/rdrand_rng.h +++ b/src/lib/rng/rdrand_rng/rdrand_rng.h @@ -34,6 +34,8 @@ class BOTAN_PUBLIC_API(2,0) RDRAND_RNG final : public Hardware_RNG */ static bool available(); + bool accepts_input() const override { return false; } + /** * Constructor will throw if CPU does not have RDRAND bit set */ diff --git a/src/lib/rng/rng.cpp b/src/lib/rng/rng.cpp index 2cf3b7b81..2947ac629 100644 --- a/src/lib/rng/rng.cpp +++ b/src/lib/rng/rng.cpp @@ -17,15 +17,22 @@ namespace Botan { void RandomNumberGenerator::randomize_with_ts_input(uint8_t output[], size_t output_len) { - /* - Form additional input which is provided to the PRNG implementation - to paramaterize the KDF output. - */ - uint8_t additional_input[16] = { 0 }; - store_le(OS::get_system_timestamp_ns(), additional_input); - store_le(OS::get_high_resolution_clock(), additional_input + 8); + if(this->accepts_input()) + { + /* + Form additional input which is provided to the PRNG implementation + to paramaterize the KDF output. + */ + uint8_t additional_input[16] = { 0 }; + store_le(OS::get_system_timestamp_ns(), additional_input); + store_le(OS::get_high_resolution_clock(), additional_input + 8); - randomize_with_input(output, output_len, additional_input, sizeof(additional_input)); + this->randomize_with_input(output, output_len, additional_input, sizeof(additional_input)); + } + else + { + this->randomize(output, output_len); + } } void RandomNumberGenerator::randomize_with_input(uint8_t output[], size_t output_len, @@ -39,14 +46,24 @@ size_t RandomNumberGenerator::reseed(Entropy_Sources& srcs, size_t poll_bits, std::chrono::milliseconds poll_timeout) { - return srcs.poll(*this, poll_bits, poll_timeout); + if(this->accepts_input()) + { + return srcs.poll(*this, poll_bits, poll_timeout); + } + else + { + return 0; + } } void RandomNumberGenerator::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits) { - secure_vector<uint8_t> buf(poll_bits / 8); - rng.randomize(buf.data(), buf.size()); - this->add_entropy(buf.data(), buf.size()); + if(this->accepts_input()) + { + secure_vector<uint8_t> buf(poll_bits / 8); + rng.randomize(buf.data(), buf.size()); + this->add_entropy(buf.data(), buf.size()); + } } RandomNumberGenerator* RandomNumberGenerator::make_rng() diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h index ec8557477..db42c8cf7 100644 --- a/src/lib/rng/rng.h +++ b/src/lib/rng/rng.h @@ -42,6 +42,15 @@ class BOTAN_PUBLIC_API(2,0) RandomNumberGenerator virtual void randomize(uint8_t output[], size_t length) = 0; /** + * Returns false if it is known that this RNG object is not able to accept + * externally provided inputs (via add_entropy, randomize_with_input, etc). + * In this case, any such provided inputs are ignored. + * + * If this function returns true, then inputs may or may not be accepted. + */ + virtual bool accepts_input() const = 0; + + /** * Incorporate some additional data into the RNG state. For * example adding nonces or timestamps from a peer's protocol * message can help hedge against VM state rollback attacks. @@ -190,6 +199,8 @@ class BOTAN_PUBLIC_API(2,0) Null_RNG final : public RandomNumberGenerator public: bool is_seeded() const override { return false; } + bool accepts_input() const override { return false; } + void clear() override {} void randomize(uint8_t[], size_t) override @@ -217,6 +228,12 @@ class BOTAN_PUBLIC_API(2,0) Serialized_RNG final : public RandomNumberGenerator m_rng->randomize(out, len); } + bool accepts_input() const override + { + lock_guard_type<mutex_type> lock(m_mutex); + return m_rng->accepts_input(); + } + bool is_seeded() const override { lock_guard_type<mutex_type> lock(m_mutex); diff --git a/src/lib/rng/stateful_rng/stateful_rng.h b/src/lib/rng/stateful_rng/stateful_rng.h index 18697ae23..9bf04327a 100644 --- a/src/lib/rng/stateful_rng/stateful_rng.h +++ b/src/lib/rng/stateful_rng/stateful_rng.h @@ -75,6 +75,8 @@ class BOTAN_PUBLIC_API(2,0) Stateful_RNG : public RandomNumberGenerator bool is_seeded() const override final; + bool accepts_input() const override final { return true; } + /** * Mark state as requiring a reseed on next use */ diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp index c3b37ea9c..5a55e0a83 100644 --- a/src/lib/rng/system_rng/system_rng.cpp +++ b/src/lib/rng/system_rng/system_rng.cpp @@ -51,6 +51,7 @@ class System_RNG_Impl final : public RandomNumberGenerator void add_entropy(const uint8_t[], size_t) override { /* ignored */ } bool is_seeded() const override { return true; } + bool accepts_input() const override { return false; } void clear() override { /* not possible */ } std::string name() const override { return "RtlGenRandom"; } private: @@ -98,6 +99,7 @@ class System_RNG_Impl final : public RandomNumberGenerator } bool is_seeded() const override { return true; } + bool accepts_input() const override { return false; } void clear() override { /* not possible */ } std::string name() const override { return "crypto_ng"; } private: @@ -116,6 +118,7 @@ class System_RNG_Impl final : public RandomNumberGenerator ::arc4random_buf(buf, len); } + bool accepts_input() const override { return false; } void add_entropy(const uint8_t[], size_t) override { /* ignored */ } bool is_seeded() const override { return true; } void clear() override { /* not possible */ } @@ -137,12 +140,19 @@ class System_RNG_Impl final : public RandomNumberGenerator m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR | O_NOCTTY); - /* - Cannot open in read-write mode. Fall back to read-only, - calls to add_entropy will fail, but randomize will work - */ - if(m_fd < 0) + if(m_fd >= 0) + { + m_writable = true; + } + else + { + /* + Cannot open in read-write mode. Fall back to read-only, + calls to add_entropy will fail, but randomize will work + */ m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY | O_NOCTTY); + m_writable = false; + } if(m_fd < 0) throw Exception("System_RNG failed to open RNG device"); @@ -157,10 +167,12 @@ class System_RNG_Impl final : public RandomNumberGenerator void randomize(uint8_t buf[], size_t len) override; void add_entropy(const uint8_t in[], size_t length) override; bool is_seeded() const override { return true; } + bool accepts_input() const override { return m_writable; } void clear() override { /* not possible */ } std::string name() const override { return BOTAN_SYSTEM_RNG_DEVICE; } private: int m_fd; + bool m_writable; }; void System_RNG_Impl::randomize(uint8_t buf[], size_t len) @@ -185,6 +197,9 @@ void System_RNG_Impl::randomize(uint8_t buf[], size_t len) void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len) { + if(!m_writable) + return; + while(len) { ssize_t got = ::write(m_fd, input, len); diff --git a/src/lib/rng/system_rng/system_rng.h b/src/lib/rng/system_rng/system_rng.h index 4e3beaf9f..e0f0181ca 100644 --- a/src/lib/rng/system_rng/system_rng.h +++ b/src/lib/rng/system_rng/system_rng.h @@ -33,6 +33,8 @@ class BOTAN_PUBLIC_API(2,0) System_RNG final : public RandomNumberGenerator bool is_seeded() const override { return system_rng().is_seeded(); } + bool accepts_input() const override { return system_rng().accepts_input(); } + void clear() override { system_rng().clear(); } }; diff --git a/src/tests/test_newhope.cpp b/src/tests/test_newhope.cpp index 38e1539ce..be75ebeb7 100644 --- a/src/tests/test_newhope.cpp +++ b/src/tests/test_newhope.cpp @@ -71,6 +71,8 @@ class NEWHOPE_RNG final : public Botan::RandomNumberGenerator return true; } + bool accepts_input() const override { return false; } + void add_entropy(const uint8_t[], size_t) override { /* ignored */ diff --git a/src/tests/test_rng.h b/src/tests/test_rng.h index 9ac93577b..942277050 100644 --- a/src/tests/test_rng.h +++ b/src/tests/test_rng.h @@ -29,6 +29,8 @@ class Fixed_Output_RNG : public Botan::RandomNumberGenerator return !m_buf.empty(); } + bool accepts_input() const override { return true; } + size_t reseed(Botan::Entropy_Sources&, size_t, std::chrono::milliseconds) override @@ -116,6 +118,8 @@ class Fixed_Output_Position_RNG final : public Fixed_Output_RNG } } + bool accepts_input() const override { return false; } + void add_entropy(const uint8_t*, size_t) override { throw Botan::Exception("add_entropy() not supported by this RNG, test bug?"); @@ -147,6 +151,8 @@ class SeedCapturing_RNG final : public Botan::RandomNumberGenerator throw Botan::Exception("SeedCapturing_RNG has no output"); } + bool accepts_input() const override { return true; } + void add_entropy(const uint8_t input[], size_t len) override { m_samples++; @@ -192,6 +198,8 @@ class Request_Counting_RNG final : public Botan::RandomNumberGenerator return m_randomize_count; } + bool accepts_input() const override { return false; } + bool is_seeded() const override { return true; diff --git a/src/tests/test_runner.cpp b/src/tests/test_runner.cpp index f69f55c0d..8d3f9b72c 100644 --- a/src/tests/test_runner.cpp +++ b/src/tests/test_runner.cpp @@ -32,6 +32,8 @@ class Testsuite_RNG final : public Botan::RandomNumberGenerator m_a = m_b = m_c = m_d = 0; } + bool accepts_input() const override { return true; } + void add_entropy(const uint8_t data[], size_t len) override { for(size_t i = 0; i != len; ++i) |