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