Crypto++  5.6.4
Free C++ class library of cryptographic schemes
randpool.cpp
1 // randpool.cpp - written and placed in the public domain by Wei Dai
2 // RandomPool used to follow the design of randpool in PGP 2.6.x,
3 // but as of version 5.5 it has been redesigned to reduce the risk
4 // of reusing random numbers after state rollback (which may occur
5 // when running in a virtual machine like VMware).
6 
7 #include "pch.h"
8 
9 #ifndef CRYPTOPP_IMPORTS
10 
11 #include "randpool.h"
12 #include "aes.h"
13 #include "sha.h"
14 #include "hrtimer.h"
15 #include <time.h>
16 
17 NAMESPACE_BEGIN(CryptoPP)
18 
20  : m_pCipher(new AES::Encryption), m_keySet(false)
21 {
22  memset(m_key, 0, m_key.SizeInBytes());
23  memset(m_seed, 0, m_seed.SizeInBytes());
24 }
25 
26 void RandomPool::IncorporateEntropy(const byte *input, size_t length)
27 {
28  SHA256 hash;
29  hash.Update(m_key, 32);
30  hash.Update(input, length);
31  hash.Final(m_key);
32  m_keySet = false;
33 }
34 
35 void RandomPool::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size)
36 {
37  if (size > 0)
38  {
39  if (!m_keySet)
40  m_pCipher->SetKey(m_key, 32);
41 
42  CRYPTOPP_COMPILE_ASSERT(sizeof(TimerWord) <= 16);
43  CRYPTOPP_COMPILE_ASSERT(sizeof(time_t) <= 8);
44 
45  Timer timer;
46  TimerWord tw = timer.GetCurrentTimerValue();
47 
48  *(TimerWord *)(void*)m_seed.data() += tw;
49  time_t t = time(NULL);
50 
51  // UBsan finding: signed integer overflow: 1876017710 + 1446085457 cannot be represented in type 'long int'
52  // *(time_t *)(m_seed.data()+8) += t;
53  word64 tt1 = 0, tt2 = (word64)t;
54  memcpy(&tt1, m_seed.data()+8, 8);
55  memcpy(m_seed.data()+8, &(tt2 += tt1), 8);
56 
57  // Wipe the intermediates
58  *((volatile TimerWord*)&tw) = 0;
59  *((volatile word64*)&tt1) = 0;
60  *((volatile word64*)&tt2) = 0;
61 
62  do
63  {
64  m_pCipher->ProcessBlock(m_seed);
65  size_t len = UnsignedMin(16, size);
66  target.ChannelPut(channel, m_seed, len);
67  size -= len;
68  } while (size > 0);
69  }
70 }
71 
72 NAMESPACE_END
73 
74 #endif
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: randpool.cpp:26
Randomness Pool based on AES-256.
Definition: randpool.h:49
high resolution timer
Definition: hrtimer.h:57
virtual void SetKey(const byte *key, size_t length, const NameValuePairs &params=g_nullNameValuePairs)
Sets or reset the key of this object.
Definition: cryptlib.cpp:97
implements the SHA-256 standard
Definition: sha.h:33
Class file for Randomness Pool.
size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true)
Input a byte for processing on a channel.
Definition: cryptlib.h:1872
void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size)
Generate random bytes into a BufferedTransformation.
Definition: randpool.cpp:35
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Definition: iterhash.cpp:12
Interface for buffered transformations.
Definition: cryptlib.h:1359
void ProcessBlock(const byte *inBlock, byte *outBlock) const
Encrypt or decrypt a block.
Definition: cryptlib.h:757
#define CRYPTOPP_COMPILE_ASSERT(expr)
Compile time assertion.
Definition: misc.h:123
A::pointer data()
Provides a pointer to the first element in the memory block.
Definition: secblock.h:516
Class file for the AES cipher (Rijndael)
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
Definition: misc.h:503
AES block cipher (Rijndael)
Definition: aes.h:16
Classes for SHA-1 and SHA-2 family of message digests.
Crypto++ library namespace.
virtual void Final(byte *digest)
Computes the hash of the current message.
Definition: cryptlib.h:963