Botan  1.11.17
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.data() + 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, &keystream_buf()[0], took);
101 
102  // Assumes feedback-sized block except for last input
103  if (BS - shift > 0)
104  {
105  copy_mem(state.data(), &state[shift], BS - shift);
106  }
107  copy_mem(&state[BS-shift], buf, took);
108  cipher().encrypt(state, keystream_buf());
109 
110  buf += took;
111  sz -= took;
112  }
113  }
114 
115 void CFB_Encryption::finish(secure_vector<byte>& buffer, size_t offset)
116  {
117  update(buffer, offset);
118  }
119 
120 void CFB_Decryption::update(secure_vector<byte>& buffer, size_t offset)
121  {
122  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
123  size_t sz = buffer.size() - offset;
124  byte* buf = buffer.data() + offset;
125 
126  const size_t BS = cipher().block_size();
127 
129  const size_t shift = feedback();
130 
131  while(sz)
132  {
133  const size_t took = std::min(shift, sz);
134 
135  // first update shift register with ciphertext
136  if (BS - shift > 0)
137  {
138  copy_mem(state.data(), &state[shift], BS - shift);
139  }
140  copy_mem(&state[BS-shift], buf, took);
141 
142  // then decrypt
143  xor_buf(buf, &keystream_buf()[0], took);
144 
145  // then update keystream
146  cipher().encrypt(state, keystream_buf());
147 
148  buf += took;
149  sz -= took;
150  }
151  }
152 
153 void CFB_Decryption::finish(secure_vector<byte>& buffer, size_t offset)
154  {
155  update(buffer, offset);
156  }
157 
158 }
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:44
const BigInt & n
Definition: rsa.cpp:107
const BlockCipher & cipher() const
Definition: cfb.h:40
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:115
size_t output_length(size_t input_length) const override
Definition: cfb.cpp:39
secure_vector< byte > & keystream_buf()
Definition: cfb.h:46
void update(secure_vector< byte > &blocks, size_t offset=0) override
Definition: cfb.cpp:120
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
Definition: alg_id.cpp:13
size_t feedback() const
Definition: cfb.h:42
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:153
size_t minimum_final_size() const override
Definition: cfb.cpp:49
std::uint8_t byte
Definition: types.h:31