1 /* Copyright (c) 2015, 2021, Oracle and/or its affiliates.
2 
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6 
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation.  The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13 
14 Without limiting anything contained in the foregoing, this file,
15 which is part of C Driver for MySQL (Connector/C), is also subject to the
16 Universal FOSS Exception, version 1.0, a copy of which can be found at
17 http://oss.oracle.com/licenses/universal-foss-exception.
18 
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 GNU General Public License, version 2.0, for more details.
23 
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
27 
28 #include <my_global.h>
29 #include <m_string.h>
30 #include <my_aes.h>
31 #include "my_aes_impl.h"
32 
33 #include <openssl/aes.h>
34 #include <openssl/evp.h>
35 #include <openssl/err.h>
36 #include <openssl/bio.h>
37 
38 /*
39   xplugin needs BIO_new_bio_pair, but the server does not.
40   Add an explicit dependency here, so that it is available when loading
41   the plugin.
42  */
dummy_function_needed_by_xplugin()43 int dummy_function_needed_by_xplugin()
44 {
45   BIO *bio1;
46   BIO *bio2;
47   return BIO_new_bio_pair(&bio1, 42U, &bio2, 42U);
48 }
49 
50 
51 /* keep in sync with enum my_aes_opmode in my_aes.h */
52 const char *my_aes_opmode_names[]=
53 {
54   "aes-128-ecb",
55   "aes-192-ecb",
56   "aes-256-ecb",
57   "aes-128-cbc",
58   "aes-192-cbc",
59   "aes-256-cbc",
60   "aes-128-cfb1",
61   "aes-192-cfb1",
62   "aes-256-cfb1",
63   "aes-128-cfb8",
64   "aes-192-cfb8",
65   "aes-256-cfb8",
66   "aes-128-cfb128",
67   "aes-192-cfb128",
68   "aes-256-cfb128",
69   "aes-128-ofb",
70   "aes-192-ofb",
71   "aes-256-ofb",
72   NULL /* needed for the type enumeration */
73 };
74 
75 
76 /* keep in sync with enum my_aes_opmode in my_aes.h */
77 static uint my_aes_opmode_key_sizes_impl[]=
78 {
79   128 /* aes-128-ecb */,
80   192 /* aes-192-ecb */,
81   256 /* aes-256-ecb */,
82   128 /* aes-128-cbc */,
83   192 /* aes-192-cbc */,
84   256 /* aes-256-cbc */,
85   128 /* aes-128-cfb1 */,
86   192 /* aes-192-cfb1 */,
87   256 /* aes-256-cfb1 */,
88   128 /* aes-128-cfb8 */,
89   192 /* aes-192-cfb8 */,
90   256 /* aes-256-cfb8 */,
91   128 /* aes-128-cfb128 */,
92   192 /* aes-192-cfb128 */,
93   256 /* aes-256-cfb128 */,
94   128 /* aes-128-ofb */,
95   192 /* aes-192-ofb */,
96   256 /* aes-256-ofb */
97 };
98 
99 uint *my_aes_opmode_key_sizes= my_aes_opmode_key_sizes_impl;
100 
101 
102 
103 static const EVP_CIPHER *
aes_evp_type(const my_aes_opmode mode)104 aes_evp_type(const my_aes_opmode mode)
105 {
106   switch (mode)
107   {
108   case my_aes_128_ecb:    return EVP_aes_128_ecb();
109   case my_aes_128_cbc:    return EVP_aes_128_cbc();
110   case my_aes_128_cfb1:   return EVP_aes_128_cfb1();
111   case my_aes_128_cfb8:   return EVP_aes_128_cfb8();
112   case my_aes_128_cfb128: return EVP_aes_128_cfb128();
113   case my_aes_128_ofb:    return EVP_aes_128_ofb();
114   case my_aes_192_ecb:    return EVP_aes_192_ecb();
115   case my_aes_192_cbc:    return EVP_aes_192_cbc();
116   case my_aes_192_cfb1:   return EVP_aes_192_cfb1();
117   case my_aes_192_cfb8:   return EVP_aes_192_cfb8();
118   case my_aes_192_cfb128: return EVP_aes_192_cfb128();
119   case my_aes_192_ofb:    return EVP_aes_192_ofb();
120   case my_aes_256_ecb:    return EVP_aes_256_ecb();
121   case my_aes_256_cbc:    return EVP_aes_256_cbc();
122   case my_aes_256_cfb1:   return EVP_aes_256_cfb1();
123   case my_aes_256_cfb8:   return EVP_aes_256_cfb8();
124   case my_aes_256_cfb128: return EVP_aes_256_cfb128();
125   case my_aes_256_ofb:    return EVP_aes_256_ofb();
126   default: return NULL;
127   }
128 }
129 
130 
my_aes_encrypt(const unsigned char * source,uint32 source_length,unsigned char * dest,const unsigned char * key,uint32 key_length,enum my_aes_opmode mode,const unsigned char * iv,bool padding)131 int my_aes_encrypt(const unsigned char *source, uint32 source_length,
132                    unsigned char *dest,
133                    const unsigned char *key, uint32 key_length,
134                    enum my_aes_opmode mode, const unsigned char *iv,
135                    bool padding)
136 {
137 #if OPENSSL_VERSION_NUMBER < 0x10100000L
138   EVP_CIPHER_CTX stack_ctx;
139   EVP_CIPHER_CTX *ctx= &stack_ctx;
140 #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
141   EVP_CIPHER_CTX *ctx= EVP_CIPHER_CTX_new();
142 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
143   const EVP_CIPHER *cipher= aes_evp_type(mode);
144   int u_len, f_len;
145   /* The real key to be used for encryption */
146   unsigned char rkey[MAX_AES_KEY_LENGTH / 8];
147 
148   my_aes_create_key(key, key_length, rkey, mode);
149   if (!ctx || !cipher || (EVP_CIPHER_iv_length(cipher) > 0 && !iv))
150     return MY_AES_BAD_DATA;
151 
152 #if OPENSSL_VERSION_NUMBER < 0x10100000L
153   EVP_CIPHER_CTX_init(ctx);
154 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
155 
156   if (!EVP_EncryptInit(ctx, cipher, rkey, iv))
157     goto aes_error;                             /* Error */
158   if (!EVP_CIPHER_CTX_set_padding(ctx, padding))
159     goto aes_error;                             /* Error */
160   if (!EVP_EncryptUpdate(ctx, dest, &u_len, source, source_length))
161     goto aes_error;                             /* Error */
162 
163   if (!EVP_EncryptFinal(ctx, dest + u_len, &f_len))
164     goto aes_error;                             /* Error */
165 
166 #if OPENSSL_VERSION_NUMBER < 0x10100000L
167   EVP_CIPHER_CTX_cleanup(ctx);
168 #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
169   EVP_CIPHER_CTX_free(ctx);
170 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
171   return u_len + f_len;
172 
173 aes_error:
174   /* need to explicitly clean up the error if we want to ignore it */
175   ERR_clear_error();
176 #if OPENSSL_VERSION_NUMBER < 0x10100000L
177   EVP_CIPHER_CTX_cleanup(ctx);
178 #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
179   EVP_CIPHER_CTX_free(ctx);
180 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
181   return MY_AES_BAD_DATA;
182 }
183 
my_aes_decrypt(const unsigned char * source,uint32 source_length,unsigned char * dest,const unsigned char * key,uint32 key_length,enum my_aes_opmode mode,const unsigned char * iv,bool padding)184 int my_aes_decrypt(const unsigned char *source, uint32 source_length,
185                    unsigned char *dest,
186                    const unsigned char *key, uint32 key_length,
187                    enum my_aes_opmode mode, const unsigned char *iv,
188                    bool padding)
189 {
190 #if OPENSSL_VERSION_NUMBER < 0x10100000L
191   EVP_CIPHER_CTX stack_ctx;
192   EVP_CIPHER_CTX *ctx= &stack_ctx;
193 #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
194   EVP_CIPHER_CTX *ctx= EVP_CIPHER_CTX_new();
195 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
196   const EVP_CIPHER *cipher= aes_evp_type(mode);
197   int u_len, f_len;
198 
199   /* The real key to be used for decryption */
200   unsigned char rkey[MAX_AES_KEY_LENGTH / 8];
201 
202   my_aes_create_key(key, key_length, rkey, mode);
203   if (!ctx || !cipher || (EVP_CIPHER_iv_length(cipher) > 0 && !iv))
204     return MY_AES_BAD_DATA;
205 
206 #if OPENSSL_VERSION_NUMBER < 0x10100000L
207   EVP_CIPHER_CTX_init(ctx);
208 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
209   if (!EVP_DecryptInit(ctx, aes_evp_type(mode), rkey, iv))
210     goto aes_error;                             /* Error */
211   if (!EVP_CIPHER_CTX_set_padding(ctx, padding))
212     goto aes_error;                             /* Error */
213   if (!EVP_DecryptUpdate(ctx, dest, &u_len, source, source_length))
214     goto aes_error;                             /* Error */
215   if (!EVP_DecryptFinal_ex(ctx, dest + u_len, &f_len))
216     goto aes_error;                             /* Error */
217 
218 #if OPENSSL_VERSION_NUMBER < 0x10100000L
219   EVP_CIPHER_CTX_cleanup(ctx);
220 #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
221   EVP_CIPHER_CTX_free(ctx);
222 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
223 
224   return u_len + f_len;
225 
226 aes_error:
227   /* need to explicitly clean up the error if we want to ignore it */
228   ERR_clear_error();
229 #if OPENSSL_VERSION_NUMBER < 0x10100000L
230   EVP_CIPHER_CTX_cleanup(ctx);
231 #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
232   EVP_CIPHER_CTX_free(ctx);
233 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
234   return MY_AES_BAD_DATA;
235 }
236 
my_aes_get_size(uint32 source_length,my_aes_opmode opmode)237 int my_aes_get_size(uint32 source_length, my_aes_opmode opmode)
238 {
239   const EVP_CIPHER *cipher= aes_evp_type(opmode);
240   size_t block_size;
241 
242   block_size= EVP_CIPHER_block_size(cipher);
243 
244   return block_size > 1 ?
245     block_size * (source_length / block_size) + block_size :
246     source_length;
247 }
248 
249 /**
250   Return true if the AES cipher and block mode requires an IV
251 
252   SYNOPSIS
253   my_aes_needs_iv()
254   @param mode           encryption mode
255 
256   @retval TRUE   IV needed
257   @retval FALSE  IV not needed
258 */
259 
my_aes_needs_iv(my_aes_opmode opmode)260 my_bool my_aes_needs_iv(my_aes_opmode opmode)
261 {
262   const EVP_CIPHER *cipher= aes_evp_type(opmode);
263   int iv_length;
264 
265   iv_length= EVP_CIPHER_iv_length(cipher);
266   assert(iv_length == 0 || iv_length == MY_AES_IV_SIZE);
267   return iv_length != 0 ? TRUE : FALSE;
268 }
269 
270