Botan  1.11.15
src/lib/rng/x931_rng/x931_rng.cpp
Go to the documentation of this file.
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 }