optimize encryption api
only one encryption key lookup in most cases instead of three (has_key, get_key_size, get_key).
This commit is contained in:
parent
c91e3260e2
commit
ef5b4889c2
@ -201,13 +201,11 @@ int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
extern struct encryption_keys_service_st {
|
||||
unsigned int (*get_latest_encryption_key_version_func)();
|
||||
unsigned int (*has_encryption_key_func)(unsigned int);
|
||||
unsigned int (*get_encryption_key_size_func)(unsigned int);
|
||||
int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int);
|
||||
unsigned int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int*);
|
||||
} *encryption_keys_service;
|
||||
unsigned int get_latest_encryption_key_version();
|
||||
unsigned int has_encryption_key(unsigned int version);
|
||||
unsigned int get_encryption_key_size(unsigned int version);
|
||||
int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize);
|
||||
unsigned int get_encryption_key(unsigned int version, unsigned char* key, unsigned int *keybufsize);
|
||||
struct st_mysql_xid {
|
||||
long formatID;
|
||||
long gtrid_length;
|
||||
|
@ -201,13 +201,11 @@ int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
extern struct encryption_keys_service_st {
|
||||
unsigned int (*get_latest_encryption_key_version_func)();
|
||||
unsigned int (*has_encryption_key_func)(unsigned int);
|
||||
unsigned int (*get_encryption_key_size_func)(unsigned int);
|
||||
int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int);
|
||||
unsigned int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int*);
|
||||
} *encryption_keys_service;
|
||||
unsigned int get_latest_encryption_key_version();
|
||||
unsigned int has_encryption_key(unsigned int version);
|
||||
unsigned int get_encryption_key_size(unsigned int version);
|
||||
int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize);
|
||||
unsigned int get_encryption_key(unsigned int version, unsigned char* key, unsigned int *keybufsize);
|
||||
struct st_mysql_xid {
|
||||
long formatID;
|
||||
long gtrid_length;
|
||||
|
@ -27,9 +27,10 @@
|
||||
|
||||
#include <mysql/plugin.h>
|
||||
|
||||
#define MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION 0x0100
|
||||
#define MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION 0x0200
|
||||
|
||||
#define BAD_ENCRYPTION_KEY_VERSION (UINT_MAX32)
|
||||
#define BAD_ENCRYPTION_KEY_VERSION (~(unsigned int)0)
|
||||
#define KEY_BUFFER_TOO_SMALL (100)
|
||||
|
||||
/**
|
||||
Encryption key management plugin descriptor
|
||||
@ -45,20 +46,28 @@ struct st_mariadb_encryption_key_management
|
||||
*/
|
||||
unsigned int (*get_latest_key_version)();
|
||||
|
||||
/** function returning if a key of the given version exists */
|
||||
unsigned int (*has_key_version)(unsigned int version);
|
||||
|
||||
/** function returning the key size in bytes */
|
||||
unsigned int (*get_key_size)(unsigned int version);
|
||||
|
||||
/**
|
||||
function returning a key for a key version
|
||||
|
||||
the key is put in 'key' buffer, that has size of 'keybufsize' bytes.
|
||||
@param version the requested key version
|
||||
@param key the key will be stored there. Can be NULL -
|
||||
in which case no key will be returned
|
||||
@param key_length in: key buffer size
|
||||
out: the actual length of the key
|
||||
|
||||
@return 0 on success, non-zero on failure
|
||||
This method can be used to query the key length - the required
|
||||
buffer size - by passing key==NULL.
|
||||
|
||||
If the buffer size is less than the key length the content of the
|
||||
key buffer is undefined (the plugin is free to partially fill it with
|
||||
the key data or leave it untouched).
|
||||
|
||||
@return 0 on success, or
|
||||
BAD_ENCRYPTION_KEY_VERSION, KEY_BUFFER_TOO_SMALL,
|
||||
or any other non-zero number for errors
|
||||
*/
|
||||
int (*get_key)(unsigned int version, unsigned char* key, unsigned int keybufsize);
|
||||
unsigned int (*get_key)(unsigned int version, unsigned char *key,
|
||||
unsigned int *key_length);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -201,13 +201,11 @@ int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
extern struct encryption_keys_service_st {
|
||||
unsigned int (*get_latest_encryption_key_version_func)();
|
||||
unsigned int (*has_encryption_key_func)(unsigned int);
|
||||
unsigned int (*get_encryption_key_size_func)(unsigned int);
|
||||
int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int);
|
||||
unsigned int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int*);
|
||||
} *encryption_keys_service;
|
||||
unsigned int get_latest_encryption_key_version();
|
||||
unsigned int has_encryption_key(unsigned int version);
|
||||
unsigned int get_encryption_key_size(unsigned int version);
|
||||
int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize);
|
||||
unsigned int get_encryption_key(unsigned int version, unsigned char* key, unsigned int *keybufsize);
|
||||
struct st_mysql_xid {
|
||||
long formatID;
|
||||
long gtrid_length;
|
||||
@ -368,7 +366,6 @@ struct st_mariadb_encryption_key_management
|
||||
{
|
||||
int interface_version;
|
||||
unsigned int (*get_latest_key_version)();
|
||||
unsigned int (*has_key_version)(unsigned int version);
|
||||
unsigned int (*get_key_size)(unsigned int version);
|
||||
int (*get_key)(unsigned int version, unsigned char* key, unsigned int keybufsize);
|
||||
unsigned int (*get_key)(unsigned int version, unsigned char *key,
|
||||
unsigned int *key_length);
|
||||
};
|
||||
|
@ -201,13 +201,11 @@ int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
extern struct encryption_keys_service_st {
|
||||
unsigned int (*get_latest_encryption_key_version_func)();
|
||||
unsigned int (*has_encryption_key_func)(unsigned int);
|
||||
unsigned int (*get_encryption_key_size_func)(unsigned int);
|
||||
int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int);
|
||||
unsigned int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int*);
|
||||
} *encryption_keys_service;
|
||||
unsigned int get_latest_encryption_key_version();
|
||||
unsigned int has_encryption_key(unsigned int version);
|
||||
unsigned int get_encryption_key_size(unsigned int version);
|
||||
int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize);
|
||||
unsigned int get_encryption_key(unsigned int version, unsigned char* key, unsigned int *keybufsize);
|
||||
struct st_mysql_xid {
|
||||
long formatID;
|
||||
long gtrid_length;
|
||||
|
@ -201,13 +201,11 @@ int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
extern struct encryption_keys_service_st {
|
||||
unsigned int (*get_latest_encryption_key_version_func)();
|
||||
unsigned int (*has_encryption_key_func)(unsigned int);
|
||||
unsigned int (*get_encryption_key_size_func)(unsigned int);
|
||||
int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int);
|
||||
unsigned int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int*);
|
||||
} *encryption_keys_service;
|
||||
unsigned int get_latest_encryption_key_version();
|
||||
unsigned int has_encryption_key(unsigned int version);
|
||||
unsigned int get_encryption_key_size(unsigned int version);
|
||||
int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize);
|
||||
unsigned int get_encryption_key(unsigned int version, unsigned char* key, unsigned int *keybufsize);
|
||||
struct st_mysql_xid {
|
||||
long formatID;
|
||||
long gtrid_length;
|
||||
|
@ -28,23 +28,20 @@ extern "C" {
|
||||
extern struct encryption_keys_service_st {
|
||||
unsigned int (*get_latest_encryption_key_version_func)();
|
||||
unsigned int (*has_encryption_key_func)(unsigned int);
|
||||
unsigned int (*get_encryption_key_size_func)(unsigned int);
|
||||
int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int);
|
||||
unsigned int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int*);
|
||||
} *encryption_keys_service;
|
||||
|
||||
#ifdef MYSQL_DYNAMIC_PLUGIN
|
||||
|
||||
#define get_latest_encryption_key_version() encryption_keys_service->get_latest_encryption_key_version_func()
|
||||
#define has_encryption_key(V) encryption_keys_service->has_encryption_key_func(V)
|
||||
#define get_encryption_key_size(V) encryption_keys_service->get_encryption_key_size_func(V)
|
||||
#define get_encryption_key(V,K,S) encryption_keys_service->get_encryption_key_func((V), (K), (S))
|
||||
|
||||
#else
|
||||
|
||||
unsigned int get_latest_encryption_key_version();
|
||||
unsigned int has_encryption_key(unsigned int version);
|
||||
unsigned int get_encryption_key_size(unsigned int version);
|
||||
int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize);
|
||||
unsigned int get_encryption_key(unsigned int version, unsigned char* key, unsigned int *keybufsize);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -35,5 +35,5 @@
|
||||
#define VERSION_thd_autoinc 0x0100
|
||||
#define VERSION_thd_error_context 0x0100
|
||||
#define VERSION_thd_specifics 0x0100
|
||||
#define VERSION_encryption_keys 0x0100
|
||||
#define VERSION_encryption_keys 0x0200
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <string.h>
|
||||
#include <myisampack.h>
|
||||
|
||||
#define KEY_SIZE 16
|
||||
|
||||
static uint key_version;
|
||||
|
||||
static MYSQL_SYSVAR_UINT(version, key_version, PLUGIN_VAR_RQCMDARG,
|
||||
@ -43,30 +45,25 @@ static unsigned int get_latest_key_version()
|
||||
return key_version;
|
||||
}
|
||||
|
||||
static int get_key(unsigned int version, unsigned char* dstbuf, unsigned buflen)
|
||||
static unsigned int get_key(unsigned int version, unsigned char* dstbuf, unsigned *buflen)
|
||||
{
|
||||
if (buflen < 4)
|
||||
return 1;
|
||||
memset(dstbuf, 0, buflen);
|
||||
if (*buflen < KEY_SIZE)
|
||||
{
|
||||
*buflen= KEY_SIZE;
|
||||
return KEY_BUFFER_TOO_SMALL;
|
||||
}
|
||||
*buflen= KEY_SIZE;
|
||||
if (!dstbuf)
|
||||
return 0;
|
||||
|
||||
memset(dstbuf, 0, KEY_SIZE);
|
||||
mi_int4store(dstbuf, version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int has_key(unsigned int ver)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned int get_key_size(unsigned int ver)
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
struct st_mariadb_encryption_key_management debug_key_management_plugin= {
|
||||
MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION,
|
||||
get_latest_key_version,
|
||||
has_key,
|
||||
get_key_size,
|
||||
get_key
|
||||
};
|
||||
|
||||
|
@ -58,34 +58,23 @@ get_latest_key_version()
|
||||
return key_version;
|
||||
}
|
||||
|
||||
static int
|
||||
get_key(unsigned int version, unsigned char* dstbuf, unsigned buflen)
|
||||
static unsigned int
|
||||
get_key(unsigned int version, unsigned char* dstbuf, unsigned *buflen)
|
||||
{
|
||||
unsigned char *dst = dstbuf;
|
||||
unsigned len = 0;
|
||||
for (; len + MD5_HASH_SIZE <= buflen; len += MD5_HASH_SIZE)
|
||||
if (*buflen < MD5_HASH_SIZE)
|
||||
{
|
||||
compute_md5_hash(dst, (const char*)&version, sizeof(version));
|
||||
dst += MD5_HASH_SIZE;
|
||||
version++;
|
||||
}
|
||||
if (len < buflen)
|
||||
{
|
||||
memset(dst, 0, buflen - len);
|
||||
*buflen= MD5_HASH_SIZE;
|
||||
return KEY_BUFFER_TOO_SMALL;
|
||||
}
|
||||
*buflen= MD5_HASH_SIZE;
|
||||
if (!dstbuf)
|
||||
return 0;
|
||||
|
||||
my_md5(dstbuf, (const char*)&version, sizeof(version));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int has_key_func(unsigned int keyID)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static unsigned int get_key_size(unsigned int keyID)
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
static int example_key_management_plugin_init(void *p)
|
||||
{
|
||||
/* init */
|
||||
@ -115,8 +104,6 @@ static int example_key_management_plugin_deinit(void *p)
|
||||
struct st_mariadb_encryption_key_management example_key_management_plugin= {
|
||||
MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION,
|
||||
get_latest_key_version,
|
||||
has_key_func,
|
||||
get_key_size,
|
||||
get_key
|
||||
};
|
||||
|
||||
|
@ -67,36 +67,25 @@ static unsigned int get_highest_key_used_in_key_file()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int has_key_from_key_file(unsigned int key_id)
|
||||
static unsigned int get_key_from_key_file(unsigned int key_id,
|
||||
unsigned char* dstbuf, unsigned *buflen)
|
||||
{
|
||||
keyentry* entry = get_key(key_id);
|
||||
|
||||
return entry != NULL;
|
||||
}
|
||||
if (entry == NULL)
|
||||
return BAD_ENCRYPTION_KEY_VERSION;
|
||||
|
||||
static unsigned int get_key_size_from_key_file(unsigned int key_id)
|
||||
{
|
||||
keyentry* entry = get_key(key_id);
|
||||
|
||||
return entry ? entry->length : CRYPT_KEY_UNKNOWN;
|
||||
}
|
||||
|
||||
static int get_key_from_key_file(unsigned int key_id, unsigned char* dstbuf,
|
||||
unsigned buflen)
|
||||
{
|
||||
keyentry* entry = get_key(key_id);
|
||||
|
||||
if (entry != NULL)
|
||||
if (*buflen < entry->length)
|
||||
{
|
||||
if (buflen < entry->length)
|
||||
return CRYPT_BUFFER_TO_SMALL;
|
||||
*buflen= entry->length;
|
||||
return KEY_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
*buflen= entry->length;
|
||||
if (dstbuf)
|
||||
memcpy(dstbuf, entry->key, entry->length);
|
||||
|
||||
return CRYPT_KEY_OK;
|
||||
}
|
||||
else
|
||||
return CRYPT_KEY_UNKNOWN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int file_key_management_plugin_init(void *p)
|
||||
@ -108,8 +97,6 @@ static int file_key_management_plugin_init(void *p)
|
||||
struct st_mariadb_encryption_key_management file_key_management_plugin= {
|
||||
MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION,
|
||||
get_highest_key_used_in_key_file,
|
||||
has_key_from_key_file,
|
||||
get_key_size_from_key_file,
|
||||
get_key_from_key_file
|
||||
};
|
||||
|
||||
|
@ -18,25 +18,20 @@ unsigned int get_latest_encryption_key_version()
|
||||
unsigned int has_encryption_key(uint version)
|
||||
{
|
||||
if (encryption_key_manager)
|
||||
return handle->has_key_version(version);
|
||||
{
|
||||
uint unused;
|
||||
return handle->get_key(version, NULL, &unused) != BAD_ENCRYPTION_KEY_VERSION;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int get_encryption_key_size(uint version)
|
||||
{
|
||||
if (encryption_key_manager)
|
||||
return handle->get_key_size(version);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_encryption_key(uint version, uchar* key, uint size)
|
||||
uint get_encryption_key(uint version, uchar* key, uint *size)
|
||||
{
|
||||
if (encryption_key_manager)
|
||||
return handle->get_key(version, key, size);
|
||||
|
||||
return 1;
|
||||
return BAD_ENCRYPTION_KEY_VERSION;
|
||||
}
|
||||
|
||||
int initialize_encryption_key_management_plugin(st_plugin_int *plugin)
|
||||
|
@ -143,7 +143,6 @@ static struct encryption_keys_service_st encryption_keys_handler=
|
||||
{
|
||||
get_latest_encryption_key_version,
|
||||
has_encryption_key,
|
||||
get_encryption_key_size,
|
||||
get_encryption_key
|
||||
};
|
||||
|
||||
|
@ -212,12 +212,12 @@ 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) {
|
||||
memcpy(dst, crypt_data->keys[i].key,
|
||||
sizeof(crypt_data->keys[i].key));
|
||||
*key_length= MY_AES_BLOCK_SIZE;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
return;
|
||||
}
|
||||
@ -231,23 +231,14 @@ fil_crypt_get_key(byte *dst, uint* key_length,
|
||||
}
|
||||
}
|
||||
|
||||
if (has_encryption_key(version)) {
|
||||
int rc;
|
||||
*key_length = get_encryption_key_size(version);
|
||||
*key_length= MY_AES_MAX_KEY_LENGTH;
|
||||
int rc = get_encryption_key(version, (unsigned char*)keybuf, key_length);
|
||||
if (rc) {
|
||||
|
||||
rc = get_encryption_key(version, (unsigned char*)keybuf, *key_length);
|
||||
|
||||
if (rc != CRYPT_KEY_OK) {
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"Key %d can not be found. Reason=%d", version, rc);
|
||||
ut_error;
|
||||
}
|
||||
} else {
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"Key %d not found", version);
|
||||
ut_error;
|
||||
}
|
||||
|
||||
|
||||
// do ctr key initialization
|
||||
if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR)
|
||||
|
@ -27,6 +27,7 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
|
||||
#include "log0crypt.h"
|
||||
#include <my_crypt.h>
|
||||
#include <my_aes.h>
|
||||
|
||||
#include "log0log.h"
|
||||
#include "srv0start.h" // for srv_start_lsn
|
||||
#include "log0recv.h" // for recv_sys
|
||||
@ -116,7 +117,8 @@ log_init_crypt_key(
|
||||
}
|
||||
|
||||
byte mysqld_key[MY_AES_BLOCK_SIZE] = {0};
|
||||
if (get_encryption_key(crypt_ver, mysqld_key, MY_AES_BLOCK_SIZE))
|
||||
uint keylen= sizeof(mysqld_key);
|
||||
if (get_encryption_key(crypt_ver, mysqld_key, &keylen))
|
||||
{
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Redo log crypto: getting mysqld crypto key "
|
||||
|
@ -212,12 +212,12 @@ 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) {
|
||||
memcpy(dst, crypt_data->keys[i].key,
|
||||
sizeof(crypt_data->keys[i].key));
|
||||
*key_length= MY_AES_BLOCK_SIZE;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
return;
|
||||
}
|
||||
@ -231,24 +231,15 @@ fil_crypt_get_key(byte *dst, uint* key_length,
|
||||
}
|
||||
}
|
||||
|
||||
if (has_encryption_key(version)) {
|
||||
int rc;
|
||||
*key_length = get_encryption_key_size(version);
|
||||
*key_length= MY_AES_MAX_KEY_LENGTH;
|
||||
int rc = get_encryption_key(version, (unsigned char*)keybuf, key_length);
|
||||
if (rc) {
|
||||
|
||||
rc = get_encryption_key(version, (unsigned char*)keybuf, *key_length);
|
||||
|
||||
if (rc != CRYPT_KEY_OK) {
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"Key %d can not be found. Reason=%d", version, rc);
|
||||
ut_error;
|
||||
}
|
||||
} else {
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"Key %d not found", version);
|
||||
"Key %d can not be found. Reason=%d", version, rc);
|
||||
ut_error;
|
||||
}
|
||||
|
||||
|
||||
// do ctr key initialization
|
||||
if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR)
|
||||
{
|
||||
|
@ -117,7 +117,8 @@ log_init_crypt_key(
|
||||
}
|
||||
|
||||
byte mysqld_key[MY_AES_BLOCK_SIZE] = {0};
|
||||
if (get_encryption_key(crypt_ver, mysqld_key, MY_AES_BLOCK_SIZE))
|
||||
uint keylen= sizeof(mysqld_key);
|
||||
if (get_encryption_key(crypt_ver, mysqld_key, &keylen))
|
||||
{
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Redo log crypto: getting mysqld crypto key "
|
||||
|
Loading…
x
Reference in New Issue
Block a user