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

randombit / botan / 11268576238

10 Oct 2024 06:22AM UTC coverage: 90.983% (-0.02%) from 91.007%
11268576238

push

github

web-flow
Merge pull request #4325 from plancksecurity/jitter

Add jitterentropy as RNG

89487 of 98356 relevant lines covered (90.98%)

8933666.37 hits per line

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

96.77
/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

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

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

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

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

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

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

36
namespace Botan {
37

38
namespace {
39

40
#if defined(BOTAN_HAS_SYSTEM_RNG)
41

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

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

53
#endif
54

55
#if defined(BOTAN_HAS_PROCESSOR_RNG)
56

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

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

84
   private:
85
      Processor_RNG m_hwrng;
86
};
87

88
#endif
89

90
#if defined(BOTAN_HAS_JITTER_RNG)
91

92
class Jitter_RNG_EntropySource final : public Entropy_Source {
1✔
93
   public:
94
      size_t poll(RandomNumberGenerator& rng) override {
1✔
95
         const size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS;
1✔
96
         rng.reseed_from_rng(m_rng, poll_bits);
1✔
97
         return poll_bits;
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) {
21✔
111
#if defined(BOTAN_HAS_SYSTEM_RNG)
112
   if(name == "system_rng") {
21✔
113
      return std::make_unique<System_RNG_EntropySource>();
4✔
114
   }
115
#endif
116

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

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

131
#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
132
   if(name == "getentropy") {
9✔
133
      return std::make_unique<Getentropy>();
4✔
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") {
5✔
145
      return std::make_unique<Jitter_RNG_EntropySource>();
1✔
146
   }
147
#endif
148

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

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

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

168
size_t Entropy_Sources::poll(RandomNumberGenerator& rng, size_t poll_bits, std::chrono::milliseconds timeout) {
10✔
169
   typedef std::chrono::system_clock clock;
10✔
170

171
   auto deadline = clock::now() + timeout;
10✔
172

173
   size_t bits_collected = 0;
10✔
174

175
   for(auto& src : m_srcs) {
14✔
176
      bits_collected += src->poll(rng);
10✔
177

178
      if(bits_collected >= poll_bits || clock::now() > deadline) {
6✔
179
         break;
180
      }
181
   }
182

183
   return bits_collected;
6✔
184
}
185

186
size_t Entropy_Sources::poll_just(RandomNumberGenerator& rng, std::string_view the_src) {
20✔
187
   for(auto& src : m_srcs) {
50✔
188
      if(src->name() == the_src) {
100✔
189
         return src->poll(rng);
20✔
190
      }
191
   }
192

193
   return 0;
194
}
195

196
Entropy_Sources::Entropy_Sources(const std::vector<std::string>& sources) {
4✔
197
   for(auto&& src_name : sources) {
24✔
198
      add_source(Entropy_Source::create(src_name));
40✔
199
   }
200
}
4✔
201

202
Entropy_Sources& Entropy_Sources::global_sources() {
9✔
203
   static Entropy_Sources global_entropy_sources(BOTAN_ENTROPY_DEFAULT_SOURCES);
9✔
204

205
   return global_entropy_sources;
9✔
206
}
207

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