8 #include <botan/block_cipher.h>
9 #include <botan/internal/openssl.h>
10 #include <openssl/evp.h>
16 class OpenSSL_BlockCipher
final :
public BlockCipher
19 OpenSSL_BlockCipher(
const std::string&
name,
20 const EVP_CIPHER* cipher);
22 OpenSSL_BlockCipher(
const std::string&
name,
23 const EVP_CIPHER* cipher,
24 size_t kl_min,
size_t kl_max,
size_t kl_mod);
26 ~OpenSSL_BlockCipher();
28 void clear()
override;
29 std::string provider()
const override {
return "openssl"; }
31 BlockCipher* clone()
const override;
33 size_t block_size()
const override {
return m_block_sz; }
37 void encrypt_n(
const uint8_t in[], uint8_t out[],
size_t blocks)
const override
42 throw OpenSSL_Error(
"EVP_EncryptUpdate", ERR_get_error());
45 void decrypt_n(
const uint8_t in[], uint8_t out[],
size_t blocks)
const override
49 if(!EVP_DecryptUpdate(
m_decrypt, out, &out_len, in, blocks * m_block_sz))
50 throw OpenSSL_Error(
"EVP_DecryptUpdate", ERR_get_error());
53 void key_schedule(
const uint8_t key[],
size_t key_len)
override;
63 OpenSSL_BlockCipher::OpenSSL_BlockCipher(
const std::string& algo_name,
64 const EVP_CIPHER* algo) :
65 m_block_sz(EVP_CIPHER_block_size(algo)),
70 if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE)
71 throw Invalid_Argument(
"OpenSSL_BlockCipher: Non-ECB EVP was passed in");
76 throw OpenSSL_Error(
"Can't allocate new context", ERR_get_error());
81 if(!EVP_EncryptInit_ex(
m_encrypt, algo,
nullptr,
nullptr,
nullptr))
82 throw OpenSSL_Error(
"EVP_EncryptInit_ex", ERR_get_error());
83 if(!EVP_DecryptInit_ex(
m_decrypt, algo,
nullptr,
nullptr,
nullptr))
84 throw OpenSSL_Error(
"EVP_DecryptInit_ex", ERR_get_error());
86 if(!EVP_CIPHER_CTX_set_padding(
m_encrypt, 0))
87 throw OpenSSL_Error(
"EVP_CIPHER_CTX_set_padding encrypt", ERR_get_error());
88 if(!EVP_CIPHER_CTX_set_padding(
m_decrypt, 0))
89 throw OpenSSL_Error(
"EVP_CIPHER_CTX_set_padding decrypt", ERR_get_error());
92 OpenSSL_BlockCipher::OpenSSL_BlockCipher(
const std::string& algo_name,
93 const EVP_CIPHER* algo,
97 m_block_sz(EVP_CIPHER_block_size(algo)),
102 if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE)
103 throw Invalid_Argument(
"OpenSSL_BlockCipher: Non-ECB EVP was passed in");
108 throw OpenSSL_Error(
"Can't allocate new context", ERR_get_error());
113 if(!EVP_EncryptInit_ex(
m_encrypt, algo,
nullptr,
nullptr,
nullptr))
114 throw OpenSSL_Error(
"EVP_EncryptInit_ex", ERR_get_error());
115 if(!EVP_DecryptInit_ex(
m_decrypt, algo,
nullptr,
nullptr,
nullptr))
116 throw OpenSSL_Error(
"EVP_DecryptInit_ex", ERR_get_error());
118 if(!EVP_CIPHER_CTX_set_padding(
m_encrypt, 0))
119 throw OpenSSL_Error(
"EVP_CIPHER_CTX_set_padding encrypt", ERR_get_error());
120 if(!EVP_CIPHER_CTX_set_padding(
m_decrypt, 0))
121 throw OpenSSL_Error(
"EVP_CIPHER_CTX_set_padding decrypt", ERR_get_error());
124 OpenSSL_BlockCipher::~OpenSSL_BlockCipher()
136 void OpenSSL_BlockCipher::key_schedule(
const uint8_t key[],
size_t length)
138 secure_vector<uint8_t> full_key(key, key + length);
142 full_key += std::make_pair(key, 8);
146 if(EVP_CIPHER_CTX_set_key_length(
m_encrypt, length) == 0 ||
147 EVP_CIPHER_CTX_set_key_length(
m_decrypt, length) == 0)
148 throw Invalid_Argument(
"OpenSSL_BlockCipher: Bad key length for " +
152 if(!EVP_EncryptInit_ex(
m_encrypt,
nullptr,
nullptr, full_key.data(),
nullptr))
153 throw OpenSSL_Error(
"EVP_EncryptInit_ex", ERR_get_error());
154 if(!EVP_DecryptInit_ex(
m_decrypt,
nullptr,
nullptr, full_key.data(),
nullptr))
155 throw OpenSSL_Error(
"EVP_DecryptInit_ex", ERR_get_error());
163 BlockCipher* OpenSSL_BlockCipher::clone()
const
175 void OpenSSL_BlockCipher::clear()
177 const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(
m_encrypt);
182 throw OpenSSL_Error(
"EVP_CIPHER_CTX_cleanup encrypt", ERR_get_error());
184 throw OpenSSL_Error(
"EVP_CIPHER_CTX_cleanup decrypt", ERR_get_error());
187 if(!EVP_EncryptInit_ex(
m_encrypt, algo,
nullptr,
nullptr,
nullptr))
188 throw OpenSSL_Error(
"EVP_EncryptInit_ex", ERR_get_error());
189 if(!EVP_DecryptInit_ex(
m_decrypt, algo,
nullptr,
nullptr,
nullptr))
190 throw OpenSSL_Error(
"EVP_DecryptInit_ex", ERR_get_error());
191 if(!EVP_CIPHER_CTX_set_padding(
m_encrypt, 0))
192 throw OpenSSL_Error(
"EVP_CIPHER_CTX_set_padding encrypt", ERR_get_error());
193 if(!EVP_CIPHER_CTX_set_padding(
m_decrypt, 0))
194 throw OpenSSL_Error(
"EVP_CIPHER_CTX_set_padding decrypt", ERR_get_error());
199 std::unique_ptr<BlockCipher>
202 #define MAKE_OPENSSL_BLOCK(evp_fn) \
203 std::unique_ptr<BlockCipher>(new OpenSSL_BlockCipher(name, evp_fn()))
204 #define MAKE_OPENSSL_BLOCK_KEYLEN(evp_fn, kl_min, kl_max, kl_mod) \
205 std::unique_ptr<BlockCipher>(new OpenSSL_BlockCipher(name, evp_fn(), kl_min, kl_max, kl_mod))
207 #if defined(BOTAN_HAS_AES) && !defined(OPENSSL_NO_AES)
208 if(name ==
"AES-128")
210 if(name ==
"AES-192")
212 if(name ==
"AES-256")
216 #if defined(BOTAN_HAS_CAMELLIA) && !defined(OPENSSL_NO_CAMELLIA)
217 if(name ==
"Camellia-128")
219 if(name ==
"Camellia-192")
221 if(name ==
"Camellia-256")
225 #if defined(BOTAN_HAS_DES) && !defined(OPENSSL_NO_DES)
226 if(name ==
"TripleDES")
Key_Length_Specification m_cipher_key_spec
std::string m_cipher_name
int(* final)(unsigned char *, CTX *)
EVP_CIPHER_CTX * m_decrypt
EVP_CIPHER_CTX * m_encrypt
#define MAKE_OPENSSL_BLOCK(evp_fn)
#define MAKE_OPENSSL_BLOCK_KEYLEN(evp_fn, kl_min, kl_max, kl_mod)
std::unique_ptr< BlockCipher > make_openssl_block_cipher(const std::string &name)