Crypto++
|
00001 // randpool.cpp - written and placed in the public domain by Wei Dai 00002 // RandomPool used to follow the design of randpool in PGP 2.6.x, 00003 // but as of version 5.5 it has been redesigned to reduce the risk 00004 // of reusing random numbers after state rollback (which may occur 00005 // when running in a virtual machine like VMware). 00006 00007 #include "pch.h" 00008 00009 #ifndef CRYPTOPP_IMPORTS 00010 00011 #include "randpool.h" 00012 #include "aes.h" 00013 #include "sha.h" 00014 #include "hrtimer.h" 00015 #include <time.h> 00016 00017 NAMESPACE_BEGIN(CryptoPP) 00018 00019 RandomPool::RandomPool() 00020 : m_pCipher(new AES::Encryption), m_keySet(false) 00021 { 00022 memset(m_key, 0, m_key.SizeInBytes()); 00023 memset(m_seed, 0, m_seed.SizeInBytes()); 00024 } 00025 00026 void RandomPool::IncorporateEntropy(const byte *input, size_t length) 00027 { 00028 SHA256 hash; 00029 hash.Update(m_key, 32); 00030 hash.Update(input, length); 00031 hash.Final(m_key); 00032 m_keySet = false; 00033 } 00034 00035 void RandomPool::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size) 00036 { 00037 if (size > 0) 00038 { 00039 if (!m_keySet) 00040 m_pCipher->SetKey(m_key, 32); 00041 00042 Timer timer; 00043 TimerWord tw = timer.GetCurrentTimerValue(); 00044 CRYPTOPP_COMPILE_ASSERT(sizeof(tw) <= 16); 00045 *(TimerWord *)m_seed.data() += tw; 00046 00047 time_t t = time(NULL); 00048 CRYPTOPP_COMPILE_ASSERT(sizeof(t) <= 8); 00049 *(time_t *)(m_seed.data()+8) += t; 00050 00051 do 00052 { 00053 m_pCipher->ProcessBlock(m_seed); 00054 size_t len = UnsignedMin(16, size); 00055 target.ChannelPut(channel, m_seed, len); 00056 size -= len; 00057 } while (size > 0); 00058 } 00059 } 00060 00061 NAMESPACE_END 00062 00063 #endif