diff options
author | Jack Lloyd <[email protected]> | 2019-08-27 10:05:49 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2019-08-27 20:04:21 -0400 |
commit | b4543c801cde2874b982bbaccba471bd14c27810 (patch) | |
tree | fd918d86ed4d114203a0c137abbbf19b66739052 /src/cli/entropy.cpp | |
parent | ecb22c16531db3023c739fa1436d8f3893fa1081 (diff) |
Add a cmdlet which allows sampling/testing raw entropy sources
Diffstat (limited to 'src/cli/entropy.cpp')
-rw-r--r-- | src/cli/entropy.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/cli/entropy.cpp b/src/cli/entropy.cpp new file mode 100644 index 000000000..0404afb99 --- /dev/null +++ b/src/cli/entropy.cpp @@ -0,0 +1,104 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "cli.h" +#include "../tests/test_rng.h" // FIXME + +#include <botan/entropy_src.h> + +#if defined(BOTAN_HAS_COMPRESSION) +#include <botan/compression.h> +#endif + +namespace Botan_CLI { + +class Entropy final : public Command + { + public: + Entropy() : Command("entropy --truncate-at=128 source") {} + + std::string group() const override + { + return "misc"; + } + + std::string description() const override + { + return "Sample a raw entropy source"; + } + + void go() override + { + const std::string req_source = get_arg("source"); + const size_t truncate_sample = get_arg_sz("truncate-at"); + + auto& entropy_sources = Botan::Entropy_Sources::global_sources(); + + std::vector<std::string> sources; + if(req_source == "all") + sources = entropy_sources.enabled_sources(); + else + sources.push_back(req_source); + + for(std::string source : sources) + { + Botan_Tests::SeedCapturing_RNG rng; + const size_t entropy_estimate = entropy_sources.poll_just(rng, source); + + if(rng.samples() == 0) + { + output() << "Source " << source << " is unavailable\n"; + continue; + } + + const auto& sample = rng.seed_material(); + + output() << "Polling " << source << " gathered " << sample.size() + << " bytes in " << rng.samples() << " outputs with estimated entropy " + << entropy_estimate << "\n"; + +#if defined(BOTAN_HAS_COMPRESSION) + if(!sample.empty()) + { + std::unique_ptr<Botan::Compression_Algorithm> comp(Botan::make_compressor("zlib")); + if(comp) + { + try + { + Botan::secure_vector<uint8_t> compressed; + compressed.assign(sample.begin(), sample.end()); + comp->start(9); + comp->finish(compressed); + + if(compressed.size() < sample.size()) + { + output() << "Sample from " << source << " was zlib compressed from " << sample.size() + << " bytes to " << compressed.size() << " bytes\n"; + } + } + catch(std::exception& e) + { + error_output() << "Error while attempting to compress: " << e.what() << "\n"; + } + } + } +#endif + + if(sample.size() <= truncate_sample) + { + output() << Botan::hex_encode(sample) << "\n"; + } + else if(truncate_sample > 0) + { + output() << Botan::hex_encode(&sample[0], truncate_sample) << "...\n"; + } + } + } + }; + +BOTAN_REGISTER_COMMAND("entropy", Entropy); + +} |