|
13 | 13 | along with this program; if not, write to the Free Software |
14 | 14 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
15 | 15 |
|
16 | | - |
17 | 16 | #include <my_global.h> |
18 | 17 | #include <m_string.h> |
19 | 18 | #include <my_aes.h> |
20 | 19 | #include <my_crypt.h> |
21 | 20 |
|
22 | | -#if defined(HAVE_YASSL) |
23 | | -#include "aes.hpp" |
24 | | -#include "openssl/ssl.h" |
25 | | -#include "crypto_wrapper.hpp" |
26 | | -#elif defined(HAVE_OPENSSL) |
27 | | -#include <openssl/aes.h> |
28 | | -#include <openssl/evp.h> |
29 | | -#include <openssl/buffer.h> |
30 | | -#include <openssl/conf.h> |
31 | | - |
32 | | -// Wrap C struct, to ensure resources are released. |
33 | | -struct MyCipherCtx |
34 | | -{ |
35 | | - MyCipherCtx() { memset(&ctx, 0, sizeof(ctx)); } |
36 | | - ~MyCipherCtx() { EVP_CIPHER_CTX_cleanup(&ctx); } |
37 | | - |
38 | | - EVP_CIPHER_CTX ctx; |
39 | | -}; |
40 | | -#endif |
41 | | - |
42 | | -enum encrypt_dir { MY_AES_ENCRYPT, MY_AES_DECRYPT }; |
43 | | - |
44 | | -/** |
45 | | - This is internal function just keeps joint code of Key generation |
46 | | -
|
47 | | - SYNOPSIS |
48 | | - my_aes_create_key() |
49 | | - @param key [in] Key to use for real key creation |
50 | | - @param key_length [in] Length of the key |
51 | | - @param rkey [out] Real key (used by OpenSSL/YaSSL) |
52 | | -
|
53 | | - @return |
54 | | - 0 Ok |
55 | | - -1 Error; Note: The current impementation never returns this |
56 | | -*/ |
57 | | - |
58 | | -static int my_aes_create_key(const char *key, int key_length, uint8 *rkey) |
59 | | -{ |
60 | | - uint8 *rkey_end= rkey + AES_KEY_LENGTH / 8; /* Real key boundary */ |
61 | | - uint8 *ptr; /* Start of the real key*/ |
62 | | - const char *sptr; /* Start of the working key */ |
63 | | - const char *key_end= key + key_length; /* Working key boundary*/ |
64 | | - |
65 | | - memset(rkey, 0, AES_KEY_LENGTH / 8); /* Set initial key */ |
66 | | - |
67 | | - for (ptr= rkey, sptr= key; sptr < key_end; ptr ++, sptr ++) |
68 | | - { |
69 | | - if (ptr == rkey_end) |
70 | | - /* Just loop over tmp_key until we used all key */ |
71 | | - ptr= rkey; |
72 | | - *ptr ^= (uint8) *sptr; |
73 | | - } |
74 | | -#ifdef AES_USE_KEY_BITS |
75 | | - /* |
76 | | - This block is intended to allow more weak encryption if application |
77 | | - build with libmysqld needs to correspond to export regulations |
78 | | - It should be never used in normal distribution as does not give |
79 | | - any speed improvement. |
80 | | - To get worse security define AES_USE_KEY_BITS to number of bits |
81 | | - you want key to be. It should be divisible by 8 |
82 | | -
|
83 | | - WARNING: Changing this value results in changing of enryption for |
84 | | - all key lengths so altering this value will result in impossibility |
85 | | - to decrypt data encrypted with previous value |
86 | | - */ |
87 | | -#define AES_USE_KEY_BYTES (AES_USE_KEY_BITS/8) |
88 | | - /* |
89 | | - To get weaker key we use first AES_USE_KEY_BYTES bytes of created key |
90 | | - and cyclically copy them until we created all required key length |
91 | | - */ |
92 | | - for (ptr= rkey+AES_USE_KEY_BYTES, sptr=rkey ; ptr < rkey_end; |
93 | | - ptr ++, sptr ++) |
94 | | - { |
95 | | - if (sptr == rkey + AES_USE_KEY_BYTES) |
96 | | - sptr= rkey; |
97 | | - *ptr= *sptr; |
98 | | - } |
99 | | -#endif |
100 | | - return 0; |
101 | | -} |
102 | | - |
103 | 21 | /** |
104 | 22 | Encryption interface that doesn't do anything (for testing) |
105 | 23 |
|
@@ -258,153 +176,6 @@ get_aes_encrypt_func(enum_my_aes_encryption_algorithm method) |
258 | 176 | return NULL; |
259 | 177 | } |
260 | 178 |
|
261 | | - |
262 | | -/**************************************************************** |
263 | | - Encryption function visible to MariaDB users |
264 | | -****************************************************************/ |
265 | | - |
266 | | -int my_aes_encrypt(const uchar* source, int source_length, uchar* dest, |
267 | | - const char* key, int key_length) |
268 | | -{ |
269 | | -#if defined(HAVE_YASSL) |
270 | | - TaoCrypt::AES_ECB_Encryption enc; |
271 | | - |
272 | | - /* 128 bit block used for padding */ |
273 | | - uint8 block[MY_AES_BLOCK_SIZE]; |
274 | | - int num_blocks; /* number of complete blocks */ |
275 | | - int i; |
276 | | -#elif defined(HAVE_OPENSSL) |
277 | | - MyCipherCtx ctx; |
278 | | - int u_len, f_len; |
279 | | -#endif |
280 | | - |
281 | | - /* The real key to be used for encryption */ |
282 | | - uint8 rkey[AES_KEY_LENGTH / 8]; |
283 | | - int rc; /* result codes */ |
284 | | - |
285 | | - if ((rc= my_aes_create_key(key, key_length, rkey))) |
286 | | - return rc; |
287 | | - |
288 | | -#if defined(HAVE_YASSL) |
289 | | - enc.SetKey((const TaoCrypt::byte *) rkey, MY_AES_BLOCK_SIZE); |
290 | | - |
291 | | - num_blocks = source_length / MY_AES_BLOCK_SIZE; |
292 | | - |
293 | | - for (i = num_blocks; i > 0; i--) /* Encode complete blocks */ |
294 | | - { |
295 | | - enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source, |
296 | | - MY_AES_BLOCK_SIZE); |
297 | | - source += MY_AES_BLOCK_SIZE; |
298 | | - dest += MY_AES_BLOCK_SIZE; |
299 | | - } |
300 | | - |
301 | | - /* Encode the rest. We always have incomplete block */ |
302 | | - char pad_len = MY_AES_BLOCK_SIZE - (source_length - |
303 | | - MY_AES_BLOCK_SIZE * num_blocks); |
304 | | - memcpy(block, source, 16 - pad_len); |
305 | | - memset(block + MY_AES_BLOCK_SIZE - pad_len, pad_len, pad_len); |
306 | | - |
307 | | - enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) block, |
308 | | - MY_AES_BLOCK_SIZE); |
309 | | - |
310 | | - return MY_AES_BLOCK_SIZE * (num_blocks + 1); |
311 | | -#elif defined(HAVE_OPENSSL) |
312 | | - if (! EVP_EncryptInit(&ctx.ctx, EVP_aes_128_ecb(), |
313 | | - (const unsigned char *) rkey, NULL)) |
314 | | - return AES_BAD_DATA; /* Error */ |
315 | | - if (! EVP_EncryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len, |
316 | | - (unsigned const char *) source, source_length)) |
317 | | - return AES_BAD_DATA; /* Error */ |
318 | | - if (! EVP_EncryptFinal(&ctx.ctx, (unsigned char *) dest + u_len, &f_len)) |
319 | | - return AES_BAD_DATA; /* Error */ |
320 | | - |
321 | | - return u_len + f_len; |
322 | | -#endif |
323 | | -} |
324 | | - |
325 | | - |
326 | | -/** |
327 | | - DeCrypt buffer with AES encryption algorithm. |
328 | | -
|
329 | | - SYNOPSIS |
330 | | - my_aes_decrypt() |
331 | | - @param source [in] Pointer to data for decryption |
332 | | - @param source_length [in] Size of encrypted data |
333 | | - @param dest [out] Buffer to place decrypted data (must |
334 | | - be large enough) |
335 | | - @param key [in] Key to be used for decryption |
336 | | - @param key_length [in] Length of the key. Will handle keys of any length |
337 | | -
|
338 | | - @return |
339 | | - >= 0 Size of encrypted data |
340 | | - < 0 Error |
341 | | -*/ |
342 | | - |
343 | | -int my_aes_decrypt(const uchar *source, int source_length, uchar *dest, |
344 | | - const char *key, int key_length) |
345 | | -{ |
346 | | -#if defined(HAVE_YASSL) |
347 | | - TaoCrypt::AES_ECB_Decryption dec; |
348 | | - /* 128 bit block used for padding */ |
349 | | - uint8 block[MY_AES_BLOCK_SIZE]; |
350 | | - int num_blocks; /* Number of complete blocks */ |
351 | | - int i; |
352 | | -#elif defined(HAVE_OPENSSL) |
353 | | - MyCipherCtx ctx; |
354 | | - int u_len, f_len; |
355 | | -#endif |
356 | | - |
357 | | - /* The real key to be used for decryption */ |
358 | | - uint8 rkey[AES_KEY_LENGTH / 8]; |
359 | | - int rc; /* Result codes */ |
360 | | - |
361 | | - if ((rc= my_aes_create_key(key, key_length, rkey))) |
362 | | - return rc; |
363 | | - |
364 | | -#if defined(HAVE_YASSL) |
365 | | - dec.SetKey((const TaoCrypt::byte *) rkey, MY_AES_BLOCK_SIZE); |
366 | | - |
367 | | - num_blocks = source_length / MY_AES_BLOCK_SIZE; |
368 | | - |
369 | | - if ((source_length != num_blocks * MY_AES_BLOCK_SIZE) || num_blocks == 0 ) |
370 | | - /* Input size has to be even and at least one block */ |
371 | | - return AES_BAD_DATA; |
372 | | - |
373 | | - /* Decode all but last blocks */ |
374 | | - for (i = num_blocks - 1; i > 0; i--) |
375 | | - { |
376 | | - dec.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source, |
377 | | - MY_AES_BLOCK_SIZE); |
378 | | - source += MY_AES_BLOCK_SIZE; |
379 | | - dest += MY_AES_BLOCK_SIZE; |
380 | | - } |
381 | | - |
382 | | - dec.Process((TaoCrypt::byte *) block, (const TaoCrypt::byte *) source, |
383 | | - MY_AES_BLOCK_SIZE); |
384 | | - |
385 | | - /* Use last char in the block as size */ |
386 | | - uint pad_len = (uint) (uchar) block[MY_AES_BLOCK_SIZE - 1]; |
387 | | - |
388 | | - if (pad_len > MY_AES_BLOCK_SIZE) |
389 | | - return AES_BAD_DATA; |
390 | | - /* We could also check whole padding but we do not really need this */ |
391 | | - |
392 | | - memcpy(dest, block, MY_AES_BLOCK_SIZE - pad_len); |
393 | | - return MY_AES_BLOCK_SIZE * num_blocks - pad_len; |
394 | | -#elif defined(HAVE_OPENSSL) |
395 | | - if (! EVP_DecryptInit(&ctx.ctx, EVP_aes_128_ecb(), |
396 | | - (const unsigned char *) rkey, NULL)) |
397 | | - return AES_BAD_DATA; /* Error */ |
398 | | - if (! EVP_DecryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len, |
399 | | - (unsigned const char *) source, source_length)) |
400 | | - return AES_BAD_DATA; /* Error */ |
401 | | - if (! EVP_DecryptFinal(&ctx.ctx, (unsigned char *) dest + u_len, &f_len)) |
402 | | - return AES_BAD_DATA; /* Error */ |
403 | | - return u_len + f_len; |
404 | | -#endif |
405 | | -} |
406 | | - |
407 | | - |
408 | 179 | /** |
409 | 180 | Get size of buffer which will be large enough for encrypted data |
410 | 181 |
|
|
0 commit comments