Skip to content

Commit

Permalink
InnoDB/XtraDB Encryption cleanup
Browse files Browse the repository at this point in the history
Step 2:

-- Introduce temporal memory array to buffer pool where to allocate
temporary memory for encryption/compression
-- Rename PAGE_ENCRYPTION -> ENCRYPTION
-- Rename PAGE_ENCRYPTION_KEY -> ENCRYPTION_KEY
-- Rename innodb_default_page_encryption_key -> innodb_default_encryption_key
-- Allow enable/disable encryption for tables by changing
 ENCRYPTION to enum having values DEFAULT, ON, OFF
-- In create table store crypt_data if ENCRYPTION is ON or OFF
-- Do not crypt tablespaces having ENCRYPTION=OFF
-- Store encryption mode to crypt_data and redo-log
  • Loading branch information
Jan Lindström authored and vuvova committed Apr 7, 2015
1 parent b4a4d82 commit 0ba9fa3
Show file tree
Hide file tree
Showing 31 changed files with 824 additions and 570 deletions.
342 changes: 177 additions & 165 deletions storage/innobase/buf/buf0buf.cc

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions storage/innobase/buf/buf0dblwr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ buf_dblwr_write_block_to_datafile(
0,
buf_block_get_page_no(block),
0,
UNIV_PAGE_SIZE,
bpage->real_size,
frame,
(void*) block,
(ulint *)&bpage->write_size);
Expand Down Expand Up @@ -1231,7 +1231,7 @@ buf_dblwr_write_single_page(
TRX_SYS_SPACE, 0,
offset,
0,
UNIV_PAGE_SIZE,
bpage->real_size,
frame,
NULL,
0);
Expand Down
6 changes: 3 additions & 3 deletions storage/innobase/buf/buf0flu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ buf_flush_write_block_low(
break;
}

frame = buf_page_encrypt_before_write(bpage, frame);
frame = buf_page_encrypt_before_write(bpage, frame, space_id);

if (!srv_use_doublewrite_buf || !buf_dblwr) {
fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
Expand All @@ -918,7 +918,7 @@ buf_flush_write_block_low(
zip_size,
buf_page_get_page_no(bpage),
0,
zip_size ? zip_size : UNIV_PAGE_SIZE,
zip_size ? zip_size : bpage->real_size,
frame,
bpage,
&bpage->write_size);
Expand All @@ -938,7 +938,7 @@ buf_flush_write_block_low(
zip_size,
buf_page_get_page_no(bpage),
0,
zip_size ? zip_size : UNIV_PAGE_SIZE,
zip_size ? zip_size : bpage->real_size,
frame,
bpage,
&bpage->write_size);
Expand Down
3 changes: 1 addition & 2 deletions storage/innobase/buf/buf0rea.cc
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ buf_read_page_low(

ut_ad(buf_page_in_file(bpage));

byte* frame = buf_page_decrypt_before_read(bpage, zip_size);
byte* frame = zip_size ? bpage->zip.data : ((buf_block_t*) bpage)->frame;

if (sync) {
thd_wait_begin(NULL, THD_WAIT_DISKIO);
Expand All @@ -202,7 +202,6 @@ buf_read_page_low(
}

if (*err != DB_SUCCESS) {
buf_page_decrypt_cleanup(bpage);
if (ignore_nonexistent_pages || *err == DB_TABLESPACE_DELETED) {
buf_read_page_handle_error(bpage);
return(0);
Expand Down
44 changes: 36 additions & 8 deletions storage/innobase/fil/fil0crypt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ fil_space_create_crypt_data()
&crypt_data->mutex, SYNC_NO_ORDER_CHECK);
crypt_data->iv_length = iv_length;
my_random_bytes(crypt_data->iv, iv_length);
crypt_data->encryption = FIL_SPACE_ENCRYPTION_DEFAULT;
return crypt_data;
}

Expand Down Expand Up @@ -421,6 +422,9 @@ fil_space_read_crypt_data(
uint min_key_version = mach_read_from_4
(page + offset + MAGIC_SZ + 2 + iv_length);

fil_encryption_t encryption = (fil_encryption_t)mach_read_from_1(
page + offset + MAGIC_SZ + 2 + iv_length + 4);

const uint sz = sizeof(fil_space_crypt_t) + iv_length;
fil_space_crypt_t* crypt_data = static_cast<fil_space_crypt_t*>(
malloc(sz));
Expand All @@ -429,6 +433,7 @@ fil_space_read_crypt_data(
crypt_data->type = type;
crypt_data->min_key_version = min_key_version;
crypt_data->page0_offset = offset;
crypt_data->encryption = encryption;
mutex_create(fil_crypt_data_mutex_key,
&crypt_data->mutex, SYNC_NO_ORDER_CHECK);
crypt_data->iv_length = iv_length;
Expand Down Expand Up @@ -474,8 +479,9 @@ fil_space_write_crypt_data_low(
page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
const uint len = crypt_data->iv_length;
const uint min_key_version = crypt_data->min_key_version;
const fil_encryption_t encryption = crypt_data->encryption;
crypt_data->page0_offset = offset;
ut_a(2 + len + 4 + MAGIC_SZ < maxsize);
ut_a(2 + len + 4 + 1 + MAGIC_SZ < maxsize);

/*
redo log this as bytewise updates to page 0
Expand All @@ -489,8 +495,10 @@ fil_space_write_crypt_data_low(
mtr);
mlog_write_ulint(page + offset + MAGIC_SZ + 2 + len, min_key_version,
MLOG_4BYTES, mtr);
mlog_write_ulint(page + offset + MAGIC_SZ + 2 + len + 4, encryption,
MLOG_1BYTE, mtr);

byte* log_ptr = mlog_open(mtr, 11 + 12 + len);
byte* log_ptr = mlog_open(mtr, 11 + 13 + len);

if (log_ptr != NULL) {
log_ptr = mlog_write_initial_log_record_fast(
Expand All @@ -507,6 +515,8 @@ fil_space_write_crypt_data_low(
log_ptr += 1;
mach_write_to_4(log_ptr, min_key_version);
log_ptr += 4;
mach_write_to_1(log_ptr, encryption);
log_ptr += 1;
mlog_close(mtr, log_ptr);

mlog_catenate_string(mtr, crypt_data->iv, len);
Expand Down Expand Up @@ -555,7 +565,8 @@ fil_parse_write_crypt_data(
2 + // size of offset
1 + // size of type
1 + // size of iv-len
4; // size of min_key_version
4 + // size of min_key_version
1; // fil_encryption_t

if (end_ptr - ptr < entry_size){
return NULL;
Expand All @@ -582,9 +593,17 @@ fil_parse_write_crypt_data(
return NULL;
}

fil_encryption_t encryption = (fil_encryption_t)mach_read_from_1(ptr);
ptr +=1;

if (end_ptr - ptr < len) {
return NULL;
}

fil_space_crypt_t* crypt_data = fil_space_create_crypt_data();
crypt_data->page0_offset = offset;
crypt_data->min_key_version = min_key_version;
crypt_data->encryption = encryption;
memcpy(crypt_data->iv, ptr, len);
ptr += len;

Expand All @@ -610,7 +629,8 @@ fil_space_clear_crypt_data(
1 + // type
1 + // len
len + // iv
4; // min key version
4 + // min key version
1; // fil_encryption_t
memset(page + offset, 0, size);
}

Expand Down Expand Up @@ -674,13 +694,11 @@ fil_space_encrypt(
const byte* src_frame, /*!< in: Source page to be encrypted */
ulint zip_size, /*!< in: compressed size if
row_format compressed */
byte* dst_frame, /*!< in: outbut buffer */
ulint encryption_key) /*!< in: encryption key id if page
encrypted */
byte* dst_frame) /*!< in: outbut buffer */
{
fil_space_crypt_t* crypt_data=NULL;
ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
uint key_version = (uint)encryption_key;
uint key_version;
unsigned char key[MY_AES_MAX_KEY_LENGTH];
uint key_length=MY_AES_MAX_KEY_LENGTH;
uint aes_method;
Expand All @@ -699,6 +717,7 @@ 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 ?
Expand Down Expand Up @@ -808,6 +827,10 @@ fil_space_check_encryption_read(
return false;
}

if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
return false;
}

return true;
}

Expand Down Expand Up @@ -1352,6 +1375,11 @@ fil_crypt_space_needs_rotation(
mutex_enter(&crypt_data->mutex);

do {
if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
/* This space is unencrypted by user request */
break;
}

/* prevent threads from starting to rotate space */
if (crypt_data->rotate_state.starting) {
/* recheck this space later */
Expand Down
102 changes: 77 additions & 25 deletions storage/innobase/fil/fil0fil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5543,6 +5543,74 @@ fil_report_invalid_page_access(
(ulong) byte_offset, (ulong) len, (ulong) type);
}

/********************************************************************//**
Find correct node from file space
@return node */
static
fil_node_t*
fil_space_get_node(
fil_space_t* space, /*!< in: file spage */
ulint space_id, /*!< in: space id */
ulint* block_offset, /*!< in/out: offset in number of blocks */
ulint byte_offset, /*!< in: remainder of offset in bytes; in
aio this must be divisible by the OS block
size */
ulint len) /*!< in: how many bytes to read or write; this
must not cross a file boundary; in aio this
must be a block size multiple */
{
fil_node_t* node;
ut_ad(mutex_own(&fil_system->mutex));

node = UT_LIST_GET_FIRST(space->chain);

for (;;) {
if (node == NULL) {
return(NULL);
} else if (fil_is_user_tablespace_id(space->id)
&& node->size == 0) {

/* We do not know the size of a single-table tablespace
before we open the file */
break;
} else if (node->size > *block_offset) {
/* Found! */
break;
} else {
*block_offset -= node->size;
node = UT_LIST_GET_NEXT(chain, node);
}
}

return (node);
}
/********************************************************************//**
Return block size of node in file space
@return file block size */
UNIV_INTERN
ulint
fil_space_get_block_size(
/*=====================*/
ulint space_id,
ulint block_offset,
ulint len)
{
ulint block_size = 512;
fil_space_t* space = fil_space_get_space(space_id);

if (space) {
mutex_enter(&fil_system->mutex);
fil_node_t* node = fil_space_get_node(space, space_id, &block_offset, 0, len);
mutex_exit(&fil_system->mutex);

if (node) {
block_size = node->file_block_size;
}
}

return block_size;
}

/********************************************************************//**
Reads or writes data. This operation is asynchronous (aio).
@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
Expand Down Expand Up @@ -5589,7 +5657,7 @@ fil_io(
ulint is_log;
ulint wake_later;
os_offset_t offset;
ibool ignore_nonexistent_pages;
bool ignore_nonexistent_pages;

is_log = type & OS_FILE_LOG;
type = type & ~OS_FILE_LOG;
Expand Down Expand Up @@ -5674,34 +5742,18 @@ fil_io(

ut_ad(mode != OS_AIO_IBUF || space->purpose == FIL_TABLESPACE);

node = UT_LIST_GET_FIRST(space->chain);

for (;;) {
if (node == NULL) {
if (ignore_nonexistent_pages) {
mutex_exit(&fil_system->mutex);
return(DB_ERROR);
}
node = fil_space_get_node(space, space_id, &block_offset, byte_offset, len);

fil_report_invalid_page_access(
if (!node) {
if (ignore_nonexistent_pages) {
mutex_exit(&fil_system->mutex);
return(DB_ERROR);
}
fil_report_invalid_page_access(
block_offset, space_id, space->name,
byte_offset, len, type);

ut_error;

} else if (fil_is_user_tablespace_id(space->id)
&& node->size == 0) {

/* We do not know the size of a single-table tablespace
before we open the file */
break;
} else if (node->size > block_offset) {
/* Found! */
break;
} else {
block_offset -= node->size;
node = UT_LIST_GET_NEXT(chain, node);
}
ut_error;
}

/* Open file if closed */
Expand Down
Loading

0 comments on commit 0ba9fa3

Please sign in to comment.