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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
2f8d101f
Commit
2f8d101f
authored
Mar 24, 2015
by
Sergei Golubchik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
unify my_{en|de}crypt_{cbc|ecb|ctr}. no yassl support yet.
parent
27cc252b
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
140 additions
and
570 deletions
+140
-570
include/my_crypt.h
include/my_crypt.h
+42
-11
mysys_ssl/my_aes.cc
mysys_ssl/my_aes.cc
+0
-530
mysys_ssl/my_crypt.cc
mysys_ssl/my_crypt.cc
+96
-29
storage/innobase/fil/fil0crypt.cc
storage/innobase/fil/fil0crypt.cc
+1
-0
storage/xtradb/fil/fil0crypt.cc
storage/xtradb/fil/fil0crypt.cc
+1
-0
No files found.
include/my_crypt.h
View file @
2f8d101f
/*
Copyright (c) 2014 Google Inc.
Copyright (c) 2014, 2015 MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
// TODO: Add Windows support
#ifndef MYSYS_MY_CRYPT_H_
...
...
@@ -12,24 +29,38 @@ Crypt_result my_aes_encrypt_ctr(const uchar* source, uint32 source_length,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
no
P
adding
);
uint
no
_p
adding
);
Crypt_result
my_aes_decrypt_ctr
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
noPadding
);
C_MODE_END
uint
no_padding
);
Crypt_result
my_aes_encrypt_cbc
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
no_padding
);
Crypt_result
my_aes_decrypt_cbc
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
no_padding
);
Crypt_result
EncryptAes128Ctr
(
const
uchar
*
key
,
const
uchar
*
iv
,
int
iv_size
,
const
uchar
*
plaintext
,
int
plaintext_size
,
uchar
*
ciphertext
,
int
*
ciphertext_used
);
Crypt_result
my_aes_encrypt_ecb
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
no_padding
);
Crypt_result
DecryptAes128Ctr
(
const
uchar
*
key
,
const
uchar
*
iv
,
int
iv_size
,
const
uchar
*
ciphertext
,
int
ciphertext_size
,
uchar
*
plaintext
,
int
*
plaintext_used
);
Crypt_result
my_aes_decrypt_ecb
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
no_padding
);
C_MODE_END
#endif
/* !defined(HAVE_YASSL) && defined(HAVE_OPENSSL) */
...
...
mysys_ssl/my_aes.cc
View file @
2f8d101f
...
...
@@ -100,536 +100,6 @@ static int my_aes_create_key(const char *key, int key_length, uint8 *rkey)
return
0
;
}
/**
Crypt buffer with AES CBC encryption algorithm.
SYNOPSIS
my_aes_encrypt_cbc()
@param source [in] Pointer to data for encryption
@param source_length [in] Size of encryption data
@param dest [out] Buffer to place encrypted data (must be large enough)
@param dest_length [out] Pointer to size of encrypted data
@param key [in] Key to be used for encryption
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
@param noPadding [in] if set to true, no padding is used. if the input length is not a
multiple of the AES block size, trailing bytes are only copied to destination buffer.
This allows currently the same interface for CBC, ECB and CTR encryption.
@return
!= 0 error
0 no error
*/
static
int
my_aes_encrypt_cbc
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
noPadding
)
{
uint8
remaining_bytes
=
(
noPadding
==
0
)
?
0
:
source_length
%
MY_AES_BLOCK_SIZE
;
source_length
=
source_length
-
remaining_bytes
;
#ifdef HAVE_YASSL
TaoCrypt
::
AES_CBC_Encryption
enc
;
/* 128 bit block used for padding */
uint8
block
[
MY_AES_BLOCK_SIZE
];
int
num_blocks
;
/* number of complete blocks */
int
i
;
switch
(
key_length
)
{
case
16
:
break
;
case
24
:
break
;
case
32
:
break
;
default:
return
AES_BAD_KEYSIZE
;
}
enc
.
SetKey
((
const
TaoCrypt
::
byte
*
)
key
,
key_length
,
(
const
TaoCrypt
::
byte
*
)
iv
);
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
;
}
if
(
noPadding
)
{
if
(
remaining_bytes
!=
0
)
{
/* Note that we moved the original pointers above */
memcpy
(
dest
,
source
,
remaining_bytes
);
}
*
dest_length
=
MY_AES_BLOCK_SIZE
*
(
num_blocks
)
+
remaining_bytes
;
return
AES_OK
;
}
/* 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
);
*
dest_length
=
MY_AES_BLOCK_SIZE
*
(
num_blocks
+
1
);
return
AES_OK
;
#elif defined(HAVE_OPENSSL)
MyCipherCtx
ctx
;
int
u_len
,
f_len
;
/* The real key to be used for encryption */
const
EVP_CIPHER
*
cipher
;
switch
(
key_length
)
{
case
16
:
cipher
=
EVP_aes_128_cbc
();
break
;
case
24
:
cipher
=
EVP_aes_192_cbc
();
break
;
case
32
:
cipher
=
EVP_aes_256_cbc
();
break
;
default:
return
AES_BAD_KEYSIZE
;
}
//Initialize Encryption Engine here, default software Engine is default
ENGINE
*
engine
=
NULL
;
if
(
!
EVP_EncryptInit_ex
(
&
ctx
.
ctx
,
cipher
,
engine
,
key
,
iv
))
return
AES_BAD_DATA
;
/* Error */
if
(
noPadding
)
{
EVP_CIPHER_CTX_set_padding
(
&
ctx
.
ctx
,
0
);
}
EVP_CIPHER_CTX_key_length
(
&
ctx
.
ctx
);
OPENSSL_assert
(
EVP_CIPHER_CTX_key_length
(
&
ctx
.
ctx
)
==
key_length
);
OPENSSL_assert
(
EVP_CIPHER_CTX_iv_length
(
&
ctx
.
ctx
)
==
iv_length
);
OPENSSL_assert
(
EVP_CIPHER_CTX_block_size
(
&
ctx
.
ctx
)
==
16
);
if
(
!
EVP_EncryptUpdate
(
&
ctx
.
ctx
,
(
unsigned
char
*
)
dest
,
&
u_len
,
(
unsigned
const
char
*
)
source
,
source_length
))
return
AES_BAD_DATA
;
/* Error */
if
(
!
EVP_EncryptFinal_ex
(
&
ctx
.
ctx
,
(
unsigned
char
*
)
dest
+
u_len
,
&
f_len
))
return
AES_BAD_DATA
;
/* Error */
if
(
remaining_bytes
!=
0
)
{
memcpy
(
dest
+
source_length
,
source
+
source_length
,
remaining_bytes
);
}
*
dest_length
=
(
unsigned
long
int
)
(
u_len
+
f_len
+
remaining_bytes
);
return
AES_OK
;
#else
/* currently Open SSL is required */
return
AES_BAD_DATA
;
#endif
}
/**
Crypt buffer with AES ECB encryption algorithm.
SYNOPSIS
my_aes_encrypt_ecb()
@param source [in] Pointer to data for encryption
@param source_length [in] Size of encryption data
@param dest [out] Buffer to place encrypted data (must be large enough)
@param dest_length [out] Pointer to size of encrypted data
@param key [in] Key to be used for encryption
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
@param noPadding [in] if set to true, no padding is used. if the input length is not a
multiple of the AES block size, trailing bytes are only copied to destination buffer.
This allows currently the same interface for CBC, ECB and CTR encryption.
@return
!= 0 error
0 no error
*/
static
int
my_aes_encrypt_ecb
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
noPadding
)
{
uint8
remaining_bytes
=
(
noPadding
==
0
)
?
0
:
source_length
%
MY_AES_BLOCK_SIZE
;
source_length
=
source_length
-
remaining_bytes
;
#ifdef 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
;
switch
(
key_length
)
{
case
16
:
break
;
case
24
:
break
;
case
32
:
break
;
default:
return
AES_BAD_KEYSIZE
;
}
enc
.
SetKey
((
const
TaoCrypt
::
byte
*
)
key
,
key_length
,
(
const
TaoCrypt
::
byte
*
)
iv
);
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
;
}
if
(
noPadding
)
{
if
(
remaining_bytes
!=
0
)
{
/* Note that we moved the original pointers above */
memcpy
(
dest
,
source
,
remaining_bytes
);
}
*
dest_length
=
MY_AES_BLOCK_SIZE
*
(
num_blocks
)
+
remaining_bytes
;
return
AES_OK
;
}
/* 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
);
*
dest_length
=
MY_AES_BLOCK_SIZE
*
(
num_blocks
+
1
);
return
AES_OK
;
#elif defined(HAVE_OPENSSL)
MyCipherCtx
ctx
;
int
u_len
,
f_len
;
/* The real key to be used for encryption */
const
EVP_CIPHER
*
cipher
;
switch
(
key_length
)
{
case
16
:
cipher
=
EVP_aes_128_ecb
();
break
;
case
24
:
cipher
=
EVP_aes_192_ecb
();
break
;
case
32
:
cipher
=
EVP_aes_256_ecb
();
break
;
default:
return
AES_BAD_KEYSIZE
;
}
//Initialize Encryption Engine here, default software Engine is default
ENGINE
*
engine
=
NULL
;
if
(
!
EVP_EncryptInit_ex
(
&
ctx
.
ctx
,
cipher
,
engine
,
key
,
iv
))
return
AES_BAD_DATA
;
/* Error */
if
(
noPadding
)
{
EVP_CIPHER_CTX_set_padding
(
&
ctx
.
ctx
,
0
);
}
EVP_CIPHER_CTX_key_length
(
&
ctx
.
ctx
);
OPENSSL_assert
(
EVP_CIPHER_CTX_key_length
(
&
ctx
.
ctx
)
==
key_length
);
// ECB does not use IV
OPENSSL_assert
(
EVP_CIPHER_CTX_iv_length
(
&
ctx
.
ctx
)
==
0
);
OPENSSL_assert
(
EVP_CIPHER_CTX_block_size
(
&
ctx
.
ctx
)
==
16
);
if
(
!
EVP_EncryptUpdate
(
&
ctx
.
ctx
,
(
unsigned
char
*
)
dest
,
&
u_len
,
(
unsigned
const
char
*
)
source
,
source_length
))
return
AES_BAD_DATA
;
/* Error */
if
(
!
EVP_EncryptFinal_ex
(
&
ctx
.
ctx
,
(
unsigned
char
*
)
dest
+
u_len
,
&
f_len
))
return
AES_BAD_DATA
;
/* Error */
if
(
remaining_bytes
!=
0
)
memcpy
(
dest
+
source_length
,
source
+
source_length
,
remaining_bytes
);
*
dest_length
=
(
unsigned
long
int
)
(
u_len
+
f_len
+
remaining_bytes
);
return
AES_OK
;
#else
/* currently Open SSL is required */
return
AES_BAD_DATA
;
#endif
}
/**
AES decryption - CBC mode
SYNOPSIS
my_aes_decrypt_cbc()
@param source [in] Pointer to data to decrypt
@param source_length [in] Size of data
@param dest [out] Buffer to place decrypted data (must be large enough)
@param dest_length [out] Pointer to size of decrypted data
@param key [in] Key to be used for decryption
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
@param noPadding [in] if set to true, no padding is used. if the input length is not a
multiple of the AES block size, trailing bytes are only copied to destination buffer.
This allows currently the same interface for CBC, ECB and CTR encryption.
@return
!= 0 error
0 no error
*/
static
int
my_aes_decrypt_cbc
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
noPadding
)
{
uint8
remaining_bytes
=
(
noPadding
==
0
)
?
0
:
source_length
%
MY_AES_BLOCK_SIZE
;
source_length
=
source_length
-
remaining_bytes
;
#ifdef HAVE_YASSL
TaoCrypt
::
AES_CBC_Decryption
dec
;
/* 128 bit block used for padding */
uint8
block
[
MY_AES_BLOCK_SIZE
];
uint
num_blocks
;
/* Number of complete blocks */
int
i
;
switch
(
key_length
)
{
case
16
:
break
;
case
24
:
break
;
case
32
:
break
;
default:
return
AES_BAD_KEYSIZE
;
}
dec
.
SetKey
((
const
TaoCrypt
::
byte
*
)
key
,
key_length
,
iv
);
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
);
if
(
noPadding
)
{
memcpy
(
dest
,
block
,
MY_AES_BLOCK_SIZE
);
if
(
remaining_bytes
!=
0
)
{
/* Note that we have moved dest and source */
memcpy
(
dest
+
MY_AES_BLOCK_SIZE
,
source
+
MY_AES_BLOCK_SIZE
,
remaining_bytes
);
}
*
dest_length
=
MY_AES_BLOCK_SIZE
*
num_blocks
+
remaining_bytes
;
return
AES_OK
;
}
/* 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
);
*
dest_length
=
MY_AES_BLOCK_SIZE
*
num_blocks
-
pad_len
;
return
AES_OK
;
#elif defined(HAVE_OPENSSL)
MyCipherCtx
ctx
;
int
u_len
,
f_len
;
const
EVP_CIPHER
*
cipher
;
switch
(
key_length
)
{
case
16
:
cipher
=
EVP_aes_128_cbc
();
break
;
case
24
:
cipher
=
EVP_aes_192_cbc
();
break
;
case
32
:
cipher
=
EVP_aes_256_cbc
();
break
;
default:
return
AES_BAD_KEYSIZE
;
}
//Initialize Encryption Engine here, default software Engine is default
ENGINE
*
engine
=
NULL
;
if
(
!
EVP_DecryptInit_ex
(
&
ctx
.
ctx
,
cipher
,
engine
,
key
,
iv
))
return
AES_BAD_DATA
;
/* Error */
if
(
noPadding
)
{
EVP_CIPHER_CTX_set_padding
(
&
ctx
.
ctx
,
0
);
}
OPENSSL_assert
(
EVP_CIPHER_CTX_key_length
(
&
ctx
.
ctx
)
==
key_length
);
OPENSSL_assert
(
EVP_CIPHER_CTX_iv_length
(
&
ctx
.
ctx
)
==
iv_length
);
OPENSSL_assert
(
EVP_CIPHER_CTX_block_size
(
&
ctx
.
ctx
)
==
16
);
if
(
!
EVP_DecryptUpdate
(
&
ctx
.
ctx
,
(
unsigned
char
*
)
dest
,
&
u_len
,
(
unsigned
char
*
)
source
,
source_length
))
return
AES_BAD_DATA
;
/* Error */
if
(
!
EVP_DecryptFinal_ex
(
&
ctx
.
ctx
,
(
unsigned
char
*
)
dest
+
u_len
,
&
f_len
))
{
*
dest_length
=
(
unsigned
long
int
)
u_len
;
return
AES_BAD_DATA
;
}
if
(
remaining_bytes
!=
0
)
{
memcpy
(
dest
+
source_length
,
source
+
source_length
,
remaining_bytes
);
}
*
dest_length
=
(
unsigned
long
int
)
(
u_len
+
f_len
)
+
remaining_bytes
;
#endif
return
AES_OK
;
}
/**
AES decryption - ECB mode
SYNOPSIS
my_aes_decrypt_ecb()
@param source [in] Pointer to data to decrypt
@param source_length [in] Size of data
@param dest [out] Buffer to place decrypted data (must be large enough)
@param dest_length [out] Pointer to size of decrypted data
@param key [in] Key to be used for decryption
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
@param noPadding [in] if set to true, no padding is used. if the input length is not a
multiple of the AES block size, trailing bytes are only copied to destination buffer.
This allows currently the same interface for CBC, ECB and CTR encryption.
@return
!= 0 error
0 no error
*/
static
int
my_aes_decrypt_ecb
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
noPadding
)
{
uint8
remaining_bytes
=
(
noPadding
==
0
)
?
0
:
source_length
%
MY_AES_BLOCK_SIZE
;
source_length
=
source_length
-
remaining_bytes
;
#ifdef HAVE_YASSL
TaoCrypt
::
AES_ECB_Decryption
dec
;
/* 128 bit block used for padding */
uint8
block
[
MY_AES_BLOCK_SIZE
];
uint
num_blocks
;
/* Number of complete blocks */
int
i
;
switch
(
key_length
)
{
case
16
:
break
;
case
24
:
break
;
case
32
:
break
;
default:
return
AES_BAD_KEYSIZE
;
}
dec
.
SetKey
((
const
TaoCrypt
::
byte
*
)
key
,
key_length
,
iv
);
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
);
if
(
noPadding
)
{
memcpy
(
dest
,
block
,
MY_AES_BLOCK_SIZE
);
if
(
remaining_bytes
!=
0
)
{
/* Note that we have moved dest and source */
memcpy
(
dest
+
MY_AES_BLOCK_SIZE
,
source
+
MY_AES_BLOCK_SIZE
,
remaining_bytes
);
}
*
dest_length
=
MY_AES_BLOCK_SIZE
*
num_blocks
+
remaining_bytes
;
return
AES_OK
;
}
/* 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
);
*
dest_length
=
MY_AES_BLOCK_SIZE
*
num_blocks
-
pad_len
;
return
AES_OK
;
#elif defined(HAVE_OPENSSL)
MyCipherCtx
ctx
;
int
u_len
,
f_len
;
const
EVP_CIPHER
*
cipher
;
switch
(
key_length
)
{
case
16
:
cipher
=
EVP_aes_128_ecb
();
break
;
case
24
:
cipher
=
EVP_aes_192_ecb
();
break
;
case
32
:
cipher
=
EVP_aes_256_ecb
();
break
;
default:
return
AES_BAD_KEYSIZE
;
}
//Initialize Encryption Engine here, default software Engine is default
ENGINE
*
engine
=
NULL
;
if
(
!
EVP_DecryptInit_ex
(
&
ctx
.
ctx
,
cipher
,
engine
,
key
,
iv
))
return
AES_BAD_DATA
;
/* Error */
if
(
noPadding
)
{
EVP_CIPHER_CTX_set_padding
(
&
ctx
.
ctx
,
0
);
}
OPENSSL_assert
(
EVP_CIPHER_CTX_key_length
(
&
ctx
.
ctx
)
==
key_length
);
// ECB does not use IV
OPENSSL_assert
(
EVP_CIPHER_CTX_iv_length
(
&
ctx
.
ctx
)
==
0
);
OPENSSL_assert
(
EVP_CIPHER_CTX_block_size
(
&
ctx
.
ctx
)
==
16
);
if
(
!
EVP_DecryptUpdate
(
&
ctx
.
ctx
,
(
unsigned
char
*
)
dest
,
&
u_len
,
(
unsigned
char
*
)
source
,
source_length
))
return
AES_BAD_DATA
;
/* Error */
if
(
!
EVP_DecryptFinal_ex
(
&
ctx
.
ctx
,
(
unsigned
char
*
)
dest
+
u_len
,
&
f_len
))
{
*
dest_length
=
(
unsigned
long
int
)
u_len
;
return
AES_BAD_DATA
;
}
if
(
remaining_bytes
!=
0
)
{
memcpy
(
dest
+
source_length
,
source
+
source_length
,
remaining_bytes
);
}
*
dest_length
=
(
unsigned
long
int
)
(
u_len
+
f_len
)
+
remaining_bytes
;
#endif
return
AES_OK
;
}
/**
Encryption interface that doesn't do anything (for testing)
...
...
mysys_ssl/my_crypt.cc
View file @
2f8d101f
/*
Copyright (c) 2014 Google Inc.
Copyright (c) 2014, 2015 MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
TODO: add support for YASSL
*/
...
...
@@ -5,10 +22,8 @@
#include <my_global.h>
#include <my_crypt.h>
/* YASSL doesn't support EVP_CIPHER_CTX */
#ifdef HAVE_EncryptAes128Ctr
#include "mysql.h"
#include <openssl/evp.h>
#include <openssl/aes.h>
...
...
@@ -17,67 +32,119 @@ static const int CRYPT_DECRYPT = 0;
C_MODE_START
static
int
do_crypt
(
const
EVP_CIPHER
*
cipher
,
int
mode
,
static
int
do_crypt
(
const
EVP_CIPHER
*
cipher
,
int
encrypt
,
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
noPadding
)
const
uchar
*
key
,
uint8
key_length
,
const
uchar
*
iv
,
uint8
iv_length
,
int
no_padding
)
{
int
res
=
AES_OPENSSL_ERROR
;
int
res
=
AES_OPENSSL_ERROR
,
fin
;
int
tail
=
no_padding
?
source_length
%
MY_AES_BLOCK_SIZE
:
0
;
EVP_CIPHER_CTX
ctx
;
EVP_CIPHER_CTX_init
(
&
ctx
);
if
(
!
EVP_CipherInit_ex
(
&
ctx
,
cipher
,
NULL
,
key
,
iv
,
mode
))
if
(
!
EVP_CipherInit_ex
(
&
ctx
,
cipher
,
NULL
,
key
,
iv
,
encrypt
))
goto
err
;
if
(
!
EVP_CipherUpdate
(
&
ctx
,
dest
,
(
int
*
)
dest_length
,
source
,
source_length
))
EVP_CIPHER_CTX_set_padding
(
&
ctx
,
!
no_padding
);
DBUG_ASSERT
(
EVP_CIPHER_CTX_key_length
(
&
ctx
)
==
key_length
);
DBUG_ASSERT
(
EVP_CIPHER_CTX_iv_length
(
&
ctx
)
==
iv_length
||
!
EVP_CIPHER_CTX_iv_length
(
&
ctx
));
DBUG_ASSERT
(
EVP_CIPHER_CTX_block_size
(
&
ctx
)
==
MY_AES_BLOCK_SIZE
||
!
no_padding
);
if
(
!
EVP_CipherUpdate
(
&
ctx
,
dest
,
(
int
*
)
dest_length
,
source
,
source_length
-
tail
))
goto
err
;
if
(
!
EVP_CipherFinal_ex
(
&
ctx
,
dest
+
*
dest_length
,
&
fin
))
goto
err
;
*
dest_length
+=
fin
;
if
(
tail
)
{
/*
Not much we can do here, block cyphers cannot encrypt data that aren't
a multiple of the block length. At least not without padding.
What we do here, we XOR the tail with the previous encrypted block.
*/
DBUG_ASSERT
(
source_length
-
tail
==
*
dest_length
);
DBUG_ASSERT
(
source_length
-
tail
>
MY_AES_BLOCK_SIZE
);
const
uchar
*
s
=
source
+
source_length
-
tail
;
const
uchar
*
e
=
source
+
source_length
;
uchar
*
d
=
dest
+
source_length
-
tail
;
const
uchar
*
m
=
(
encrypt
?
d
:
s
)
-
MY_AES_BLOCK_SIZE
;
while
(
s
<
e
)
*
d
++
=
*
s
++
^
*
m
++
;
*
dest_length
=
source_length
;
}
res
=
AES_OK
;
err:
EVP_CIPHER_CTX_cleanup
(
&
ctx
);
return
res
;
}
/* CTR is a stream cypher mode, it needs no special padding code */
int
my_aes_encrypt_ctr
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
noP
adding
)
const
u
char
*
key
,
uint8
key_length
,
const
u
char
*
iv
,
uint8
iv_length
,
uint
no_p
adding
)
{
return
do_crypt
(
EVP_aes_128_ctr
(),
CRYPT_ENCRYPT
,
source
,
source_length
,
dest
,
dest_length
,
key
,
key_length
,
iv
,
iv_length
,
noPadding
);
dest
,
dest_length
,
key
,
key_length
,
iv
,
iv_length
,
0
);
}
int
my_aes_decrypt_ctr
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
noP
adding
)
const
u
char
*
key
,
uint8
key_length
,
const
u
char
*
iv
,
uint8
iv_length
,
uint
no_p
adding
)
{
return
do_crypt
(
EVP_aes_128_ctr
(),
CRYPT_DECRYPT
,
source
,
source_length
,
dest
,
dest_length
,
key
,
key_length
,
iv
,
iv_length
,
noPadding
);
dest
,
dest_length
,
key
,
key_length
,
iv
,
iv_length
,
0
);
}
int
my_aes_encrypt_ecb
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
noP
adding
)
const
u
char
*
key
,
uint8
key_length
,
const
u
char
*
iv
,
uint8
iv_length
,
uint
no_p
adding
)
{
return
do_crypt
(
EVP_aes_128_ecb
(),
CRYPT_ENCRYPT
,
source
,
source_length
,
dest
,
dest_length
,
key
,
key_length
,
iv
,
iv_length
,
noP
adding
);
dest
,
dest_length
,
key
,
key_length
,
iv
,
iv_length
,
no_p
adding
);
}
int
my_aes_decrypt_ecb
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
unsigned
char
*
key
,
uint8
key_length
,
const
unsigned
char
*
iv
,
uint8
iv_length
,
uint
noP
adding
)
const
u
char
*
key
,
uint8
key_length
,
const
u
char
*
iv
,
uint8
iv_length
,
uint
no_p
adding
)
{
return
do_crypt
(
EVP_aes_128_ecb
(),
CRYPT_DECRYPT
,
source
,
source_length
,
dest
,
dest_length
,
key
,
key_length
,
iv
,
iv_length
,
noPadding
);
dest
,
dest_length
,
key
,
key_length
,
iv
,
iv_length
,
no_padding
);
}
int
my_aes_encrypt_cbc
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
uchar
*
key
,
uint8
key_length
,
const
uchar
*
iv
,
uint8
iv_length
,
uint
no_padding
)
{
return
do_crypt
(
EVP_aes_128_cbc
(),
CRYPT_ENCRYPT
,
source
,
source_length
,
dest
,
dest_length
,
key
,
key_length
,
iv
,
iv_length
,
no_padding
);
}
int
my_aes_decrypt_cbc
(
const
uchar
*
source
,
uint32
source_length
,
uchar
*
dest
,
uint32
*
dest_length
,
const
uchar
*
key
,
uint8
key_length
,
const
uchar
*
iv
,
uint8
iv_length
,
uint
no_padding
)
{
return
do_crypt
(
EVP_aes_128_cbc
(),
CRYPT_DECRYPT
,
source
,
source_length
,
dest
,
dest_length
,
key
,
key_length
,
iv
,
iv_length
,
no_padding
);
}
C_MODE_END
...
...
storage/innobase/fil/fil0crypt.cc
View file @
2f8d101f
...
...
@@ -212,6 +212,7 @@ fil_crypt_get_key(byte *dst, uint* key_length,
mutex_enter
(
&
crypt_data
->
mutex
);
if
(
!
page_encrypted
)
{
*
key_length
=
get_encryption_key_size
(
version
);
// Check if we already have key
for
(
uint
i
=
0
;
i
<
crypt_data
->
key_count
;
i
++
)
{
if
(
crypt_data
->
keys
[
i
].
key_version
==
version
)
{
...
...
storage/xtradb/fil/fil0crypt.cc
View file @
2f8d101f
...
...
@@ -212,6 +212,7 @@ fil_crypt_get_key(byte *dst, uint* key_length,
mutex_enter
(
&
crypt_data
->
mutex
);
if
(
!
page_encrypted
)
{
*
key_length
=
get_encryption_key_size
(
version
);
// Check if we already have key
for
(
uint
i
=
0
;
i
<
crypt_data
->
key_count
;
i
++
)
{
if
(
crypt_data
->
keys
[
i
].
key_version
==
version
)
{
...
...
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