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

randombit / botan / 13274522654

11 Feb 2025 11:26PM UTC coverage: 91.645% (-0.007%) from 91.652%
13274522654

push

github

web-flow
Merge pull request #4647 from randombit/jack/internal-assert-and-mem-ops

Avoid using mem_ops.h or assert.h in public headers

94854 of 103501 relevant lines covered (91.65%)

11334975.77 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/assert.h>
11
#include <botan/rng.h>
12
#include <botan/internal/target_info.h>
13

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

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

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

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

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

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

38
namespace Botan {
39

40
namespace {
41

42
#if defined(BOTAN_HAS_SYSTEM_RNG)
43

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

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

55
#endif
56

57
#if defined(BOTAN_HAS_PROCESSOR_RNG)
58

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

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

86
   private:
87
      Processor_RNG m_hwrng;
88
};
89

90
#endif
91

92
#if defined(BOTAN_HAS_JITTER_RNG)
93

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

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

103
   private:
104
      Jitter_RNG m_rng;
105
};
106

107
#endif
108

109
}  // namespace
110

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

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

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

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

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

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

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

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

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

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

177
   size_t bits_collected = 0;
10✔
178

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

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

187
   return bits_collected;
6✔
188
}
189

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

197
   return 0;
198
}
199

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

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

209
   return global_entropy_sources;
8✔
210
}
211

212
}  // 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