Commit 2f8d101f authored by Sergei Golubchik's avatar Sergei Golubchik

unify my_{en|de}crypt_{cbc|ecb|ctr}. no yassl support yet.

parent 27cc252b
/*
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 noPadding);
uint no_padding);
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) */
......
This diff is collapsed.
/*
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 noPadding)
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_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 noPadding)
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_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 noPadding)
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_ecb(), CRYPT_ENCRYPT, 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_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)
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_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
......
......@@ -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) {
......
......@@ -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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment