Botan  1.11.15
cfb.cpp
Go to the documentation of this file.
1 /*
2 * CFB Mode
3 * (C) 1999-2007,2013 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/internal/mode_utils.h>
9 #include <botan/cfb.h>
10 #include <botan/parsing.h>
11 
12 namespace Botan {
13 
14 BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(CFB_Encryption, CFB_Decryption, 0);
15 
16 CFB_Mode::CFB_Mode(BlockCipher* cipher, size_t feedback_bits) :
17  m_cipher(cipher),
18  m_feedback_bytes(feedback_bits ? feedback_bits / 8 : cipher->block_size())
19  {
20  if(feedback_bits % 8 || feedback() > cipher->block_size())
21  throw std::invalid_argument(name() + ": feedback bits " +
22  std::to_string(feedback_bits) + " not supported");
23  }
24 
26  {
27  m_cipher->clear();
28  m_shift_register.clear();
29  }
30 
31 std::string CFB_Mode::name() const
32  {
33  if(feedback() == cipher().block_size())
34  return cipher().name() + "/CFB";
35  else
36  return cipher().name() + "/CFB(" + std::to_string(feedback()*8) + ")";
37  }
38 
39 size_t CFB_Mode::output_length(size_t input_length) const
40  {
41  return input_length;
42  }
43 
45  {
46  return feedback();
47  }
48 
50  {
51  return 0;
52  }
53 
55  {
56  return cipher().key_spec();
57  }
58 
60  {
61  return cipher().block_size();
62  }
63 
64 bool CFB_Mode::valid_nonce_length(size_t n) const
65  {
66  return (n == cipher().block_size());
67  }
68 
69 void CFB_Mode::key_schedule(const byte key[], size_t length)
70  {
71  m_cipher->set_key(key, length);
72  }
73 
74 secure_vector<byte> CFB_Mode::start_raw(const byte nonce[], size_t nonce_len)
75  {
76  if(!valid_nonce_length(nonce_len))
77  throw Invalid_IV_Length(name(), nonce_len);
78 
79  m_shift_register.assign(nonce, nonce + nonce_len);
80  m_keystream_buf.resize(m_shift_register.size());
81  cipher().encrypt(m_shift_register, m_keystream_buf);
82 
83  return secure_vector<byte>();
84  }
85 
86 void CFB_Encryption::update(secure_vector<byte>& buffer, size_t offset)
87  {
88  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
89  size_t sz = buffer.size() - offset;
90  byte* buf = &buffer[offset];
91 
92  const size_t BS = cipher().block_size();
93 
95  const size_t shift = feedback();
96 
97  while(sz)
98  {
99  const size_t took = std::min(shift, sz);
100  xor_buf(&buf[0], &keystream_buf()[0], took);
101 
102  // Assumes feedback-sized block except for last input
103  copy_mem(&state[0], &state[shift], BS - shift);
104  copy_mem(&state[BS-shift], &buf[0], took);
105  cipher().encrypt(state, keystream_buf());
106 
107  buf += took;
108  sz -= took;
109  }
110  }
111 
112 void CFB_Encryption::finish(secure_vector<byte>& buffer, size_t offset)
113  {
114  update(buffer, offset);
115  }
116 
117 void CFB_Decryption::update(secure_vector<byte>& buffer, size_t offset)
118  {
119  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
120  size_t sz = buffer.size() - offset;
121  byte* buf = &buffer[offset];
122 
123  const size_t BS = cipher().block_size();
124 
126  const size_t shift = feedback();
127 
128  while(sz)
129  {
130  const size_t took = std::min(shift, sz);
131 
132  // first update shift register with ciphertext
133  copy_mem(&state[0], &state[shift], BS - shift);
134  copy_mem(&state[BS-shift], &buf[0], took);
135 
136  // then decrypt
137  xor_buf(&buf[0], &keystream_buf()[0], took);
138 
139  // then update keystream
140  cipher().encrypt(state, keystream_buf());
141 
142  buf += took;
143  sz -= took;
144  }
145  }
146 
147 void CFB_Decryption::finish(secure_vector<byte>& buffer, size_t offset)
148  {
149  update(buffer, offset);
150  }
151 
152 }
void xor_buf(T out[], const T in[], size_t length)
Definition: xor_buf.h:23
size_t update_granularity() const override
Definition: cfb.cpp:44
secure_vector< byte > & shift_register()
Definition: cfb.h:45
const BigInt & n
Definition: rsa.cpp:107
const BlockCipher & cipher() const
Definition: cfb.h:41
BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(EAX_Encryption, EAX_Decryption, 0)
Key_Length_Specification key_spec() const override
Definition: cfb.cpp:54
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:46
CFB_Mode(BlockCipher *cipher, size_t feedback_bits)
Definition: cfb.cpp:16
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:93
virtual std::string name() const =0
void finish(secure_vector< byte > &final_block, size_t offset=0) override
Definition: cfb.cpp:112
size_t output_length(size_t input_length) const override
Definition: cfb.cpp:39
secure_vector< byte > & keystream_buf()
Definition: cfb.h:47
uint8_t byte
Definition: types.h:31
void update(secure_vector< byte > &blocks, size_t offset=0) override
Definition: cfb.cpp:117
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:39
void update(secure_vector< byte > &blocks, size_t offset=0) override
Definition: cfb.cpp:86
size_t feedback() const
Definition: cfb.h:43
size_t default_nonce_length() const override
Definition: cfb.cpp:59
bool valid_nonce_length(size_t n) const override
Definition: cfb.cpp:64
void clear() override
Definition: cfb.cpp:25
virtual Key_Length_Specification key_spec() const =0
std::string name() const override
Definition: cfb.cpp:31
void encrypt(const byte in[], byte out[]) const
Definition: block_cipher.h:49
virtual size_t block_size() const =0
void finish(secure_vector< byte > &final_block, size_t offset=0) override
Definition: cfb.cpp:147
size_t minimum_final_size() const override
Definition: cfb.cpp:49