aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-11-24 17:51:59 -0500
committerJack Lloyd <[email protected]>2015-11-24 17:51:59 -0500
commit5f208fab1890e2ad64b52306eccd82f031425c7a (patch)
tree6bbbf1408e10538e441e3d603d80ebb2cabc6a78 /src/tests
parentbf59ffc4de374d7b27b7ab400789ab2723131b7a (diff)
New reseed_with_sources call on RNGs
Provides an easier way for an application to configure a list of entropy sources they'd like to use, or add a custom entropy source to their seeding. Exposes some toggles for the global/default entropy sources to build.h Adds basic entropy tests which runs the polls and does sanity checking on the results, including compression tests if available. These are less useful for the CSPRNG outputs but a good check for the ones producing plain ASCII like the /proc reader.
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/test_entropy.cpp107
-rw-r--r--src/tests/test_rng.h4
-rw-r--r--src/tests/tests.h9
3 files changed, 118 insertions, 2 deletions
diff --git a/src/tests/test_entropy.cpp b/src/tests/test_entropy.cpp
new file mode 100644
index 000000000..f2475e47e
--- /dev/null
+++ b/src/tests/test_entropy.cpp
@@ -0,0 +1,107 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+#include <botan/entropy_src.h>
+
+#if defined(BOTAN_HAS_COMPRESSION)
+ #include <botan/compression.h>
+#endif
+
+namespace Botan_Tests {
+
+namespace {
+
+class Entropy_Source_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ static const size_t MAX_ENTROPY = 512;
+ static const size_t MAX_SAMPLES = 256;
+ static const size_t MAX_ENTROPY_BYTES = 256*1024;
+
+ Botan::Entropy_Sources& srcs = Botan::Entropy_Sources::global_sources();
+
+ std::vector<std::string> src_names = srcs.enabled_sources();
+
+ std::vector<Test::Result> results;
+
+ for(auto&& src_name : src_names)
+ {
+ Test::Result result("Entropy source " + src_name);
+
+ result.start_timer();
+
+ std::vector<uint8_t> entropy;
+ size_t samples = 0;
+ size_t entropy_estimate = 0;
+
+ // TODO: add a timeout
+
+ Botan::Entropy_Accumulator accum([&](const uint8_t buf[], size_t buf_len, size_t buf_entropy) -> bool
+ {
+ entropy.insert(entropy.end(), buf, buf + buf_len);
+ entropy_estimate += buf_entropy;
+ ++samples;
+
+ result.test_note("sample " + std::to_string(samples) + " " +
+ Botan::hex_encode(buf, buf_len) + " " + std::to_string(buf_entropy));
+
+ result.test_gte("impossible entropy", buf_len * 8, buf_entropy);
+
+ return (entropy_estimate > MAX_ENTROPY ||
+ samples > MAX_SAMPLES ||
+ entropy.size() > MAX_ENTROPY_BYTES);
+ });
+
+ result.confirm("polled source", srcs.poll_just(accum, src_name));
+
+ result.test_note("saw " + std::to_string(samples) +
+ " samples with total estimated entropy " +
+ std::to_string(entropy_estimate));
+
+ //result.test_gte("impossible entropy", entropy.size() * 8, entropy_estimate);
+
+ if(!entropy.empty())
+ {
+#if defined(BOTAN_HAS_COMPRESSION)
+ for(auto comp_algo : { "zlib", "bzip2", "lzma" })
+ {
+ std::unique_ptr<Botan::Compressor_Transform> comp(Botan::make_compressor(comp_algo, 9));
+
+ if(comp)
+ {
+ Botan::secure_vector<byte> compressed;
+ compressed.assign(entropy.begin(), entropy.end());
+
+ comp->start();
+ comp->finish(compressed);
+
+ result.test_gte("compressed entropy better than advertised",
+ compressed.size() * 8, entropy_estimate);
+
+ // TODO: perform 2nd poll and check compression differential
+ }
+
+ }
+#endif
+ }
+
+ result.end_timer();
+
+ results.push_back(result);
+ }
+
+ return results;
+ }
+ };
+
+BOTAN_REGISTER_TEST("entropy", Entropy_Source_Tests);
+
+}
+
+}
diff --git a/src/tests/test_rng.h b/src/tests/test_rng.h
index f1d40f7f1..7d30fd6cc 100644
--- a/src/tests/test_rng.h
+++ b/src/tests/test_rng.h
@@ -30,7 +30,9 @@ class Fixed_Output_RNG : public Botan::RandomNumberGenerator
return out;
}
- void reseed(size_t) override {}
+ size_t reseed_with_sources(Botan::Entropy_Sources&,
+ size_t,
+ std::chrono::milliseconds) { return 0; }
void randomize(byte out[], size_t len) override
{
diff --git a/src/tests/tests.h b/src/tests/tests.h
index 9f511c4fb..1af278cce 100644
--- a/src/tests/tests.h
+++ b/src/tests/tests.h
@@ -99,7 +99,7 @@ class Test
else
{
Result r(result.who());
- r.test_note("Got expected failure " + result.result_string());
+ r.test_note("Got expected failure");
return r;
}
}
@@ -108,6 +108,13 @@ class Test
void test_note(const std::string& note, const char* extra = nullptr);
+ template<typename Alloc>
+ void test_note(const std::string& who, const std::vector<uint8_t, Alloc>& vec)
+ {
+ const std::string hex = Botan::hex_encode(vec);
+ return test_note(who, hex.c_str());
+ }
+
void note_missing(const std::string& thing);
bool test_success(const std::string& note = "");