summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-03-25 19:36:10 +0100
committerSergei Golubchik <serg@mariadb.org>2015-04-08 10:58:46 +0200
commitb937574293ee731dc7b5c949d27fede1f5d17db5 (patch)
tree3f75c7eb84197a885df6a2d16f453afe27dee1ba
parent91f7363e4baff9debe43cf039fe4525c43aee4cc (diff)
downloadmariadb-git-b937574293ee731dc7b5c949d27fede1f5d17db5.tar.gz
remove old my_aes_encrypt/decrypt
and simplify Item_func_aes_encrypt/decrypt
-rw-r--r--include/my_aes.h49
-rw-r--r--mysys_ssl/my_aes.cc229
-rw-r--r--sql/item_strfunc.cc81
-rw-r--r--sql/item_strfunc.h22
4 files changed, 51 insertions, 330 deletions
diff --git a/include/my_aes.h b/include/my_aes.h
index 3d9c9c1a8c9..e7376a6b08e 100644
--- a/include/my_aes.h
+++ b/include/my_aes.h
@@ -47,8 +47,6 @@ typedef int Crypt_result;
C_MODE_START
-#define AES_KEY_LENGTH 128 /* Must be 128 192 or 256 */
-
/**
Crypt buffer with AES dynamic (defined at startup) encryption algorithm.
@@ -127,53 +125,6 @@ my_bool my_aes_init_dynamic_encrypt(enum enum_my_aes_encryption_algorithm method
extern MYSQL_PLUGIN_IMPORT enum enum_my_aes_encryption_algorithm current_aes_dynamic_method;
-/**
- Crypt buffer with AES encryption algorithm.
-
- SYNOPSIS
- my_aes_encrypt()
-
- @param source Pointer to data for encryption
- @param source_length Size of encryption data
- @param dest Buffer to place encrypted data (must be large enough)
- @param key Key to be used for encryption
- @param kel_length Length of the key. Will handle keys of any length
-
- @return Size of encrypted data, or negative in case of error.
-*/
-
-int my_aes_encrypt(const uchar *source, int source_length, uchar *dest,
- const char *key, int key_length);
-
-/**
- DeCrypt buffer with AES encryption algorithm.
-
- SYNOPSIS
- my_aes_decrypt()
-
- @param source Pointer to data for decryption
- @param source_length size of encrypted data
- @param dest buffer to place decrypted data (must be large enough)
- @param key Key to be used for decryption
- @param kel_length Length of the key. Will handle keys of any length
-
- @return size of original data, or negative in case of error.
-*/
-
-
-int my_aes_decrypt(const uchar *source, int source_length, uchar *dest,
- const char *key, int key_length);
-
-/**
- get size of buffer which will be large enough for encrypted data
-
- SYNOPSIS
- my_aes_get_size()
- @param source_length Length of data to be encrypted
-
- @return Size of buffer required to store encrypted data
-*/
-
int my_aes_get_size(int source_length);
C_MODE_END
diff --git a/mysys_ssl/my_aes.cc b/mysys_ssl/my_aes.cc
index 0a81cef9ab1..97af3c39381 100644
--- a/mysys_ssl/my_aes.cc
+++ b/mysys_ssl/my_aes.cc
@@ -13,93 +13,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
#include <my_global.h>
#include <m_string.h>
#include <my_aes.h>
#include <my_crypt.h>
-#if defined(HAVE_YASSL)
-#include "aes.hpp"
-#include "openssl/ssl.h"
-#include "crypto_wrapper.hpp"
-#elif defined(HAVE_OPENSSL)
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-#include <openssl/buffer.h>
-#include <openssl/conf.h>
-
-// Wrap C struct, to ensure resources are released.
-struct MyCipherCtx
-{
- MyCipherCtx() { memset(&ctx, 0, sizeof(ctx)); }
- ~MyCipherCtx() { EVP_CIPHER_CTX_cleanup(&ctx); }
-
- EVP_CIPHER_CTX ctx;
-};
-#endif
-
-enum encrypt_dir { MY_AES_ENCRYPT, MY_AES_DECRYPT };
-
-/**
- This is internal function just keeps joint code of Key generation
-
- SYNOPSIS
- my_aes_create_key()
- @param key [in] Key to use for real key creation
- @param key_length [in] Length of the key
- @param rkey [out] Real key (used by OpenSSL/YaSSL)
-
- @return
- 0 Ok
- -1 Error; Note: The current impementation never returns this
-*/
-
-static int my_aes_create_key(const char *key, int key_length, uint8 *rkey)
-{
- uint8 *rkey_end= rkey + AES_KEY_LENGTH / 8; /* Real key boundary */
- uint8 *ptr; /* Start of the real key*/
- const char *sptr; /* Start of the working key */
- const char *key_end= key + key_length; /* Working key boundary*/
-
- memset(rkey, 0, AES_KEY_LENGTH / 8); /* Set initial key */
-
- for (ptr= rkey, sptr= key; sptr < key_end; ptr ++, sptr ++)
- {
- if (ptr == rkey_end)
- /* Just loop over tmp_key until we used all key */
- ptr= rkey;
- *ptr ^= (uint8) *sptr;
- }
-#ifdef AES_USE_KEY_BITS
- /*
- This block is intended to allow more weak encryption if application
- build with libmysqld needs to correspond to export regulations
- It should be never used in normal distribution as does not give
- any speed improvement.
- To get worse security define AES_USE_KEY_BITS to number of bits
- you want key to be. It should be divisible by 8
-
- WARNING: Changing this value results in changing of enryption for
- all key lengths so altering this value will result in impossibility
- to decrypt data encrypted with previous value
- */
-#define AES_USE_KEY_BYTES (AES_USE_KEY_BITS/8)
- /*
- To get weaker key we use first AES_USE_KEY_BYTES bytes of created key
- and cyclically copy them until we created all required key length
- */
- for (ptr= rkey+AES_USE_KEY_BYTES, sptr=rkey ; ptr < rkey_end;
- ptr ++, sptr ++)
- {
- if (sptr == rkey + AES_USE_KEY_BYTES)
- sptr= rkey;
- *ptr= *sptr;
- }
-#endif
- return 0;
-}
-
/**
Encryption interface that doesn't do anything (for testing)
@@ -258,153 +176,6 @@ get_aes_encrypt_func(enum_my_aes_encryption_algorithm method)
return NULL;
}
-
-/****************************************************************
- Encryption function visible to MariaDB users
-****************************************************************/
-
-int my_aes_encrypt(const uchar* source, int source_length, uchar* dest,
- const char* key, int key_length)
-{
-#if defined(HAVE_YASSL)
- TaoCrypt::AES_ECB_Encryption enc;
-
- /* 128 bit block used for padding */
- uint8 block[MY_AES_BLOCK_SIZE];
- int num_blocks; /* number of complete blocks */
- int i;
-#elif defined(HAVE_OPENSSL)
- MyCipherCtx ctx;
- int u_len, f_len;
-#endif
-
- /* The real key to be used for encryption */
- uint8 rkey[AES_KEY_LENGTH / 8];
- int rc; /* result codes */
-
- if ((rc= my_aes_create_key(key, key_length, rkey)))
- return rc;
-
-#if defined(HAVE_YASSL)
- enc.SetKey((const TaoCrypt::byte *) rkey, MY_AES_BLOCK_SIZE);
-
- num_blocks = source_length / MY_AES_BLOCK_SIZE;
-
- for (i = num_blocks; i > 0; i--) /* Encode complete blocks */
- {
- enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source,
- MY_AES_BLOCK_SIZE);
- source += MY_AES_BLOCK_SIZE;
- dest += MY_AES_BLOCK_SIZE;
- }
-
- /* Encode the rest. We always have incomplete block */
- char pad_len = MY_AES_BLOCK_SIZE - (source_length -
- MY_AES_BLOCK_SIZE * num_blocks);
- memcpy(block, source, 16 - pad_len);
- memset(block + MY_AES_BLOCK_SIZE - pad_len, pad_len, pad_len);
-
- enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) block,
- MY_AES_BLOCK_SIZE);
-
- return MY_AES_BLOCK_SIZE * (num_blocks + 1);
-#elif defined(HAVE_OPENSSL)
- if (! EVP_EncryptInit(&ctx.ctx, EVP_aes_128_ecb(),
- (const unsigned char *) rkey, NULL))
- return AES_BAD_DATA; /* Error */
- if (! EVP_EncryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len,
- (unsigned const char *) source, source_length))
- return AES_BAD_DATA; /* Error */
- if (! EVP_EncryptFinal(&ctx.ctx, (unsigned char *) dest + u_len, &f_len))
- return AES_BAD_DATA; /* Error */
-
- return u_len + f_len;
-#endif
-}
-
-
-/**
- DeCrypt buffer with AES encryption algorithm.
-
- SYNOPSIS
- my_aes_decrypt()
- @param source [in] Pointer to data for decryption
- @param source_length [in] Size of encrypted data
- @param dest [out] Buffer to place decrypted data (must
- be large enough)
- @param key [in] Key to be used for decryption
- @param key_length [in] Length of the key. Will handle keys of any length
-
- @return
- >= 0 Size of encrypted data
- < 0 Error
-*/
-
-int my_aes_decrypt(const uchar *source, int source_length, uchar *dest,
- const char *key, int key_length)
-{
-#if defined(HAVE_YASSL)
- TaoCrypt::AES_ECB_Decryption dec;
- /* 128 bit block used for padding */
- uint8 block[MY_AES_BLOCK_SIZE];
- int num_blocks; /* Number of complete blocks */
- int i;
-#elif defined(HAVE_OPENSSL)
- MyCipherCtx ctx;
- int u_len, f_len;
-#endif
-
- /* The real key to be used for decryption */
- uint8 rkey[AES_KEY_LENGTH / 8];
- int rc; /* Result codes */
-
- if ((rc= my_aes_create_key(key, key_length, rkey)))
- return rc;
-
-#if defined(HAVE_YASSL)
- dec.SetKey((const TaoCrypt::byte *) rkey, MY_AES_BLOCK_SIZE);
-
- num_blocks = source_length / MY_AES_BLOCK_SIZE;
-
- if ((source_length != num_blocks * MY_AES_BLOCK_SIZE) || num_blocks == 0 )
- /* Input size has to be even and at least one block */
- return AES_BAD_DATA;
-
- /* Decode all but last blocks */
- for (i = num_blocks - 1; i > 0; i--)
- {
- dec.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source,
- MY_AES_BLOCK_SIZE);
- source += MY_AES_BLOCK_SIZE;
- dest += MY_AES_BLOCK_SIZE;
- }
-
- dec.Process((TaoCrypt::byte *) block, (const TaoCrypt::byte *) source,
- MY_AES_BLOCK_SIZE);
-
- /* Use last char in the block as size */
- uint pad_len = (uint) (uchar) block[MY_AES_BLOCK_SIZE - 1];
-
- if (pad_len > MY_AES_BLOCK_SIZE)
- return AES_BAD_DATA;
- /* We could also check whole padding but we do not really need this */
-
- memcpy(dest, block, MY_AES_BLOCK_SIZE - pad_len);
- return MY_AES_BLOCK_SIZE * num_blocks - pad_len;
-#elif defined(HAVE_OPENSSL)
- if (! EVP_DecryptInit(&ctx.ctx, EVP_aes_128_ecb(),
- (const unsigned char *) rkey, NULL))
- return AES_BAD_DATA; /* Error */
- if (! EVP_DecryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len,
- (unsigned const char *) source, source_length))
- return AES_BAD_DATA; /* Error */
- if (! EVP_DecryptFinal(&ctx.ctx, (unsigned char *) dest + u_len, &f_len))
- return AES_BAD_DATA; /* Error */
- return u_len + f_len;
-#endif
-}
-
-
/**
Get size of buffer which will be large enough for encrypted data
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 32b6d6348ac..544284b2c0b 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -366,29 +366,48 @@ void Item_func_sha2::fix_length_and_dec()
}
/* Implementation of AES encryption routines */
+void Item_aes_crypt::create_key(String *user_key, uchar *real_key)
+{
+ uchar *real_key_end= real_key + AES_KEY_LENGTH / 8;
+ uchar *ptr;
+ const char *sptr= user_key->ptr();
+ const char *key_end= sptr + user_key->length();
+
+ bzero(real_key, AES_KEY_LENGTH / 8);
+
+ for (ptr= real_key; sptr < key_end; ptr++, sptr++)
+ {
+ if (ptr == real_key_end)
+ ptr= real_key;
+ *ptr ^= (uchar) *sptr;
+ }
+}
+
-String *Item_func_aes_encrypt::val_str(String *str)
+String *Item_aes_crypt::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- char key_buff[80];
- String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info);
- String *sptr= args[0]->val_str(str); // String to encrypt
- String *key= args[1]->val_str(&tmp_key_value); // key
- int aes_length;
- if (sptr && key) // we need both arguments to be not NULL
+ StringBuffer<80> user_key_buf;
+ String *sptr= args[0]->val_str(str);
+ String *user_key= args[1]->val_str(&user_key_buf);
+ uint32 aes_length;
+
+ if (sptr && user_key) // we need both arguments to be not NULL
{
null_value=0;
aes_length=my_aes_get_size(sptr->length()); // Calculate result length
if (!str_value.alloc(aes_length)) // Ensure that memory is free
{
- // finally encrypt directly to allocated buffer.
- if (my_aes_encrypt((const uchar*) sptr->ptr(), sptr->length(), (uchar*) str_value.ptr(),
- key->ptr(), key->length()) == aes_length)
+ uchar rkey[AES_KEY_LENGTH / 8];
+ create_key(user_key, rkey);
+
+ if (crypt((uchar*)sptr->ptr(), sptr->length(),
+ (uchar*)str_value.ptr(), &aes_length,
+ rkey, AES_KEY_LENGTH / 8, 0, 0, 0) == AES_OK)
{
- // We got the expected result length
- str_value.length((uint) aes_length);
- return &str_value;
+ str_value.length((uint) aes_length);
+ return &str_value;
}
}
}
@@ -396,43 +415,10 @@ String *Item_func_aes_encrypt::val_str(String *str)
return 0;
}
-
void Item_func_aes_encrypt::fix_length_and_dec()
{
max_length=my_aes_get_size(args[0]->max_length);
-}
-
-
-String *Item_func_aes_decrypt::val_str(String *str)
-{
- DBUG_ASSERT(fixed == 1);
- char key_buff[80];
- String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info);
- String *sptr, *key;
- DBUG_ENTER("Item_func_aes_decrypt::val_str");
-
- sptr= args[0]->val_str(str); // String to decrypt
- key= args[1]->val_str(&tmp_key_value); // Key
- if (sptr && key) // Need to have both arguments not NULL
- {
- null_value=0;
- if (!str_value.alloc(sptr->length())) // Ensure that memory is free
- {
- // finally decrypt directly to allocated buffer.
- int length;
- length=my_aes_decrypt((const uchar*)sptr->ptr(), sptr->length(),
- (uchar*) str_value.ptr(),
- key->ptr(), key->length());
- if (length >= 0) // if we got correct data data
- {
- str_value.length((uint) length);
- DBUG_RETURN(&str_value);
- }
- }
- }
- // Bad parameters. No memory or bad data will all go here
- null_value=1;
- DBUG_RETURN(0);
+ crypt= my_aes_encrypt_ecb;
}
@@ -440,6 +426,7 @@ void Item_func_aes_decrypt::fix_length_and_dec()
{
max_length=args[0]->max_length;
maybe_null= 1;
+ crypt= my_aes_decrypt_ecb;
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index b79009c6778..e11d2c41bc6 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -134,21 +134,33 @@ public:
const char *func_name() const { return "from_base64"; }
};
+#include <my_crypt.h>
-class Item_func_aes_encrypt :public Item_str_func
+class Item_aes_crypt :public Item_str_func
{
+ enum { AES_KEY_LENGTH = 128 };
+ void create_key(String *user_key, uchar* key);
+
+protected:
+ my_aes_encrypt_dynamic_type crypt;
+
public:
- Item_func_aes_encrypt(Item *a, Item *b) :Item_str_func(a,b) {}
+ Item_aes_crypt(Item *a, Item *b) :Item_str_func(a,b) {}
String *val_str(String *);
+};
+
+class Item_func_aes_encrypt :public Item_aes_crypt
+{
+public:
+ Item_func_aes_encrypt(Item *a, Item *b) :Item_aes_crypt(a,b) {}
void fix_length_and_dec();
const char *func_name() const { return "aes_encrypt"; }
};
-class Item_func_aes_decrypt :public Item_str_func
+class Item_func_aes_decrypt :public Item_aes_crypt
{
public:
- Item_func_aes_decrypt(Item *a, Item *b) :Item_str_func(a,b) {}
- String *val_str(String *);
+ Item_func_aes_decrypt(Item *a, Item *b) :Item_aes_crypt(a,b) {}
void fix_length_and_dec();
const char *func_name() const { return "aes_decrypt"; }
};