9 #include <botan/cipher_mode.h>
10 #include <botan/internal/rounding.h>
11 #include <botan/internal/openssl.h>
12 #include <openssl/evp.h>
19 class OpenSSL_Cipher_Mode
final :
public Cipher_Mode
22 OpenSSL_Cipher_Mode(
const std::string&
name,
23 const EVP_CIPHER* cipher,
25 ~OpenSSL_Cipher_Mode();
27 std::string provider()
const override {
return "openssl"; }
30 void start_msg(
const uint8_t nonce[],
size_t nonce_len)
override;
31 size_t process(uint8_t msg[],
size_t msg_len)
override;
32 void finish(secure_vector<uint8_t>& final_block,
size_t offset0)
override;
33 size_t output_length(
size_t input_length)
const override;
34 size_t update_granularity()
const override;
35 size_t minimum_final_size()
const override;
36 size_t default_nonce_length()
const override;
37 bool valid_nonce_length(
size_t nonce_len)
const override;
38 void clear()
override;
39 void reset()
override;
40 Key_Length_Specification key_spec()
const override;
43 void key_schedule(
const uint8_t key[],
size_t length)
override;
53 OpenSSL_Cipher_Mode::OpenSSL_Cipher_Mode(
const std::string&
name,
54 const EVP_CIPHER* algo,
63 if(EVP_CIPHER_mode(algo) != EVP_CIPH_CBC_MODE)
64 throw Invalid_Argument(
"OpenSSL_BlockCipher: Non-CBC EVP was passed in");
68 throw OpenSSL_Error(
"Can't allocate new context", ERR_get_error());
71 if(!EVP_CipherInit_ex(
m_cipher, algo,
nullptr,
nullptr,
nullptr,
73 throw OpenSSL_Error(
"EVP_CipherInit_ex", ERR_get_error());
74 if(!EVP_CIPHER_CTX_set_padding(
m_cipher, 0))
75 throw OpenSSL_Error(
"EVP_CIPHER_CTX_set_padding", ERR_get_error());
78 OpenSSL_Cipher_Mode::~OpenSSL_Cipher_Mode()
83 void OpenSSL_Cipher_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len)
87 if(!valid_nonce_length(nonce_len))
88 throw Invalid_IV_Length(
name(), nonce_len);
92 if(!EVP_CipherInit_ex(
m_cipher,
nullptr,
nullptr,
nullptr, nonce, -1))
93 throw OpenSSL_Error(
"EVP_CipherInit_ex nonce", ERR_get_error());
98 if(!EVP_CipherInit_ex(
m_cipher,
nullptr,
nullptr,
nullptr, zeros.data(), -1))
99 throw OpenSSL_Error(
"EVP_CipherInit_ex nonce", ERR_get_error());
106 size_t OpenSSL_Cipher_Mode::process(uint8_t msg[],
size_t msg_len)
113 if(msg_len > INT_MAX)
116 secure_vector<uint8_t> out(outl);
118 if(!EVP_CipherUpdate(
m_cipher, out.data(), &outl, msg, msg_len))
119 throw OpenSSL_Error(
"EVP_CipherUpdate", ERR_get_error());
124 void OpenSSL_Cipher_Mode::finish(secure_vector<uint8_t>& buffer,
131 uint8_t* buf = buffer.data() + offset;
132 const size_t buf_size = buffer.size() - offset;
134 size_t written = process(buf, buf_size);
135 int outl = buf_size - written;
136 secure_vector<uint8_t> out(outl);
138 if(!EVP_CipherFinal_ex(
m_cipher, out.data(), &outl))
139 throw OpenSSL_Error(
"EVP_CipherFinal_ex", ERR_get_error());
140 copy_mem(buf + written, out.data(), outl);
142 buffer.resize(offset + written);
145 size_t OpenSSL_Cipher_Mode::update_granularity()
const
150 size_t OpenSSL_Cipher_Mode::minimum_final_size()
const
155 size_t OpenSSL_Cipher_Mode::default_nonce_length()
const
160 bool OpenSSL_Cipher_Mode::valid_nonce_length(
size_t nonce_len)
const
165 size_t OpenSSL_Cipher_Mode::output_length(
size_t input_length)
const
167 if(input_length == 0)
173 void OpenSSL_Cipher_Mode::clear()
178 const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(
m_cipher);
180 if(!EVP_CIPHER_CTX_cleanup(
m_cipher))
181 throw OpenSSL_Error(
"EVP_CIPHER_CTX_cleanup", ERR_get_error());
183 if(!EVP_CipherInit_ex(
m_cipher, algo,
nullptr,
nullptr,
nullptr,
185 throw OpenSSL_Error(
"EVP_CipherInit_ex clear", ERR_get_error());
186 if(!EVP_CIPHER_CTX_set_padding(
m_cipher, 0))
187 throw OpenSSL_Error(
"EVP_CIPHER_CTX_set_padding clear", ERR_get_error());
190 void OpenSSL_Cipher_Mode::reset()
192 if(!EVP_CipherInit_ex(
m_cipher,
nullptr,
nullptr,
nullptr,
nullptr, -1))
193 throw OpenSSL_Error(
"EVP_CipherInit_ex clear", ERR_get_error());
197 Key_Length_Specification OpenSSL_Cipher_Mode::key_spec()
const
199 return Key_Length_Specification(EVP_CIPHER_CTX_key_length(
m_cipher));
202 void OpenSSL_Cipher_Mode::key_schedule(
const uint8_t key[],
size_t length)
204 if(!EVP_CIPHER_CTX_set_key_length(
m_cipher, length))
205 throw OpenSSL_Error(
"EVP_CIPHER_CTX_set_key_length", ERR_get_error());
206 if(!EVP_CipherInit_ex(
m_cipher,
nullptr,
nullptr, key,
nullptr, -1))
207 throw OpenSSL_Error(
"EVP_CipherInit_ex key", ERR_get_error());
217 #define MAKE_OPENSSL_MODE(evp_fn) \
218 new OpenSSL_Cipher_Mode(name, (evp_fn)(), direction)
220 #if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_MODE_CBC) && !defined(OPENSSL_NO_AES)
221 if(name ==
"AES-128/CBC/NoPadding")
223 if(name ==
"AES-192/CBC/NoPadding")
225 if(name ==
"AES-256/CBC/NoPadding")
229 #undef MAKE_OPENSSL_MODE
const Cipher_Dir m_direction
const std::string m_mode_name
int(* final)(unsigned char *, CTX *)
#define BOTAN_STATE_CHECK(expr)
Cipher_Mode * make_openssl_cipher_mode(const std::string &name, Cipher_Dir direction)
#define BOTAN_ASSERT(expr, assertion_made)
EVP_CIPHER_CTX * m_cipher
void copy_mem(T *out, const T *in, size_t n)
size_t round_up(size_t n, size_t align_to)
#define MAKE_OPENSSL_MODE(evp_fn)