diff options
Diffstat (limited to 'src/cli/utils.cpp')
-rw-r--r-- | src/cli/utils.cpp | 109 |
1 files changed, 73 insertions, 36 deletions
diff --git a/src/cli/utils.cpp b/src/cli/utils.cpp index 63e0fc7d6..ce461cb65 100644 --- a/src/cli/utils.cpp +++ b/src/cli/utils.cpp @@ -29,6 +29,10 @@ #include <botan/rdrand_rng.h> #endif +#if defined(BOTAN_HAS_HMAC_DRBG) + #include <botan/hmac_drbg.h> +#endif + #if defined(BOTAN_HAS_HTTP_UTIL) #include <botan/http_util.h> #endif @@ -47,6 +51,64 @@ 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") + { + 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") + { + 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) + 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); + } + class Config_Info final : public Command { public: @@ -170,49 +232,24 @@ BOTAN_REGISTER_COMMAND("hash", Hash); class RNG final : public Command { public: - RNG() : Command("rng --system --rdrand --entropy *bytes") {} + RNG() : Command("rng --system --rdrand --auto --entropy --drbg --drbg-seed= *bytes") {} void go() override { - std::unique_ptr<Botan::RNG> rng; + std::string type = "auto"; // default - if(flag_set("system")) - { -#if defined(BOTAN_HAS_SYSTEM_RNG) - rng.reset(new Botan::System_RNG); -#else - error_output() << "system_rng disabled in build\n"; - return; -#endif - } - else if(flag_set("rdrand")) + for(std::string flag : { "system", "rdrand", "auto", "entropy", "drbg" }) { -#if defined(BOTAN_HAS_RDRAND_RNG) - rng.reset(new Botan::RDRAND_RNG); -#else - error_output() << "rdrand_rng disabled in build\n"; - return; -#endif - } - else if(flag_set("entropy")) - { -#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - rng.reset(new Botan::AutoSeeded_RNG(Botan::Entropy_Sources::global_sources())); -#else - error_output() << "auto_rng disabled in build\n"; - return; -#endif - } - else - { -#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - rng.reset(new Botan::AutoSeeded_RNG); -#else - error_output() << "auto_rng disabled in build\n"; - return; -#endif + if(flag_set(flag)) + { + type = flag; + break; + } } + const std::string drbg_seed = get_arg("drbg-seed"); + std::unique_ptr<Botan::RNG> rng = cli_make_rng(type, drbg_seed); + for(const std::string& req : get_arg_list("bytes")) { output() << Botan::hex_encode(rng->random_vec(Botan::to_u32bit(req))) << "\n"; |