Botan  1.11.10
ecb.cpp
Go to the documentation of this file.
1 /*
2 * ECB Mode
3 * (C) 1999-2009,2013 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/ecb.h>
9 #include <botan/loadstor.h>
10 #include <botan/internal/xor_buf.h>
11 #include <botan/internal/rounding.h>
12 
13 namespace Botan {
14 
16  m_cipher(cipher),
17  m_padding(padding)
18  {
19  if(!m_padding->valid_blocksize(cipher->block_size()))
20  throw std::invalid_argument("Padding " + m_padding->name() +
21  " cannot be used with " +
22  cipher->name() + "/ECB");
23  }
24 
26  {
27  m_cipher->clear();
28  }
29 
30 std::string ECB_Mode::name() const
31  {
32  return cipher().name() + "/ECB/" + padding().name();
33  }
34 
36  {
37  return cipher().parallel_bytes();
38  }
39 
41  {
42  return cipher().key_spec();
43  }
44 
46  {
47  return 0;
48  }
49 
50 bool ECB_Mode::valid_nonce_length(size_t n) const
51  {
52  return (n == 0);
53  }
54 
55 void ECB_Mode::key_schedule(const byte key[], size_t length)
56  {
57  m_cipher->set_key(key, length);
58  }
59 
60 secure_vector<byte> ECB_Mode::start_raw(const byte[], size_t nonce_len)
61  {
62  if(!valid_nonce_length(nonce_len))
63  throw Invalid_IV_Length(name(), nonce_len);
64 
65  return secure_vector<byte>();
66  }
67 
69  {
70  return 0;
71  }
72 
73 size_t ECB_Encryption::output_length(size_t input_length) const
74  {
75  return round_up(input_length, cipher().block_size());
76  }
77 
78 void ECB_Encryption::update(secure_vector<byte>& buffer, size_t offset)
79  {
80  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
81  const size_t sz = buffer.size() - offset;
82  byte* buf = &buffer[offset];
83 
84  const size_t BS = cipher().block_size();
85 
86  BOTAN_ASSERT(sz % BS == 0, "ECB input is full blocks");
87  const size_t blocks = sz / BS;
88 
89  cipher().encrypt_n(&buf[0], &buf[0], blocks);
90  }
91 
92 void ECB_Encryption::finish(secure_vector<byte>& buffer, size_t offset)
93  {
94  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
95  const size_t sz = buffer.size() - offset;
96 
97  const size_t BS = cipher().block_size();
98 
99  const size_t bytes_in_final_block = sz % BS;
100 
101  padding().add_padding(buffer, bytes_in_final_block, BS);
102 
103  if(buffer.size() % BS)
104  throw std::runtime_error("Did not pad to full block size in " + name());
105 
106  update(buffer, offset);
107  }
108 
109 size_t ECB_Decryption::output_length(size_t input_length) const
110  {
111  return input_length;
112  }
113 
115  {
116  return cipher().block_size();
117  }
118 
119 void ECB_Decryption::update(secure_vector<byte>& buffer, size_t offset)
120  {
121  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
122  const size_t sz = buffer.size() - offset;
123  byte* buf = &buffer[offset];
124 
125  const size_t BS = cipher().block_size();
126 
127  BOTAN_ASSERT(sz % BS == 0, "Input is full blocks");
128  size_t blocks = sz / BS;
129 
130  cipher().decrypt_n(&buf[0], &buf[0], blocks);
131  }
132 
133 void ECB_Decryption::finish(secure_vector<byte>& buffer, size_t offset)
134  {
135  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
136  const size_t sz = buffer.size() - offset;
137 
138  const size_t BS = cipher().block_size();
139 
140  if(sz == 0 || sz % BS)
141  throw Decoding_Error(name() + ": Ciphertext not a multiple of block size");
142 
143  update(buffer, offset);
144 
145  const size_t pad_bytes = BS - padding().unpad(&buffer[buffer.size()-BS], BS);
146  buffer.resize(buffer.size() - pad_bytes); // remove padding
147  }
148 
149 }
const BlockCipher & cipher() const
Definition: ecb.h:37
void finish(secure_vector< byte > &final_block, size_t offset=0) override
Definition: ecb.cpp:133
ECB_Mode(BlockCipher *cipher, BlockCipherModePaddingMethod *padding)
Definition: ecb.cpp:15
Key_Length_Specification key_spec() const override
Definition: ecb.cpp:40
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
void clear() override
Definition: ecb.cpp:25
size_t minimum_final_size() const override
Definition: ecb.cpp:114
size_t output_length(size_t input_length) const override
Definition: ecb.cpp:109
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:92
virtual std::string name() const =0
bool valid_nonce_length(size_t n) const override
Definition: ecb.cpp:50
uint8_t byte
Definition: types.h:30
size_t parallel_bytes() const
Definition: block_cipher.h:35
Definition: buf_comp.h:15
size_t update_granularity() const override
Definition: ecb.cpp:35
size_t minimum_final_size() const override
Definition: ecb.cpp:68
size_t output_length(size_t input_length) const override
Definition: ecb.cpp:73
void update(secure_vector< byte > &blocks, size_t offset=0) override
Definition: ecb.cpp:78
const BlockCipherModePaddingMethod & padding() const
Definition: ecb.h:39
virtual Key_Length_Specification key_spec() const =0
T round_up(T n, T align_to)
Definition: rounding.h:22
size_t default_nonce_length() const override
Definition: ecb.cpp:45
virtual void encrypt_n(const byte in[], byte out[], size_t blocks) const =0
std::string name() const override
Definition: ecb.cpp:30
void update(secure_vector< byte > &blocks, size_t offset=0) override
Definition: ecb.cpp:119
virtual void add_padding(secure_vector< byte > &buffer, size_t final_block_bytes, size_t block_size) const =0
virtual void decrypt_n(const byte in[], byte out[], size_t blocks) const =0
virtual std::string name() const =0
virtual size_t block_size() const =0
void finish(secure_vector< byte > &final_block, size_t offset=0) override
Definition: ecb.cpp:92
virtual size_t unpad(const byte block[], size_t size) const =0