Add encryption key id to the API as a distinct concept

which is separate from the encryption key version
This commit is contained in:
Sergei Golubchik 2015-04-09 00:37:47 +02:00
parent 5dffda3ccc
commit 97d5de4ccf
27 changed files with 197 additions and 144 deletions

View File

@ -202,11 +202,13 @@ typedef int (*encrypt_decrypt_func)(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 key_version);
int no_padding, unsigned int key_id,
unsigned int key_version);
struct encryption_service_st {
unsigned int (*encryption_key_get_latest_version_func)();
unsigned int (*encryption_key_exists_func)(unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned char*, unsigned int*);
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
unsigned int (*encryption_key_id_exists_func)(unsigned int);
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
encrypt_decrypt_func encryption_encrypt_func;
encrypt_decrypt_func encryption_decrypt_func;
};

View File

@ -202,11 +202,13 @@ typedef int (*encrypt_decrypt_func)(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 key_version);
int no_padding, unsigned int key_id,
unsigned int key_version);
struct encryption_service_st {
unsigned int (*encryption_key_get_latest_version_func)();
unsigned int (*encryption_key_exists_func)(unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned char*, unsigned int*);
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
unsigned int (*encryption_key_id_exists_func)(unsigned int);
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
encrypt_decrypt_func encryption_encrypt_func;
encrypt_decrypt_func encryption_decrypt_func;
};

View File

@ -37,11 +37,11 @@ struct st_mariadb_encryption
int interface_version; /**< version plugin uses */
/**
function returning latest key version.
function returning latest key version for a given key id
@return a version or BAD_ENCRYPTION_KEY_VERSION to indicate an error.
@return a version or ENCRYPTION_KEY_VERSION_INVALID to indicate an error.
*/
unsigned int (*get_latest_key_version)();
unsigned int (*get_latest_key_version)(unsigned int key_id);
/**
function returning a key for a key version
@ -60,11 +60,11 @@ struct st_mariadb_encryption
the key data or leave it untouched).
@return 0 on success, or
BAD_ENCRYPTION_KEY_VERSION, KEY_BUFFER_TOO_SMALL,
ENCRYPTION_KEY_VERSION_INVALID, ENCRYPTION_KEY_BUFFER_TOO_SMALL
or any other non-zero number for errors
*/
unsigned int (*get_key)(unsigned int version, unsigned char *key,
unsigned int *key_length);
unsigned int (*get_key)(unsigned int key_id, unsigned int version,
unsigned char *key, unsigned int *key_length);
encrypt_decrypt_func encrypt;
encrypt_decrypt_func decrypt;

View File

@ -202,11 +202,13 @@ typedef int (*encrypt_decrypt_func)(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 key_version);
int no_padding, unsigned int key_id,
unsigned int key_version);
struct encryption_service_st {
unsigned int (*encryption_key_get_latest_version_func)();
unsigned int (*encryption_key_exists_func)(unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned char*, unsigned int*);
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
unsigned int (*encryption_key_id_exists_func)(unsigned int);
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
encrypt_decrypt_func encryption_encrypt_func;
encrypt_decrypt_func encryption_decrypt_func;
};
@ -370,9 +372,9 @@ void thd_wakeup_subsequent_commits(void* thd, int wakeup_error);
struct st_mariadb_encryption
{
int interface_version;
unsigned int (*get_latest_key_version)();
unsigned int (*get_key)(unsigned int version, unsigned char *key,
unsigned int *key_length);
unsigned int (*get_latest_key_version)(unsigned int key_id);
unsigned int (*get_key)(unsigned int key_id, unsigned int version,
unsigned char *key, unsigned int *key_length);
encrypt_decrypt_func encrypt;
encrypt_decrypt_func decrypt;
};

View File

@ -202,11 +202,13 @@ typedef int (*encrypt_decrypt_func)(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 key_version);
int no_padding, unsigned int key_id,
unsigned int key_version);
struct encryption_service_st {
unsigned int (*encryption_key_get_latest_version_func)();
unsigned int (*encryption_key_exists_func)(unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned char*, unsigned int*);
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
unsigned int (*encryption_key_id_exists_func)(unsigned int);
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
encrypt_decrypt_func encryption_encrypt_func;
encrypt_decrypt_func encryption_decrypt_func;
};

View File

@ -202,11 +202,13 @@ typedef int (*encrypt_decrypt_func)(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 key_version);
int no_padding, unsigned int key_id,
unsigned int key_version);
struct encryption_service_st {
unsigned int (*encryption_key_get_latest_version_func)();
unsigned int (*encryption_key_exists_func)(unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned char*, unsigned int*);
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
unsigned int (*encryption_key_id_exists_func)(unsigned int);
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
encrypt_decrypt_func encryption_encrypt_func;
encrypt_decrypt_func encryption_decrypt_func;
};

View File

@ -30,7 +30,7 @@ extern "C" {
/* returned from encryption_key_get_latest_version() */
#define ENCRYPTION_KEY_VERSION_INVALID (~(unsigned int)0)
#define ENCRYPTION_KEY_VERSION_NOT_ENCRYPTED (0)
#define ENCRYPTION_KEY_NOT_ENCRYPTED (0)
/* returned from encryption_key_get() */
#define ENCRYPTION_KEY_BUFFER_TOO_SMALL (100)
@ -39,12 +39,14 @@ typedef int (*encrypt_decrypt_func)(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 key_version);
int no_padding, unsigned int key_id,
unsigned int key_version);
struct encryption_service_st {
unsigned int (*encryption_key_get_latest_version_func)();
unsigned int (*encryption_key_exists_func)(unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned char*, unsigned int*);
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
unsigned int (*encryption_key_id_exists_func)(unsigned int);
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
encrypt_decrypt_func encryption_encrypt_func;
encrypt_decrypt_func encryption_decrypt_func;
};
@ -53,20 +55,22 @@ struct encryption_service_st {
extern struct encryption_service_st *encryption_service;
#define encryption_key_get_latest_version() encryption_service->encryption_key_get_latest_version_func()
#define encryption_key_exists(V) encryption_service->encryption_key_exists_func(V)
#define encryption_key_get(V,K,S) encryption_service->encryption_key_get_func((V), (K), (S))
#define encryption_encrypt(S,SL,D,DL,K,KL,I,IL,NP,KV) encryption_service->encryption_encrypt_func(S,SL,D,DL,K,KL,I,IL,NP,KV)
#define encryption_decrypt(S,SL,D,DL,K,KL,I,IL,NP,KV) encryption_service->encryption_decrypt_func(S,SL,D,DL,K,KL,I,IL,NP,KV)
#define encryption_key_get_latest_version(KI) encryption_service->encryption_key_get_latest_version_func(KI)
#define encryption_key_id_exists(KI) encryption_service->encryption_key_id_exists_func((KI))
#define encryption_key_version_exists(KI,KV) encryption_service->encryption_key_version_exists_func((KI),(KV))
#define encryption_key_get(KI,KV,K,S) encryption_service->encryption_key_get_func((KI),(KV),(K),(S))
#define encryption_encrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_service->encryption_encrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV))
#define encryption_decrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_service->encryption_decrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV))
#else
extern struct encryption_service_st encryption_handler;
#define encryption_key_get_latest_version() encryption_handler.encryption_key_get_latest_version_func()
#define encryption_key_exists(V) encryption_handler.encryption_key_exists_func(V)
#define encryption_key_get(V,K,S) encryption_handler.encryption_key_get_func((V), (K), (S))
#define encryption_encrypt(S,SL,D,DL,K,KL,I,IL,NP,KV) encryption_handler.encryption_encrypt_func(S,SL,D,DL,K,KL,I,IL,NP,KV)
#define encryption_decrypt(S,SL,D,DL,K,KL,I,IL,NP,KV) encryption_handler.encryption_decrypt_func(S,SL,D,DL,K,KL,I,IL,NP,KV)
#define encryption_key_get_latest_version(KI) encryption_handler.encryption_key_get_latest_version_func(KI)
#define encryption_key_id_exists(KI) encryption_handler.encryption_key_id_exists_func((KI))
#define encryption_key_version_exists(KI,KV) encryption_handler.encryption_key_version_exists_func((KI),(KV))
#define encryption_key_get(KI,KV,K,S) encryption_handler.encryption_key_get_func((KI),(KV),(K),(S))
#define encryption_encrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_handler.encryption_encrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV))
#define encryption_decrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_handler.encryption_decrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV))
#endif
#ifdef __cplusplus

View File

@ -19,6 +19,8 @@
It's used to debug the encryption code with a fixed keys that change
only on user request.
It does not support different key ids, the only valid key id is 1.
THIS IS AN EXAMPLE ONLY! ENCRYPTION KEYS ARE HARD-CODED AND *NOT* SECRET!
DO NOT USE THIS PLUGIN IN PRODUCTION! EVER!
*/
@ -40,13 +42,20 @@ static struct st_mysql_sys_var* sysvars[] = {
NULL
};
static unsigned int get_latest_key_version()
static unsigned int get_latest_key_version(unsigned int keyid)
{
if (keyid != 1)
return ENCRYPTION_KEY_VERSION_INVALID;
return key_version;
}
static unsigned int get_key(unsigned int version, unsigned char* dstbuf, unsigned *buflen)
static unsigned int get_key(unsigned int keyid, unsigned int version,
unsigned char* dstbuf, unsigned *buflen)
{
if (keyid != 1)
return ENCRYPTION_KEY_VERSION_INVALID;
if (*buflen < KEY_SIZE)
{
*buflen= KEY_SIZE;

View File

@ -21,6 +21,8 @@
different pages in the same tablespace encrypted with different keys
and what the background re-encryption thread does.
It does not support different key ids, for all ids the key will be the same.
THIS IS AN EXAMPLE ONLY! ENCRYPTION KEYS ARE HARD-CODED AND *NOT* SECRET!
DO NOT USE THIS PLUGIN IN PRODUCTION! EVER!
*/
@ -41,7 +43,7 @@ static unsigned int next_key_version = 0;
static pthread_mutex_t mutex;
static unsigned int
get_latest_key_version()
get_latest_key_version(unsigned int key_id)
{
uint now = time(0);
pthread_mutex_lock(&mutex);
@ -57,7 +59,8 @@ get_latest_key_version()
}
static unsigned int
get_key(unsigned int version, unsigned char* dstbuf, unsigned *buflen)
get_key(unsigned int key_id, unsigned int version,
unsigned char* dstbuf, unsigned *buflen)
{
if (*buflen < MY_MD5_HASH_SIZE)
{
@ -81,7 +84,7 @@ int 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 key_version)
int no_padding, unsigned int keyid, unsigned int key_version)
{
return ((key_version & 1) ? my_aes_encrypt_cbc : my_aes_encrypt_ecb)
(src, slen, dst, dlen, key, klen, iv, ivlen, no_padding);
@ -91,7 +94,7 @@ int 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 key_version)
int no_padding, unsigned int keyid, unsigned int key_version)
{
return ((key_version & 1) ? my_aes_decrypt_cbc : my_aes_decrypt_ecb)
(src, slen, dst, dlen, key, klen, iv, ivlen, no_padding);
@ -101,7 +104,7 @@ static int example_key_management_plugin_init(void *p)
{
/* init */
my_rnd_init(&seed, time(0), 0);
get_latest_key_version();
get_latest_key_version(1);
pthread_mutex_init(&mutex, NULL);
return 0;

View File

@ -78,20 +78,18 @@ static keyentry *get_key(unsigned int key_id)
return a->id == key_id ? a : 0;
}
/**
This method is using with the id 0 if exists.
This method is used by innobase/xtradb for the key
rotation feature of encrypting log files.
*/
static unsigned int get_highest_key_used_in_key_file()
/* the version is always the same, no automatic key rotation */
static unsigned int get_latest_version(uint key_id)
{
return 0;
return get_key(key_id) ? 1 : ENCRYPTION_KEY_VERSION_INVALID;
}
static unsigned int get_key_from_key_file(unsigned int key_id,
unsigned char* dstbuf, unsigned *buflen)
unsigned int key_version, unsigned char* dstbuf, unsigned *buflen)
{
if (key_version != 1)
return ENCRYPTION_KEY_VERSION_INVALID;
keyentry* entry = get_key(key_id);
if (entry == NULL)
@ -112,7 +110,7 @@ static unsigned int get_key_from_key_file(unsigned int key_id,
struct st_mariadb_encryption file_key_management_plugin= {
MariaDB_ENCRYPTION_INTERFACE_VERSION,
get_highest_key_used_in_key_file,
get_latest_version,
get_key_from_key_file,
0,0
};

View File

@ -23,13 +23,18 @@
static plugin_ref encryption_manager= 0;
struct encryption_service_st encryption_handler;
unsigned int has_key(uint version)
unsigned int has_key_id(uint id)
{
uint unused;
return encryption_key_get(version, NULL, &unused) != ENCRYPTION_KEY_VERSION_INVALID;
return encryption_key_get_latest_version(id) != ENCRYPTION_KEY_VERSION_INVALID;
}
uint no_key()
unsigned int has_key_version(uint id, uint version)
{
uint unused;
return encryption_key_get(id, version, NULL, &unused) != ENCRYPTION_KEY_VERSION_INVALID;
}
uint no_key(uint)
{
return ENCRYPTION_KEY_VERSION_INVALID;
}
@ -38,7 +43,7 @@ static int no_crypt(const uchar* source, uint source_length,
uchar* dest, uint* dest_length,
const uchar* key, uint key_length,
const uchar* iv, uint iv_length,
int no_padding, uint key_version)
int no_padding, uint key_id, uint key_version)
{
return 1;
}
@ -81,9 +86,10 @@ int finalize_encryption_plugin(st_plugin_int *plugin)
{
encryption_handler.encryption_encrypt_func= no_crypt;
encryption_handler.encryption_decrypt_func= no_crypt;
encryption_handler.encryption_key_exists_func= has_key;
encryption_handler.encryption_key_id_exists_func= has_key_id;
encryption_handler.encryption_key_version_exists_func= has_key_version;
encryption_handler.encryption_key_get_func=
(uint (*)(uint, uchar*, uint*))no_key;
(uint (*)(uint, uint, uchar*, uint*))no_key;
encryption_handler.encryption_key_get_latest_version_func= no_key;
if (plugin && plugin->plugin->deinit && plugin->plugin->deinit(NULL))

View File

@ -177,10 +177,11 @@ fil_crypt_get_key(
}
*key_length = sizeof(keybuf);
int rc = encryption_key_get(version, keybuf, key_length);
uint rc = encryption_key_get(crypt_data->key_id, version, keybuf, key_length);
if (rc) {
ib_logf(IB_LOG_LEVEL_FATAL,
"Key %d can not be found. Reason=%d", version, rc);
"Key id %u version %u can not be found. Reason=%u",
crypt_data->key_id, version, rc);
ut_error;
}
@ -229,11 +230,13 @@ fil_crypt_get_latest_key(
uint* version) /*!< in: Key version */
{
// used for key rotation - get the next key id from the key provider
uint rc = encryption_key_get_latest_version();
uint rc = *version = encryption_key_get_latest_version(crypt_data->key_id);
// if no new key was created use the last one
if (rc != ENCRYPTION_KEY_VERSION_INVALID) {
*version = rc;
if (rc == ENCRYPTION_KEY_VERSION_INVALID) {
ib_logf(IB_LOG_LEVEL_FATAL,
"Unknown key id %u. Can't continue!\n",
crypt_data->key_id);
ut_error;
}
return fil_crypt_get_key(dst, key_length, crypt_data, *version);
@ -259,7 +262,7 @@ fil_space_create_crypt_data()
crypt_data->min_key_version = 0;
} else {
crypt_data->type = CRYPT_SCHEME_1;
crypt_data->min_key_version = encryption_key_get_latest_version();
crypt_data->min_key_version = encryption_key_get_latest_version(crypt_data->key_id);
}
mutex_create(fil_crypt_data_mutex_key,
@ -612,11 +615,11 @@ fil_space_encrypt(
row_format compressed */
byte* dst_frame) /*!< in: outbut buffer */
{
fil_space_crypt_t* crypt_data=NULL;
fil_space_crypt_t* crypt_data = NULL;
ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
uint key_version;
unsigned char key[MY_AES_MAX_KEY_LENGTH];
uint key_length=MY_AES_MAX_KEY_LENGTH;
uint key_length = MY_AES_MAX_KEY_LENGTH;
unsigned char iv[MY_AES_BLOCK_SIZE];
ulint orig_page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
@ -632,7 +635,6 @@ fil_space_encrypt(
/* Get crypt data from file space */
crypt_data = fil_space_get_crypt_data(space);
key_version = crypt_data->keys[0].key_id;
if (crypt_data == NULL) {
//TODO: Is this really needed ?
@ -674,8 +676,8 @@ fil_space_encrypt(
}
int rc = encryption_encrypt(src, srclen, dst, &dstlen,
key, key_length,
iv, sizeof(iv), 1, key_version);
key, key_length, iv, sizeof(iv), 1,
crypt_data->key_id, key_version);
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
ib_logf(IB_LOG_LEVEL_FATAL,
@ -775,7 +777,7 @@ fil_space_decrypt(
uint key_version = mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED);
if (key_version == ENCRYPTION_KEY_VERSION_NOT_ENCRYPTED) {
if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) {
//TODO: is this really needed ?
memcpy(dst_frame, src_frame, page_size);
return false; /* page not decrypted */
@ -820,7 +822,8 @@ fil_space_decrypt(
}
int rc = encryption_decrypt(src, srclen, dst, &dstlen, key, key_length,
iv, sizeof(iv), 1, key_version);
iv, sizeof(iv), 1,
crypt_data->key_id, key_version);
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
ib_logf(IB_LOG_LEVEL_FATAL,
@ -968,10 +971,11 @@ fil_crypt_get_key_state(
key_state_t *new_state) /*!< out: key state */
{
if (srv_encrypt_tables == TRUE) {
new_state->key_version = encryption_key_get_latest_version();
new_state->key_version =
encryption_key_get_latest_version(FIL_DEFAULT_ENCRYPTION_KEY);
new_state->rotate_key_age = srv_fil_crypt_rotate_key_age;
ut_a(new_state->key_version != ENCRYPTION_KEY_VERSION_INVALID);
ut_a(new_state->key_version != ENCRYPTION_KEY_VERSION_NOT_ENCRYPTED);
ut_a(new_state->key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
} else {
new_state->key_version = 0;
new_state->rotate_key_age = 0;
@ -2422,15 +2426,17 @@ fil_space_crypt_get_status(
status->rotating = false;
}
mutex_exit(&crypt_data->mutex);
if (srv_encrypt_tables == TRUE) {
status->current_key_version =
encryption_key_get_latest_version(crypt_data->key_id);
} else {
status->current_key_version = 0;
}
} else {
memset(status, 0, sizeof(*status));
}
if (srv_encrypt_tables == TRUE) {
status->current_key_version = encryption_key_get_latest_version();
} else {
status->current_key_version = 0;
}
return crypt_data == NULL ? 1 : 0;
}

View File

@ -1994,7 +1994,7 @@ fil_read_first_page(
if ((cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_ON) ||
( srv_encrypt_tables &&
cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) {
uint rc = encryption_key_get_latest_version();
uint rc = encryption_key_get_latest_version(cdata->key_id);
if (rc == ENCRYPTION_KEY_VERSION_INVALID) {
ib_logf(IB_LOG_LEVEL_FATAL,

View File

@ -11380,11 +11380,11 @@ ha_innobase::check_table_options(
/* ignore this to allow alter table without changing page_encryption_key ...*/
}
if (!encryption_key_exists(options->encryption_key_id)) {
if (!encryption_key_id_exists(options->encryption_key_id)) {
push_warning_printf(
thd, Sql_condition::WARN_LEVEL_WARN,
HA_WRONG_CREATE_OPTION,
"InnoDB: ENCRYPTION_KEY_ID key %lu not available",
"InnoDB: ENCRYPTION_KEY_ID %lu not available",
options->encryption_key_id
);
return "ENCRYPTION_KEY_ID";
@ -11715,7 +11715,7 @@ ha_innobase::create(
crypt_data = fil_space_create_crypt_data();
crypt_data->page0_offset = fsp_header_get_crypt_offset(zip_size, &maxsize);
crypt_data->keys[0].key_id = key_id;
crypt_data->key_id = key_id;
crypt_data->encryption = encrypt;
/* If there is old crypt data, copy IV */

View File

@ -58,10 +58,7 @@ typedef enum {
/* Cached L or key for given key_version */
struct key_struct
{
uint key_version; /*!< Key version used as
identifier */
uint key_id; /*1< Key id used as
identifier */
uint key_version; /*!< Version of the key */
uint key_length; /*!< Key length */
unsigned char key[MY_AES_MAX_KEY_LENGTH]; /*!< Cached key
(that is L in CRYPT_SCHEME_1) */
@ -88,6 +85,7 @@ struct fil_space_crypt_struct
ulint type; // CRYPT_SCHEME
uint keyserver_requests; // no of key requests to key server
uint key_count; // No of initalized key-structs
uint key_id; // Key id for this space
key_struct keys[3]; // cached L = AES_ECB(KEY, IV)
uint min_key_version; // min key version for this space
ulint page0_offset; // byte offset on page 0 for crypt data

View File

@ -48,20 +48,19 @@ fil_page_encryption_status(
const byte *buf, /*!< in: page */
ulint space_id) /*!< in: space_id */
{
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space_id);
ulint page_type = mach_read_from_2(buf+FIL_PAGE_TYPE);
if (page_type == FIL_PAGE_TYPE_FSP_HDR) {
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space_id);
if (crypt_data != NULL) {
if (!encryption_key_exists(crypt_data->keys[0].key_version)) {
if (!encryption_key_id_exists(crypt_data->key_id)) {
/* accessing table would surely fail, because no key or no key provider available */
return 1;
}
}
} else {
ulint key = mach_read_from_4(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
if (!encryption_key_exists(key)) {
if (!encryption_key_version_exists(crypt_data->key_id, key)) {
return 1;
}
}

View File

@ -15,7 +15,7 @@ Created 11/25/2013 Minli Zhu
#define PURPOSE_BYTE_LEN MY_AES_BLOCK_SIZE - 1
#define PURPOSE_BYTE_OFFSET 0
#define UNENCRYPTED_KEY_VER ENCRYPTION_KEY_VERSION_NOT_ENCRYPTED
#define UNENCRYPTED_KEY_VER ENCRYPTION_KEY_NOT_ENCRYPTED
typedef int Crypt_result;

View File

@ -47,6 +47,8 @@ byte redo_log_crypt_msg[MY_AES_BLOCK_SIZE] = {0};
* encryption/decryption. */
byte aes_ctr_nonce[MY_AES_BLOCK_SIZE] = {0};
#define LOG_DEFAULT_ENCRYPTION_KEY 1
/*********************************************************************//**
Generate a 128-bit value used to generate crypt key for redo log.
It is generated via the concatenation of 1 purpose byte (0x02) and 15-byte
@ -117,7 +119,7 @@ log_init_crypt_key(
byte mysqld_key[MY_AES_BLOCK_SIZE] = {0};
uint keylen= sizeof(mysqld_key);
if (encryption_key_get(crypt_ver, mysqld_key, &keylen))
if (encryption_key_get(LOG_DEFAULT_ENCRYPTION_KEY, crypt_ver, mysqld_key, &keylen))
{
ib_logf(IB_LOG_LEVEL_ERROR,
"Redo log crypto: getting mysqld crypto key "
@ -201,6 +203,7 @@ log_blocks_crypt(
dst_block + LOG_BLOCK_HDR_SIZE, &dst_len,
(unsigned char*)(log_sys->redo_log_crypt_key), 16,
aes_ctr_counter, MY_AES_BLOCK_SIZE, 1,
LOG_DEFAULT_ENCRYPTION_KEY,
log_sys->redo_log_crypt_ver);
} else {
ut_a(recv_sys);
@ -209,6 +212,7 @@ log_blocks_crypt(
dst_block + LOG_BLOCK_HDR_SIZE, &dst_len,
(unsigned char*)(recv_sys->recv_log_crypt_key), 16,
aes_ctr_counter, MY_AES_BLOCK_SIZE, 1,
LOG_DEFAULT_ENCRYPTION_KEY,
recv_sys->recv_log_crypt_ver);
}
@ -261,7 +265,7 @@ log_crypt_set_ver_and_key(
if (srv_encrypt_log) {
unsigned int vkey;
vkey = encryption_key_get_latest_version();
vkey = encryption_key_get_latest_version(LOG_DEFAULT_ENCRYPTION_KEY);
encrypted = true;
if (vkey == UNENCRYPTED_KEY_VER ||

View File

@ -30,7 +30,7 @@ static unsigned int no_key()
struct encryption_service_st encryption_handler=
{
no_key, 0, 0, 0, 0
no_key, 0, 0, 0, 0, 0
};
/* only those that included myisamchk.h may need and can use the below */

View File

@ -20,6 +20,9 @@
#include "ma_blockrec.h"
#include <my_crypt.h>
#define HARD_CODED_ENCRYPTION_KEY_VERSION 1
#define HARD_CODED_ENCRYPTION_KEY_ID 1
#define CRYPT_SCHEME_1 1
#define CRYPT_SCHEME_1_ID_LEN 4 /* 4 bytes for counter-block */
#define CRYPT_SCHEME_1_IV_LEN 16
@ -28,6 +31,7 @@
struct st_maria_crypt_data
{
uchar type;
uint keyid;
uchar iv_length;
uchar iv[1]; // var size
};
@ -68,6 +72,7 @@ ma_crypt_create(MARIA_SHARE* share)
MARIA_CRYPT_DATA *crypt_data= (MARIA_CRYPT_DATA*)my_malloc(sz, MYF(0));
bzero(crypt_data, sz);
crypt_data->type= CRYPT_SCHEME_1;
crypt_data->keyid= HARD_CODED_ENCRYPTION_KEY_ID;
crypt_data->iv_length= iv_length;
my_random_bytes(crypt_data->iv, iv_length);
share->crypt_data= crypt_data;
@ -118,6 +123,7 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff)
MARIA_CRYPT_DATA *crypt_data= (MARIA_CRYPT_DATA*)my_malloc(sz, MYF(0));
crypt_data->type= type;
crypt_data->keyid= HARD_CODED_ENCRYPTION_KEY_ID;
crypt_data->iv_length= iv_length;
memcpy(crypt_data->iv, buff + 2, iv_length);
share->crypt_data= crypt_data;
@ -290,7 +296,8 @@ void ma_crypt_set_data_pagecache_callbacks(PAGECACHE_FILE *file,
__attribute__((unused)))
{
/* Only use encryption if we have defined it */
if (encryption_key_get_latest_version() != ENCRYPTION_KEY_VERSION_INVALID)
if (encryption_key_get_latest_version(HARD_CODED_ENCRYPTION_KEY_ID) !=
ENCRYPTION_KEY_VERSION_INVALID)
{
file->pre_read_hook= ma_crypt_pre_read_hook;
file->post_read_hook= ma_crypt_data_post_read_hook;
@ -410,7 +417,7 @@ static int ma_encrypt(MARIA_CRYPT_DATA *crypt_data,
int rc;
uint32 dstlen;
uchar counter[COUNTER_LEN];
*key_version= 1;
*key_version= HARD_CODED_ENCRYPTION_KEY_VERSION;
// create counter block
memcpy(counter + 0, crypt_data->iv + CRYPT_SCHEME_1_IV_LEN, 4);
@ -419,7 +426,8 @@ static int ma_encrypt(MARIA_CRYPT_DATA *crypt_data,
rc = encryption_encrypt(src, size, dst, &dstlen,
crypt_data->iv, CRYPT_SCHEME_1_IV_LEN,
counter, sizeof(counter), 1, *key_version);
counter, sizeof(counter), 1,
crypt_data->keyid, *key_version);
DBUG_ASSERT(rc == MY_AES_OK);
DBUG_ASSERT(dstlen == size);
@ -451,7 +459,8 @@ static int ma_decrypt(MARIA_CRYPT_DATA *crypt_data,
rc =encryption_decrypt(src, size, dst, &dstlen,
crypt_data->iv, CRYPT_SCHEME_1_IV_LEN,
counter, sizeof(counter), 1, key_version);
counter, sizeof(counter), 1, crypt_data->keyid,
key_version);
DBUG_ASSERT(rc == MY_AES_OK);
DBUG_ASSERT(dstlen == size);

View File

@ -177,10 +177,11 @@ fil_crypt_get_key(
}
*key_length = sizeof(keybuf);
int rc = encryption_key_get(version, keybuf, key_length);
uint rc = encryption_key_get(crypt_data->key_id, version, keybuf, key_length);
if (rc) {
ib_logf(IB_LOG_LEVEL_FATAL,
"Key %d can not be found. Reason=%d", version, rc);
"Key id %u version %u can not be found. Reason=%u",
crypt_data->key_id, version, rc);
ut_error;
}
@ -229,11 +230,13 @@ fil_crypt_get_latest_key(
uint* version) /*!< in: Key version */
{
// used for key rotation - get the next key id from the key provider
uint rc = encryption_key_get_latest_version();
uint rc = *version = encryption_key_get_latest_version(crypt_data->key_id);
// if no new key was created use the last one
if (rc != ENCRYPTION_KEY_VERSION_INVALID) {
*version = rc;
if (rc == ENCRYPTION_KEY_VERSION_INVALID) {
ib_logf(IB_LOG_LEVEL_FATAL,
"Unknown key id %u. Can't continue!\n",
crypt_data->key_id);
ut_error;
}
return fil_crypt_get_key(dst, key_length, crypt_data, *version);
@ -259,7 +262,7 @@ fil_space_create_crypt_data()
crypt_data->min_key_version = 0;
} else {
crypt_data->type = CRYPT_SCHEME_1;
crypt_data->min_key_version = encryption_key_get_latest_version();
crypt_data->min_key_version = encryption_key_get_latest_version(crypt_data->key_id);
}
mutex_create(fil_crypt_data_mutex_key,
@ -612,11 +615,11 @@ fil_space_encrypt(
row_format compressed */
byte* dst_frame) /*!< in: outbut buffer */
{
fil_space_crypt_t* crypt_data=NULL;
fil_space_crypt_t* crypt_data = NULL;
ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
uint key_version;
unsigned char key[MY_AES_MAX_KEY_LENGTH];
uint key_length=MY_AES_MAX_KEY_LENGTH;
uint key_length = MY_AES_MAX_KEY_LENGTH;
unsigned char iv[MY_AES_BLOCK_SIZE];
ulint orig_page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
@ -632,7 +635,6 @@ fil_space_encrypt(
/* Get crypt data from file space */
crypt_data = fil_space_get_crypt_data(space);
key_version = crypt_data->keys[0].key_id;
if (crypt_data == NULL) {
//TODO: Is this really needed ?
@ -674,8 +676,8 @@ fil_space_encrypt(
}
int rc = encryption_encrypt(src, srclen, dst, &dstlen,
key, key_length,
iv, sizeof(iv), 1, key_version);
key, key_length, iv, sizeof(iv), 1,
crypt_data->key_id, key_version);
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
ib_logf(IB_LOG_LEVEL_FATAL,
@ -775,7 +777,7 @@ fil_space_decrypt(
uint key_version = mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED);
if (key_version == ENCRYPTION_KEY_VERSION_NOT_ENCRYPTED) {
if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) {
//TODO: is this really needed ?
memcpy(dst_frame, src_frame, page_size);
return false; /* page not decrypted */
@ -820,7 +822,8 @@ fil_space_decrypt(
}
int rc = encryption_decrypt(src, srclen, dst, &dstlen, key, key_length,
iv, sizeof(iv), 1, key_version);
iv, sizeof(iv), 1,
crypt_data->key_id, key_version);
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
ib_logf(IB_LOG_LEVEL_FATAL,
@ -968,10 +971,11 @@ fil_crypt_get_key_state(
key_state_t *new_state) /*!< out: key state */
{
if (srv_encrypt_tables == TRUE) {
new_state->key_version = encryption_key_get_latest_version();
new_state->key_version =
encryption_key_get_latest_version(FIL_DEFAULT_ENCRYPTION_KEY);
new_state->rotate_key_age = srv_fil_crypt_rotate_key_age;
ut_a(new_state->key_version != ENCRYPTION_KEY_VERSION_INVALID);
ut_a(new_state->key_version != ENCRYPTION_KEY_VERSION_NOT_ENCRYPTED);
ut_a(new_state->key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
} else {
new_state->key_version = 0;
new_state->rotate_key_age = 0;
@ -2422,15 +2426,17 @@ fil_space_crypt_get_status(
status->rotating = false;
}
mutex_exit(&crypt_data->mutex);
if (srv_encrypt_tables == TRUE) {
status->current_key_version =
encryption_key_get_latest_version(crypt_data->key_id);
} else {
status->current_key_version = 0;
}
} else {
memset(status, 0, sizeof(*status));
}
if (srv_encrypt_tables == TRUE) {
status->current_key_version = encryption_key_get_latest_version();
} else {
status->current_key_version = 0;
}
return crypt_data == NULL ? 1 : 0;
}

View File

@ -2032,7 +2032,7 @@ fil_read_first_page(
if ((cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_ON) ||
( srv_encrypt_tables &&
cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) {
uint rc = encryption_key_get_latest_version();
uint rc = encryption_key_get_latest_version(cdata->key_id);
if (rc == ENCRYPTION_KEY_VERSION_INVALID) {
ib_logf(IB_LOG_LEVEL_FATAL,

View File

@ -11887,7 +11887,7 @@ ha_innobase::check_table_options(
/* ignore this to allow alter table without changing page_encryption_key ...*/
}
if (!encryption_key_exists(options->encryption_key_id)) {
if (!encryption_key_id_exists(options->encryption_key_id)) {
push_warning_printf(
thd, Sql_condition::WARN_LEVEL_WARN,
HA_WRONG_CREATE_OPTION,
@ -12229,7 +12229,7 @@ ha_innobase::create(
crypt_data = fil_space_create_crypt_data();
crypt_data->page0_offset = fsp_header_get_crypt_offset(zip_size, &maxsize);
crypt_data->keys[0].key_id = key_id;
crypt_data->key_id = key_id;
crypt_data->encryption = encrypt;
/* If there is old crypt data, copy IV */

View File

@ -58,10 +58,7 @@ typedef enum {
/* Cached L or key for given key_version */
struct key_struct
{
uint key_version; /*!< Key version used as
identifier */
uint key_id; /*1< Key id used as
identifier */
uint key_version; /*!< Version of the key */
uint key_length; /*!< Key length */
unsigned char key[MY_AES_MAX_KEY_LENGTH]; /*!< Cached key
(that is L in CRYPT_SCHEME_1) */
@ -88,6 +85,7 @@ struct fil_space_crypt_struct
ulint type; // CRYPT_SCHEME
uint keyserver_requests; // no of key requests to key server
uint key_count; // No of initalized key-structs
uint key_id; // Key id for this space
key_struct keys[3]; // cached L = AES_ECB(KEY, IV)
uint min_key_version; // min key version for this space
ulint page0_offset; // byte offset on page 0 for crypt data

View File

@ -48,20 +48,19 @@ fil_page_encryption_status(
const byte *buf, /*!< in: page */
ulint space_id) /*!< in: space_id */
{
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space_id);
ulint page_type = mach_read_from_2(buf+FIL_PAGE_TYPE);
if (page_type == FIL_PAGE_TYPE_FSP_HDR) {
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space_id);
if (crypt_data != NULL) {
if (!encryption_key_exists(crypt_data->keys[0].key_version)) {
if (!encryption_key_id_exists(crypt_data->key_id)) {
/* accessing table would surely fail, because no key or no key provider available */
return 1;
}
}
} else {
ulint key = mach_read_from_4(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
if (!encryption_key_exists(key)) {
if (!encryption_key_version_exists(crypt_data->key_id, key)) {
return 1;
}
}

View File

@ -15,7 +15,7 @@ Created 11/25/2013 Minli Zhu
#define PURPOSE_BYTE_LEN MY_AES_BLOCK_SIZE - 1
#define PURPOSE_BYTE_OFFSET 0
#define UNENCRYPTED_KEY_VER ENCRYPTION_KEY_VERSION_NOT_ENCRYPTED
#define UNENCRYPTED_KEY_VER ENCRYPTION_KEY_NOT_ENCRYPTED
typedef int Crypt_result;

View File

@ -47,6 +47,8 @@ byte redo_log_crypt_msg[MY_AES_BLOCK_SIZE] = {0};
* encryption/decryption. */
byte aes_ctr_nonce[MY_AES_BLOCK_SIZE] = {0};
#define LOG_DEFAULT_ENCRYPTION_KEY 1
/*********************************************************************//**
Generate a 128-bit value used to generate crypt key for redo log.
It is generated via the concatenation of 1 purpose byte (0x02) and 15-byte
@ -117,7 +119,7 @@ log_init_crypt_key(
byte mysqld_key[MY_AES_BLOCK_SIZE] = {0};
uint keylen= sizeof(mysqld_key);
if (encryption_key_get(crypt_ver, mysqld_key, &keylen))
if (encryption_key_get(LOG_DEFAULT_ENCRYPTION_KEY, crypt_ver, mysqld_key, &keylen))
{
ib_logf(IB_LOG_LEVEL_ERROR,
"Redo log crypto: getting mysqld crypto key "
@ -201,6 +203,7 @@ log_blocks_crypt(
dst_block + LOG_BLOCK_HDR_SIZE, &dst_len,
(unsigned char*)(log_sys->redo_log_crypt_key), 16,
aes_ctr_counter, MY_AES_BLOCK_SIZE, 1,
LOG_DEFAULT_ENCRYPTION_KEY,
log_sys->redo_log_crypt_ver);
} else {
ut_a(recv_sys);
@ -209,6 +212,7 @@ log_blocks_crypt(
dst_block + LOG_BLOCK_HDR_SIZE, &dst_len,
(unsigned char*)(recv_sys->recv_log_crypt_key), 16,
aes_ctr_counter, MY_AES_BLOCK_SIZE, 1,
LOG_DEFAULT_ENCRYPTION_KEY,
recv_sys->recv_log_crypt_ver);
}
@ -261,7 +265,7 @@ log_crypt_set_ver_and_key(
if (srv_encrypt_log) {
unsigned int vkey;
vkey = encryption_key_get_latest_version();
vkey = encryption_key_get_latest_version(LOG_DEFAULT_ENCRYPTION_KEY);
encrypted = true;
if (vkey == UNENCRYPTED_KEY_VER ||