New encryption API. Piece-wise encryption.

Instead of encrypt(src, dst, key, iv) that encrypts all
data in one go, now we have encrypt_init(key,iv),
encrypt_update(src,dst), and encrypt_finish(dst).

This also causes collateral changes in the internal my_crypt.cc
encryption functions and in the encryption service.

There are wrappers to provide the old all-at-once encryption
functionality. But binlog events are often written piecewise,
they'll need the new api.
This commit is contained in:
Sergei Golubchik 2015-09-04 10:32:52 +02:00
commit 66b9a9409c
24 changed files with 896 additions and 647 deletions

View file

@ -113,65 +113,59 @@ static unsigned int get_key_from_key_file(unsigned int key_id,
return 0;
}
// let's simplify the condition below
#ifndef HAVE_EncryptAes128Gcm
#define MY_AES_GCM MY_AES_CTR
#ifndef HAVE_EncryptAes128Ctr
#define MY_AES_CTR MY_AES_CBC
#endif
#endif
static inline enum my_aes_mode mode(int flags)
{
/*
If encryption_algorithm is AES_CTR then
if no-padding, use AES_CTR
else use AES_GCM (like CTR but appends a "checksum" block)
else
use AES_CBC
*/
if (encryption_algorithm)
if (flags & ENCRYPTION_FLAG_NOPAD)
return MY_AES_CTR;
else
return MY_AES_GCM;
else
return MY_AES_CBC;
}
static int ctx_init(void *ctx, const unsigned char* key, unsigned int klen,
const unsigned char* iv, unsigned int ivlen, int flags,
unsigned int key_id, unsigned int key_version)
{
return my_aes_crypt_init(ctx, mode(flags), flags, key, klen, iv, ivlen);
}
static unsigned int get_length(unsigned int slen, unsigned int key_id,
unsigned int key_version)
{
return my_aes_get_size(mode(0), slen);
}
struct st_mariadb_encryption file_key_management_plugin= {
MariaDB_ENCRYPTION_INTERFACE_VERSION,
get_latest_version,
get_key_from_key_file,
0,0
(uint (*)(unsigned int, unsigned int))my_aes_ctx_size,
ctx_init,
my_aes_crypt_update,
my_aes_crypt_finish,
get_length
};
#ifdef HAVE_EncryptAes128Gcm
/*
use AES-CTR when cyphertext length must be the same as plaintext length,
and AES-GCM when cyphertext can be longer than plaintext.
*/
static int ctr_gcm_encrypt(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen,
const unsigned char* key, unsigned int klen,
const unsigned char* iv, unsigned int ivlen,
int no_padding, unsigned int keyid, unsigned int key_version)
{
return (no_padding ? my_aes_encrypt_ctr : my_aes_encrypt_gcm)
(src, slen, dst, dlen, key, klen, iv, ivlen);
}
static int ctr_gcm_decrypt(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen,
const unsigned char* key, unsigned int klen,
const unsigned char* iv, unsigned int ivlen,
int no_padding, unsigned int keyid, unsigned int key_version)
{
return (no_padding ? my_aes_decrypt_ctr : my_aes_decrypt_gcm)
(src, slen, dst, dlen, key, klen, iv, ivlen);
}
#endif
static int file_key_management_plugin_init(void *p)
{
Parser parser(filename, filekey);
switch (encryption_algorithm) {
case 0: // AES_CBC
file_key_management_plugin.encrypt=
(encrypt_decrypt_func)my_aes_encrypt_cbc;
file_key_management_plugin.decrypt=
(encrypt_decrypt_func)my_aes_decrypt_cbc;
break;
#ifdef HAVE_EncryptAes128Ctr
case 1: // AES_CTR
#ifdef HAVE_EncryptAes128Gcm
file_key_management_plugin.encrypt= ctr_gcm_encrypt;
file_key_management_plugin.decrypt= ctr_gcm_decrypt;
#else
file_key_management_plugin.encrypt=
(encrypt_decrypt_func)my_aes_encrypt_ctr;
file_key_management_plugin.decrypt=
(encrypt_decrypt_func)my_aes_decrypt_ctr;
#endif
break;
#endif
default:
return 1; // cannot happen
}
return parser.parse(&keys);
}

View file

@ -336,10 +336,11 @@ char* Parser::read_and_decrypt_file(const char *secret)
bytes_to_key(buffer + OpenSSL_prefix_len, secret, key, iv);
uint32 d_size;
if (my_aes_decrypt_cbc(buffer + OpenSSL_prefix_len + OpenSSL_salt_len,
file_size - OpenSSL_prefix_len - OpenSSL_salt_len,
decrypted, &d_size, key, OpenSSL_key_len,
iv, OpenSSL_iv_len, 0))
if (my_aes_crypt(MY_AES_CBC, ENCRYPTION_FLAG_DECRYPT,
buffer + OpenSSL_prefix_len + OpenSSL_salt_len,
file_size - OpenSSL_prefix_len - OpenSSL_salt_len,
decrypted, &d_size, key, OpenSSL_key_len,
iv, OpenSSL_iv_len))
{
my_printf_error(EE_READ, "Cannot decrypt %s. Wrong key?", MYF(ME_NOREFRESH), filename);