Botan  1.11.30
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 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 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.data() + 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, &keystream_buf()[0], took);
99 
100  // Assumes feedback-sized block except for last input
101  if (BS - shift > 0)
102  {
103  copy_mem(state.data(), &state[shift], BS - shift);
104  }
105  copy_mem(&state[BS-shift], buf, took);
106  cipher().encrypt(state, keystream_buf());
107 
108  buf += took;
109  sz -= took;
110  }
111  }
112 
113 void CFB_Encryption::finish(secure_vector<byte>& buffer, size_t offset)
114  {
115  update(buffer, offset);
116  }
117 
118 void CFB_Decryption::update(secure_vector<byte>& buffer, size_t offset)
119  {
120  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
121  size_t sz = buffer.size() - offset;
122  byte* buf = buffer.data() + offset;
123 
124  const size_t BS = cipher().block_size();
125 
127  const size_t shift = feedback();
128 
129  while(sz)
130  {
131  const size_t took = std::min(shift, sz);
132 
133  // first update shift register with ciphertext
134  if (BS - shift > 0)
135  {
136  copy_mem(state.data(), &state[shift], BS - shift);
137  }
138  copy_mem(&state[BS-shift], buf, took);
139 
140  // then decrypt
141  xor_buf(buf, &keystream_buf()[0], took);
142 
143  // then update keystream
144  cipher().encrypt(state, keystream_buf());
145 
146  buf += took;
147  sz -= took;
148  }
149  }
150 
151 void CFB_Decryption::finish(secure_vector<byte>& buffer, size_t offset)
152  {
153  update(buffer, offset);
154  }
155 
156 }
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:90
virtual void update(secure_vector< byte > &blocks, size_t offset=0)=0
size_t update_granularity() const override
Definition: cfb.cpp:42
secure_vector< byte > & shift_register()
Definition: cfb.h:44
const BlockCipher & cipher() const
Definition: cfb.h:40
Key_Length_Specification key_spec() const override
Definition: cfb.cpp:52
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
CFB_Mode(BlockCipher *cipher, size_t feedback_bits)
Definition: cfb.cpp:14
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:96
virtual std::string name() const =0
void finish(secure_vector< byte > &final_block, size_t offset=0) override
Definition: cfb.cpp:113
size_t output_length(size_t input_length) const override
Definition: cfb.cpp:37
secure_vector< byte > & keystream_buf()
Definition: cfb.h:46
void update(secure_vector< byte > &blocks, size_t offset=0) override
Definition: cfb.cpp:118
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:43
void update(secure_vector< byte > &blocks, size_t offset=0) override
Definition: cfb.cpp:84
Definition: alg_id.cpp:13
size_t feedback() const
Definition: cfb.h:42
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:62
T min(T a, T b)
Definition: ct_utils.h:180
virtual size_t block_size() const =0
void finish(secure_vector< byte > &final_block, size_t offset=0) override
Definition: cfb.cpp:151
size_t minimum_final_size() const override
Definition: cfb.cpp:47
std::uint8_t byte
Definition: types.h:31