Botan  2.12.1
Crypto and TLS for C++11
stateful_rng.cpp
Go to the documentation of this file.
1 /*
2 * (C) 2016 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6 
7 #include <botan/stateful_rng.h>
8 #include <botan/internal/os_utils.h>
9 #include <botan/loadstor.h>
10 
11 #if defined(BOTAN_HAS_RDRAND_RNG)
12  #include <botan/rdrand_rng.h>
13 #endif
14 
15 namespace Botan {
16 
18  {
19  m_reseed_counter = 0;
20  m_last_pid = 0;
21  }
22 
24  {
25  m_reseed_counter = 0;
26  }
27 
29  {
30  return m_reseed_counter > 0;
31  }
32 
33 void Stateful_RNG::initialize_with(const uint8_t input[], size_t len)
34  {
35  add_entropy(input, len);
36 
37  if(8*len >= security_level())
38  {
40  }
41  }
42 
43 void Stateful_RNG::randomize_with_ts_input(uint8_t output[], size_t output_len)
44  {
45  uint8_t additional_input[24] = { 0 };
46 
47 #if defined(BOTAN_HAS_RDRAND_RNG)
49  {
50  RDRAND_RNG rdrand;
51  rdrand.randomize(additional_input, sizeof(additional_input));
52  }
53  else
54 #endif
55  {
56  store_le(OS::get_system_timestamp_ns(), additional_input);
57  store_le(OS::get_high_resolution_clock(), additional_input + 8);
58  store_le(m_last_pid, additional_input + 16);
59  store_le(static_cast<uint32_t>(m_reseed_counter), additional_input + 20);
60  }
61 
62  randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
63  }
64 
66  size_t poll_bits,
67  std::chrono::milliseconds poll_timeout)
68  {
69  size_t bits_collected = RandomNumberGenerator::reseed(srcs, poll_bits, poll_timeout);
70 
71  if(bits_collected >= security_level())
72  {
74  }
75 
76  return bits_collected;
77  }
78 
80  {
82 
83  if(poll_bits >= security_level())
84  {
86  }
87  }
88 
90  {
91  const uint32_t cur_pid = OS::get_process_id();
92 
93  const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid);
94 
95  if(is_seeded() == false ||
96  fork_detected ||
97  (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval))
98  {
99  m_reseed_counter = 0;
100  m_last_pid = cur_pid;
101 
102  if(m_underlying_rng)
103  {
104  reseed_from_rng(*m_underlying_rng, security_level());
105  }
106 
107  if(m_entropy_sources)
108  {
109  reseed(*m_entropy_sources, security_level());
110  }
111 
112  if(!is_seeded())
113  {
114  if(fork_detected)
115  throw Invalid_State("Detected use of fork but cannot reseed DRBG");
116  else
117  throw PRNG_Unseeded(name());
118  }
119  }
120  else
121  {
122  BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded");
123  m_reseed_counter += 1;
124  }
125  }
126 
127 }
virtual void add_entropy(const uint8_t input[], size_t length)=0
virtual void randomize_with_input(uint8_t output[], size_t output_len, const uint8_t input[], size_t input_len)
Definition: rng.cpp:38
void randomize_with_ts_input(uint8_t output[], size_t output_len) override final
static bool available()
Definition: rdrand_rng.cpp:85
void randomize(uint8_t out[], size_t out_len) override
Definition: rdrand_rng.cpp:60
bool is_seeded() const override final
uint32_t BOTAN_TEST_API get_process_id()
Definition: os_utils.cpp:95
virtual size_t security_level() const =0
void clear() override
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
virtual size_t reseed(Entropy_Sources &srcs, size_t poll_bits=BOTAN_RNG_RESEED_POLL_BITS, std::chrono::milliseconds poll_timeout=BOTAN_RNG_RESEED_DEFAULT_TIMEOUT)
Definition: rng.cpp:45
virtual std::string name() const =0
uint64_t BOTAN_TEST_API get_system_timestamp_ns()
Definition: os_utils.cpp:292
void reseed_from_rng(RandomNumberGenerator &rng, size_t poll_bits=BOTAN_RNG_RESEED_POLL_BITS) override final
Definition: alg_id.cpp:13
virtual void reseed_from_rng(RandomNumberGenerator &rng, size_t poll_bits=BOTAN_RNG_RESEED_POLL_BITS)
Definition: rng.cpp:59
void initialize_with(const uint8_t input[], size_t length)
size_t reseed(Entropy_Sources &srcs, size_t poll_bits=BOTAN_RNG_RESEED_POLL_BITS, std::chrono::milliseconds poll_timeout=BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:454
uint64_t BOTAN_TEST_API get_high_resolution_clock()
Definition: os_utils.cpp:240