Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
b9375742
Commit
b9375742
authored
Mar 25, 2015
by
Sergei Golubchik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
remove old my_aes_encrypt/decrypt
and simplify Item_func_aes_encrypt/decrypt
parent
91f7363e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
51 additions
and
330 deletions
+51
-330
include/my_aes.h
include/my_aes.h
+0
-49
mysys_ssl/my_aes.cc
mysys_ssl/my_aes.cc
+0
-229
sql/item_strfunc.cc
sql/item_strfunc.cc
+34
-47
sql/item_strfunc.h
sql/item_strfunc.h
+17
-5
No files found.
include/my_aes.h
View file @
b9375742
...
...
@@ -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
...
...
mysys_ssl/my_aes.cc
View file @
b9375742
...
...
@@ -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
...
...
sql/item_strfunc.cc
View file @
b9375742
...
...
@@ -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_en
crypt
::
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
;
}
...
...
sql/item_strfunc.h
View file @
b9375742
...
...
@@ -134,21 +134,33 @@ class Item_func_from_base64 :public Item_str_func
const
char
*
func_name
()
const
{
return
"from_base64"
;
}
};
#include <my_crypt.h>
class
Item_
func_aes_en
crypt
:
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_en
crypt
(
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"
;
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment