aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/prov/pkcs11/p11_randomgenerator.h3
-rw-r--r--src/lib/prov/tpm/tpm.h2
-rw-r--r--src/lib/rng/auto_rng/auto_rng.h2
-rw-r--r--src/lib/rng/rdrand_rng/rdrand_rng.h2
-rw-r--r--src/lib/rng/rng.cpp41
-rw-r--r--src/lib/rng/rng.h17
-rw-r--r--src/lib/rng/stateful_rng/stateful_rng.h2
-rw-r--r--src/lib/rng/system_rng/system_rng.cpp25
-rw-r--r--src/lib/rng/system_rng/system_rng.h2
-rw-r--r--src/tests/test_newhope.cpp2
-rw-r--r--src/tests/test_rng.h8
-rw-r--r--src/tests/test_runner.cpp2
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)