Botan 1.10.17

cbc.cpp
Go to the documentation of this file.
1 /*
2 * CBC Mode
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #include <botan/cbc.h>
9 #include <botan/internal/xor_buf.h>
10 #include <algorithm>
11
12 namespace Botan {
13
14 /*
15 * CBC Encryption Constructor
16 */
17 CBC_Encryption::CBC_Encryption(BlockCipher* ciph,
18 BlockCipherModePaddingMethod* pad) :
19 Buffered_Filter(ciph->block_size(), 0),
20 cipher(ciph), padder(pad)
21 {
22 if(!padder->valid_blocksize(cipher->block_size()))
23 throw Invalid_Block_Size(name(), padder->name());
24
25 state.resize(cipher->block_size());
26 }
27
28 /*
29 * CBC Encryption Constructor
30 */
31 CBC_Encryption::CBC_Encryption(BlockCipher* ciph,
32 BlockCipherModePaddingMethod* pad,
33 const SymmetricKey& key,
34 const InitializationVector& iv) :
35 Buffered_Filter(ciph->block_size(), 0),
36 cipher(ciph), padder(pad)
37 {
38 if(!padder->valid_blocksize(cipher->block_size()))
39 throw Invalid_Block_Size(name(), padder->name());
40
41 state.resize(cipher->block_size());
42
43 set_key(key);
44 set_iv(iv);
45 }
46
47 /*
48 * Set the IV
49 */
50 void CBC_Encryption::set_iv(const InitializationVector& iv)
51 {
52 if(!valid_iv_length(iv.length()))
53 throw Invalid_IV_Length(name(), iv.length());
54
55 state = iv.bits_of();
56 buffer_reset();
57 }
58
59 /*
60 * Encrypt in CBC mode
61 */
62 void CBC_Encryption::buffered_block(const byte input[], size_t length)
63 {
64 size_t blocks = length / state.size();
65
66 for(size_t i = 0; i != blocks; ++i)
67 {
68 xor_buf(state, input + i * cipher->block_size(), state.size());
69 cipher->encrypt(state);
70 send(state, state.size());
71 }
72 }
73
74 /*
75 * Finish encrypting in CBC mode
76 */
77 void CBC_Encryption::buffered_final(const byte input[], size_t length)
78 {
79 if(length % cipher->block_size() == 0)
80 buffered_block(input, length);
81 else if(length != 0)
82 throw Encoding_Error(name() + ": Did not pad to full blocksize");
83 }
84
85 void CBC_Encryption::write(const byte input[], size_t input_length)
86 {
87 Buffered_Filter::write(input, input_length);
88 }
89
90 void CBC_Encryption::end_msg()
91 {
92 size_t last_block = current_position() % cipher->block_size();
93
94 SecureVector<byte> padding(cipher->block_size());
95 padder->pad(padding, padding.size(), last_block);
96
97 size_t pad_bytes = padder->pad_bytes(cipher->block_size(), last_block);
98
99 if(pad_bytes)
100 Buffered_Filter::write(padding, pad_bytes);
101 Buffered_Filter::end_msg();
102 }
103
104 /*
105 * Return a CBC mode name
106 */
107 std::string CBC_Encryption::name() const
108 {
109 return (cipher->name() + "/CBC/" + padder->name());
110 }
111
112 /*
113 * CBC Decryption Constructor
114 */
115 CBC_Decryption::CBC_Decryption(BlockCipher* ciph,
116 BlockCipherModePaddingMethod* pad) :
117 Buffered_Filter(ciph->parallel_bytes(), ciph->block_size()),
118 cipher(ciph), padder(pad)
119 {
120 if(!padder->valid_blocksize(cipher->block_size()))
121 throw Invalid_Block_Size(name(), padder->name());
122
123 state.resize(cipher->block_size());
124 temp.resize(buffered_block_size());
125 }
126
127 /*
128 * CBC Decryption Constructor
129 */
130 CBC_Decryption::CBC_Decryption(BlockCipher* ciph,
131 BlockCipherModePaddingMethod* pad,
132 const SymmetricKey& key,
133 const InitializationVector& iv) :
134 Buffered_Filter(ciph->parallel_bytes(), ciph->block_size()),
135 cipher(ciph), padder(pad)
136 {
137 if(!padder->valid_blocksize(cipher->block_size()))
138 throw Invalid_Block_Size(name(), padder->name());
139
140 state.resize(cipher->block_size());
141 temp.resize(buffered_block_size());
142
143 set_key(key);
144 set_iv(iv);
145 }
146
147 /*
148 * Set the IV
149 */
150 void CBC_Decryption::set_iv(const InitializationVector& iv)
151 {
152 if(!valid_iv_length(iv.length()))
153 throw Invalid_IV_Length(name(), iv.length());
154
155 state = iv.bits_of();
156 buffer_reset();
157 }
158
159 /*
160 * Decrypt in CBC mode
161 */
162 void CBC_Decryption::buffered_block(const byte input[], size_t length)
163 {
164 const size_t blocks_in_temp = temp.size() / cipher->block_size();
165 size_t blocks = length / cipher->block_size();
166
167 while(blocks)
168 {
169 size_t to_proc = std::min<size_t>(blocks, blocks_in_temp);
170
171 cipher->decrypt_n(input, &temp[0], to_proc);
172
173 xor_buf(temp, state, cipher->block_size());
174
175 for(size_t i = 1; i < to_proc; ++i)
176 xor_buf(&temp[i * cipher->block_size()],
177 input + (i-1) * cipher->block_size(),
178 cipher->block_size());
179
180 copy_mem(&state[0],
181 input + (to_proc - 1) * cipher->block_size(),
182 cipher->block_size());
183
184 send(temp, to_proc * cipher->block_size());
185
186 input += to_proc * cipher->block_size();
187 blocks -= to_proc;
188 }
189 }
190
191 /*
192 * Finish encrypting in CBC mode
193 */
194 void CBC_Decryption::buffered_final(const byte input[], size_t length)
195 {
196 if(length == 0 || length % cipher->block_size() != 0)
197 throw Decoding_Error(name() + ": Ciphertext not multiple of block size");
198
199 size_t extra_blocks = (length - 1) / cipher->block_size();
200
201 buffered_block(input, extra_blocks * cipher->block_size());
202
203 input += extra_blocks * cipher->block_size();
204
205 cipher->decrypt(input, temp);
206 xor_buf(temp, state, cipher->block_size());
207 send(temp, padder->unpad(temp, cipher->block_size()));
208
209 copy_mem(&state[0], input, state.size()); // save for IV chaining
210 }
211
212 /*
213 * Decrypt in CBC mode
214 */
215 void CBC_Decryption::write(const byte input[], size_t length)
216 {
217 Buffered_Filter::write(input, length);
218 }
219
220 /*
221 * Finish decrypting in CBC mode
222 */
223 void CBC_Decryption::end_msg()
224 {
225 Buffered_Filter::end_msg();
226 }
227
228 /*
229 * Return a CBC mode name
230 */
231 std::string CBC_Decryption::name() const
232 {
233 return (cipher->name() + "/CBC/" + padder->name());
234 }
235
236 }
Botan::Buffered_Filter
Definition: buf_filt.h:19
Botan::CBC_Decryption::name
std::string name() const
Definition: cbc.cpp:231
Botan::MemoryRegion::resize
void resize(size_t n)
Definition: secmem.h:217
Botan::OctetString
Definition: symkey.h:19
Botan::CBC_Encryption::valid_iv_length
bool valid_iv_length(size_t iv_len) const
Definition: cbc.h:34
Botan::CBC_Encryption::name
std::string name() const
Definition: cbc.cpp:107
Botan::BlockCipherModePaddingMethod::valid_blocksize
virtual bool valid_blocksize(size_t block_size) const =0
Botan::Buffered_Filter::end_msg
void end_msg()
Definition: buf_filt.cpp:82
Botan::Invalid_IV_Length
Definition: exceptn.h:78
Botan::CBC_Decryption::valid_iv_length
bool valid_iv_length(size_t iv_len) const
Definition: cbc.h:74
Botan::BlockCipherModePaddingMethod::pad_bytes
virtual size_t pad_bytes(size_t block_size, size_t position) const
Definition: mode_pad.cpp:17
Botan::CBC_Decryption::set_iv
void set_iv(const InitializationVector &iv)
Definition: cbc.cpp:150
Botan::CBC_Encryption::CBC_Encryption
CBC_Encryption(BlockCipher *cipher, BlockCipherModePaddingMethod *padding)
Definition: cbc.cpp:17
Botan::Buffered_Filter::write
void write(const byte in[], size_t length)
Definition: buf_filt.cpp:34
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::BlockCipher::decrypt
void decrypt(const byte in[], byte out[]) const
Definition: block_cipher.h:57
Botan::Filter::send
void send(const byte in[], size_t length)
Definition: filter.cpp:28
Botan::BlockCipher::encrypt
void encrypt(const byte in[], byte out[]) const
Definition: block_cipher.h:47
Botan::Buffered_Filter::current_position
size_t current_position() const
Definition: buf_filt.h:72
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:22
Botan
Definition: algo_base.h:14
Botan::Algorithm::name
virtual std::string name() const =0
Botan::BlockCipherModePaddingMethod
Definition: mode_pad.h:25
Botan::OctetString::length
size_t length() const
Definition: symkey.h:25
Botan::CBC_Decryption::CBC_Decryption
CBC_Decryption(BlockCipher *cipher, BlockCipherModePaddingMethod *padding)
Definition: cbc.cpp:115
Botan::CBC_Encryption::set_key
void set_key(const SymmetricKey &key)
Definition: cbc.h:29
Botan::MemoryRegion::size
size_t size() const
Definition: secmem.h:29
Botan::Buffered_Filter::buffer_reset
void buffer_reset()
Definition: buf_filt.h:77
Botan::Buffered_Filter::buffered_block_size
size_t buffered_block_size() const
Definition: buf_filt.h:67
Botan::CBC_Decryption::set_key
void set_key(const SymmetricKey &key)
Definition: cbc.h:69
Botan::OctetString::bits_of
SecureVector< byte > bits_of() const
Definition: symkey.h:30
Botan::xor_buf
void xor_buf(byte out[], const byte in[], size_t length)
Definition: xor_buf.h:21
Botan::BlockCipher::decrypt_n
virtual void decrypt_n(const byte in[], byte out[], size_t blocks) const =0
Botan::BlockCipherModePaddingMethod::name
virtual std::string name() const =0
Botan::Invalid_Block_Size
Definition: exceptn.h:66
Botan::BlockCipher::block_size
virtual size_t block_size() const =0
Botan::BlockCipherModePaddingMethod::unpad
virtual size_t unpad(const byte block[], size_t size) const =0
Botan::BlockCipherModePaddingMethod::pad
virtual void pad(byte block[], size_t size, size_t current_position) const =0
Botan::BlockCipher
Definition: block_cipher.h:18
Botan::CBC_Encryption::set_iv
void set_iv(const InitializationVector &iv)
Definition: cbc.cpp:50