Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

cfb.cpp
Go to the documentation of this file.
1 /*
2 * CFB Mode
3 * (C) 1999-2007,2013,2017 Jack Lloyd
4 * (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9 #include <botan/cfb.h>
10
11 namespace Botan {
12
13 CFB_Mode::CFB_Mode(BlockCipher* cipher, size_t feedback_bits) :
14 m_cipher(cipher),
15 m_block_size(m_cipher->block_size()),
16 m_feedback_bytes(feedback_bits ? feedback_bits / 8 : m_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
23 void CFB_Mode::clear()
24 {
25 m_cipher->clear();
26 m_keystream.clear();
27 reset();
28 }
29
30 void CFB_Mode::reset()
31 {
32 m_state.clear();
33 zeroise(m_keystream);
34 }
35
36 std::string CFB_Mode::name() const
37 {
38 if(feedback() == cipher().block_size())
39 return cipher().name() + "/CFB";
40 else
41 return cipher().name() + "/CFB(" + std::to_string(feedback()*8) + ")";
42 }
43
44 size_t CFB_Mode::output_length(size_t input_length) const
45 {
46 return input_length;
47 }
48
49 size_t CFB_Mode::update_granularity() const
50 {
51 return feedback();
52 }
53
54 size_t CFB_Mode::minimum_final_size() const
55 {
56 return 0;
57 }
58
59 Key_Length_Specification CFB_Mode::key_spec() const
60 {
61 return cipher().key_spec();
62 }
63
64 size_t CFB_Mode::default_nonce_length() const
65 {
66 return block_size();
67 }
68
69 bool CFB_Mode::valid_nonce_length(size_t n) const
70 {
71 return (n == 0 || n == block_size());
72 }
73
74 void CFB_Mode::key_schedule(const uint8_t key[], size_t length)
75 {
76 m_cipher->set_key(key, length);
77 m_keystream.resize(m_cipher->block_size());
78 }
79
80 void CFB_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
81 {
82 if(!valid_nonce_length(nonce_len))
83 throw Invalid_IV_Length(name(), nonce_len);
84
85 verify_key_set(!m_keystream.empty());
86
87 if(nonce_len == 0)
88 {
89 if(m_state.empty())
90 {
91 throw Invalid_State("CFB requires a non-empty initial nonce");
92 }
93 // No reason to encrypt state->keystream_buf, because no change
94 }
95 else
96 {
97 m_state.assign(nonce, nonce + nonce_len);
98 cipher().encrypt(m_state, m_keystream);
99 m_keystream_pos = 0;
100 }
101 }
102
103 void CFB_Mode::shift_register()
104 {
105 const size_t shift = feedback();
106 const size_t carryover = block_size() - shift;
107
108 if(carryover > 0)
109 {
110 copy_mem(m_state.data(), &m_state[shift], carryover);
111 }
112 copy_mem(&m_state[carryover], m_keystream.data(), shift);
113 cipher().encrypt(m_state, m_keystream);
114 m_keystream_pos = 0;
115 }
116
117 size_t CFB_Encryption::process(uint8_t buf[], size_t sz)
118 {
119 verify_key_set(!m_keystream.empty());
120 BOTAN_STATE_CHECK(m_state.empty() == false);
121
122 const size_t shift = feedback();
123
124 size_t left = sz;
125
126 if(m_keystream_pos != 0)
127 {
128 const size_t take = std::min<size_t>(left, shift - m_keystream_pos);
129
130 xor_buf(m_keystream.data() + m_keystream_pos, buf, take);
131 copy_mem(buf, m_keystream.data() + m_keystream_pos, take);
132
133 m_keystream_pos += take;
134 left -= take;
135 buf += take;
136
137 if(m_keystream_pos == shift)
138 {
139 shift_register();
140 }
141 }
142
143 while(left >= shift)
144 {
145 xor_buf(m_keystream.data(), buf, shift);
146 copy_mem(buf, m_keystream.data(), shift);
147
148 left -= shift;
149 buf += shift;
150 shift_register();
151 }
152
153 if(left > 0)
154 {
155 xor_buf(m_keystream.data(), buf, left);
156 copy_mem(buf, m_keystream.data(), left);
157 m_keystream_pos += left;
158 }
159
160 return sz;
161 }
162
163 void CFB_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
164 {
165 update(buffer, offset);
166 }
167
168 namespace {
169
170 inline void xor_copy(uint8_t buf[], uint8_t key_buf[], size_t len)
171 {
172 for(size_t i = 0; i != len; ++i)
173 {
174 uint8_t k = key_buf[i];
175 key_buf[i] = buf[i];
176 buf[i] ^= k;
177 }
178 }
179
180 }
181
182 size_t CFB_Decryption::process(uint8_t buf[], size_t sz)
183 {
184 verify_key_set(!m_keystream.empty());
185 BOTAN_STATE_CHECK(m_state.empty() == false);
186
187 const size_t shift = feedback();
188
189 size_t left = sz;
190
191 if(m_keystream_pos != 0)
192 {
193 const size_t take = std::min<size_t>(left, shift - m_keystream_pos);
194
195 xor_copy(buf, m_keystream.data() + m_keystream_pos, take);
196
197 m_keystream_pos += take;
198 left -= take;
199 buf += take;
200
201 if(m_keystream_pos == shift)
202 {
203 shift_register();
204 }
205 }
206
207 while(left >= shift)
208 {
209 xor_copy(buf, m_keystream.data(), shift);
210 left -= shift;
211 buf += shift;
212 shift_register();
213 }
214
215 if(left > 0)
216 {
217 xor_copy(buf, m_keystream.data(), left);
218 m_keystream_pos += left;
219 }
220
221 return sz;
222 }
223
224 void CFB_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
225 {
226 update(buffer, offset);
227 }
228
229 }
Botan::BlockCipher::encrypt
void encrypt(const uint8_t in[], uint8_t out[]) const
Definition: block_cipher.h:82
Botan::Invalid_Argument
Definition: exceptn.h:136
m_cipher
CCCryptorRef m_cipher
Definition: commoncrypto_mode.cpp:50
Botan::CFB_Mode::update_granularity
size_t update_granularity() const overridefinal
Definition: cfb.cpp:49
Botan::CFB_Mode::cipher
const BlockCipher & cipher() const
Definition: cfb.h:48
Botan::CFB_Mode::block_size
size_t block_size() const
Definition: cfb.h:49
Botan::CFB_Encryption::finish
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition: cfb.cpp:163
Botan::CFB_Mode::name
std::string name() const overridefinal
Definition: cfb.cpp:36
Botan::CFB_Mode::m_keystream
secure_vector< uint8_t > m_keystream
Definition: cfb.h:52
Botan::CFB_Mode::output_length
size_t output_length(size_t input_length) const overridefinal
Definition: cfb.cpp:44
Botan::Cipher_Mode::update
void update(secure_vector< uint8_t > &buffer, size_t offset=0)
Definition: cipher_mode.h:112
Botan::Key_Length_Specification
Definition: key_spec.h:18
BOTAN_STATE_CHECK
#define BOTAN_STATE_CHECK(expr)
Definition: assert.h:49
Botan::CFB_Mode::reset
void reset() overridefinal
Definition: cfb.cpp:30
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
Botan::CFB_Mode::shift_register
void shift_register()
Definition: cfb.cpp:103
Botan::CFB_Mode::CFB_Mode
CFB_Mode(BlockCipher *cipher, size_t feedback_bits)
Definition: cfb.cpp:13
Botan::CFB_Mode::valid_nonce_length
bool valid_nonce_length(size_t n) const overridefinal
Definition: cfb.cpp:69
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
Botan::xor_buf
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition: mem_ops.h:232
Botan::SymmetricAlgorithm::name
virtual std::string name() const =0
Botan::CFB_Decryption::finish
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition: cfb.cpp:224
Botan::CFB_Mode::minimum_final_size
size_t minimum_final_size() const overridefinal
Definition: cfb.cpp:54
Botan::CFB_Mode::key_spec
Key_Length_Specification key_spec() const overridefinal
Definition: cfb.cpp:59
Botan::CFB_Mode::default_nonce_length
size_t default_nonce_length() const overridefinal
Definition: cfb.cpp:64
Botan::CFB_Mode::m_state
secure_vector< uint8_t > m_state
Definition: cfb.h:51
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:132
Botan
Definition: alg_id.cpp:13
Botan::CFB_Mode::feedback
size_t feedback() const
Definition: cfb.h:47
Botan::CFB_Mode::m_keystream_pos
size_t m_keystream_pos
Definition: cfb.h:53
Botan::CFB_Decryption::process
size_t process(uint8_t buf[], size_t size) override
Definition: cfb.cpp:182
Botan::SymmetricAlgorithm::verify_key_set
void verify_key_set(bool cond) const
Definition: sym_algo.h:89
Botan::SymmetricAlgorithm::key_spec
virtual Key_Length_Specification key_spec() const =0
Botan::CFB_Mode::clear
void clear() overridefinal
Definition: cfb.cpp:23
m_block_size
size_t m_block_size
Definition: openssl_mode.cpp:47
Botan::CFB_Encryption::process
size_t process(uint8_t buf[], size_t size) override
Definition: cfb.cpp:117
Botan::BlockCipher::block_size
virtual size_t block_size() const =0
Botan::BlockCipher
Definition: block_cipher.h:21
Botan::zeroise
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:160