source: git/src-cryptopp/randpool.cpp

Last change on this file was e230cb0, checked in by David Stainton <dstainton415@…>, at 2016-10-12T13:27:29Z

Add cryptopp from tag CRYPTOPP_5_6_5

  • Property mode set to 100644
File size: 1.9 KB
Line 
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
17NAMESPACE_BEGIN(CryptoPP)
18
19RandomPool::RandomPool()
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
26void 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
35void 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
72NAMESPACE_END
73
74#endif
Note: See TracBrowser for help on using the repository browser.