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

randombit / botan / 13212092742

08 Feb 2025 12:33AM UTC coverage: 91.658% (-0.004%) from 91.662%
13212092742

push

github

web-flow
Merge pull request #4642 from randombit/jack/target-info-header

Add internal target_info.h header

94839 of 103471 relevant lines covered (91.66%)

11295178.12 hits per line

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

96.72
/src/lib/entropy/entropy_srcs.cpp
1
/*
2
* Entropy Source Polling
3
* (C) 2008-2010,2015 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/entropy_src.h>
9

10
#include <botan/rng.h>
11
#include <botan/internal/target_info.h>
12

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

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

21
#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
22
   #include <botan/internal/rdseed.h>
23
#endif
24

25
#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
26
   #include <botan/internal/es_win32.h>
27
#endif
28

29
#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
30
   #include <botan/internal/getentropy.h>
31
#endif
32

33
#if defined(BOTAN_HAS_JITTER_RNG)
34
   #include <botan/jitter_rng.h>
35
#endif
36

37
namespace Botan {
38

39
namespace {
40

41
#if defined(BOTAN_HAS_SYSTEM_RNG)
42

43
class System_RNG_EntropySource final : public Entropy_Source {
3✔
44
   public:
45
      size_t poll(RandomNumberGenerator& rng) override {
4✔
46
         const size_t poll_bits = RandomNumberGenerator::DefaultPollBits;
4✔
47
         rng.reseed_from_rng(system_rng(), poll_bits);
4✔
48
         return poll_bits;
4✔
49
      }
50

51
      std::string name() const override { return "system_rng"; }
6✔
52
};
53

54
#endif
55

56
#if defined(BOTAN_HAS_PROCESSOR_RNG)
57

58
class Processor_RNG_EntropySource final : public Entropy_Source {
3✔
59
   public:
60
      size_t poll(RandomNumberGenerator& rng) override {
5✔
61
         /*
62
         * Intel's documentation for RDRAND at
63
         * https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
64
         * claims that software can guarantee a reseed event by polling enough data:
65
         * "There is an upper bound of 511 samples per seed in the implementation
66
         * where samples are 128 bits in size and can provide two 64-bit random
67
         * numbers each."
68
         *
69
         * By requesting 65536 bits we are asking for 512 samples and thus are assured
70
         * that at some point in producing the output, at least one reseed of the
71
         * internal state will occur.
72
         *
73
         * The reseeding conditions of the POWER and ARM processor RNGs are not known
74
         * but probably work in a somewhat similar manner. The exact amount requested
75
         * may be tweaked if and when such conditions become publically known.
76
         */
77
         const size_t poll_bits = 65536;
5✔
78
         rng.reseed_from_rng(m_hwrng, poll_bits);
5✔
79
         // Avoid trusting a black box, don't count this as contributing entropy:
80
         return 0;
5✔
81
      }
82

83
      std::string name() const override { return m_hwrng.name(); }
14✔
84

85
   private:
86
      Processor_RNG m_hwrng;
87
};
88

89
#endif
90

91
#if defined(BOTAN_HAS_JITTER_RNG)
92

93
class Jitter_RNG_EntropySource final : public Entropy_Source {
1✔
94
   public:
95
      size_t poll(RandomNumberGenerator& rng) override {
1✔
96
         rng.reseed_from_rng(m_rng);
1✔
97
         return RandomNumberGenerator::DefaultPollBits;
1✔
98
      }
99

100
      std::string name() const override { return m_rng.name(); }
×
101

102
   private:
103
      Jitter_RNG m_rng;
104
};
105

106
#endif
107

108
}  // namespace
109

110
std::unique_ptr<Entropy_Source> Entropy_Source::create(std::string_view name) {
16✔
111
#if defined(BOTAN_HAS_SYSTEM_RNG)
112
   if(name == "system_rng") {
16✔
113
      return std::make_unique<System_RNG_EntropySource>();
3✔
114
   }
115
#endif
116

117
#if defined(BOTAN_HAS_PROCESSOR_RNG)
118
   if(name == "hwrng") {
13✔
119
      if(Processor_RNG::available()) {
3✔
120
         return std::make_unique<Processor_RNG_EntropySource>();
3✔
121
      }
122
   }
123
#endif
124

125
#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
126
   if(name == "rdseed") {
10✔
127
      return std::make_unique<Intel_Rdseed>();
3✔
128
   }
129
#endif
130

131
#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
132
   if(name == "getentropy") {
7✔
133
      return std::make_unique<Getentropy>();
3✔
134
   }
135
#endif
136

137
#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
138
   if(name == "system_stats") {
139
      return std::make_unique<Win32_EntropySource>();
140
   }
141
#endif
142

143
#if defined(BOTAN_HAS_JITTER_RNG)
144
   if(name == "jitter_rng") {
4✔
145
      return std::make_unique<Jitter_RNG_EntropySource>();
1✔
146
   }
147
#endif
148

149
   BOTAN_UNUSED(name);
3✔
150
   return nullptr;
3✔
151
}
152

153
void Entropy_Sources::add_source(std::unique_ptr<Entropy_Source> src) {
22✔
154
   if(src) {
22✔
155
      m_srcs.push_back(std::move(src));
19✔
156
   }
157
}
22✔
158

159
std::vector<std::string> Entropy_Sources::enabled_sources() const {
2✔
160
   std::vector<std::string> sources;
2✔
161
   sources.reserve(m_srcs.size());
2✔
162
   for(const auto& src : m_srcs) {
10✔
163
      sources.push_back(src->name());
16✔
164
   }
165
   return sources;
2✔
166
}
×
167

168
size_t Entropy_Sources::poll(RandomNumberGenerator& rng, size_t poll_bits, std::chrono::milliseconds timeout) {
10✔
169
#if defined(BOTAN_TARGET_OS_HAS_SYSTEM_CLOCK)
170
   typedef std::chrono::system_clock clock;
10✔
171
   auto timeout_expired = [to = clock::now() + timeout] { return clock::now() > to; };
14✔
172
#else
173
   auto timeout_expired = [] { return false; };
174
#endif
175

176
   size_t bits_collected = 0;
10✔
177

178
   for(auto& src : m_srcs) {
14✔
179
      bits_collected += src->poll(rng);
10✔
180

181
      if(bits_collected >= poll_bits || timeout_expired()) {
10✔
182
         break;
183
      }
184
   }
185

186
   return bits_collected;
6✔
187
}
188

189
size_t Entropy_Sources::poll_just(RandomNumberGenerator& rng, std::string_view the_src) {
16✔
190
   for(auto& src : m_srcs) {
40✔
191
      if(src->name() == the_src) {
80✔
192
         return src->poll(rng);
16✔
193
      }
194
   }
195

196
   return 0;
197
}
198

199
Entropy_Sources::Entropy_Sources(const std::vector<std::string>& sources) {
3✔
200
   for(auto&& src_name : sources) {
18✔
201
      add_source(Entropy_Source::create(src_name));
30✔
202
   }
203
}
3✔
204

205
Entropy_Sources& Entropy_Sources::global_sources() {
8✔
206
   static Entropy_Sources global_entropy_sources({"rdseed", "hwrng", "getentropy", "system_rng", "system_stats"});
8✔
207

208
   return global_entropy_sources;
8✔
209
}
210

211
}  // namespace Botan
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