Commit ef5b4889 authored by Sergei Golubchik's avatar Sergei Golubchik

optimize encryption api

only one encryption key lookup in most cases instead of three
(has_key, get_key_size, get_key).
parent c91e3260
......@@ -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
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, non-zero on failure
@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);
mi_int4store(dstbuf, version);
if (*buflen < KEY_SIZE)
{
*buflen= KEY_SIZE;
return KEY_BUFFER_TOO_SMALL;
}
*buflen= KEY_SIZE;
if (!dstbuf)
return 0;
}
static unsigned int has_key(unsigned int ver)
{
return 1;
}
static unsigned int get_key_size(unsigned int ver)
{
return 16;
memset(dstbuf, 0, KEY_SIZE);
mi_int4store(dstbuf, version);
return 0;
}
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,32 +58,21 @@ 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)
{
compute_md5_hash(dst, (const char*)&version, sizeof(version));
dst += MD5_HASH_SIZE;
version++;
}
if (len < buflen)
if (*buflen < MD5_HASH_SIZE)
{
memset(dst, 0, buflen - len);
*buflen= MD5_HASH_SIZE;
return KEY_BUFFER_TOO_SMALL;
}
*buflen= MD5_HASH_SIZE;
if (!dstbuf)
return 0;
}
static unsigned int has_key_func(unsigned int keyID)
{
return true;
}
my_md5(dstbuf, (const char*)&version, sizeof(version));
static unsigned int get_key_size(unsigned int keyID)
{
return 16;
return 0;
}
static int example_key_management_plugin_init(void *p)
......@@ -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;
}
static unsigned int get_key_size_from_key_file(unsigned int key_id)
{
keyentry* entry = get_key(key_id);
if (entry == NULL)
return BAD_ENCRYPTION_KEY_VERSION;
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);
return 0;
}
unsigned int get_encryption_key_size(uint version)
{
if (encryption_key_manager)
return handle->get_key_size(version);
{
uint unused;
return handle->get_key(version, NULL, &unused) != BAD_ENCRYPTION_KEY_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,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)
......
......@@ -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 "
......
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