1 /* 2 * (C) 2014,2015,2017 Jack Lloyd 3 * (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity 4 * 5 * Botan is released under the Simplified BSD License (see license.txt) 6 */ 7 8 #include "tests.h" 9 10 #if defined(BOTAN_HAS_HMAC_DRBG) 11 #include <botan/hmac_drbg.h> 12 #endif 13 14 #if defined(BOTAN_HAS_CHACHA_RNG) 15 #include <botan/chacha_rng.h> 16 #endif 17 18 namespace Botan_Tests { 19 20 namespace { 21 22 #if defined(BOTAN_HAS_HMAC_DRBG) 23 24 class HMAC_DRBG_Tests final : public Text_Based_Test 25 { 26 public: HMAC_DRBG_Tests()27 HMAC_DRBG_Tests() 28 : Text_Based_Test("rng/hmac_drbg.vec", 29 "EntropyInput,EntropyInputReseed,Out", 30 "AdditionalInput1,AdditionalInput2") {} 31 run_one_test(const std::string & algo,const VarMap & vars)32 Test::Result run_one_test(const std::string& algo, const VarMap& vars) override 33 { 34 const std::vector<uint8_t> seed_input = vars.get_req_bin("EntropyInput"); 35 const std::vector<uint8_t> reseed_input = vars.get_req_bin("EntropyInputReseed"); 36 const std::vector<uint8_t> expected = vars.get_req_bin("Out"); 37 38 const std::vector<uint8_t> ad1 = vars.get_opt_bin("AdditionalInput1"); 39 const std::vector<uint8_t> ad2 = vars.get_opt_bin("AdditionalInput2"); 40 41 Test::Result result("HMAC_DRBG(" + algo + ")"); 42 43 auto mac = Botan::MessageAuthenticationCode::create("HMAC(" + algo + ")"); 44 45 if(!mac) 46 { 47 result.note_missing("HMAC(" + algo + ")"); 48 return result; 49 } 50 51 std::unique_ptr<Botan::HMAC_DRBG> rng(new Botan::HMAC_DRBG(std::move(mac))); 52 rng->initialize_with(seed_input.data(), seed_input.size()); 53 54 // now reseed 55 rng->add_entropy(reseed_input.data(), reseed_input.size()); 56 57 std::vector<uint8_t> out(expected.size()); 58 // first block is discarded 59 rng->randomize_with_input(out.data(), out.size(), ad1.data(), ad1.size()); 60 rng->randomize_with_input(out.data(), out.size(), ad2.data(), ad2.size()); 61 62 result.test_eq("rng", out, expected); 63 return result; 64 } 65 66 }; 67 68 BOTAN_REGISTER_TEST("rng", "hmac_drbg", HMAC_DRBG_Tests); 69 70 #endif 71 72 #if defined(BOTAN_HAS_CHACHA_RNG) 73 74 class ChaCha_RNG_Tests final : public Text_Based_Test 75 { 76 public: ChaCha_RNG_Tests()77 ChaCha_RNG_Tests() 78 : Text_Based_Test("rng/chacha_rng.vec", 79 "EntropyInput,EntropyInputReseed,Out", 80 "AdditionalInput1,AdditionalInput2") {} 81 run_one_test(const std::string &,const VarMap & vars)82 Test::Result run_one_test(const std::string&, const VarMap& vars) override 83 { 84 const std::vector<uint8_t> seed_input = vars.get_req_bin("EntropyInput"); 85 const std::vector<uint8_t> reseed_input = vars.get_req_bin("EntropyInputReseed"); 86 const std::vector<uint8_t> expected = vars.get_req_bin("Out"); 87 88 const std::vector<uint8_t> ad1 = vars.get_opt_bin("AdditionalInput1"); 89 const std::vector<uint8_t> ad2 = vars.get_opt_bin("AdditionalInput2"); 90 91 Test::Result result("ChaCha_RNG"); 92 93 Botan::ChaCha_RNG rng; 94 rng.initialize_with(seed_input.data(), seed_input.size()); 95 96 // now reseed 97 rng.add_entropy(reseed_input.data(), reseed_input.size()); 98 99 std::vector<uint8_t> out(expected.size()); 100 // first block is discarded 101 rng.randomize_with_input(out.data(), out.size(), ad1.data(), ad1.size()); 102 rng.randomize_with_input(out.data(), out.size(), ad2.data(), ad2.size()); 103 104 result.test_eq("rng", out, expected); 105 return result; 106 } 107 108 }; 109 110 BOTAN_REGISTER_TEST("rng", "chacha_rng", ChaCha_RNG_Tests); 111 112 #endif 113 114 } 115 116 } 117