mirror of
https://github.com/MariaDB/server.git
synced 2026-04-23 08:45:33 +02:00
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:
parent
d94a982adb
commit
66b9a9409c
24 changed files with 896 additions and 647 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue