Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
17 void Stateful_RNG::clear()
18 {
19 m_reseed_counter = 0;
20 m_last_pid = 0;
21 }
22
23 void Stateful_RNG::force_reseed()
24 {
25 m_reseed_counter = 0;
26 }
27
28 bool Stateful_RNG::is_seeded() const
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 {
39 reset_reseed_counter();
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 store_le(OS::get_high_resolution_clock(), additional_input);
48
49 #if defined(BOTAN_HAS_RDRAND_RNG)
50 if(RDRAND_RNG::available())
51 {
52 RDRAND_RNG rdrand;
53 rdrand.randomize(additional_input + 8, sizeof(additional_input) - 8);
54 }
55 else
56 #endif
57 {
58 store_le(OS::get_system_timestamp_ns(), additional_input + 8);
59 store_le(m_last_pid, additional_input + 16);
60 store_le(static_cast<uint32_t>(m_reseed_counter), additional_input + 20);
61 }
62
63 randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
64 }
65
66 size_t Stateful_RNG::reseed(Entropy_Sources& srcs,
67 size_t poll_bits,
68 std::chrono::milliseconds poll_timeout)
69 {
70 size_t bits_collected = RandomNumberGenerator::reseed(srcs, poll_bits, poll_timeout);
71
72 if(bits_collected >= security_level())
73 {
74 reset_reseed_counter();
75 }
76
77 return bits_collected;
78 }
79
80 void Stateful_RNG::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits)
81 {
82 RandomNumberGenerator::reseed_from_rng(rng, poll_bits);
83
84 if(poll_bits >= security_level())
85 {
86 reset_reseed_counter();
87 }
88 }
89
90 void Stateful_RNG::reseed_check()
91 {
92 const uint32_t cur_pid = OS::get_process_id();
93
94 const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid);
95
96 if(is_seeded() == false ||
97 fork_detected ||
98 (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval))
99 {
100 m_reseed_counter = 0;
101 m_last_pid = cur_pid;
102
103 if(m_underlying_rng)
104 {
105 reseed_from_rng(*m_underlying_rng, security_level());
106 }
107
108 if(m_entropy_sources)
109 {
110 reseed(*m_entropy_sources, security_level());
111 }
112
113 if(!is_seeded())
114 {
115 if(fork_detected)
116 throw Invalid_State("Detected use of fork but cannot reseed DRBG");
117 else
118 throw PRNG_Unseeded(name());
119 }
120 }
121 else
122 {
123 BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded");
124 m_reseed_counter += 1;
125 }
126 }
127
128 }
Botan::Stateful_RNG::randomize_with_ts_input
void randomize_with_ts_input(uint8_t output[], size_t output_len) overridefinal
Definition: stateful_rng.cpp:43
Botan::RandomNumberGenerator::add_entropy
virtual void add_entropy(const uint8_t input[], size_t length)=0
Botan::RandomNumberGenerator::randomize_with_input
virtual void randomize_with_input(uint8_t output[], size_t output_len, const uint8_t input[], size_t input_len)
Definition: rng.cpp:38
Botan::RandomNumberGenerator
Definition: rng.h:24
Botan::RDRAND_RNG::available
static bool available()
Definition: rdrand_rng.cpp:85
Botan::RDRAND_RNG::randomize
void randomize(uint8_t out[], size_t out_len) override
Definition: rdrand_rng.cpp:60
Botan::OS::get_process_id
uint32_t BOTAN_TEST_API get_process_id()
Definition: os_utils.cpp:96
Botan::Stateful_RNG::security_level
virtual size_t security_level() const =0
Botan::RDRAND_RNG
Definition: rdrand_rng.h:15
Botan::Stateful_RNG::clear
void clear() override
Definition: stateful_rng.cpp:17
Botan::PRNG_Unseeded
Definition: exceptn.h:226
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
Botan::Stateful_RNG::reseed_from_rng
void reseed_from_rng(RandomNumberGenerator &rng, size_t poll_bits=BOTAN_RNG_RESEED_POLL_BITS) overridefinal
Definition: stateful_rng.cpp:80
Botan::RandomNumberGenerator::reseed
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
Botan::RandomNumberGenerator::name
virtual std::string name() const =0
Botan::OS::get_system_timestamp_ns
uint64_t BOTAN_TEST_API get_system_timestamp_ns()
Definition: os_utils.cpp:293
Botan::Stateful_RNG::is_seeded
bool is_seeded() const overridefinal
Definition: stateful_rng.cpp:28
Botan::Stateful_RNG::force_reseed
void force_reseed()
Definition: stateful_rng.cpp:23
Botan
Definition: alg_id.cpp:13
Botan::Stateful_RNG::reseed_check
void reseed_check()
Definition: stateful_rng.cpp:90
Botan::RandomNumberGenerator::reseed_from_rng
virtual void reseed_from_rng(RandomNumberGenerator &rng, size_t poll_bits=BOTAN_RNG_RESEED_POLL_BITS)
Definition: rng.cpp:59
Botan::Stateful_RNG::initialize_with
void initialize_with(const uint8_t input[], size_t length)
Definition: stateful_rng.cpp:33
Botan::Invalid_State
Definition: exceptn.h:215
Botan::Stateful_RNG::reseed
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
Definition: stateful_rng.cpp:66
Botan::Stateful_RNG::reset_reseed_counter
void reset_reseed_counter()
Definition: stateful_rng.h:131
Botan::Entropy_Sources
Definition: entropy_src.h:56
Botan::store_le
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:454
Botan::OS::get_high_resolution_clock
uint64_t BOTAN_TEST_API get_high_resolution_clock()
Definition: os_utils.cpp:241