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