diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 22bd8d52a30..c4661e2b383 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -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; diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index e14d5359c19..09986993139 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -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; diff --git a/include/mysql/plugin_encryption_key_management.h b/include/mysql/plugin_encryption_key_management.h index b989fa14db1..a7fc379962b 100644 --- a/include/mysql/plugin_encryption_key_management.h +++ b/include/mysql/plugin_encryption_key_management.h @@ -27,9 +27,10 @@ #include -#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 diff --git a/include/mysql/plugin_encryption_key_management.h.pp b/include/mysql/plugin_encryption_key_management.h.pp index 9012fe9252b..fb39b807d1c 100644 --- a/include/mysql/plugin_encryption_key_management.h.pp +++ b/include/mysql/plugin_encryption_key_management.h.pp @@ -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); }; diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index bd9ec23c811..e9315f4fe83 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -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; diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp index b417dbb5e6d..a82d5fd9150 100644 --- a/include/mysql/plugin_password_validation.h.pp +++ b/include/mysql/plugin_password_validation.h.pp @@ -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; diff --git a/include/mysql/service_encryption_keys.h b/include/mysql/service_encryption_keys.h index 063f3444f5f..69304899405 100644 --- a/include/mysql/service_encryption_keys.h +++ b/include/mysql/service_encryption_keys.h @@ -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 diff --git a/include/service_versions.h b/include/service_versions.h index 3d85be92519..d25d9507dff 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -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 diff --git a/plugin/debug_key_management/debug_key_management_plugin.cc b/plugin/debug_key_management/debug_key_management_plugin.cc index 1d332e62381..7ade1b8fde7 100644 --- a/plugin/debug_key_management/debug_key_management_plugin.cc +++ b/plugin/debug_key_management/debug_key_management_plugin.cc @@ -28,6 +28,8 @@ #include #include +#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 }; diff --git a/plugin/example_key_management/example_key_management_plugin.cc b/plugin/example_key_management/example_key_management_plugin.cc index 6548baef20c..28cae3c311e 100644 --- a/plugin/example_key_management/example_key_management_plugin.cc +++ b/plugin/example_key_management/example_key_management_plugin.cc @@ -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 }; diff --git a/plugin/file_key_management/file_key_management_plugin.cc b/plugin/file_key_management/file_key_management_plugin.cc index 125f5b6e91d..60007e4487d 100644 --- a/plugin/file_key_management/file_key_management_plugin.cc +++ b/plugin/file_key_management/file_key_management_plugin.cc @@ -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 }; diff --git a/sql/encryption_keys.cc b/sql/encryption_keys.cc index f3e8fe6a9d2..7a07581722b 100644 --- a/sql/encryption_keys.cc +++ b/sql/encryption_keys.cc @@ -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) diff --git a/sql/sql_plugin_services.h b/sql/sql_plugin_services.h index 8da2af801cf..4511d8bca59 100644 --- a/sql/sql_plugin_services.h +++ b/sql/sql_plugin_services.h @@ -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 }; diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index f4602fa7fdc..eba17d9842b 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -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) diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc index 6f487e36b56..2aaa0aa4550 100644 --- a/storage/innobase/log/log0crypt.cc +++ b/storage/innobase/log/log0crypt.cc @@ -27,6 +27,7 @@ Modified Jan Lindström jan.lindstrom@mariadb.com #include "log0crypt.h" #include #include + #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 " diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index f4602fa7fdc..f17fee926ca 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -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) { diff --git a/storage/xtradb/log/log0crypt.cc b/storage/xtradb/log/log0crypt.cc index abebdd8c61a..2aaa0aa4550 100644 --- a/storage/xtradb/log/log0crypt.cc +++ b/storage/xtradb/log/log0crypt.cc @@ -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 "