Botan  1.11.15
src/lib/modes/cfb/cfb.cpp
Go to the documentation of this file.
00001 /*
00002 * CFB Mode
00003 * (C) 1999-2007,2013 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/mode_utils.h>
00009 #include <botan/cfb.h>
00010 #include <botan/parsing.h>
00011 
00012 namespace Botan {
00013 
00014 BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(CFB_Encryption, CFB_Decryption, 0);
00015 
00016 CFB_Mode::CFB_Mode(BlockCipher* cipher, size_t feedback_bits) :
00017    m_cipher(cipher),
00018    m_feedback_bytes(feedback_bits ? feedback_bits / 8 : cipher->block_size())
00019    {
00020    if(feedback_bits % 8 || feedback() > cipher->block_size())
00021       throw std::invalid_argument(name() + ": feedback bits " +
00022                                   std::to_string(feedback_bits) + " not supported");
00023    }
00024 
00025 void CFB_Mode::clear()
00026    {
00027    m_cipher->clear();
00028    m_shift_register.clear();
00029    }
00030 
00031 std::string CFB_Mode::name() const
00032    {
00033    if(feedback() == cipher().block_size())
00034       return cipher().name() + "/CFB";
00035    else
00036       return cipher().name() + "/CFB(" + std::to_string(feedback()*8) + ")";
00037    }
00038 
00039 size_t CFB_Mode::output_length(size_t input_length) const
00040    {
00041    return input_length;
00042    }
00043 
00044 size_t CFB_Mode::update_granularity() const
00045    {
00046    return feedback();
00047    }
00048 
00049 size_t CFB_Mode::minimum_final_size() const
00050    {
00051    return 0;
00052    }
00053 
00054 Key_Length_Specification CFB_Mode::key_spec() const
00055    {
00056    return cipher().key_spec();
00057    }
00058 
00059 size_t CFB_Mode::default_nonce_length() const
00060    {
00061    return cipher().block_size();
00062    }
00063 
00064 bool CFB_Mode::valid_nonce_length(size_t n) const
00065    {
00066    return (n == cipher().block_size());
00067    }
00068 
00069 void CFB_Mode::key_schedule(const byte key[], size_t length)
00070    {
00071    m_cipher->set_key(key, length);
00072    }
00073 
00074 secure_vector<byte> CFB_Mode::start_raw(const byte nonce[], size_t nonce_len)
00075    {
00076    if(!valid_nonce_length(nonce_len))
00077       throw Invalid_IV_Length(name(), nonce_len);
00078 
00079    m_shift_register.assign(nonce, nonce + nonce_len);
00080    m_keystream_buf.resize(m_shift_register.size());
00081    cipher().encrypt(m_shift_register, m_keystream_buf);
00082 
00083    return secure_vector<byte>();
00084    }
00085 
00086 void CFB_Encryption::update(secure_vector<byte>& buffer, size_t offset)
00087    {
00088    BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
00089    size_t sz = buffer.size() - offset;
00090    byte* buf = &buffer[offset];
00091 
00092    const size_t BS = cipher().block_size();
00093 
00094    secure_vector<byte>& state = shift_register();
00095    const size_t shift = feedback();
00096 
00097    while(sz)
00098       {
00099       const size_t took = std::min(shift, sz);
00100       xor_buf(&buf[0], &keystream_buf()[0], took);
00101 
00102       // Assumes feedback-sized block except for last input
00103       copy_mem(&state[0], &state[shift], BS - shift);
00104       copy_mem(&state[BS-shift], &buf[0], took);
00105       cipher().encrypt(state, keystream_buf());
00106 
00107       buf += took;
00108       sz -= took;
00109       }
00110    }
00111 
00112 void CFB_Encryption::finish(secure_vector<byte>& buffer, size_t offset)
00113    {
00114    update(buffer, offset);
00115    }
00116 
00117 void CFB_Decryption::update(secure_vector<byte>& buffer, size_t offset)
00118    {
00119    BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
00120    size_t sz = buffer.size() - offset;
00121    byte* buf = &buffer[offset];
00122 
00123    const size_t BS = cipher().block_size();
00124 
00125    secure_vector<byte>& state = shift_register();
00126    const size_t shift = feedback();
00127 
00128    while(sz)
00129       {
00130       const size_t took = std::min(shift, sz);
00131 
00132       // first update shift register with ciphertext
00133       copy_mem(&state[0], &state[shift], BS - shift);
00134       copy_mem(&state[BS-shift], &buf[0], took);
00135 
00136       // then decrypt
00137       xor_buf(&buf[0], &keystream_buf()[0], took);
00138 
00139       // then update keystream
00140       cipher().encrypt(state, keystream_buf());
00141 
00142       buf += took;
00143       sz -= took;
00144       }
00145    }
00146 
00147 void CFB_Decryption::finish(secure_vector<byte>& buffer, size_t offset)
00148    {
00149    update(buffer, offset);
00150    }
00151 
00152 }