• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 10424747817

16 Aug 2024 06:46PM UTC coverage: 91.272% (+0.002%) from 91.27%
10424747817

Pull #4309

github

web-flow
Merge a74946721 into c2491c780
Pull Request #4309: Add Entropy Source and DRNG Manager (ESDM) RNG support

87820 of 96218 relevant lines covered (91.27%)

9031769.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.93
/src/cli/cli_rng.cpp
1
/*
2
* (C) 2015,2017 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "cli.h"
8
#include <botan/entropy_src.h>
9
#include <botan/hex.h>
10
#include <botan/rng.h>
11
#include <botan/internal/parsing.h>
12

13
#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
14
   #include <botan/auto_rng.h>
15
#endif
16

17
#if defined(BOTAN_HAS_ESDM_RNG)
18
   #include <botan/esdm_rng.h>
19
#endif
20

21
#if defined(BOTAN_HAS_SYSTEM_RNG)
22
   #include <botan/system_rng.h>
23
#endif
24

25
#if defined(BOTAN_HAS_PROCESSOR_RNG)
26
   #include <botan/processor_rng.h>
27
#endif
28

29
#if defined(BOTAN_HAS_HMAC_DRBG)
30
   #include <botan/hmac_drbg.h>
31
#endif
32

33
namespace Botan_CLI {
34

35
std::shared_ptr<Botan::RandomNumberGenerator> cli_make_rng(const std::string& rng_type,
154✔
36
                                                           const std::string& hex_drbg_seed) {
37
#if defined(BOTAN_HAS_SYSTEM_RNG)
38
   if(rng_type == "system" || rng_type.empty()) {
154✔
39
      return std::make_shared<Botan::System_RNG>();
28✔
40
   }
41
#endif
42

43
#if defined(BOTAN_HAS_ESDM_RNG)
44
   if(rng_type == "esdm-full") {
45
      return std::make_shared<Botan::ESDM_RNG>(false);
46
   }
47
   if(rng_type == "esdm-pr") {
48
      return std::make_shared<Botan::ESDM_RNG>(true);
49
   }
50
#endif
51

52
   const std::vector<uint8_t> drbg_seed = Botan::hex_decode(hex_drbg_seed);
126✔
53

54
#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
55
   if(rng_type == "auto" || rng_type == "entropy" || rng_type.empty()) {
126✔
56
      std::shared_ptr<Botan::RandomNumberGenerator> rng;
2✔
57

58
      if(rng_type == "entropy") {
2✔
59
         rng = std::make_shared<Botan::AutoSeeded_RNG>(Botan::Entropy_Sources::global_sources());
1✔
60
      } else {
61
         rng = std::make_shared<Botan::AutoSeeded_RNG>();
1✔
62
      }
63

64
      if(!drbg_seed.empty()) {
2✔
65
         rng->add_entropy(drbg_seed.data(), drbg_seed.size());
×
66
      }
67
      return rng;
2✔
68
   }
2✔
69
#endif
70

71
#if defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32)
72
   if(rng_type == "drbg" || (rng_type.empty() && drbg_seed.empty() == false)) {
124✔
73
      auto mac = Botan::MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)");
123✔
74
      auto rng = std::make_shared<Botan::HMAC_DRBG>(std::move(mac));
123✔
75
      rng->add_entropy(drbg_seed.data(), drbg_seed.size());
123✔
76

77
      if(rng->is_seeded() == false) {
123✔
78
         throw CLI_Error("For " + rng->name() + " a seed of at least " + std::to_string(rng->security_level() / 8) +
×
79
                         " bytes must be provided");
×
80
      }
81

82
      return rng;
123✔
83
   }
123✔
84
#endif
85

86
#if defined(BOTAN_HAS_PROCESSOR_RNG)
87
   if(rng_type == "rdrand" || rng_type == "cpu" || rng_type.empty()) {
1✔
88
      if(Botan::Processor_RNG::available()) {
1✔
89
         return std::make_shared<Botan::Processor_RNG>();
1✔
90
      } else if(rng_type.empty() == false) {
×
91
         throw CLI_Error("RNG instruction not supported on this processor");
×
92
      }
93
   }
94
#endif
95

96
   if(rng_type.empty()) {
×
97
      throw CLI_Error_Unsupported("No random number generator seems to be available in the current build");
×
98
   } else {
99
      throw CLI_Error_Unsupported("RNG", rng_type);
×
100
   }
101
}
126✔
102

103
class RNG final : public Command {
104
   public:
105
      RNG() :
16✔
106
            Command(
107
               "rng --format=hex --system --esdm-full --esdm-pr --rdrand --auto --entropy --drbg --drbg-seed= *bytes") {
16✔
108
      }
16✔
109

110
      std::string group() const override { return "misc"; }
1✔
111

112
      std::string description() const override { return "Sample random bytes from the specified rng"; }
1✔
113

114
      void go() override {
15✔
115
         const std::string format = get_arg("format");
15✔
116
         std::string type = get_arg("rng-type");
15✔
117

118
         if(type.empty()) {
15✔
119
            for(std::string flag : {"system", "rdrand", "auto", "entropy", "drbg", "esdm-full", "esdm-pr"}) {
10✔
120
               if(flag_set(flag)) {
10✔
121
                  type = flag;
4✔
122
                  break;
4✔
123
               }
124
            }
10✔
125
         }
126

127
         const std::string drbg_seed = get_arg("drbg-seed");
15✔
128
         auto rng = cli_make_rng(type, drbg_seed);
15✔
129

130
         for(const std::string& req : get_arg_list("bytes")) {
32✔
131
            const size_t req_len = Botan::to_u32bit(req);
17✔
132
            const auto blob = rng->random_vec(req_len);
17✔
133

134
            if(format == "binary" || format == "raw") {
17✔
135
               write_output(blob);
×
136
            } else {
137
               output() << format_blob(format, blob) << "\n";
34✔
138
            }
139
         }
32✔
140
      }
15✔
141
};
142

143
BOTAN_REGISTER_COMMAND("rng", RNG);
16✔
144

145
}  // namespace Botan_CLI
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc