10 #include <botan/mode_pad.h>
11 #include <botan/internal/rounding.h>
18 m_state(m_cipher->block_size())
20 if(m_padding && !m_padding->valid_blocksize(cipher->
block_size()))
22 " cannot be used with " +
23 cipher->
name() +
"/CBC");
62 return (n == 0 || n ==
cipher().block_size());
65 void CBC_Mode::key_schedule(
const uint8_t key[],
size_t length)
67 m_cipher->set_key(key, length);
70 void CBC_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len)
73 throw Invalid_IV_Length(
name(), nonce_len);
81 m_state.assign(nonce, nonce + nonce_len);
102 const size_t blocks = sz / BS;
108 for(
size_t i = 0; i != blocks; ++i)
110 xor_buf(&buf[BS*i], prev_block, BS);
112 prev_block = &buf[BS*i];
115 state().assign(&buf[BS*(blocks-1)], &buf[BS*blocks]);
123 BOTAN_ASSERT(buffer.size() >= offset,
"Offset is sane");
127 const size_t bytes_in_final_block = (buffer.size()-offset) % BS;
131 if((buffer.size()-offset) % BS)
132 throw Exception(
"Did not pad to full block size in " +
name());
139 return (n ==
cipher().block_size());
154 BOTAN_ASSERT(buffer.size() >= offset,
"Offset is sane");
155 uint8_t* buf = buffer.data() + offset;
156 const size_t sz = buffer.size() - offset;
168 for(
size_t i = 0; i != BS; ++i)
169 std::swap(buffer[buffer.size()-BS+i], buffer[buffer.size()-2*BS+i]);
173 const size_t full_blocks = ((sz / BS) - 1) * BS;
174 const size_t final_bytes = sz - full_blocks;
175 BOTAN_ASSERT(final_bytes > BS && final_bytes < 2*BS,
"Left over size in expected range");
178 buffer.resize(full_blocks + offset);
184 for(
size_t i = 0; i != final_bytes - BS; ++i)
186 last[i] ^= last[i + BS];
187 last[i + BS] ^= last[i];
211 size_t blocks = sz / BS;
215 const size_t to_proc =
std::min(BS * blocks, m_tempbuf.size());
220 xor_buf(&m_tempbuf[BS], buf, to_proc - BS);
223 copy_mem(buf, m_tempbuf.data(), to_proc);
226 blocks -= to_proc / BS;
234 BOTAN_ASSERT(buffer.size() >= offset,
"Offset is sane");
235 const size_t sz = buffer.size() - offset;
239 if(sz == 0 || sz % BS)
244 const size_t pad_bytes = BS -
padding().
unpad(&buffer[buffer.size()-BS], BS);
245 buffer.resize(buffer.size() - pad_bytes);
246 if(pad_bytes == 0 &&
padding().
name() !=
"NoPadding")
260 return (n ==
cipher().block_size());
270 BOTAN_ASSERT(buffer.size() >= offset,
"Offset is sane");
271 const size_t sz = buffer.size() - offset;
272 uint8_t* buf = buffer.data() + offset;
283 for(
size_t i = 0; i != BS; ++i)
284 std::swap(buffer[buffer.size()-BS+i], buffer[buffer.size()-2*BS+i]);
290 const size_t full_blocks = ((sz / BS) - 1) * BS;
291 const size_t final_bytes = sz - full_blocks;
292 BOTAN_ASSERT(final_bytes > BS && final_bytes < 2*BS,
"Left over size in expected range");
295 buffer.resize(full_blocks + offset);
300 xor_buf(last.data(), &last[BS], final_bytes - BS);
302 for(
size_t i = 0; i != final_bytes - BS; ++i)
303 std::swap(last[i], last[i + BS]);
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
void xor_buf(T out[], const T in[], size_t length)
secure_vector< uint8_t > & state()
void encrypt(const uint8_t in[], uint8_t out[]) const
Key_Length_Specification key_spec() const override
void decrypt(const uint8_t in[], uint8_t out[]) const
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
std::string name() const override
bool valid_nonce_length(size_t n) const override
virtual void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const =0
size_t update_granularity() const override
CBC_Mode(BlockCipher *cipher, BlockCipherModePaddingMethod *padding)
void update(secure_vector< uint8_t > &buffer, size_t offset=0)
const BlockCipherModePaddingMethod & padding() const
size_t default_nonce_length() const override
#define BOTAN_ASSERT(expr, assertion_made)
size_t minimum_final_size() const override
bool valid_nonce_length(size_t n) const override
std::vector< T, secure_allocator< T >> secure_vector
virtual std::string name() const =0
size_t output_length(size_t input_length) const override
size_t process(uint8_t buf[], size_t size) override
size_t parallel_bytes() const
void copy_mem(T *out, const T *in, size_t n)
virtual Key_Length_Specification key_spec() const =0
const BlockCipher & cipher() const
virtual void add_padding(secure_vector< uint8_t > &buffer, size_t final_block_bytes, size_t block_size) const =0
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
size_t minimum_final_size() const override
virtual size_t unpad(const uint8_t block[], size_t size) const =0
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
size_t minimum_final_size() const override
size_t output_length(size_t input_length) const override
size_t round_up(size_t n, size_t align_to)
virtual std::string name() const =0
virtual size_t block_size() const =0
size_t output_length(size_t input_length) const override
size_t process(uint8_t buf[], size_t size) override
bool valid_nonce_length(size_t n) const override
size_t minimum_final_size() const override
void zeroise(std::vector< T, Alloc > &vec)