1 /*
2 * Cipher Modes via OpenSSL
3 * (C) 1999-2010,2015 Jack Lloyd
4 * (C) 2017 Alexander Bluhm (genua GmbH)
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #include <botan/cipher_mode.h>
10 #include <botan/internal/rounding.h>
11 #include <botan/internal/openssl.h>
12 #include <openssl/evp.h>
13 #include <limits.h>
14 
15 namespace Botan {
16 
17 namespace {
18 
19 class OpenSSL_Cipher_Mode final : public Cipher_Mode
20    {
21    public:
22       OpenSSL_Cipher_Mode(const std::string& name,
23                           const EVP_CIPHER* cipher,
24                           Cipher_Dir direction);
25       ~OpenSSL_Cipher_Mode();
26 
provider() const27       std::string provider() const override { return "openssl"; }
name() const28       std::string name() const override { return m_mode_name; }
29 
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;
41 
42    private:
43       void key_schedule(const uint8_t key[], size_t length) override;
44 
45       const std::string m_mode_name;
46       const Cipher_Dir m_direction;
47       size_t m_block_size;
48       EVP_CIPHER_CTX* m_cipher;
49       bool m_key_set;
50       bool m_nonce_set;
51    };
52 
OpenSSL_Cipher_Mode(const std::string & name,const EVP_CIPHER * algo,Cipher_Dir direction)53 OpenSSL_Cipher_Mode::OpenSSL_Cipher_Mode(const std::string& name,
54                                          const EVP_CIPHER* algo,
55                                          Cipher_Dir direction) :
56    m_mode_name(name),
57    m_direction(direction),
58    m_key_set(false),
59    m_nonce_set(false)
60    {
61    m_block_size = EVP_CIPHER_block_size(algo);
62 
63    if(EVP_CIPHER_mode(algo) != EVP_CIPH_CBC_MODE)
64       throw Invalid_Argument("OpenSSL_BlockCipher: Non-CBC EVP was passed in");
65 
66    m_cipher = EVP_CIPHER_CTX_new();
67    if (m_cipher == nullptr)
68       throw OpenSSL_Error("Can't allocate new context", ERR_get_error());
69 
70    EVP_CIPHER_CTX_init(m_cipher);
71    if(!EVP_CipherInit_ex(m_cipher, algo, nullptr, nullptr, nullptr,
72                          m_direction == ENCRYPTION ? 1 : 0))
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());
76    }
77 
~OpenSSL_Cipher_Mode()78 OpenSSL_Cipher_Mode::~OpenSSL_Cipher_Mode()
79    {
80    EVP_CIPHER_CTX_free(m_cipher);
81    }
82 
start_msg(const uint8_t nonce[],size_t nonce_len)83 void OpenSSL_Cipher_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
84    {
85    verify_key_set(m_key_set);
86 
87    if(!valid_nonce_length(nonce_len))
88       throw Invalid_IV_Length(name(), nonce_len);
89 
90    if(nonce_len)
91       {
92       if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, nonce, -1))
93          throw OpenSSL_Error("EVP_CipherInit_ex nonce", ERR_get_error());
94       }
95    else if(m_nonce_set == false)
96       {
97       const std::vector<uint8_t> zeros(m_block_size);
98       if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, zeros.data(), -1))
99          throw OpenSSL_Error("EVP_CipherInit_ex nonce", ERR_get_error());
100       }
101    // otherwise existing CBC state left unchanged
102 
103    m_nonce_set = true;
104    }
105 
process(uint8_t msg[],size_t msg_len)106 size_t OpenSSL_Cipher_Mode::process(uint8_t msg[], size_t msg_len)
107    {
108    verify_key_set(m_key_set);
109    BOTAN_STATE_CHECK(m_nonce_set);
110 
111    if(msg_len == 0)
112       return 0;
113    if(msg_len > INT_MAX)
114       throw Internal_Error("msg_len overflow");
115    int outl = msg_len;
116    secure_vector<uint8_t> out(outl);
117 
118    if(!EVP_CipherUpdate(m_cipher, out.data(), &outl, msg, msg_len))
119       throw OpenSSL_Error("EVP_CipherUpdate", ERR_get_error());
120    copy_mem(msg, out.data(), outl);
121    return outl;
122    }
123 
finish(secure_vector<uint8_t> & buffer,size_t offset)124 void OpenSSL_Cipher_Mode::finish(secure_vector<uint8_t>& buffer,
125                                  size_t offset)
126    {
127    verify_key_set(m_key_set);
128    BOTAN_STATE_CHECK(m_nonce_set);
129 
130    BOTAN_ASSERT(buffer.size() >= offset, "Offset ok");
131    uint8_t* buf = buffer.data() + offset;
132    const size_t buf_size = buffer.size() - offset;
133 
134    size_t written = process(buf, buf_size);
135    int outl = buf_size - written;
136    secure_vector<uint8_t> out(outl);
137 
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);
141    written += outl;
142    buffer.resize(offset + written);
143    }
144 
update_granularity() const145 size_t OpenSSL_Cipher_Mode::update_granularity() const
146    {
147    return m_block_size * BOTAN_BLOCK_CIPHER_PAR_MULT;
148    }
149 
minimum_final_size() const150 size_t OpenSSL_Cipher_Mode::minimum_final_size() const
151    {
152    return 0; // no padding
153    }
154 
default_nonce_length() const155 size_t OpenSSL_Cipher_Mode::default_nonce_length() const
156    {
157    return m_block_size;
158    }
159 
valid_nonce_length(size_t nonce_len) const160 bool OpenSSL_Cipher_Mode::valid_nonce_length(size_t nonce_len) const
161    {
162    return (nonce_len == 0 || nonce_len == m_block_size);
163    }
164 
output_length(size_t input_length) const165 size_t OpenSSL_Cipher_Mode::output_length(size_t input_length) const
166    {
167    if(input_length == 0)
168       return m_block_size;
169    else
170       return round_up(input_length, m_block_size);
171    }
172 
clear()173 void OpenSSL_Cipher_Mode::clear()
174    {
175    m_key_set = false;
176    m_nonce_set = false;
177 
178    const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(m_cipher);
179 
180    if(!EVP_CIPHER_CTX_cleanup(m_cipher))
181       throw OpenSSL_Error("EVP_CIPHER_CTX_cleanup", ERR_get_error());
182    EVP_CIPHER_CTX_init(m_cipher);
183    if(!EVP_CipherInit_ex(m_cipher, algo, nullptr, nullptr, nullptr,
184                          m_direction == ENCRYPTION ? 1 : 0))
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());
188    }
189 
reset()190 void OpenSSL_Cipher_Mode::reset()
191    {
192    if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, nullptr, -1))
193       throw OpenSSL_Error("EVP_CipherInit_ex clear", ERR_get_error());
194    m_nonce_set = false;
195    }
196 
key_spec() const197 Key_Length_Specification OpenSSL_Cipher_Mode::key_spec() const
198    {
199    return Key_Length_Specification(EVP_CIPHER_CTX_key_length(m_cipher));
200    }
201 
key_schedule(const uint8_t key[],size_t length)202 void OpenSSL_Cipher_Mode::key_schedule(const uint8_t key[], size_t length)
203    {
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());
208    m_key_set = true;
209    m_nonce_set = false;
210    }
211 
212 }
213 
214 Cipher_Mode*
make_openssl_cipher_mode(const std::string & name,Cipher_Dir direction)215 make_openssl_cipher_mode(const std::string& name, Cipher_Dir direction)
216    {
217 #define MAKE_OPENSSL_MODE(evp_fn) \
218    new OpenSSL_Cipher_Mode(name, (evp_fn)(), direction)
219 
220 #if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_MODE_CBC) && !defined(OPENSSL_NO_AES)
221    if(name == "AES-128/CBC/NoPadding")
222       return MAKE_OPENSSL_MODE(EVP_aes_128_cbc);
223    if(name == "AES-192/CBC/NoPadding")
224       return MAKE_OPENSSL_MODE(EVP_aes_192_cbc);
225    if(name == "AES-256/CBC/NoPadding")
226       return MAKE_OPENSSL_MODE(EVP_aes_256_cbc);
227 #endif
228 
229 #undef MAKE_OPENSSL_MODE
230    return nullptr;
231    }
232 
233 }
234