Botan  1.11.31
Public Member Functions | Static Public Member Functions | Protected Member Functions | List of all members
Botan::HMAC_RNG Class Referencefinal

#include <hmac_rng.h>

Inheritance diagram for Botan::HMAC_RNG:
Botan::Stateful_RNG Botan::RandomNumberGenerator

Public Member Functions

void add_entropy (const byte[], size_t) override
 
template<typename T >
void add_entropy_T (const T &t)
 
void clear () override
 
void force_reseed ()
 
 HMAC_RNG (std::unique_ptr< MessageAuthenticationCode > prf, RandomNumberGenerator &underlying_rng, Entropy_Sources &entropy_sources, size_t reseed_interval=BOTAN_RNG_DEFAULT_RESEED_INTERVAL)
 
 HMAC_RNG (std::unique_ptr< MessageAuthenticationCode > prf, RandomNumberGenerator &underlying_rng, size_t reseed_interval=BOTAN_RNG_DEFAULT_RESEED_INTERVAL)
 
 HMAC_RNG (std::unique_ptr< MessageAuthenticationCode > prf, Entropy_Sources &entropy_sources, size_t reseed_interval=BOTAN_RNG_DEFAULT_RESEED_INTERVAL)
 
 HMAC_RNG (std::unique_ptr< MessageAuthenticationCode > prf)
 
void initialize_with (const byte input[], size_t length)
 
bool is_seeded () const overridefinal
 
std::string name () const override
 
byte next_byte ()
 
byte next_nonzero_byte ()
 
secure_vector< byterandom_vec (size_t bytes)
 
void randomize (byte buf[], size_t len) override
 
virtual void randomize_with_input (byte output[], size_t output_len, const byte input[], size_t input_len)
 
void randomize_with_ts_input (byte output[], size_t output_len) overridefinal
 
size_t reseed (Entropy_Sources &srcs, size_t poll_bits, std::chrono::milliseconds poll_timeout) override
 
void reseed_from_rng (RandomNumberGenerator &rng, size_t poll_bits=BOTAN_RNG_RESEED_POLL_BITS) overridefinal
 
size_t security_level () const override
 

Static Public Member Functions

static RandomNumberGeneratormake_rng ()
 

Protected Member Functions

uint32_t last_pid () const
 
void reseed_check ()
 

Detailed Description

HMAC_RNG - based on the design described in "On Extract-then-Expand Key Derivation Functions and an HMAC-based KDF" by Hugo Krawczyk (henceforce, 'E-t-E')

However it actually could be parameterized with any two MAC functions, not restricted to HMAC (this variation is also described in Krawczyk's paper), for instance one could use HMAC(SHA-512) as the extractor and CMAC(AES-256) as the PRF.

Definition at line 26 of file hmac_rng.h.

Constructor & Destructor Documentation

Botan::HMAC_RNG::HMAC_RNG ( std::unique_ptr< MessageAuthenticationCode prf,
RandomNumberGenerator underlying_rng,
Entropy_Sources entropy_sources,
size_t  reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL 
)

Initialize an HMAC_RNG instance with the given MAC as PRF (normally HMAC)

Parameters
underlying_rngis a reference to some RNG which will be used to perform the periodic reseeding.
entropy_sourceswill be polled to perform reseeding periodically
reseed_intervalspecifies a limit of how many times the RNG will be called before automatic reseeding is performed.

Definition at line 15 of file hmac_rng.cpp.

References BOTAN_ASSERT_NONNULL, and clear().

18  :
19  Stateful_RNG(underlying_rng, reseed_interval),
20  m_prf(std::move(prf))
21  {
22  BOTAN_ASSERT_NONNULL(m_prf);
23 
24  if(!m_prf->valid_keylength(m_prf->output_length()))
25  {
26  throw Invalid_Argument("HMAC_RNG cannot use " + m_prf->name());
27  }
28 
29  m_extractor.reset(m_prf->clone());
30  this->clear();
31  }
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:66
void clear() override
Definition: hmac_rng.cpp:83
Botan::HMAC_RNG::HMAC_RNG ( std::unique_ptr< MessageAuthenticationCode prf,
RandomNumberGenerator underlying_rng,
size_t  reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL 
)

Initialize an HMAC_RNG instance with the given MAC as PRF (normally HMAC)

Parameters
underlying_rngis a reference to some RNG which will be used to perform the periodic reseeding.
reseed_intervalspecifies a limit of how many times the RNG will be called before automatic reseeding is performed.

Definition at line 33 of file hmac_rng.cpp.

References BOTAN_ASSERT_NONNULL, and clear().

35  :
36  Stateful_RNG(underlying_rng, reseed_interval),
37  m_prf(std::move(prf))
38  {
39  BOTAN_ASSERT_NONNULL(m_prf);
40 
41  if(!m_prf->valid_keylength(m_prf->output_length()))
42  {
43  throw Invalid_Argument("HMAC_RNG cannot use " + m_prf->name());
44  }
45 
46  m_extractor.reset(m_prf->clone());
47  this->clear();
48  }
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:66
void clear() override
Definition: hmac_rng.cpp:83
Botan::HMAC_RNG::HMAC_RNG ( std::unique_ptr< MessageAuthenticationCode prf,
Entropy_Sources entropy_sources,
size_t  reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL 
)

Definition at line 50 of file hmac_rng.cpp.

References BOTAN_ASSERT_NONNULL, and clear().

52  :
53  Stateful_RNG(entropy_sources, reseed_interval),
54  m_prf(std::move(prf)),
55  m_extractor(m_prf->clone())
56  {
57  BOTAN_ASSERT_NONNULL(m_prf);
58 
59  if(!m_prf->valid_keylength(m_prf->output_length()))
60  {
61  throw Invalid_Argument("HMAC_RNG cannot use " + m_prf->name());
62  }
63 
64  m_extractor.reset(m_prf->clone());
65  this->clear();
66  }
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:66
void clear() override
Definition: hmac_rng.cpp:83
Botan::HMAC_RNG::HMAC_RNG ( std::unique_ptr< MessageAuthenticationCode prf)

Initialize an HMAC_RNG instance with the given MAC as PRF (normally HMAC) Automatic reseeding is disabled completely.

Definition at line 68 of file hmac_rng.cpp.

References BOTAN_ASSERT_NONNULL, and clear().

68  :
69  Stateful_RNG(),
70  m_prf(std::move(prf))
71  {
72  BOTAN_ASSERT_NONNULL(m_prf);
73 
74  if(!m_prf->valid_keylength(m_prf->output_length()))
75  {
76  throw Invalid_Argument("HMAC_RNG cannot use " + m_prf->name());
77  }
78 
79  m_extractor.reset(m_prf->clone());
80  this->clear();
81  }
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:66
void clear() override
Definition: hmac_rng.cpp:83

Member Function Documentation

void Botan::HMAC_RNG::add_entropy ( const byte  input[],
size_t  length 
)
overridevirtual

Incorporate some additional data into the RNG state. For example adding nonces or timestamps from a peer's protocol message can help hedge against VM state rollback attacks. A few RNG types do not accept any externally provided input, in which case this function is a no-op.

Parameters
inputsa byte array containg the entropy to be added
lengththe length of the byte array in

Implements Botan::RandomNumberGenerator.

Definition at line 185 of file hmac_rng.cpp.

References Botan::Stateful_RNG::force_reseed().

186  {
187  m_extractor->update(input, length);
188  force_reseed();
189  }
template<typename T >
void Botan::RandomNumberGenerator::add_entropy_T ( const T &  t)
inlineinherited

Incorporate some additional data into the RNG state.

Definition at line 60 of file rng.h.

Referenced by Botan::Win32_EntropySource::poll(), Botan::Intel_Rdseed::poll(), and Botan::UnixProcessInfo_EntropySource::poll().

61  {
62  this->add_entropy(reinterpret_cast<const uint8_t*>(&t), sizeof(T));
63  }
virtual void add_entropy(const byte input[], size_t length)=0
void Botan::HMAC_RNG::clear ( )
overridevirtual

Clear all internally held values of this RNG

Postcondition
is_seeded() == false

Implements Botan::RandomNumberGenerator.

Definition at line 83 of file hmac_rng.cpp.

References Botan::Stateful_RNG::clear(), Botan::OS::get_processor_timestamp(), Botan::OS::get_system_timestamp_ns(), Botan::Stateful_RNG::last_pid(), and Botan::zeroise().

Referenced by HMAC_RNG().

84  {
86  m_counter = 0;
87 
88  // First PRF inputs are all zero, as specified in section 2
89  m_K.resize(m_prf->output_length());
90  zeroise(m_K);
91 
92  /*
93  Normally we want to feedback PRF outputs to the extractor function
94  to ensure a single bad poll does not reduce entropy. Thus in reseed
95  we'll want to invoke the PRF before we reset the PRF key, but until
96  the first reseed the PRF is unkeyed. Rather than trying to keep
97  track of this, just set the initial PRF key to constant zero.
98  Since all PRF inputs in the first reseed are constants, this
99  amounts to suffixing the seed in the first poll with a fixed
100  constant string.
101 
102  The PRF key will not be used to generate outputs until after reseed
103  sets m_seeded to true.
104  */
105  std::vector<byte> prf_zero_key(m_extractor->output_length());
106  m_prf->set_key(prf_zero_key.data(), prf_zero_key.size());
107 
108  /*
109  Use PRF("Botan HMAC_RNG XTS") as the intitial XTS key.
110 
111  This will be used during the first extraction sequence; XTS values
112  after this one are generated using the PRF.
113 
114  If I understand the E-t-E paper correctly (specifically Section 4),
115  using this fixed initial extractor key is safe to do.
116  */
117  m_extractor->set_key(m_prf->process("Botan HMAC_RNG XTS"));
118  }
void clear() override
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:191
void Botan::Stateful_RNG::force_reseed ( )
inherited

Mark state as requiring a reseed on next use

Definition at line 19 of file stateful_rng.cpp.

Referenced by add_entropy().

20  {
21  m_reseed_counter = 0;
22  }
void Botan::Stateful_RNG::initialize_with ( const byte  input[],
size_t  length 
)
inherited

Consume this input and mark the RNG as initialized regardless of the length of the input or the current seeded state of the RNG.

Definition at line 29 of file stateful_rng.cpp.

References Botan::RandomNumberGenerator::add_entropy(), and Botan::Stateful_RNG::security_level().

30  {
31  add_entropy(input, len);
32 
33  if(8*len >= security_level())
34  {
35  m_reseed_counter = 1;
36  }
37  }
virtual size_t security_level() const =0
virtual void add_entropy(const byte input[], size_t length)=0
bool Botan::Stateful_RNG::is_seeded ( ) const
finaloverridevirtualinherited

Check whether this RNG is seeded.

Returns
true if this RNG was already seeded, false otherwise.

Implements Botan::RandomNumberGenerator.

Definition at line 24 of file stateful_rng.cpp.

Referenced by Botan::Stateful_RNG::reseed_check().

25  {
26  return m_reseed_counter > 0;
27  }
uint32_t Botan::Stateful_RNG::last_pid ( ) const
inlineprotectedinherited

Definition at line 96 of file stateful_rng.h.

Referenced by clear().

96 { return m_last_pid; }
RandomNumberGenerator * Botan::RandomNumberGenerator::make_rng ( )
staticinherited

Create a seeded and active RNG object for general application use Added in 1.8.0 Use AutoSeeded_RNG instead

Definition at line 51 of file rng.cpp.

References Botan::Serialized_RNG::Serialized_RNG().

52  {
53 #if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
54  return new AutoSeeded_RNG;
55 #else
56  throw Exception("make_rng failed, no AutoSeeded_RNG in this build");
57 #endif
58  }
std::string Botan::HMAC_RNG::name ( ) const
overridevirtual

Return the name of this RNG type

Implements Botan::RandomNumberGenerator.

Definition at line 194 of file hmac_rng.cpp.

195  {
196  return "HMAC_RNG(" + m_extractor->name() + "," + m_prf->name() + ")";
197  }
byte Botan::RandomNumberGenerator::next_byte ( )
inlineinherited

Return a random byte

Returns
random byte

Definition at line 139 of file rng.h.

Referenced by Botan::Blinded_Point_Multiply::blinded_multiply(), and Botan::random_prime().

140  {
141  byte b;
142  this->randomize(&b, 1);
143  return b;
144  }
virtual void randomize(byte output[], size_t length)=0
std::uint8_t byte
Definition: types.h:31
byte Botan::RandomNumberGenerator::next_nonzero_byte ( )
inlineinherited

Definition at line 146 of file rng.h.

147  {
148  byte b = this->next_byte();
149  while(b == 0)
150  b = this->next_byte();
151  return b;
152  }
std::uint8_t byte
Definition: types.h:31
secure_vector<byte> Botan::RandomNumberGenerator::random_vec ( size_t  bytes)
inlineinherited
void Botan::HMAC_RNG::randomize ( byte  output[],
size_t  length 
)
overridevirtual

Randomize a byte array.

Parameters
outputthe byte array to hold the random output.
lengththe length of the byte array output.

Implements Botan::RandomNumberGenerator.

Definition at line 134 of file hmac_rng.cpp.

References Botan::copy_mem(), and Botan::Stateful_RNG::reseed_check().

135  {
136  reseed_check();
137 
138  while(length)
139  {
140  new_K_value(Running);
141 
142  const size_t copied = std::min<size_t>(length, m_prf->output_length());
143 
144  copy_mem(out, m_K.data(), copied);
145  out += copied;
146  length -= copied;
147  }
148 
149  new_K_value(BlockFinished);
150  }
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:43
void Botan::RandomNumberGenerator::randomize_with_input ( byte  output[],
size_t  output_len,
const byte  input[],
size_t  input_len 
)
virtualinherited

Incorporate entropy into the RNG state then produce output. Some RNG types implement this using a single operation, default calls add_entropy + randomize in sequence.

Use this to further bind the outputs to your current process/protocol state. For instance if generating a new key for use in a session, include a session ID or other such value. See NIST SP 800-90 A, B, C series for more ideas.

Reimplemented in Botan::HMAC_DRBG, and Botan::AutoSeeded_RNG.

Definition at line 30 of file rng.cpp.

References Botan::RandomNumberGenerator::add_entropy(), and Botan::RandomNumberGenerator::randomize().

Referenced by Botan::Stateful_RNG::randomize_with_ts_input(), and Botan::RandomNumberGenerator::randomize_with_ts_input().

32  {
33  this->add_entropy(input, input_len);
34  this->randomize(output, output_len);
35  }
virtual void randomize(byte output[], size_t length)=0
virtual void add_entropy(const byte input[], size_t length)=0
void Botan::Stateful_RNG::randomize_with_ts_input ( byte  output[],
size_t  output_len 
)
finaloverridevirtualinherited

Overrides default implementation and also includes the current process ID and the reseed counter.

Reimplemented from Botan::RandomNumberGenerator.

Definition at line 39 of file stateful_rng.cpp.

References Botan::OS::get_processor_timestamp(), Botan::OS::get_system_timestamp_ns(), Botan::RandomNumberGenerator::randomize_with_input(), and Botan::store_le().

40  {
41  byte additional_input[24] = { 0 };
42  store_le(OS::get_system_timestamp_ns(), additional_input);
43  store_le(OS::get_processor_timestamp(), additional_input + 8);
44  store_le(m_last_pid, additional_input + 16);
45  store_le(static_cast<uint32_t>(m_reseed_counter), additional_input + 20);
46 
47  randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
48  }
virtual void randomize_with_input(byte output[], size_t output_len, const byte input[], size_t input_len)
Definition: rng.cpp:30
void store_le(u16bit in, byte out[2])
Definition: loadstor.h:461
uint64_t get_processor_timestamp()
Definition: os_utils.cpp:41
uint64_t get_system_timestamp_ns()
Definition: os_utils.cpp:88
std::uint8_t byte
Definition: types.h:31
size_t Botan::HMAC_RNG::reseed ( Entropy_Sources srcs,
size_t  poll_bits,
std::chrono::milliseconds  poll_timeout 
)
overridevirtual

Poll provided sources for up to poll_bits bits of entropy or until the timeout expires. Returns estimate of the number of bits collected.

Reimplemented from Botan::RandomNumberGenerator.

Definition at line 152 of file hmac_rng.cpp.

References Botan::Stateful_RNG::reseed(), and Botan::zeroise().

155  {
156  new_K_value(Reseed);
157  m_extractor->update(m_K); // m_K is the PRF output
158 
159  /*
160  * This ends up calling add_entropy which provides input to the extractor
161  */
162  size_t bits_collected = Stateful_RNG::reseed(srcs, poll_bits, timeout);
163 
164  /*
165  Now derive the new PRK using everything that has been fed into
166  the extractor, and set the PRF key to that
167  */
168  m_prf->set_key(m_extractor->final());
169 
170  // Now generate a new PRF output to use as the XTS extractor salt
171  new_K_value(ExtractorSeed);
172  m_extractor->set_key(m_K);
173 
174  // Reset state
175  zeroise(m_K);
176  m_counter = 0;
177 
178  return bits_collected;
179  }
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 zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:191
void Botan::Stateful_RNG::reseed_check ( )
protectedinherited

Called with lock held

Definition at line 74 of file stateful_rng.cpp.

References BOTAN_ASSERT, Botan::OS::get_process_id(), Botan::Stateful_RNG::is_seeded(), Botan::RandomNumberGenerator::name(), Botan::Stateful_RNG::reseed(), Botan::Stateful_RNG::reseed_from_rng(), and Botan::Stateful_RNG::security_level().

Referenced by randomize(), and Botan::HMAC_DRBG::randomize_with_input().

75  {
76  const uint32_t cur_pid = OS::get_process_id();
77 
78  const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid);
79 
80  if(is_seeded() == false ||
81  fork_detected ||
82  (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval))
83  {
84  m_reseed_counter = 0;
85  m_last_pid = cur_pid;
86 
87  if(m_underlying_rng)
88  {
89  reseed_from_rng(*m_underlying_rng, security_level());
90  }
91 
92  if(m_entropy_sources)
93  {
94  reseed(*m_entropy_sources, security_level());
95  }
96 
97  if(!is_seeded())
98  {
99  if(fork_detected)
100  throw Exception("Detected use of fork but cannot reseed DRBG");
101  else
102  throw PRNG_Unseeded(name());
103  }
104  }
105  else
106  {
107  BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded");
108  m_reseed_counter += 1;
109  }
110  }
uint32_t get_process_id()
Definition: os_utils.cpp:30
virtual size_t security_level() const =0
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
void reseed_from_rng(RandomNumberGenerator &rng, size_t poll_bits=BOTAN_RNG_RESEED_POLL_BITS) overridefinal
virtual std::string name() const =0
bool is_seeded() const overridefinal
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 Botan::Stateful_RNG::reseed_from_rng ( RandomNumberGenerator rng,
size_t  poll_bits = BOTAN_RNG_RESEED_POLL_BITS 
)
finaloverridevirtualinherited

Reseed by reading specified bits from the RNG

Reimplemented from Botan::RandomNumberGenerator.

Definition at line 64 of file stateful_rng.cpp.

References Botan::RandomNumberGenerator::reseed_from_rng(), and Botan::Stateful_RNG::security_level().

Referenced by Botan::Stateful_RNG::reseed_check().

65  {
67 
68  if(poll_bits >= security_level())
69  {
70  m_reseed_counter = 1;
71  }
72  }
virtual size_t security_level() const =0
virtual void reseed_from_rng(RandomNumberGenerator &rng, size_t poll_bits=BOTAN_RNG_RESEED_POLL_BITS)
Definition: rng.cpp:44
size_t Botan::HMAC_RNG::security_level ( ) const
inlineoverridevirtual

Return intended security level of this DRBG

Implements Botan::Stateful_RNG.

Definition at line 79 of file hmac_rng.h.

79 { return m_prf->output_length() * 8 / 2; }

The documentation for this class was generated from the following files: