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