mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-9069 extend AES_ENCRYPT() and AES_DECRYPT() to support IV and the algorithm
AES_ENCRYPT(str, key, [, iv [, mode ]]) AES_DECRYPT(str, key, [, iv [, mode ]]) mode is aes-{128,192,256}-{ecb,cbc,ctr} e.g. "aes-128-cbc". and a @@block_encryption_mode variable for the default value of mode change in behavior: AES_ENCRYPT(str, key) can no longer be used in persistent virtual columns (and alike)
This commit is contained in:
@ -5448,3 +5448,69 @@ Warning 1292 Truncated incorrect BINARY(2) value: '...random bytes...'
|
|||||||
#
|
#
|
||||||
# End of 10.10 tests
|
# End of 10.10 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# MDEV-9069 extend AES_ENCRYPT() and AES_DECRYPT() to support IV and the algorithm
|
||||||
|
#
|
||||||
|
select aes_encrypt('foo', 'bar', '1234') = aes_encrypt('foo', 'bar') `expected 1`;
|
||||||
|
expected 1
|
||||||
|
1
|
||||||
|
select aes_encrypt('foo', 'bar', NULL, 'aes-128-ecb') = aes_encrypt('foo', 'bar') `expected 1`;
|
||||||
|
expected 1
|
||||||
|
1
|
||||||
|
select aes_encrypt(1);
|
||||||
|
ERROR 42000: Incorrect parameter count in the call to native function 'aes_encrypt'
|
||||||
|
select aes_encrypt(1,2,3,4,5);
|
||||||
|
ERROR 42000: Incorrect parameter count in the call to native function 'aes_encrypt'
|
||||||
|
select aes_encrypt('foo', 'bar', '0123', 'something');
|
||||||
|
aes_encrypt('foo', 'bar', '0123', 'something')
|
||||||
|
NULL
|
||||||
|
select aes_encrypt('foo', 'bar', '0123', 'aes-111-ecb');
|
||||||
|
aes_encrypt('foo', 'bar', '0123', 'aes-111-ecb')
|
||||||
|
NULL
|
||||||
|
select aes_encrypt('foo', 'bar', '0123', 'aes-128-bar');
|
||||||
|
aes_encrypt('foo', 'bar', '0123', 'aes-128-bar')
|
||||||
|
NULL
|
||||||
|
select aes_encrypt('foo', 'bar', '0123', 'aes-128-cbc');
|
||||||
|
aes_encrypt('foo', 'bar', '0123', 'aes-128-cbc')
|
||||||
|
NULL
|
||||||
|
select hex(aes_encrypt('foo', 'bar', '0123456789abcdef', 'aes-256-cbc')) `x`;
|
||||||
|
x
|
||||||
|
42A3EB91E6DFC40A900D278F99E0726E
|
||||||
|
select aes_decrypt(x'42A3EB91E6DFC40A900D278F99E0726E', 'bar', '0123456789abcdef###', 'AES-256-CBC') `expected foo`;
|
||||||
|
expected foo
|
||||||
|
foo
|
||||||
|
select hex(aes_encrypt('foo', 'bar', '0123456789abcdef', 'aes-128-ctr')) `x`;
|
||||||
|
x
|
||||||
|
C57C4B
|
||||||
|
select aes_decrypt(x'C57C4B', 'bar', '0123456789abcdef', 'aes-128-ctr') `expected foo`;
|
||||||
|
expected foo
|
||||||
|
foo
|
||||||
|
set @@block_encryption_mode='aes-128-ctr';
|
||||||
|
select aes_decrypt(x'C57C4B', 'bar', '0123456789abcdef');
|
||||||
|
aes_decrypt(x'C57C4B', 'bar', '0123456789abcdef')
|
||||||
|
foo
|
||||||
|
set @@block_encryption_mode='aes-192-cbc';
|
||||||
|
select hex(aes_encrypt('foo', 'bar'));
|
||||||
|
hex(aes_encrypt('foo', 'bar'))
|
||||||
|
NULL
|
||||||
|
select hex(aes_encrypt('foo', 'bar', 'abcdefghabcdefgh'));
|
||||||
|
hex(aes_encrypt('foo', 'bar', 'abcdefghabcdefgh'))
|
||||||
|
9E6F76516B4DE68FED7A77632FC0913D
|
||||||
|
select aes_decrypt(x'9E6F76516B4DE68FED7A77632FC0913D', 'bar', 'abcdefghabcdefgh') `expected foo`;
|
||||||
|
expected foo
|
||||||
|
foo
|
||||||
|
select aes_decrypt(x'00000000000000011111111111111111', 'bar', 'abcdefghabcdefgh') `expected NULL`;
|
||||||
|
expected NULL
|
||||||
|
NULL
|
||||||
|
select aes_decrypt(x'9E6F76516B4DE68FED7A77632FC0913D', 'bar', '0000000011111111') `expected NULL`;
|
||||||
|
expected NULL
|
||||||
|
NULL
|
||||||
|
select aes_decrypt(x'9E6F76516B4DE68FED7A77632FC0913D', 'bar', 'abcdefghabcdefgh', 'aes-128-ecb') `expected NULL`;
|
||||||
|
expected NULL
|
||||||
|
NULL
|
||||||
|
select hex(aes_decrypt(x'9E6F76516B4DE68FED7A77632FC0913D', 'bar', 'abcdefghabcdefgh', 'aes-128-ctr')) `expected garbage`;
|
||||||
|
expected garbage
|
||||||
|
98D7BC3151620F384B0A953686AF37C9
|
||||||
|
#
|
||||||
|
# End of 11.2 tests
|
||||||
|
#
|
||||||
|
@ -2420,3 +2420,42 @@ select "a" in ("abc", (convert(random_bytes(8) ,binary(2))));
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.10 tests
|
--echo # End of 10.10 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-9069 extend AES_ENCRYPT() and AES_DECRYPT() to support IV and the algorithm
|
||||||
|
--echo #
|
||||||
|
select aes_encrypt('foo', 'bar', '1234') = aes_encrypt('foo', 'bar') `expected 1`;
|
||||||
|
select aes_encrypt('foo', 'bar', NULL, 'aes-128-ecb') = aes_encrypt('foo', 'bar') `expected 1`;
|
||||||
|
|
||||||
|
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
|
||||||
|
select aes_encrypt(1);
|
||||||
|
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
|
||||||
|
select aes_encrypt(1,2,3,4,5);
|
||||||
|
select aes_encrypt('foo', 'bar', '0123', 'something');
|
||||||
|
select aes_encrypt('foo', 'bar', '0123', 'aes-111-ecb');
|
||||||
|
select aes_encrypt('foo', 'bar', '0123', 'aes-128-bar');
|
||||||
|
select aes_encrypt('foo', 'bar', '0123', 'aes-128-cbc');
|
||||||
|
select hex(aes_encrypt('foo', 'bar', '0123456789abcdef', 'aes-256-cbc')) `x`;
|
||||||
|
select aes_decrypt(x'42A3EB91E6DFC40A900D278F99E0726E', 'bar', '0123456789abcdef###', 'AES-256-CBC') `expected foo`;
|
||||||
|
select hex(aes_encrypt('foo', 'bar', '0123456789abcdef', 'aes-128-ctr')) `x`;
|
||||||
|
select aes_decrypt(x'C57C4B', 'bar', '0123456789abcdef', 'aes-128-ctr') `expected foo`;
|
||||||
|
|
||||||
|
set @@block_encryption_mode='aes-128-ctr';
|
||||||
|
select aes_decrypt(x'C57C4B', 'bar', '0123456789abcdef');
|
||||||
|
set @@block_encryption_mode='aes-192-cbc';
|
||||||
|
select hex(aes_encrypt('foo', 'bar'));
|
||||||
|
select hex(aes_encrypt('foo', 'bar', 'abcdefghabcdefgh'));
|
||||||
|
select aes_decrypt(x'9E6F76516B4DE68FED7A77632FC0913D', 'bar', 'abcdefghabcdefgh') `expected foo`;
|
||||||
|
|
||||||
|
# wrong key
|
||||||
|
select aes_decrypt(x'00000000000000011111111111111111', 'bar', 'abcdefghabcdefgh') `expected NULL`;
|
||||||
|
# wrong iv
|
||||||
|
select aes_decrypt(x'9E6F76516B4DE68FED7A77632FC0913D', 'bar', '0000000011111111') `expected NULL`;
|
||||||
|
# wrong alg
|
||||||
|
select aes_decrypt(x'9E6F76516B4DE68FED7A77632FC0913D', 'bar', 'abcdefghabcdefgh', 'aes-128-ecb') `expected NULL`;
|
||||||
|
# but ctr doesn't use padding, so:
|
||||||
|
select hex(aes_decrypt(x'9E6F76516B4DE68FED7A77632FC0913D', 'bar', 'abcdefghabcdefgh', 'aes-128-ctr')) `expected garbage`;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 11.2 tests
|
||||||
|
--echo #
|
||||||
|
@ -136,6 +136,11 @@ The following specify which files/extra groups are read (specified before remain
|
|||||||
non-transactional engines for the binary log. If you
|
non-transactional engines for the binary log. If you
|
||||||
often use statements updating a great number of rows, you
|
often use statements updating a great number of rows, you
|
||||||
can increase this to get more performance.
|
can increase this to get more performance.
|
||||||
|
--block-encryption-mode=name
|
||||||
|
Default block encryption mode for AES_ENCRYPT() and
|
||||||
|
AES_DECRYPT() functions. One of: aes-128-ecb, aes-192-ecb,
|
||||||
|
aes-256-ecb, aes-128-cbc, aes-192-cbc, aes-256-cbc,
|
||||||
|
aes-128-ctr, aes-192-ctr, aes-256-ctr
|
||||||
--bootstrap Used by mysql installation scripts.
|
--bootstrap Used by mysql installation scripts.
|
||||||
--bulk-insert-buffer-size=#
|
--bulk-insert-buffer-size=#
|
||||||
Size of tree cache used in bulk insert optimisation. Note
|
Size of tree cache used in bulk insert optimisation. Note
|
||||||
@ -1570,6 +1575,7 @@ binlog-row-event-max-size 8192
|
|||||||
binlog-row-image FULL
|
binlog-row-image FULL
|
||||||
binlog-row-metadata NO_LOG
|
binlog-row-metadata NO_LOG
|
||||||
binlog-stmt-cache-size 32768
|
binlog-stmt-cache-size 32768
|
||||||
|
block-encryption-mode aes-128-ecb
|
||||||
bulk-insert-buffer-size 8388608
|
bulk-insert-buffer-size 8388608
|
||||||
character-set-client-handshake TRUE
|
character-set-client-handshake TRUE
|
||||||
character-set-collations
|
character-set-collations
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -472,6 +472,16 @@ NUMERIC_BLOCK_SIZE 4096
|
|||||||
ENUM_VALUE_LIST NULL
|
ENUM_VALUE_LIST NULL
|
||||||
READ_ONLY NO
|
READ_ONLY NO
|
||||||
COMMAND_LINE_ARGUMENT REQUIRED
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
|
VARIABLE_NAME BLOCK_ENCRYPTION_MODE
|
||||||
|
VARIABLE_SCOPE SESSION
|
||||||
|
VARIABLE_TYPE ENUM
|
||||||
|
VARIABLE_COMMENT Default block encryption mode for AES_ENCRYPT() and AES_DECRYPT() functions
|
||||||
|
NUMERIC_MIN_VALUE NULL
|
||||||
|
NUMERIC_MAX_VALUE NULL
|
||||||
|
NUMERIC_BLOCK_SIZE NULL
|
||||||
|
ENUM_VALUE_LIST aes-128-ecb,aes-192-ecb,aes-256-ecb,aes-128-cbc,aes-192-cbc,aes-256-cbc,aes-128-ctr,aes-192-ctr,aes-256-ctr
|
||||||
|
READ_ONLY NO
|
||||||
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
VARIABLE_NAME BULK_INSERT_BUFFER_SIZE
|
VARIABLE_NAME BULK_INSERT_BUFFER_SIZE
|
||||||
VARIABLE_SCOPE SESSION
|
VARIABLE_SCOPE SESSION
|
||||||
VARIABLE_TYPE BIGINT UNSIGNED
|
VARIABLE_TYPE BIGINT UNSIGNED
|
||||||
|
@ -512,6 +512,16 @@ NUMERIC_BLOCK_SIZE 4096
|
|||||||
ENUM_VALUE_LIST NULL
|
ENUM_VALUE_LIST NULL
|
||||||
READ_ONLY NO
|
READ_ONLY NO
|
||||||
COMMAND_LINE_ARGUMENT REQUIRED
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
|
VARIABLE_NAME BLOCK_ENCRYPTION_MODE
|
||||||
|
VARIABLE_SCOPE SESSION
|
||||||
|
VARIABLE_TYPE ENUM
|
||||||
|
VARIABLE_COMMENT Default block encryption mode for AES_ENCRYPT() and AES_DECRYPT() functions
|
||||||
|
NUMERIC_MIN_VALUE NULL
|
||||||
|
NUMERIC_MAX_VALUE NULL
|
||||||
|
NUMERIC_BLOCK_SIZE NULL
|
||||||
|
ENUM_VALUE_LIST aes-128-ecb,aes-192-ecb,aes-256-ecb,aes-128-cbc,aes-192-cbc,aes-256-cbc,aes-128-ctr,aes-192-ctr,aes-256-ctr
|
||||||
|
READ_ONLY NO
|
||||||
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
VARIABLE_NAME BULK_INSERT_BUFFER_SIZE
|
VARIABLE_NAME BULK_INSERT_BUFFER_SIZE
|
||||||
VARIABLE_SCOPE SESSION
|
VARIABLE_SCOPE SESSION
|
||||||
VARIABLE_TYPE BIGINT UNSIGNED
|
VARIABLE_TYPE BIGINT UNSIGNED
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
SET @@session.default_storage_engine = 'MyISAM';
|
SET @@session.default_storage_engine = 'MyISAM';
|
||||||
|
# AES_ENCRYPT() without the mode (4th argument)
|
||||||
|
create or replace table t1 (b blob as (aes_encrypt('abc', 'bcd')) PERSISTENT);
|
||||||
|
ERROR HY000: Function or expression 'aes_encrypt()' cannot be used in the GENERATED ALWAYS AS clause of `b`
|
||||||
|
create or replace table t1 (b blob as (aes_encrypt('abc', 'bcd','def')) PERSISTENT);
|
||||||
|
ERROR HY000: Function or expression 'aes_encrypt()' cannot be used in the GENERATED ALWAYS AS clause of `b`
|
||||||
|
create or replace table t1 (b blob as (aes_decrypt('abc', 'bcd')) PERSISTENT);
|
||||||
|
ERROR HY000: Function or expression 'aes_decrypt()' cannot be used in the GENERATED ALWAYS AS clause of `b`
|
||||||
|
create or replace table t1 (b blob as (aes_decrypt('abc', 'bcd','def')) PERSISTENT);
|
||||||
|
ERROR HY000: Function or expression 'aes_decrypt()' cannot be used in the GENERATED ALWAYS AS clause of `b`
|
||||||
# RAND()
|
# RAND()
|
||||||
create or replace table t1 (b double as (rand()));
|
create or replace table t1 (b double as (rand()));
|
||||||
create or replace table t1 (b double as (rand()) PERSISTENT);
|
create or replace table t1 (b double as (rand()) PERSISTENT);
|
||||||
|
@ -19,6 +19,16 @@
|
|||||||
# to check for things that should not work for either VIRTUAL or PERSISTENT
|
# to check for things that should not work for either VIRTUAL or PERSISTENT
|
||||||
#
|
#
|
||||||
|
|
||||||
|
--echo # AES_ENCRYPT() without the mode (4th argument)
|
||||||
|
-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
||||||
|
create or replace table t1 (b blob as (aes_encrypt('abc', 'bcd')) PERSISTENT);
|
||||||
|
-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
||||||
|
create or replace table t1 (b blob as (aes_encrypt('abc', 'bcd','def')) PERSISTENT);
|
||||||
|
-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
||||||
|
create or replace table t1 (b blob as (aes_decrypt('abc', 'bcd')) PERSISTENT);
|
||||||
|
-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
||||||
|
create or replace table t1 (b blob as (aes_decrypt('abc', 'bcd','def')) PERSISTENT);
|
||||||
|
|
||||||
--echo # RAND()
|
--echo # RAND()
|
||||||
create or replace table t1 (b double as (rand()));
|
create or replace table t1 (b double as (rand()));
|
||||||
-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
||||||
|
@ -141,10 +141,11 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Create_func_aes_encrypt : public Create_func_arg2
|
class Create_func_aes_encrypt : public Create_native_func
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
|
virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
|
||||||
|
List<Item> *item_list);
|
||||||
|
|
||||||
static Create_func_aes_encrypt s_singleton;
|
static Create_func_aes_encrypt s_singleton;
|
||||||
|
|
||||||
@ -154,10 +155,11 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Create_func_aes_decrypt : public Create_func_arg2
|
class Create_func_aes_decrypt : public Create_native_func
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
|
virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
|
||||||
|
List<Item> *item_list);
|
||||||
|
|
||||||
static Create_func_aes_decrypt s_singleton;
|
static Create_func_aes_decrypt s_singleton;
|
||||||
|
|
||||||
@ -2953,18 +2955,48 @@ Create_func_addtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
|
|||||||
Create_func_aes_encrypt Create_func_aes_encrypt::s_singleton;
|
Create_func_aes_encrypt Create_func_aes_encrypt::s_singleton;
|
||||||
|
|
||||||
Item*
|
Item*
|
||||||
Create_func_aes_encrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
|
Create_func_aes_encrypt::create_native(THD *thd, const LEX_CSTRING *name,
|
||||||
|
List<Item> *item_list)
|
||||||
{
|
{
|
||||||
return new (thd->mem_root) Item_func_aes_encrypt(thd, arg1, arg2);
|
uint arg_count= item_list->elements;
|
||||||
|
Item *a[4];
|
||||||
|
for (uint i=0; i < MY_MIN(array_elements(a), arg_count); i++)
|
||||||
|
a[i]= item_list->pop();
|
||||||
|
switch (arg_count)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
return new (thd->mem_root) Item_func_aes_encrypt(thd, a[0], a[1]);
|
||||||
|
case 3:
|
||||||
|
return new (thd->mem_root) Item_func_aes_encrypt(thd, a[0], a[1], a[2]);
|
||||||
|
case 4:
|
||||||
|
return new (thd->mem_root) Item_func_aes_encrypt(thd, a[0], a[1], a[2], a[3]);
|
||||||
|
}
|
||||||
|
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Create_func_aes_decrypt Create_func_aes_decrypt::s_singleton;
|
Create_func_aes_decrypt Create_func_aes_decrypt::s_singleton;
|
||||||
|
|
||||||
Item*
|
Item*
|
||||||
Create_func_aes_decrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
|
Create_func_aes_decrypt::create_native(THD *thd, const LEX_CSTRING *name,
|
||||||
|
List<Item> *item_list)
|
||||||
{
|
{
|
||||||
return new (thd->mem_root) Item_func_aes_decrypt(thd, arg1, arg2);
|
uint arg_count= item_list->elements;
|
||||||
|
Item *a[4];
|
||||||
|
for (uint i=0; i < MY_MIN(array_elements(a), arg_count); i++)
|
||||||
|
a[i]= item_list->pop();
|
||||||
|
switch (arg_count)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
return new (thd->mem_root) Item_func_aes_decrypt(thd, a[0], a[1]);
|
||||||
|
case 3:
|
||||||
|
return new (thd->mem_root) Item_func_aes_decrypt(thd, a[0], a[1], a[2]);
|
||||||
|
case 4:
|
||||||
|
return new (thd->mem_root) Item_func_aes_decrypt(thd, a[0], a[1], a[2], a[3]);
|
||||||
|
}
|
||||||
|
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ C_MODE_END
|
|||||||
#include "sql_show.h" // append_identifier
|
#include "sql_show.h" // append_identifier
|
||||||
#include <sql_repl.h>
|
#include <sql_repl.h>
|
||||||
#include "sql_statistics.h"
|
#include "sql_statistics.h"
|
||||||
|
#include "strfunc.h"
|
||||||
|
|
||||||
/* fmtlib include (https://fmt.dev/). */
|
/* fmtlib include (https://fmt.dev/). */
|
||||||
#define FMT_STATIC_THOUSANDS_SEPARATOR ','
|
#define FMT_STATIC_THOUSANDS_SEPARATOR ','
|
||||||
@ -309,24 +310,54 @@ bool Item_func_sha2::fix_length_and_dec(THD *thd)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
push_warning_printf(thd,
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||||
Sql_condition::WARN_LEVEL_WARN,
|
|
||||||
ER_WRONG_PARAMETERS_TO_NATIVE_FCT,
|
ER_WRONG_PARAMETERS_TO_NATIVE_FCT,
|
||||||
ER_THD(thd, ER_WRONG_PARAMETERS_TO_NATIVE_FCT),
|
ER_THD(thd, ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2");
|
||||||
"sha2");
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *block_encryption_mode_values[]= {
|
||||||
|
"aes-128-ecb", "aes-192-ecb", "aes-256-ecb",
|
||||||
|
"aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
|
||||||
|
"aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
|
||||||
|
NullS };
|
||||||
|
TYPELIB block_encryption_mode_typelib= {9, 0, block_encryption_mode_values, 0};
|
||||||
|
static inline uint block_encryption_mode_to_key_length(ulong bem)
|
||||||
|
{ return (bem % 3 + 2) * 64; }
|
||||||
|
static inline my_aes_mode block_encryption_mode_to_aes_mode(ulong bem)
|
||||||
|
{ return (my_aes_mode)(bem / 3); }
|
||||||
|
|
||||||
/* Implementation of AES encryption routines */
|
/* Implementation of AES encryption routines */
|
||||||
|
int Item_aes_crypt::parse_mode()
|
||||||
|
{
|
||||||
|
StringBuffer<80> buf;
|
||||||
|
String *ptr= args[3]->val_str_ascii(&buf);
|
||||||
|
ulong bem;
|
||||||
|
|
||||||
|
if (ptr == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
bem= find_type(&block_encryption_mode_typelib, ptr->ptr(), ptr->length(), 0);
|
||||||
|
if (!bem)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
aes_key_length= block_encryption_mode_to_key_length(bem - 1);
|
||||||
|
aes_mode= block_encryption_mode_to_aes_mode(bem - 1);
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_aes_crypt::create_key(String *user_key, uchar *real_key)
|
void Item_aes_crypt::create_key(String *user_key, uchar *real_key)
|
||||||
{
|
{
|
||||||
uchar *real_key_end= real_key + AES_KEY_LENGTH / 8;
|
uchar *real_key_end= real_key + aes_key_length / 8;
|
||||||
uchar *ptr;
|
uchar *ptr;
|
||||||
const char *sptr= user_key->ptr();
|
const char *sptr= user_key->ptr();
|
||||||
const char *key_end= sptr + user_key->length();
|
const char *key_end= sptr + user_key->length();
|
||||||
|
|
||||||
bzero(real_key, AES_KEY_LENGTH / 8);
|
bzero(real_key, aes_key_length / 8);
|
||||||
|
|
||||||
for (ptr= real_key; sptr < key_end; ptr++, sptr++)
|
for (ptr= real_key; sptr < key_end; ptr++, sptr++)
|
||||||
{
|
{
|
||||||
@ -340,24 +371,36 @@ void Item_aes_crypt::create_key(String *user_key, uchar *real_key)
|
|||||||
String *Item_aes_crypt::val_str(String *str2)
|
String *Item_aes_crypt::val_str(String *str2)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed());
|
DBUG_ASSERT(fixed());
|
||||||
StringBuffer<80> user_key_buf;
|
StringBuffer<80> user_key_buf, iv_buf;
|
||||||
String *sptr= args[0]->val_str(&tmp_value);
|
String *sptr= args[0]->val_str(&tmp_value);
|
||||||
String *user_key= args[1]->val_str(&user_key_buf);
|
String *user_key= args[1]->val_str(&user_key_buf);
|
||||||
|
String *iv= NULL;
|
||||||
uint32 aes_length;
|
uint32 aes_length;
|
||||||
|
|
||||||
if (sptr && user_key) // we need both arguments to be not NULL
|
if (sptr && user_key) // we need both arguments to be not NULL
|
||||||
{
|
{
|
||||||
null_value=0;
|
if (arg_count > 3 && (null_value= parse_mode()))
|
||||||
aes_length=my_aes_get_size(MY_AES_ECB, sptr->length());
|
return 0;
|
||||||
|
|
||||||
|
if (aes_mode != MY_AES_ECB)
|
||||||
|
{
|
||||||
|
if (arg_count > 2)
|
||||||
|
iv= args[2]->val_str(&iv_buf);
|
||||||
|
if ((null_value= (!iv || iv->length() < MY_AES_BLOCK_SIZE)))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
aes_length=my_aes_get_size(aes_mode, sptr->length());
|
||||||
|
|
||||||
if (!str2->alloc(aes_length)) // Ensure that memory is free
|
if (!str2->alloc(aes_length)) // Ensure that memory is free
|
||||||
{
|
{
|
||||||
uchar rkey[AES_KEY_LENGTH / 8];
|
uchar *rkey= (uchar*)alloca(aes_key_length / 8);
|
||||||
create_key(user_key, rkey);
|
create_key(user_key, rkey);
|
||||||
|
|
||||||
if (!my_aes_crypt(MY_AES_ECB, what, (uchar*)sptr->ptr(), sptr->length(),
|
if (!my_aes_crypt(aes_mode, what, (uchar*)sptr->ptr(), sptr->length(),
|
||||||
(uchar*)str2->ptr(), &aes_length,
|
(uchar*)str2->ptr(), &aes_length,
|
||||||
rkey, AES_KEY_LENGTH / 8, 0, 0))
|
rkey, aes_key_length / 8,
|
||||||
|
iv ? (uchar*)iv->ptr() : 0, iv ? iv->length() : 0))
|
||||||
{
|
{
|
||||||
str2->length((uint) aes_length);
|
str2->length((uint) aes_length);
|
||||||
DBUG_ASSERT(collation.collation == &my_charset_bin);
|
DBUG_ASSERT(collation.collation == &my_charset_bin);
|
||||||
@ -370,20 +413,23 @@ String *Item_aes_crypt::val_str(String *str2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Item_aes_crypt::fix_fields(THD *thd, Item **ref)
|
||||||
|
{
|
||||||
|
aes_key_length= block_encryption_mode_to_key_length(thd->variables.block_encryption_mode);
|
||||||
|
aes_mode= block_encryption_mode_to_aes_mode(thd->variables.block_encryption_mode);
|
||||||
|
return Item_str_binary_checksum_func::fix_fields(thd, ref);
|
||||||
|
}
|
||||||
|
|
||||||
bool Item_func_aes_encrypt::fix_length_and_dec(THD *thd)
|
bool Item_func_aes_encrypt::fix_length_and_dec(THD *thd)
|
||||||
{
|
{
|
||||||
max_length=my_aes_get_size(MY_AES_ECB, args[0]->max_length);
|
max_length=my_aes_get_size(MY_AES_ECB, args[0]->max_length);
|
||||||
what= ENCRYPTION_FLAG_ENCRYPT;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_aes_decrypt::fix_length_and_dec(THD *thd)
|
bool Item_func_aes_decrypt::fix_length_and_dec(THD *thd)
|
||||||
{
|
{
|
||||||
max_length=args[0]->max_length;
|
max_length=args[0]->max_length;
|
||||||
set_maybe_null();
|
set_maybe_null();
|
||||||
what= ENCRYPTION_FLAG_DECRYPT;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +129,10 @@ public:
|
|||||||
:Item_str_func(thd, a) { }
|
:Item_str_func(thd, a) { }
|
||||||
Item_str_binary_checksum_func(THD *thd, Item *a, Item *b)
|
Item_str_binary_checksum_func(THD *thd, Item *a, Item *b)
|
||||||
:Item_str_func(thd, a, b) { }
|
:Item_str_func(thd, a, b) { }
|
||||||
|
Item_str_binary_checksum_func(THD *thd, Item *a, Item *b, Item *c)
|
||||||
|
:Item_str_func(thd, a, b, c) { }
|
||||||
|
Item_str_binary_checksum_func(THD *thd, Item *a, Item *b, Item *c, Item *d)
|
||||||
|
:Item_str_func(thd, a, b, c, d) { }
|
||||||
bool eq(const Item *item, bool binary_cmp) const
|
bool eq(const Item *item, bool binary_cmp) const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -229,23 +233,39 @@ public:
|
|||||||
|
|
||||||
class Item_aes_crypt :public Item_str_binary_checksum_func
|
class Item_aes_crypt :public Item_str_binary_checksum_func
|
||||||
{
|
{
|
||||||
enum { AES_KEY_LENGTH = 128 };
|
|
||||||
void create_key(String *user_key, uchar* key);
|
void create_key(String *user_key, uchar* key);
|
||||||
|
int parse_mode();
|
||||||
protected:
|
|
||||||
int what;
|
|
||||||
String tmp_value;
|
String tmp_value;
|
||||||
|
const int what;
|
||||||
|
uint aes_key_length;
|
||||||
|
enum my_aes_mode aes_mode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item_aes_crypt(THD *thd, Item *a, Item *b)
|
Item_aes_crypt(THD *thd, int what, Item *a, Item *b)
|
||||||
:Item_str_binary_checksum_func(thd, a, b) {}
|
: Item_str_binary_checksum_func(thd, a, b), what(what) {}
|
||||||
String *val_str(String *);
|
Item_aes_crypt(THD *thd, int what, Item *a, Item *b, Item *c)
|
||||||
|
: Item_str_binary_checksum_func(thd, a, b, c), what(what) {}
|
||||||
|
Item_aes_crypt(THD *thd, int what, Item *a, Item *b, Item *c, Item *d)
|
||||||
|
: Item_str_binary_checksum_func(thd, a, b, c, d), what(what) {}
|
||||||
|
bool fix_fields(THD *thd, Item **ref) override;
|
||||||
|
String *val_str(String *) override;
|
||||||
|
bool check_vcol_func_processor(void *arg) override
|
||||||
|
{
|
||||||
|
if (arg_count > 3)
|
||||||
|
return FALSE;
|
||||||
|
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_func_aes_encrypt :public Item_aes_crypt
|
class Item_func_aes_encrypt :public Item_aes_crypt
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Item_func_aes_encrypt(THD *thd, Item *a, Item *b)
|
Item_func_aes_encrypt(THD *thd, Item *a, Item *b)
|
||||||
:Item_aes_crypt(thd, a, b) {}
|
:Item_aes_crypt(thd, ENCRYPTION_FLAG_ENCRYPT, a, b) {}
|
||||||
|
Item_func_aes_encrypt(THD *thd, Item *a, Item *b, Item *c)
|
||||||
|
:Item_aes_crypt(thd, ENCRYPTION_FLAG_ENCRYPT, a, b, c) {}
|
||||||
|
Item_func_aes_encrypt(THD *thd, Item *a, Item *b, Item *c, Item *d)
|
||||||
|
:Item_aes_crypt(thd, ENCRYPTION_FLAG_ENCRYPT, a, b, c, d) {}
|
||||||
bool fix_length_and_dec(THD *thd) override;
|
bool fix_length_and_dec(THD *thd) override;
|
||||||
LEX_CSTRING func_name_cstring() const override
|
LEX_CSTRING func_name_cstring() const override
|
||||||
{
|
{
|
||||||
@ -260,7 +280,11 @@ class Item_func_aes_decrypt :public Item_aes_crypt
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Item_func_aes_decrypt(THD *thd, Item *a, Item *b):
|
Item_func_aes_decrypt(THD *thd, Item *a, Item *b):
|
||||||
Item_aes_crypt(thd, a, b) {}
|
Item_aes_crypt(thd, ENCRYPTION_FLAG_DECRYPT, a, b) {}
|
||||||
|
Item_func_aes_decrypt(THD *thd, Item *a, Item *b, Item *c):
|
||||||
|
Item_aes_crypt(thd, ENCRYPTION_FLAG_DECRYPT, a, b, c) {}
|
||||||
|
Item_func_aes_decrypt(THD *thd, Item *a, Item *b, Item *c, Item *d):
|
||||||
|
Item_aes_crypt(thd, ENCRYPTION_FLAG_DECRYPT, a, b, c, d) {}
|
||||||
bool fix_length_and_dec(THD *thd) override;
|
bool fix_length_and_dec(THD *thd) override;
|
||||||
LEX_CSTRING func_name_cstring() const override
|
LEX_CSTRING func_name_cstring() const override
|
||||||
{
|
{
|
||||||
|
@ -781,6 +781,7 @@ typedef struct system_variables
|
|||||||
ulong trans_alloc_block_size;
|
ulong trans_alloc_block_size;
|
||||||
ulong trans_prealloc_size;
|
ulong trans_prealloc_size;
|
||||||
ulong log_warnings;
|
ulong log_warnings;
|
||||||
|
ulong block_encryption_mode;
|
||||||
/* Flags for slow log filtering */
|
/* Flags for slow log filtering */
|
||||||
ulong log_slow_rate_limit;
|
ulong log_slow_rate_limit;
|
||||||
ulong binlog_format; ///< binlog format for this thd (see enum_binlog_format)
|
ulong binlog_format; ///< binlog format for this thd (see enum_binlog_format)
|
||||||
|
@ -7174,3 +7174,10 @@ static Sys_var_optimizer_cost Sys_optimizer_scan_cost(
|
|||||||
CMD_LINE(REQUIRED_ARG),
|
CMD_LINE(REQUIRED_ARG),
|
||||||
VALID_RANGE(0, 100000000), DEFAULT(DEFAULT_TABLE_SCAN_SETUP_COST),
|
VALID_RANGE(0, 100000000), DEFAULT(DEFAULT_TABLE_SCAN_SETUP_COST),
|
||||||
COST_ADJUST(1000));
|
COST_ADJUST(1000));
|
||||||
|
|
||||||
|
extern const char *block_encryption_mode_values[];
|
||||||
|
static Sys_var_enum Sys_block_encryption_mode(
|
||||||
|
"block_encryption_mode", "Default block encryption mode for "
|
||||||
|
"AES_ENCRYPT() and AES_DECRYPT() functions",
|
||||||
|
SESSION_VAR(block_encryption_mode), CMD_LINE(REQUIRED_ARG),
|
||||||
|
block_encryption_mode_values, DEFAULT(0));
|
||||||
|
Reference in New Issue
Block a user