/* * (C) 2015,2017 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include "cli.h" #include #include #include #include #if defined(BOTAN_HAS_AUTO_SEEDING_RNG) #include #endif #if defined(BOTAN_HAS_SYSTEM_RNG) #include #endif #if defined(BOTAN_HAS_RDRAND_RNG) #include #endif #if defined(BOTAN_HAS_HMAC_DRBG) #include #endif namespace Botan_CLI { std::unique_ptr 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(new Botan::System_RNG); } #endif #if defined(BOTAN_HAS_RDRAND_RNG) if(rng_type == "rdrand") { if(Botan::CPUID::has_rdrand()) return std::unique_ptr(new Botan::RDRAND_RNG); else throw CLI_Error("RDRAND instruction not supported on this processor"); } #endif const std::vector 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 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_HAS_SHA2_32) if(rng_type == "drbg") { std::unique_ptr mac = Botan::MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); std::unique_ptr 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(rng.release()); } #endif throw CLI_Error_Unsupported("RNG", rng_type); } }