Botan  1.10.17
ossl_bc.cpp
Go to the documentation of this file.
1 /*
2 * OpenSSL Block Cipher
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/internal/openssl_engine.h>
9 #include <openssl/evp.h>
10 
11 #if OPENSSL_VERSION_NUMBER >= 0x10100000
12  #error "OpenSSL 1.1 API not supported in Botan 1.10, upgrade to 2.x"
13 #endif
14 
15 namespace Botan {
16 
17 namespace {
18 
19 /*
20 * EVP Block Cipher
21 */
22 class EVP_BlockCipher : public BlockCipher
23  {
24  public:
25  void clear();
26  std::string name() const { return cipher_name; }
27  BlockCipher* clone() const;
28 
29  size_t block_size() const { return block_sz; }
30 
31  EVP_BlockCipher(const EVP_CIPHER*, const std::string&);
32 
33  EVP_BlockCipher(const EVP_CIPHER*, const std::string&,
34  size_t, size_t, size_t);
35 
36  Key_Length_Specification key_spec() const { return cipher_key_spec; }
37 
38  ~EVP_BlockCipher();
39  private:
40  void encrypt_n(const byte in[], byte out[], size_t blocks) const;
41  void decrypt_n(const byte in[], byte out[], size_t blocks) const;
42  void key_schedule(const byte[], size_t);
43 
44  size_t block_sz;
45  Key_Length_Specification cipher_key_spec;
46  std::string cipher_name;
47  mutable EVP_CIPHER_CTX encrypt, decrypt;
48  };
49 
50 /*
51 * EVP Block Cipher Constructor
52 */
53 EVP_BlockCipher::EVP_BlockCipher(const EVP_CIPHER* algo,
54  const std::string& algo_name) :
55  block_sz(EVP_CIPHER_block_size(algo)),
56  cipher_key_spec(EVP_CIPHER_key_length(algo)),
57  cipher_name(algo_name)
58  {
59  if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE)
60  throw Invalid_Argument("EVP_BlockCipher: Non-ECB EVP was passed in");
61 
62  EVP_CIPHER_CTX_init(&encrypt);
63  EVP_CIPHER_CTX_init(&decrypt);
64 
65  EVP_EncryptInit_ex(&encrypt, algo, 0, 0, 0);
66  EVP_DecryptInit_ex(&decrypt, algo, 0, 0, 0);
67 
68  EVP_CIPHER_CTX_set_padding(&encrypt, 0);
69  EVP_CIPHER_CTX_set_padding(&decrypt, 0);
70  }
71 
72 /*
73 * EVP Block Cipher Constructor
74 */
75 EVP_BlockCipher::EVP_BlockCipher(const EVP_CIPHER* algo,
76  const std::string& algo_name,
77  size_t key_min, size_t key_max,
78  size_t key_mod) :
79  block_sz(EVP_CIPHER_block_size(algo)),
80  cipher_key_spec(key_min, key_max, key_mod),
81  cipher_name(algo_name)
82  {
83  if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE)
84  throw Invalid_Argument("EVP_BlockCipher: Non-ECB EVP was passed in");
85 
86  EVP_CIPHER_CTX_init(&encrypt);
87  EVP_CIPHER_CTX_init(&decrypt);
88 
89  EVP_EncryptInit_ex(&encrypt, algo, 0, 0, 0);
90  EVP_DecryptInit_ex(&decrypt, algo, 0, 0, 0);
91 
92  EVP_CIPHER_CTX_set_padding(&encrypt, 0);
93  EVP_CIPHER_CTX_set_padding(&decrypt, 0);
94  }
95 
96 /*
97 * EVP Block Cipher Destructor
98 */
99 EVP_BlockCipher::~EVP_BlockCipher()
100  {
101  EVP_CIPHER_CTX_cleanup(&encrypt);
102  EVP_CIPHER_CTX_cleanup(&decrypt);
103  }
104 
105 /*
106 * Encrypt a block
107 */
108 void EVP_BlockCipher::encrypt_n(const byte in[], byte out[],
109  size_t blocks) const
110  {
111  int out_len = 0;
112  EVP_EncryptUpdate(&encrypt, out, &out_len, in, blocks * block_sz);
113  }
114 
115 /*
116 * Decrypt a block
117 */
118 void EVP_BlockCipher::decrypt_n(const byte in[], byte out[],
119  size_t blocks) const
120  {
121  int out_len = 0;
122  EVP_DecryptUpdate(&decrypt, out, &out_len, in, blocks * block_sz);
123  }
124 
125 /*
126 * Set the key
127 */
128 void EVP_BlockCipher::key_schedule(const byte key[], size_t length)
129  {
130  SecureVector<byte> full_key(key, length);
131 
132  if(cipher_name == "TripleDES" && length == 16)
133  {
134  full_key += std::make_pair(key, 8);
135  }
136  else
137  if(EVP_CIPHER_CTX_set_key_length(&encrypt, length) == 0 ||
138  EVP_CIPHER_CTX_set_key_length(&decrypt, length) == 0)
139  throw Invalid_Argument("EVP_BlockCipher: Bad key length for " +
140  cipher_name);
141 
142  if(cipher_name == "RC2")
143  {
144  EVP_CIPHER_CTX_ctrl(&encrypt, EVP_CTRL_SET_RC2_KEY_BITS, length*8, 0);
145  EVP_CIPHER_CTX_ctrl(&decrypt, EVP_CTRL_SET_RC2_KEY_BITS, length*8, 0);
146  }
147 
148  EVP_EncryptInit_ex(&encrypt, 0, 0, full_key.begin(), 0);
149  EVP_DecryptInit_ex(&decrypt, 0, 0, full_key.begin(), 0);
150  }
151 
152 /*
153 * Return a clone of this object
154 */
155 BlockCipher* EVP_BlockCipher::clone() const
156  {
157  return new EVP_BlockCipher(EVP_CIPHER_CTX_cipher(&encrypt),
158  cipher_name,
159  cipher_key_spec.minimum_keylength(),
160  cipher_key_spec.maximum_keylength(),
161  cipher_key_spec.keylength_multiple());
162  }
163 
164 /*
165 * Clear memory of sensitive data
166 */
167 void EVP_BlockCipher::clear()
168  {
169  const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(&encrypt);
170 
171  EVP_CIPHER_CTX_cleanup(&encrypt);
172  EVP_CIPHER_CTX_cleanup(&decrypt);
173  EVP_CIPHER_CTX_init(&encrypt);
174  EVP_CIPHER_CTX_init(&decrypt);
175  EVP_EncryptInit_ex(&encrypt, algo, 0, 0, 0);
176  EVP_DecryptInit_ex(&decrypt, algo, 0, 0, 0);
177  EVP_CIPHER_CTX_set_padding(&encrypt, 0);
178  EVP_CIPHER_CTX_set_padding(&decrypt, 0);
179  }
180 
181 }
182 
183 /*
184 * Look for an algorithm with this name
185 */
186 BlockCipher*
188  Algorithm_Factory&) const
189  {
190 #define HANDLE_EVP_CIPHER(NAME, EVP) \
191  if(request.algo_name() == NAME && request.arg_count() == 0) \
192  return new EVP_BlockCipher(EVP, NAME);
193 
194 #define HANDLE_EVP_CIPHER_KEYLEN(NAME, EVP, MIN, MAX, MOD) \
195  if(request.algo_name() == NAME && request.arg_count() == 0) \
196  return new EVP_BlockCipher(EVP, NAME, MIN, MAX, MOD);
197 
198 #if !defined(OPENSSL_NO_AES)
199  /*
200  Using OpenSSL's AES causes crashes inside EVP on x86-64 with OpenSSL 0.9.8g
201  cause is unknown
202  */
203  HANDLE_EVP_CIPHER("AES-128", EVP_aes_128_ecb());
204  HANDLE_EVP_CIPHER("AES-192", EVP_aes_192_ecb());
205  HANDLE_EVP_CIPHER("AES-256", EVP_aes_256_ecb());
206 #endif
207 
208 #if !defined(OPENSSL_NO_DES)
209  HANDLE_EVP_CIPHER("DES", EVP_des_ecb());
210  HANDLE_EVP_CIPHER_KEYLEN("TripleDES", EVP_des_ede3_ecb(), 16, 24, 8);
211 #endif
212 
213 #if !defined(OPENSSL_NO_BF)
214  HANDLE_EVP_CIPHER_KEYLEN("Blowfish", EVP_bf_ecb(), 1, 56, 1);
215 #endif
216 
217 #if !defined(OPENSSL_NO_CAST)
218  HANDLE_EVP_CIPHER_KEYLEN("CAST-128", EVP_cast5_ecb(), 1, 16, 1);
219 #endif
220 
221 #if !defined(OPENSSL_NO_CAMELLIA)
222  HANDLE_EVP_CIPHER("Camellia-128", EVP_camellia_128_ecb());
223  HANDLE_EVP_CIPHER("Camellia-192", EVP_camellia_192_ecb());
224  HANDLE_EVP_CIPHER("Camellia-256", EVP_camellia_256_ecb());
225 #endif
226 
227 #if !defined(OPENSSL_NO_RC2)
228  HANDLE_EVP_CIPHER_KEYLEN("RC2", EVP_rc2_ecb(), 1, 32, 1);
229 #endif
230 
231 #if !defined(OPENSSL_NO_RC5) && 0
232  if(request.algo_name() == "RC5")
233  if(request.arg_as_integer(0, 12) == 12)
234  return new EVP_BlockCipher(EVP_rc5_32_12_16_ecb(),
235  "RC5(12)", 1, 32, 1);
236 #endif
237 
238 #if !defined(OPENSSL_NO_IDEA) && 0
239  HANDLE_EVP_CIPHER("IDEA", EVP_idea_ecb());
240 #endif
241 
242 #if !defined(OPENSSL_NO_SEED)
243  HANDLE_EVP_CIPHER("SEED", EVP_seed_ecb());
244 #endif
245 
246 #undef HANDLE_EVP_CIPHER
247 #undef HANDLE_EVP_CIPHER_KEYLEN
248 
249  return 0;
250  }
251 
252 }
#define HANDLE_EVP_CIPHER_KEYLEN(NAME, EVP, MIN, MAX, MOD)
size_t maximum_keylength() const
Definition: key_spec.h:69
size_t arg_as_integer(size_t i, size_t def_value) const
Definition: scan_name.cpp:167
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
#define HANDLE_EVP_CIPHER(NAME, EVP)
unsigned char byte
Definition: types.h:22
size_t keylength_multiple() const
Definition: key_spec.h:77
BlockCipher * find_block_cipher(const SCAN_Name &, Algorithm_Factory &) const
Definition: ossl_bc.cpp:187
size_t minimum_keylength() const
Definition: key_spec.h:61
std::string algo_name() const
Definition: scan_name.h:37