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