Botan  1.11.17
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  return round_up(input_length, cipher().block_size());
87  }
88 
89 void ECB_Encryption::update(secure_vector<byte>& buffer, size_t offset)
90  {
91  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
92  const size_t sz = buffer.size() - offset;
93  byte* buf = &buffer[offset];
94 
95  const size_t BS = cipher().block_size();
96 
97  BOTAN_ASSERT(sz % BS == 0, "ECB input is full blocks");
98  const size_t blocks = sz / BS;
99 
100  cipher().encrypt_n(&buf[0], &buf[0], blocks);
101  }
102 
103 void ECB_Encryption::finish(secure_vector<byte>& buffer, size_t offset)
104  {
105  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
106  const size_t sz = buffer.size() - offset;
107 
108  const size_t BS = cipher().block_size();
109 
110  const size_t bytes_in_final_block = sz % BS;
111 
112  padding().add_padding(buffer, bytes_in_final_block, BS);
113 
114  if(buffer.size() % BS)
115  throw std::runtime_error("Did not pad to full block size in " + name());
116 
117  update(buffer, offset);
118  }
119 
120 size_t ECB_Decryption::output_length(size_t input_length) const
121  {
122  return input_length;
123  }
124 
126  {
127  return cipher().block_size();
128  }
129 
130 void ECB_Decryption::update(secure_vector<byte>& buffer, size_t offset)
131  {
132  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
133  const size_t sz = buffer.size() - offset;
134  byte* buf = &buffer[offset];
135 
136  const size_t BS = cipher().block_size();
137 
138  BOTAN_ASSERT(sz % BS == 0, "Input is full blocks");
139  size_t blocks = sz / BS;
140 
141  cipher().decrypt_n(&buf[0], &buf[0], blocks);
142  }
143 
144 void ECB_Decryption::finish(secure_vector<byte>& buffer, size_t offset)
145  {
146  BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
147  const size_t sz = buffer.size() - offset;
148 
149  const size_t BS = cipher().block_size();
150 
151  if(sz == 0 || sz % BS)
152  throw Decoding_Error(name() + ": Ciphertext not a multiple of block size");
153 
154  update(buffer, offset);
155 
156  const size_t pad_bytes = BS - padding().unpad(&buffer[buffer.size()-BS], BS);
157  buffer.resize(buffer.size() - pad_bytes); // remove padding
158  }
159 
160 }
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
int m_padding
Definition: openssl_rsa.cpp:88
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:144
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:125
size_t output_length(size_t input_length) const override
Definition: ecb.cpp:120
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
uint8_t byte
Definition: types.h:31
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:89
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: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:130
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:103
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