aboutsummaryrefslogtreecommitdiffstats
path: root/src/cli/cli_rng.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-10-22 12:39:45 -0400
committerJack Lloyd <[email protected]>2017-10-24 11:51:28 -0400
commit3feae2f7893090b263e762c79b47b99f7f4d07ba (patch)
tree09f0bac281886ff0003d8d07ee90c7aa2e729985 /src/cli/cli_rng.cpp
parentda0a1124242e3a108819df58054e8dd909268a00 (diff)
Refactor option parsing in cli and test code
Allows cleaning up header includes, also somewhat smaller binaries.
Diffstat (limited to 'src/cli/cli_rng.cpp')
-rw-r--r--src/cli/cli_rng.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/cli/cli_rng.cpp b/src/cli/cli_rng.cpp
new file mode 100644
index 000000000..1e3ecb141
--- /dev/null
+++ b/src/cli/cli_rng.cpp
@@ -0,0 +1,89 @@
+/*
+* (C) 2015,2017 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "cli.h"
+#include <botan/rng.h>
+#include <botan/entropy_src.h>
+#include <botan/cpuid.h>
+#include <botan/hex.h>
+
+#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
+ #include <botan/auto_rng.h>
+#endif
+
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ #include <botan/system_rng.h>
+#endif
+
+#if defined(BOTAN_HAS_RDRAND_RNG)
+ #include <botan/rdrand_rng.h>
+#endif
+
+#if defined(BOTAN_HAS_HMAC_DRBG)
+ #include <botan/hmac_drbg.h>
+#endif
+
+namespace Botan_CLI {
+
+std::unique_ptr<Botan::RandomNumberGenerator>
+cli_make_rng(const std::string& rng_type, const std::string& hex_drbg_seed)
+ {
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ if(rng_type == "system" || rng_type.empty())
+ {
+ return std::unique_ptr<Botan::RandomNumberGenerator>(new Botan::System_RNG);
+ }
+#endif
+
+#if defined(BOTAN_HAS_RDRAND_RNG)
+ if(rng_type == "rdrand")
+ {
+ if(Botan::CPUID::has_rdrand())
+ return std::unique_ptr<Botan::RandomNumberGenerator>(new Botan::RDRAND_RNG);
+ else
+ throw CLI_Error("RDRAND instruction not supported on this processor");
+ }
+#endif
+
+ const std::vector<uint8_t> drbg_seed = Botan::hex_decode(hex_drbg_seed);
+
+#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
+ if(rng_type == "auto" || rng_type == "entropy" || rng_type.empty())
+ {
+ std::unique_ptr<Botan::RandomNumberGenerator> rng;
+
+ if(rng_type == "entropy")
+ rng.reset(new Botan::AutoSeeded_RNG(Botan::Entropy_Sources::global_sources()));
+ else
+ rng.reset(new Botan::AutoSeeded_RNG);
+
+ if(drbg_seed.size() > 0)
+ rng->add_entropy(drbg_seed.data(), drbg_seed.size());
+ return rng;
+ }
+#endif
+
+#if defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_AUTO_RNG_HMAC)
+ if(rng_type == "drbg")
+ {
+ std::unique_ptr<Botan::MessageAuthenticationCode> mac =
+ Botan::MessageAuthenticationCode::create(BOTAN_AUTO_RNG_HMAC);
+ std::unique_ptr<Botan::Stateful_RNG> rng(new Botan::HMAC_DRBG(std::move(mac)));
+ rng->add_entropy(drbg_seed.data(), drbg_seed.size());
+
+ if(rng->is_seeded() == false)
+ throw CLI_Error("For " + rng->name() + " a seed of at least " +
+ std::to_string(rng->security_level()/8) +
+ " bytes must be provided");
+
+ return std::unique_ptr<Botan::RandomNumberGenerator>(rng.release());
+ }
+#endif
+
+ throw CLI_Error_Unsupported("RNG", rng_type);
+ }
+
+}