Botan
1.11.15
|
00001 /* 00002 * ANSI X9.31 RNG 00003 * (C) 1999-2009,2014 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/x931_rng.h> 00009 #include <botan/internal/xor_buf.h> 00010 #include <algorithm> 00011 00012 namespace Botan { 00013 00014 void ANSI_X931_RNG::randomize(byte out[], size_t length) 00015 { 00016 if(!is_seeded()) 00017 { 00018 reseed(BOTAN_RNG_RESEED_POLL_BITS); 00019 00020 if(!is_seeded()) 00021 throw PRNG_Unseeded(name()); 00022 } 00023 00024 while(length) 00025 { 00026 if(m_R_pos == m_R.size()) 00027 update_buffer(); 00028 00029 const size_t copied = std::min<size_t>(length, m_R.size() - m_R_pos); 00030 00031 copy_mem(out, &m_R[m_R_pos], copied); 00032 out += copied; 00033 length -= copied; 00034 m_R_pos += copied; 00035 } 00036 } 00037 00038 /* 00039 * Refill the internal state 00040 */ 00041 void ANSI_X931_RNG::update_buffer() 00042 { 00043 const size_t BLOCK_SIZE = m_cipher->block_size(); 00044 00045 secure_vector<byte> DT = m_prng->random_vec(BLOCK_SIZE); 00046 m_cipher->encrypt(DT); 00047 00048 xor_buf(&m_R[0], &m_V[0], &DT[0], BLOCK_SIZE); 00049 m_cipher->encrypt(m_R); 00050 00051 xor_buf(&m_V[0], &m_R[0], &DT[0], BLOCK_SIZE); 00052 m_cipher->encrypt(m_V); 00053 00054 m_R_pos = 0; 00055 } 00056 00057 /* 00058 * Reset V and the cipher key with new values 00059 */ 00060 void ANSI_X931_RNG::rekey() 00061 { 00062 const size_t BLOCK_SIZE = m_cipher->block_size(); 00063 00064 if(m_prng->is_seeded()) 00065 { 00066 m_cipher->set_key(m_prng->random_vec(m_cipher->maximum_keylength())); 00067 00068 if(m_V.size() != BLOCK_SIZE) 00069 m_V.resize(BLOCK_SIZE); 00070 m_prng->randomize(&m_V[0], m_V.size()); 00071 00072 update_buffer(); 00073 } 00074 } 00075 00076 void ANSI_X931_RNG::reseed(size_t poll_bits) 00077 { 00078 m_prng->reseed(poll_bits); 00079 rekey(); 00080 } 00081 00082 void ANSI_X931_RNG::add_entropy(const byte input[], size_t length) 00083 { 00084 m_prng->add_entropy(input, length); 00085 rekey(); 00086 } 00087 00088 bool ANSI_X931_RNG::is_seeded() const 00089 { 00090 return (m_V.size() > 0); 00091 } 00092 00093 void ANSI_X931_RNG::clear() 00094 { 00095 m_cipher->clear(); 00096 m_prng->clear(); 00097 zeroise(m_R); 00098 m_V.clear(); 00099 00100 m_R_pos = 0; 00101 } 00102 00103 std::string ANSI_X931_RNG::name() const 00104 { 00105 return "X9.31(" + m_cipher->name() + ")"; 00106 } 00107 00108 ANSI_X931_RNG::ANSI_X931_RNG(BlockCipher* cipher, 00109 RandomNumberGenerator* prng) : 00110 m_cipher(cipher), 00111 m_prng(prng), 00112 m_R(m_cipher->block_size()), 00113 m_R_pos(0) 00114 { 00115 } 00116 00117 }