summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/CMakeLists.txt2
-rw-r--r--storage/innobase/fil/fil0crypt.cc261
-rw-r--r--storage/innobase/fil/fil0fil.cc8
-rw-r--r--storage/innobase/handler/ha_innodb.cc50
-rw-r--r--storage/innobase/include/EncKeys.h88
-rw-r--r--storage/innobase/include/KeySingleton.h59
-rw-r--r--storage/innobase/include/fil0pageencryption.h2
-rw-r--r--storage/innobase/include/fsp0pageencryption.ic13
-rw-r--r--storage/innobase/log/log0crypt.cc4
-rw-r--r--storage/innobase/os/os0file.cc6
-rwxr-xr-xstorage/tokudb/ft-index/ft/ftverifybin0 -> 5744338 bytes
-rwxr-xr-xstorage/tokudb/ft-index/ft/tdb-recoverbin0 -> 5650769 bytes
-rwxr-xr-xstorage/tokudb/ft-index/ft/tdb_logprintbin0 -> 5772550 bytes
-rwxr-xr-xstorage/tokudb/ft-index/ft/tokuftdumpbin0 -> 5719044 bytes
-rw-r--r--storage/xtradb/CMakeLists.txt2
-rw-r--r--storage/xtradb/buf/buf0buf.cc2
-rw-r--r--storage/xtradb/enc/EncKeys.cc458
-rw-r--r--storage/xtradb/enc/KeySingleton.cc65
-rw-r--r--storage/xtradb/fil/fil0crypt.cc510
-rw-r--r--storage/xtradb/fil/fil0fil.cc4
-rw-r--r--storage/xtradb/fil/fil0pageencryption.cc88
-rw-r--r--storage/xtradb/handler/ha_innodb.cc50
-rw-r--r--storage/xtradb/include/EncKeys.h88
-rw-r--r--storage/xtradb/include/KeySingleton.h59
-rw-r--r--storage/xtradb/include/fil0fil.h6
-rw-r--r--storage/xtradb/include/fsp0pageencryption.ic26
-rw-r--r--storage/xtradb/os/os0file.cc129
27 files changed, 699 insertions, 1281 deletions
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index 5fcd30cfa18..3693620d394 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -359,8 +359,6 @@ SET(INNOBASE_SOURCES
dict/dict0stats.cc
dict/dict0stats_bg.cc
dyn/dyn0dyn.cc
- enc/EncKeys.cc
- enc/KeySingleton.cc
eval/eval0eval.cc
eval/eval0proc.cc
fil/fil0fil.cc
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index dbc6db8b4b8..49eef1c5f7a 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -16,7 +16,6 @@
#include <my_crypt_key_management.h>
#include <my_aes.h>
-#include <KeySingleton.h>
#include <math.h>
@@ -180,18 +179,14 @@ fil_space_crypt_cleanup()
Get key bytes for a space/key-version */
static
void
-fil_crypt_get_key(byte *dst, uint dstlen,
+fil_crypt_get_key(byte *dst, uint* key_length,
fil_space_crypt_t* crypt_data, uint version, bool page_encrypted)
{
- /* TODO: Find a better way to do this */
- unsigned char keybuf[CRYPT_SCHEME_1_IV_LEN];
- byte key[CRYPT_SCHEME_1_IV_LEN];
- uint8 key_len = sizeof(keybuf);
+ unsigned char keybuf[MY_AES_MAX_KEY_LENGTH];
unsigned char iv[CRYPT_SCHEME_1_IV_LEN];
ulint iv_len = sizeof(iv);
- bool key_error = false;
- if (!page_encrypted) {
+ if (!page_encrypted) {
mutex_enter(&crypt_data->mutex);
// Check if we already have key
@@ -210,77 +205,82 @@ fil_crypt_get_key(byte *dst, uint dstlen,
for (uint i = 1; i < array_elements(crypt_data->keys); i++) {
crypt_data->keys[i] = crypt_data->keys[i - 1];
}
+ }
+ else
+ {
+ // load iv
- // TODO(jonaso): Integrate with real key server
- int rc = GetCryptoKey(version, keybuf, key_len);
- if (rc != 0) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Unable to retrieve key with"
- " version %u return-code: %d. Can't continue!\n",
- version, rc);
- ut_error;
- }
- } else {
- /* For page encrypted tables we need to get the L */
-
- /* Get key and IV */
- KeySingleton& keys = KeySingleton::getInstance();
-
- if (keys.isAvailable() && keys.getKeys(version) != NULL) {
- char* keyString = keys.getKeys(version)->key;
- char* ivString = keys.getKeys(version)->iv;
+ int rc = GetCryptoIV(version, (unsigned char*)iv, iv_len);
- if (keyString == NULL || ivString == NULL) {
- key_error=true;
- } else {
- my_aes_hex2uint(keyString, (unsigned char*)&keybuf, key_len);
- my_aes_hex2uint(ivString, (unsigned char*)&iv, iv_len);
- }
- } else {
- key_error = true;
- }
-
- if (key_error == true) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Key file not found");
- ut_error;
- }
- }
+ if (rc != CRYPT_KEY_OK) {
+ ib_logf(IB_LOG_LEVEL_FATAL,
+ "IV %d can not be found. Reason=%d", version, rc);
+ ut_error;
+ }
+ }
- // Now compute L by encrypting IV using this key
- const unsigned char* src = page_encrypted ? iv : crypt_data->iv;
- const int srclen = page_encrypted ? iv_len : crypt_data->iv_length;
- unsigned char* buf = page_encrypted ? key : crypt_data->keys[0].key;
- uint32 buflen = page_encrypted ? key_len : sizeof(crypt_data->keys[0].key);
+ if (HasCryptoKey(version)) {
+ *key_length = GetCryptoKeySize(version);
- // call ecb explicit
- my_aes_encrypt_dynamic_type func= get_aes_encrypt_func(MY_AES_ALGORITHM_ECB);
- int rc = (*func)(src, srclen,
- buf, &buflen,
- (unsigned char*)&keybuf, key_len,
- NULL, 0,
- 1);
+ int rc = GetCryptoKey(version, (unsigned char*)keybuf, *key_length);
- if (rc != AES_OK) {
+ if (rc != CRYPT_KEY_OK) {
ib_logf(IB_LOG_LEVEL_FATAL,
- "Unable to encrypt key-block "
- " src: %p srclen: %d buf: %p buflen: %d."
- " return-code: %d. Can't continue!\n",
- src, srclen, buf, buflen, rc);
+ "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;
}
- if (!page_encrypted) {
- crypt_data->keys[0].key_version = version;
- crypt_data->key_count++;
- if (crypt_data->key_count > array_elements(crypt_data->keys)) {
- crypt_data->key_count = array_elements(crypt_data->keys);
- }
+ // do ctr key initialization
+ if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR)
+ {
+ // Now compute L by encrypting IV using this key
+ const unsigned char* src = page_encrypted ? iv : crypt_data->iv;
+ const int srclen = page_encrypted ? iv_len : crypt_data->iv_length;
+ unsigned char* buf = page_encrypted ? keybuf : crypt_data->keys[0].key;
+ uint32 buflen = page_encrypted ? *key_length : sizeof(crypt_data->keys[0].key);
+
+ // call ecb explicit
+ my_aes_encrypt_dynamic_type func = get_aes_encrypt_func(MY_AES_ALGORITHM_ECB);
+ int rc = (*func)(src, srclen,
+ buf, &buflen,
+ (unsigned char*)keybuf, *key_length,
+ NULL, 0,
+ 1);
+
+ if (rc != AES_OK) {
+ ib_logf(IB_LOG_LEVEL_FATAL,
+ "Unable to encrypt key-block "
+ " src: %p srclen: %d buf: %p buflen: %d."
+ " return-code: %d. Can't continue!\n",
+ src, srclen, buf, buflen, rc);
+ ut_error;
+ }
+
+ if (!page_encrypted) {
+ crypt_data->keys[0].key_version = version;
+ crypt_data->key_count++;
+
+ if (crypt_data->key_count > array_elements(crypt_data->keys)) {
+ crypt_data->key_count = array_elements(crypt_data->keys);
+ }
+ }
+
+ // set the key size to the aes block size because this encrypted data is the key
+ *key_length = MY_AES_BLOCK_SIZE;
+ memcpy(dst, buf, buflen);
+ }
+ else
+ {
+ // otherwise keybuf contains the right key
+ memcpy(dst, keybuf, *key_length);
}
- memcpy(dst, buf, buflen);
-
if (!page_encrypted) {
mutex_exit(&crypt_data->mutex);
}
@@ -290,14 +290,22 @@ fil_crypt_get_key(byte *dst, uint dstlen,
Get key bytes for a space/latest(key-version) */
static inline
void
-fil_crypt_get_latest_key(byte *dst, uint dstlen,
+fil_crypt_get_latest_key(byte *dst, uint* key_length,
fil_space_crypt_t* crypt_data, uint *version)
{
if (srv_encrypt_tables) {
- *version = GetLatestCryptoKeyVersion();
- return fil_crypt_get_key(dst, dstlen, crypt_data, *version, false);
+ // used for key rotation - get the next key id from the key provider
+ int rc = GetLatestCryptoKeyVersion();
+
+ // if no new key was created use the last one
+ if (rc >= 0)
+ {
+ *version = rc;
+ }
+
+ return fil_crypt_get_key(dst, key_length, crypt_data, *version, false);
} else {
- return fil_crypt_get_key(dst, dstlen, NULL, *version, true);
+ return fil_crypt_get_key(dst, key_length, NULL, *version, true);
}
}
@@ -614,7 +622,8 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn,
// get key (L)
uint key_version;
- byte key[CRYPT_SCHEME_1_IV_LEN];
+ byte key[MY_AES_MAX_KEY_LENGTH];
+ uint key_length;
if (srv_encrypt_tables) {
crypt_data = fil_space_get_crypt_data(space);
@@ -623,12 +632,45 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn,
memcpy(dst_frame, src_frame, page_size);
return;
}
- fil_crypt_get_latest_key(key, sizeof(key), crypt_data, &key_version);
+ fil_crypt_get_latest_key(key, &key_length, crypt_data, &key_version);
} else {
key_version = encryption_key;
- fil_crypt_get_latest_key(key, sizeof(key), NULL, (uint*)&key_version);
+ fil_crypt_get_latest_key(key, &key_length, NULL, (uint*)&key_version);
}
+
+ /* Load the iv or counter (depending to the encryption algorithm used) */
+ unsigned char iv[MY_AES_BLOCK_SIZE];
+
+ if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR)
+ {
+ // create counter block (C)
+ mach_write_to_4(iv + 0, space);
+ ulint space_offset = mach_read_from_4(
+ src_frame + FIL_PAGE_OFFSET);
+ mach_write_to_4(iv + 4, space_offset);
+ mach_write_to_8(iv + 8, lsn);
+ }
+ else
+ {
+ // take the iv from the key provider
+
+ int load_iv_rc = GetCryptoIV(key_version, (uchar *) iv, sizeof(iv));
+
+ // if the iv can not be loaded the whole page can not be encrypted
+ if (load_iv_rc != CRYPT_KEY_OK)
+ {
+ ib_logf(IB_LOG_LEVEL_FATAL,
+ "Unable to decrypt data-block. "
+ " Can not load iv for key %d"
+ " return-code: %d. Can't continue!\n",
+ key_version, load_iv_rc);
+
+ ut_error;
+ }
+ }
+
+
ibool page_compressed = (mach_read_from_2(src_frame+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED);
ibool page_encrypted = fil_space_is_page_encrypted(space);
@@ -662,14 +704,6 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn,
key_version);
}
- // create counter block (C)
- unsigned char counter[MY_AES_BLOCK_SIZE];
- mach_write_to_4(counter + 0, space);
- ulint space_offset = mach_read_from_4(
- src_frame + FIL_PAGE_OFFSET);
- mach_write_to_4(counter + 4, space_offset);
- mach_write_to_8(counter + 8, lsn);
-
// encrypt page data
ulint unencrypted_bytes = FIL_PAGE_DATA + FIL_PAGE_DATA_END;
ulint srclen = page_size - unencrypted_bytes;
@@ -683,10 +717,10 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn,
int rc = (* my_aes_encrypt_dynamic)(src, srclen,
- dst, &dstlen,
- (unsigned char*)&key, sizeof(key),
- (unsigned char*)&counter, sizeof(counter),
- 1);
+ dst, &dstlen,
+ (unsigned char*)key, key_length,
+ (unsigned char*)iv, sizeof(iv),
+ 1);
if (! ((rc == AES_OK) && ((ulint) dstlen == srclen))) {
ib_logf(IB_LOG_LEVEL_FATAL,
@@ -776,6 +810,7 @@ bool
fil_space_decrypt(fil_space_crypt_t* crypt_data,
const byte* src_frame, ulint page_size, byte* dst_frame)
{
+ ulint space_id = mach_read_from_4(src_frame + FIL_PAGE_SPACE_ID);
ulint page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
// key version
uint key_version;
@@ -791,7 +826,7 @@ fil_space_decrypt(fil_space_crypt_t* crypt_data,
if (page_type == FIL_PAGE_PAGE_ENCRYPTED) {
key_version = mach_read_from_2(
src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
- fprintf(stderr, "JAN: key_version %u\n", key_version);
+ fprintf(stderr, "JAN: key_version %lu\n", key_version);
orig_page_type = mach_read_from_2(
src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 2);
fprintf(stderr, "JAN: decrypt: orig_page_type %lu\n", orig_page_type);
@@ -816,10 +851,6 @@ fil_space_decrypt(fil_space_crypt_t* crypt_data,
fprintf(stderr, "JAN: space %lu, offset %lu lsn %lu\n", space, offset, lsn);
- // get key (L)
- byte key[CRYPT_SCHEME_1_IV_LEN];
- fil_crypt_get_key(key, sizeof(key), crypt_data, key_version, page_encrypted);
-
// copy page header
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
@@ -828,11 +859,41 @@ fil_space_decrypt(fil_space_crypt_t* crypt_data,
mach_write_to_2(dst_frame+FIL_PAGE_TYPE, orig_page_type);
}
- // create counter block
- unsigned char counter[MY_AES_BLOCK_SIZE];
- mach_write_to_4(counter + 0, space);
- mach_write_to_4(counter + 4, offset);
- mach_write_to_8(counter + 8, lsn);
+
+ // get key
+ byte key[MY_AES_MAX_KEY_LENGTH];
+ uint key_length;
+ fil_crypt_get_key(key, &key_length, crypt_data, key_version, page_encrypted);
+
+ // get the iv
+ unsigned char iv[MY_AES_BLOCK_SIZE];
+
+ if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR)
+ {
+ // create counter block
+
+ mach_write_to_4(iv + 0, space);
+ mach_write_to_4(iv + 4, offset);
+ mach_write_to_8(iv + 8, lsn);
+ }
+ else
+ {
+ // take the iv from the key provider
+
+ int load_iv_rc = GetCryptoIV(key_version, (uchar *) iv, sizeof(iv));
+
+ // if the iv can not be loaded the whole page can not be decrypted
+ if (load_iv_rc != CRYPT_KEY_OK)
+ {
+ ib_logf(IB_LOG_LEVEL_FATAL,
+ "Unable to decrypt data-block. "
+ " Can not load iv for key %d"
+ " return-code: %d. Can't continue!\n",
+ key_version, load_iv_rc);
+
+ return AES_KEY_CREATION_FAILED;
+ }
+ }
// decrypt page data
ulint unencrypted_bytes = FIL_PAGE_DATA + FIL_PAGE_DATA_END;
@@ -857,10 +918,10 @@ fil_space_decrypt(fil_space_crypt_t* crypt_data,
srclen = pow((double)2, (double)((int)compressed_len));
}
int rc = (* my_aes_decrypt_dynamic)(src, srclen,
- dst, &dstlen,
- (unsigned char*)&key, sizeof(key),
- (unsigned char*)&counter, sizeof(counter),
- 1);
+ dst, &dstlen,
+ (unsigned char*)key, key_length,
+ (unsigned char*)iv, sizeof(iv),
+ 1);
if (! ((rc == AES_OK) && ((ulint) dstlen == srclen))) {
ib_logf(IB_LOG_LEVEL_FATAL,
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 18b65c83949..30b021cb319 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -30,7 +30,6 @@ Created 10/25/1995 Heikki Tuuri
#include "fil0pageencryption.h"
#include "fsp0pageencryption.h"
-#include "KeySingleton.h"
#include <debug_sync.h>
#include <my_dbug.h>
@@ -824,7 +823,7 @@ fil_node_open_file(
success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE,
space->flags);
- if (fil_page_can_not_decrypt(page)) {
+ if (fil_page_encryption_status(page)) {
/* if page is (still) encrypted, write an error and return.
* Otherwise the server would crash if decrypting is not possible.
* This may be the case, if the key file could not be
@@ -1329,8 +1328,7 @@ fil_space_create(
ut_a(fil_system);
if (fsp_flags_is_page_encrypted(flags)) {
- if (!KeySingleton::getInstance().isAvailable()
- || KeySingleton::getInstance().getKeys(fsp_flags_get_page_encryption_key(flags))==NULL) {
+ if (!HasCryptoKey(fsp_flags_get_page_encryption_key(flags))) {
/* by returning here it should be avoided that
* the server crashes, if someone tries to access an
* encrypted table and the encryption key is not available.
@@ -2099,7 +2097,7 @@ fil_check_first_page(
or the encryption key is not available, the
check for reading the first page should intentionally fail
with "can not decrypt" message. */
- page_is_encrypted = fil_page_can_not_decrypt(page);
+ page_is_encrypted = fil_page_encryption_status(page);
if ((page_is_encrypted == PAGE_ENCRYPTION_KEY_MISSING) && page_is_encrypted) {
page_is_encrypted = 1;
} else {
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 0f0ab32c7f5..99d619092d4 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -104,8 +104,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "page0zip.h"
#include "fil0pagecompress.h"
-#include "KeySingleton.h"
-
#define thd_get_trx_isolation(X) ((enum_tx_isolation)thd_tx_isolation(X))
@@ -203,12 +201,6 @@ static char* innobase_disable_monitor_counter = NULL;
static char* innobase_reset_monitor_counter = NULL;
static char* innobase_reset_all_monitor_counter = NULL;
-/* Encryption for tables and columns */
-static char* innobase_data_encryption_providername = NULL;
-static char* innobase_data_encryption_providerurl = NULL;
-static uint innobase_data_encryption_providertype = 0; // 1 == file, 2 == server
-static char* innobase_data_encryption_filekey = NULL;
-
/* The highest file format being used in the database. The value can be
set by user, however, it will be adjusted to the newer file format if
a table of such format is created/opened. */
@@ -3131,10 +3123,6 @@ innobase_init(
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
- KeySingleton::getInstance(
- innobase_data_encryption_providername, innobase_data_encryption_providerurl,
- innobase_data_encryption_providertype, innobase_data_encryption_filekey);
-
#ifndef DBUG_OFF
static const char test_filename[] = "-@";
char test_tablename[sizeof test_filename
@@ -3760,8 +3748,6 @@ innobase_end(
mysql_mutex_destroy(&pending_checkpoint_mutex);
}
- KeySingleton::getInstance().~KeySingleton();
-
DBUG_RETURN(err);
}
@@ -11254,15 +11240,6 @@ ha_innobase::check_table_options(
" innodb_file_per_table.");
return "PAGE_ENCRYPTION";
}
-
- if (!KeySingleton::getInstance().isAvailable()) {
- push_warning(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_WRONG_CREATE_OPTION,
- "InnoDB: PAGE_ENCRYPTION needs a key provider"
- );
- return "PAGE_ENCRYPTION";
- }
}
/* Check page compression requirements */
@@ -11352,7 +11329,7 @@ ha_innobase::check_table_options(
return "PAGE_ENCRYPTION_KEY";
}
- if (!KeySingleton::getInstance().isAvailable() || KeySingleton::getInstance().getKeys(options->page_encryption_key)==NULL) {
+ if (!HasCryptoKey(options->page_encryption_key)) {
push_warning_printf(
thd, Sql_condition::WARN_LEVEL_WARN,
HA_WRONG_CREATE_OPTION,
@@ -19044,26 +19021,6 @@ static MYSQL_SYSVAR_ULONG(fatal_semaphore_wait_threshold, srv_fatal_semaphore_wa
UINT_MAX32, /* Maximum setting */
0);
-static MYSQL_SYSVAR_UINT(data_encryption_providertype, innobase_data_encryption_providertype,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Use table or column encryption / decryption. Default is 0 for no use, 1 for keyfile and 2 for keyserver.",
- NULL, NULL, 1, 0, 2, 0);
-
-static MYSQL_SYSVAR_STR(data_encryption_providername, innobase_data_encryption_providername,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Name of keyfile or keyserver.",
- NULL, NULL, NULL);
-
-static MYSQL_SYSVAR_STR(data_encryption_providerurl, innobase_data_encryption_providerurl,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Path or URL for keyfile or keyserver.",
- NULL, NULL, NULL);
-
-static MYSQL_SYSVAR_STR(data_encryption_filekey, innobase_data_encryption_filekey,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Key to encrypt / decrypt the keyfile.",
- NULL, NULL, NULL);
-
static MYSQL_SYSVAR_BOOL(encrypt_tables, srv_encrypt_tables, 0,
"Encrypt tables",
0, 0, 0);
@@ -19342,11 +19299,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(compression_algorithm),
MYSQL_SYSVAR(mtflush_threads),
MYSQL_SYSVAR(use_mtflush),
- /* Table encryption feature */
- MYSQL_SYSVAR(data_encryption_providertype),
- MYSQL_SYSVAR(data_encryption_providername),
- MYSQL_SYSVAR(data_encryption_providerurl),
- MYSQL_SYSVAR(data_encryption_filekey),
/* Encryption feature */
MYSQL_SYSVAR(encrypt_tables),
MYSQL_SYSVAR(encryption_threads),
diff --git a/storage/innobase/include/EncKeys.h b/storage/innobase/include/EncKeys.h
deleted file mode 100644
index 43f2920fd7f..00000000000
--- a/storage/innobase/include/EncKeys.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright (C) 2014 eperi GmbH. All Rights Reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-/******************************************************************//**
-@file EncKeys.h
-A structure and class to keep keys for encryption/decryption.
-
-Created 09/15/2014
-***********************************************************************/
-
-#ifndef ENCKEYS_H_
-#define ENCKEYS_H_
-
-#include "univ.i"
-#include <sys/types.h>
-#include <stdio.h>
-
-
-
-
-struct keyentry {
- ulint id;
- char *iv;
- char *key;
-};
-
-
-class EncKeys
-{
-private:
- static const char *strMAGIC, *newLine;
- static const int magicSize;
-
- enum constants { MAX_OFFSETS_IN_PCRE_PATTERNS = 30};
- enum keyAttributes { KEY_MIN = 1, KEY_MAX = 255, MAX_KEYS = 255,
- MAX_IVLEN = 256, MAX_KEYLEN = 512, ivSize16 = 16, keySize32 = 32 };
- enum keyInitType { KEYINITTYPE_FILE = 1, KEYINITTYPE_SERVER = 2 };
- enum errorAttributes { MAX_KEY_LINE_SIZE = 3 * MAX_KEYLEN, MAX_KEY_FILE_SIZE = 1048576 };
- enum errorCodesLine { NO_ERROR_PARSE_OK = 0, NO_ERROR_ISCOMMENT = 10, NO_ERROR_KEY_GREATER_THAN_ASKED = 20,
- ERROR_NOINITIALIZEDKEY = 30, ERROR_ID_TOO_BIG = 40, ERROR_WRONG_NUMBER_OF_MATCHES = 50,
- ERROR_EQUAL_DOUBLE_KEY = 60, ERROR_UNEQUAL_DOUBLE_KEY = 70 };
-
- static const char *errorNoKeyId, *errorInMatches, *errorExceedKeyFileSize,
- *errorExceedKeySize, *errorEqualDoubleKey, *errorUnequalDoubleKey,
- *errorNoInitializedKey, *errorFalseFileKey,
- *errorNotImplemented, *errorOpenFile, *errorReadingFile, *errorFileSize;
-
- static const char* initialPwd;
- ulint countKeys, keyLineInKeyFile;
- keyentry keys[MAX_KEYS], *oneKey;
-
- void printKeyEntry( ulint id);
- int initKeysThroughFile( const char *name, const char *path, const char *filekey);
- int initKeysThroughServer( const char *name, const char *path, const char *filekey);
- bool isComment( const char *line);
- char * decryptFile( const char* filename, const char *secret, int *errorCode);
- int parseFile( const char* filename, const ulint maxKeyId, const char *secret);
- int parseLine( const char *line, const ulint maxKeyId);
-
-public:
- static const size_t MAX_SECRET_SIZE = 256;
-
- enum errorCodesFile { NO_ERROR_KEY_FILE_PARSE_OK = 0, ERROR_KEY_FILE_PARSE_NULL = 110,
- ERROR_KEY_FILE_TOO_BIG = 120, ERROR_KEY_FILE_EXCEEDS_MAX_NUMBERS_OF_KEYS = 130,
- ERROR_OPEN_FILE = 140, ERROR_READING_FILE = 150, ERROR_FALSE_FILE_KEY = 160,
- ERROR_KEYINITTYPE_SERVER_NOT_IMPLEMENTED = 170, ERROR_ENCRYPTION_SECRET_NULL = 180 };
- EncKeys();
- virtual ~EncKeys();
- bool initKeys( const char *name, const char *url, const int initType, const char *filekey);
- keyentry *getKeys( int id);
- /* made public for unit testing */
- static void parseSecret( const char *filename, char *secret );
-
-};
-
-#endif /* ENCKEYS_H_ */
diff --git a/storage/innobase/include/KeySingleton.h b/storage/innobase/include/KeySingleton.h
deleted file mode 100644
index 2b2f3991998..00000000000
--- a/storage/innobase/include/KeySingleton.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (C) 2014 eperi GmbH. All Rights Reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-/******************************************************************//**
-@file KeySingletonPattern.h
-Implementation of single pattern to keep keys for encrypting/decrypting pages.
-
-Created 09/13/2014
-***********************************************************************/
-
-
-#ifndef KEYSINGLETON_H_
-#define KEYSINGLETON_H_
-
-#include "EncKeys.h"
-
-
-class KeySingleton
-{
-private:
- static bool instanceInited;
- static KeySingleton theInstance;
- static EncKeys encKeys;
-
- // No new instance or object possible
- KeySingleton() {}
-
- // No new instance possible through copy constructor
- KeySingleton( const KeySingleton&) {}
-
- // No new instance possible through copy
- KeySingleton & operator = (const KeySingleton&);
-
-public:
- virtual ~KeySingleton() {encKeys.~EncKeys();}
- static KeySingleton& getInstance();
- // Init the instance for only one time
- static KeySingleton& getInstance(const char *name, const char *url,
- const int initType, const char *filekey);
- keyentry *getKeys(int id);
- ibool hasKey(int id);
- static bool isAvailable() {
- return instanceInited;
- }
-};
-
-#endif /* KEYSINGLETON_H_ */
diff --git a/storage/innobase/include/fil0pageencryption.h b/storage/innobase/include/fil0pageencryption.h
index 395361bcd04..9769f8c1912 100644
--- a/storage/innobase/include/fil0pageencryption.h
+++ b/storage/innobase/include/fil0pageencryption.h
@@ -69,7 +69,7 @@ Find out whether the page can be decrypted
@return true if page can be decrypted, false if not. */
UNIV_INLINE
ulint
-fil_page_can_not_decrypt(
+fil_page_encryption_status(
/*===================*/
const byte *buf); /*!< in: page */
diff --git a/storage/innobase/include/fsp0pageencryption.ic b/storage/innobase/include/fsp0pageencryption.ic
index ad016c46fdb..42c980b0430 100644
--- a/storage/innobase/include/fsp0pageencryption.ic
+++ b/storage/innobase/include/fsp0pageencryption.ic
@@ -24,8 +24,8 @@ Created 08/28/2014
***********************************************************************/
#include "fsp0fsp.h"
-#include "KeySingleton.h"
#include "fil0pageencryption.h"
+#include <my_crypt_key_management.h>
/********************************************************************//**
@@ -138,7 +138,7 @@ The function for decrypting the page should already be executed before this.
*/
UNIV_INLINE
ulint
-fil_page_can_not_decrypt(
+fil_page_encryption_status(
/*=====================*/
const byte *buf) /*!< in: page */
{
@@ -147,11 +147,9 @@ fil_page_can_not_decrypt(
if (page_type == FIL_PAGE_TYPE_FSP_HDR) {
ulint flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + buf);
if (fsp_flags_is_page_encrypted(flags)) {
- if (!KeySingleton::getInstance().isAvailable() ||
- !KeySingleton::getInstance().hasKey(fsp_flags_get_page_encryption_key(flags))) {
+ if (!HasCryptoKey(fsp_flags_get_page_encryption_key(flags))) {
/* accessing table would surely fail, because no key or no key provider available */
- if (KeySingleton::getInstance().isAvailable() &&
- !KeySingleton::getInstance().hasKey(fsp_flags_get_page_encryption_key(flags))) {
+ if (!HasCryptoKey(fsp_flags_get_page_encryption_key(flags))) {
return PAGE_ENCRYPTION_KEY_MISSING;
}
return PAGE_ENCRYPTION_ERROR;
@@ -161,8 +159,7 @@ fil_page_can_not_decrypt(
if(page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
ulint key = mach_read_from_4(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
- if (KeySingleton::getInstance().isAvailable() &&
- !KeySingleton::getInstance().hasKey(key)) {
+ if (!HasCryptoKey(key)) {
return PAGE_ENCRYPTION_KEY_MISSING;
}
return PAGE_ENCRYPTION_ERROR;
diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc
index f902df61484..d7dd6b38459 100644
--- a/storage/innobase/log/log0crypt.cc
+++ b/storage/innobase/log/log0crypt.cc
@@ -4,11 +4,13 @@ Innodb log encrypt/decrypt
Created 11/25/2013 Minli Zhu
*******************************************************/
+#include "m_string.h"
#include "log0crypt.h"
+#include <my_crypt.h>
+
#include "log0log.h"
#include "srv0start.h" // for srv_start_lsn
#include "log0recv.h" // for recv_sys
-#include <my_crypt.h>
/* If true, enable redo log encryption. */
UNIV_INTERN my_bool srv_encrypt_log = FALSE;
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 20f6d4d1db0..0bcbe01c0f6 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -4703,9 +4703,9 @@ found:
}
- if (srv_encrypt_tables) {
- page_encryption = TRUE;
- }
+// if (srv_encrypt_tables) {
+ //page_encryption = TRUE;
+// }
/* If the space is page encryption and this is write operation
then we encrypt the page */
diff --git a/storage/tokudb/ft-index/ft/ftverify b/storage/tokudb/ft-index/ft/ftverify
new file mode 100755
index 00000000000..96b86bfe250
--- /dev/null
+++ b/storage/tokudb/ft-index/ft/ftverify
Binary files differ
diff --git a/storage/tokudb/ft-index/ft/tdb-recover b/storage/tokudb/ft-index/ft/tdb-recover
new file mode 100755
index 00000000000..8df5480b705
--- /dev/null
+++ b/storage/tokudb/ft-index/ft/tdb-recover
Binary files differ
diff --git a/storage/tokudb/ft-index/ft/tdb_logprint b/storage/tokudb/ft-index/ft/tdb_logprint
new file mode 100755
index 00000000000..3055805b767
--- /dev/null
+++ b/storage/tokudb/ft-index/ft/tdb_logprint
Binary files differ
diff --git a/storage/tokudb/ft-index/ft/tokuftdump b/storage/tokudb/ft-index/ft/tokuftdump
new file mode 100755
index 00000000000..5b0b4c3b78a
--- /dev/null
+++ b/storage/tokudb/ft-index/ft/tokuftdump
Binary files differ
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index d0a8b137791..121d7914083 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -359,8 +359,6 @@ SET(INNOBASE_SOURCES
dict/dict0stats.cc
dict/dict0stats_bg.cc
dyn/dyn0dyn.cc
- enc/EncKeys.cc
- enc/KeySingleton.cc
eval/eval0eval.cc
eval/eval0proc.cc
fil/fil0fil.cc
diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc
index 227570626ca..d32c5fb138f 100644
--- a/storage/xtradb/buf/buf0buf.cc
+++ b/storage/xtradb/buf/buf0buf.cc
@@ -5807,7 +5807,7 @@ buf_page_encrypt_before_write(
// encrypt page content
fil_space_encrypt(bpage->space, bpage->offset,
bpage->newest_modification,
- src_frame, zip_size, dst_frame);
+ src_frame, zip_size, dst_frame, 0);
unsigned key_version =
mach_read_from_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
diff --git a/storage/xtradb/enc/EncKeys.cc b/storage/xtradb/enc/EncKeys.cc
deleted file mode 100644
index 3b5e9f4121c..00000000000
--- a/storage/xtradb/enc/EncKeys.cc
+++ /dev/null
@@ -1,458 +0,0 @@
-/* Copyright (C) 2014 eperi GmbH. All Rights Reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-/******************************************************************//**
- @file EncKeys.cc
- A class to keep keys for encryption/decryption.
-
-How it works...
-The location and usage can be configured via the configuration file.
-Example
-
-[mysqld]
-...
-innodb_data_encryption_providertype = 1
-innodb_data_encryption_providername = keys.enc
-innodb_data_encryption_providerurl = /home/mdb/
-innodb_data_encryption_filekey = secret
-...
-
-As provider type currently only value 1 is supported, which means, the keys are read from a file.
-The filename is set up via the innodb_data_encryption_providername configuration value.
-innodb_data_encryption_providerurl is used to configure the path to this file. This is usually
-a folder name.
-Examples:
-innodb_data_encryption_providerurl = \\\\unc (windows share)
-innodb_data_encryption_providerurl = e:/tmp/ (windows path)
-innodb_data_encryption_providerurl = /tmp (linux path)
-
-The key file contains AES keys and initialization vectors as hex-encoded Strings.
-Supported are keys of size 128, 192 or 256 bits. IV consists of 16 bytes.
-
-The key file should be encrypted and the key to decrypt the file can be given with the
-innodb_data_encryption_filekey parameter.
-
-The file key can also be located if FILE: is prepended to the key. Then the following part is interpreted
-as absolut to the file containing the file key. This file can optionally be encrypted, currently with a fix key.
-Example:
-innodb_data_encryption_filekey = FILE:y:/secret256.enc
-
-If the key file can not be read at server startup, for example if the file key is not present,
-page_encryption feature is not availabe and access to page_encryption tables is not possible.
-
-Example files can be found inside the unittest/eperi folder.
-
-Open SSL command line utility can be used to create an encrypted key file.
-Examples:
-openssl enc –aes-256-cbc –md sha1 –k secret –in keys.txt –out keys.enc
-openssl enc –aes-256-cbc –md sha1 –k <initialPwd> –in secret –out secret.enc
-
- Created 09/15/2014
- ***********************************************************************/
-#ifdef __WIN__
-#define PCRE_STATIC 1
-#endif
-
-#include "EncKeys.h"
-#include <my_global.h>
-#include <my_aes.h>
-#include <memory.h>
-#include <my_sys.h>
-#include <pcre.h>
-#include <string.h>
-#include <my_sys.h>
-
-
-
-
-const char* EncKeys::strMAGIC = "Salted__";
-#define magicSize 8 //strlen(strMAGIC); // 8 byte
-const char* EncKeys::newLine = "\n";
-
-const char* EncKeys::errorNoKeyId = "KeyID = %u not found or with error. Check the key and the log file.\n";
-const char* EncKeys::errorInMatches = "Wrong match of the keyID in line %u, see the template.\n";
-const char* EncKeys::errorExceedKeyFileSize = "The size of the key file %s exceeds "
- "the maximum allowed of %u bytes.\n";
-const char* EncKeys::errorExceedKeySize = "The key size exceeds the maximum allowed size of %u in line %u.\n";
-const char* EncKeys::errorEqualDoubleKey = "More than one identical key with keyID = %u found"
- " in lines %u and %u.\nDelete one of them in the key file.\n";
-const char* EncKeys::errorUnequalDoubleKey = "More than one not identical key with keyID = %u found"
- " in lines %u and %u.\nChoose the right one and delete the other in the key file.\n"
- "I'll take the key from line %u\n";
-const char* EncKeys::errorNoInitializedKey = "The key could not be initialized.\n";
-const char* EncKeys::errorNotImplemented = "Initializing keys through key server is not"
- " yet implemented.\nYou can not read encrypted tables or columns\n\n";
-const char* EncKeys::errorOpenFile = "Could not open %s for reading. You can not read encrypted tables or columns.\n\n";
-const char* EncKeys::errorReadingFile = "Could not read from %s. You can not read encrypted tables or columns\n\n";
-const char* EncKeys::errorFileSize = "Could not get the file size from %s. You can not read encrypted tables or columns\n\n";
-const char* EncKeys::errorFalseFileKey = "Wrong encryption / decryption key for keyfile '%s'.\n";
-
-/* read this from a secret source in some later version */
-const char* EncKeys::initialPwd = "lg28s9ac5ffa537fd8798875c98e190df289da7e047c05";
-
-EncKeys::EncKeys() {
- countKeys = keyLineInKeyFile = 0;
- for (int ii = 0; ii < MAX_KEYS; ii++) {
- keys[ii].id = 0;
- keys[ii].iv = keys[ii].key = NULL;
- }
- oneKey = NULL;
-}
-
-EncKeys::~EncKeys() {
- for (int ii = MAX_KEYS - 1; ii >= 0 ; ii--) {
- delete[] keys[ii].iv; keys[ii].iv = NULL;
- delete[] keys[ii].key; keys[ii].key = NULL;
-
- }
-}
-
-bool EncKeys::initKeys(const char *name, const char *url, const int initType, const char *filekey) {
- if (KEYINITTYPE_FILE == initType)
- {
- int result = initKeysThroughFile(name, url, filekey);
- return ERROR_FALSE_FILE_KEY != result && ERROR_OPEN_FILE != result && ERROR_READING_FILE != result;
- }
- else if (KEYINITTYPE_SERVER == initType)
- {
- return NO_ERROR_KEY_FILE_PARSE_OK == initKeysThroughServer(name, url, filekey);
- }
- return false;
-}
-
-int EncKeys::initKeysThroughFile(const char *name, const char *path, const char *filekey) {
- if (path==NULL || name==NULL) return ERROR_OPEN_FILE;
- size_t len1 = strlen(path);
- size_t len2 = strlen(name);
- const char *MAGIC = "FILE:";
- const short MAGIC_LEN = 5;
- int ret = NO_ERROR_KEY_FILE_PARSE_OK;
- bool isUncPath= (len1>2) ? ((strncmp("\\\\", path, 2)==0) ? TRUE : FALSE) : FALSE;
- bool isSlash = ((isUncPath? '\\':'/') == path[len1 - 1]);
- char *secret = (char*) malloc(MAX_SECRET_SIZE +1 * sizeof(char));
- char *filename = (char*) malloc((len1 + len2 + (isSlash ? 1 : 2)) * sizeof(char));
- if(filekey != NULL)
- {
- //If secret starts with FILE: interpret the secret as filename.
- if(memcmp(MAGIC, filekey, MAGIC_LEN) == 0) {
- int fk_len = strlen(filekey);
- char *secretfile = (char*)malloc( (1 + fk_len - MAGIC_LEN)* sizeof(char));
- memcpy(secretfile, filekey+MAGIC_LEN, fk_len - MAGIC_LEN);
- secretfile[fk_len-MAGIC_LEN] = '\0';
- parseSecret(secretfile, secret);
- free(secretfile);
- } else
- {
- sprintf(secret, "%s", filekey);
- }
- }
- sprintf(filename, "%s%s%s", path, isSlash ? "" : (isUncPath ? "\\":"/"), name);
- ret = parseFile((const char *)filename, 254, secret);
- free(filename);
- free(secret);
- return ret;
-}
-
-int EncKeys::initKeysThroughServer( const char *name, const char *path, const char *filekey)
-{
- //TODO
-#ifdef UNIV_DEBUG
- fprintf(stderr, errorNotImplemented);
-#endif //UNIV_DEBUG
- return ERROR_KEYINITTYPE_SERVER_NOT_IMPLEMENTED;
-}
-
-
-/*
- secret is limited to MAX_SECRET_SIZE characters
-*/
-
-void EncKeys::parseSecret(const char *secretfile, char *secret)
-{
- int maxSize = (MAX_SECRET_SIZE +16 + magicSize*2) ;
- uchar* buf = (uchar*)malloc((maxSize) * sizeof(uchar));
- char* _initPwd = (char*)malloc((strlen(initialPwd)+1) * sizeof(char));
-
- FILE *fp = fopen(secretfile, "rb");
- fseek(fp, 0L, SEEK_END);
- long file_size = ftell(fp);
- rewind(fp);
- int bytes_to_read = MY_MIN(maxSize, file_size);
- if ((fread(buf, 1, bytes_to_read, fp)) != bytes_to_read)
- {
- secret[0]=0;
- goto err;
- }
-
- if (memcmp(buf, strMAGIC, magicSize))
- {
- bytes_to_read = ((unsigned int) bytes_to_read>MAX_SECRET_SIZE) ? MAX_SECRET_SIZE : bytes_to_read;
- memcpy(secret, buf, bytes_to_read);
- secret[bytes_to_read] = '\0';
- }
- else
- {
- unsigned char salt[magicSize];
- unsigned char *key = new unsigned char[keySize32];
- unsigned char *iv = new unsigned char[ivSize16];
- memcpy(&salt, buf + magicSize, magicSize);
- memcpy(_initPwd, initialPwd, strlen(initialPwd));
- _initPwd[strlen(initialPwd)]= '\0';
- my_bytes_to_key((unsigned char *) salt, _initPwd, key, iv);
- uint32 d_size = 0;
-
- /* This file is always encoded with cbc */
- enum_my_aes_encryption_algorithm org_method= current_aes_dynamic_method;
- my_aes_init_dynamic_encrypt(MY_AES_ALGORITHM_CBC);
- int res = my_aes_decrypt_dynamic((const uchar*)buf + 2 * magicSize,
- bytes_to_read - 2 * magicSize,
- (uchar*)secret, &d_size, (const uchar*)key, keySize32,
- iv, ivSize16, 0);
- my_aes_init_dynamic_encrypt(org_method);
- /* We would prefer a better error handling, but this will due for now */
- if (res != 0)
- d_size= 0;
- if (d_size>EncKeys::MAX_SECRET_SIZE)
- d_size = EncKeys::MAX_SECRET_SIZE;
- secret[d_size] = '\0';
- delete[] key;
- delete[] iv;
- }
-
-err:
- free(buf);
- free(_initPwd);
- fclose(fp);
-}
-
-/**
- * Returns a struct keyentry with the asked 'id' or NULL.
- */
-
-keyentry *EncKeys::getKeys(int id)
-{
- if (KEY_MIN <= id && KEY_MAX >= id && (&keys[id - 1])->iv)
- {
- return &keys[id - 1];
- }
- DBUG_PRINT("error", (errorNoKeyId, id));
- return NULL;
-}
-
-/**
- * Get the keys from the key file <filename> and decrypt it with the key <secret>.
- * Store the keys with id smaller then <maxKeyId> in an array of structs keyentry.
- * Returns NO_ERROR_PARSE_OK or an appropriate error code.
- */
-int EncKeys::parseFile(const char* filename, const ulint maxKeyId, const char *secret) {
- int errorCode = 0;
- char *buffer = decryptFile(filename, secret, &errorCode);
- ulint id = 0;
-
- if (NO_ERROR_PARSE_OK != errorCode) return errorCode;
- else errorCode = NO_ERROR_KEY_FILE_PARSE_OK;
-
- char *line = strtok(buffer, newLine);
- while ( NULL != line) {
- keyLineInKeyFile++;
- switch (parseLine(line, maxKeyId)) {
- case NO_ERROR_PARSE_OK:
- id = oneKey->id;
- keys[oneKey->id - 1] = *oneKey;
- delete(oneKey);
- countKeys++;
- fprintf(stderr, "Line: %u --> ", (uint) keyLineInKeyFile); printKeyEntry(id);
- break;
- case ERROR_ID_TOO_BIG:
- fprintf(stderr, errorExceedKeySize, KEY_MAX, keyLineInKeyFile);
- fprintf(stderr, " --> %s\n", line);
- errorCode = ERROR_KEY_FILE_EXCEEDS_MAX_NUMBERS_OF_KEYS;
- break;
- case ERROR_NOINITIALIZEDKEY:
- fprintf(stderr, errorNoInitializedKey);
- fprintf(stderr, " --> %s\n", line);
- errorCode = ERROR_KEY_FILE_PARSE_NULL;
- break;
- case ERROR_WRONG_NUMBER_OF_MATCHES:
- fprintf(stderr, errorInMatches, keyLineInKeyFile);
- fprintf(stderr, " --> %s\n", line);
- errorCode = ERROR_KEY_FILE_PARSE_NULL;
- break;
- case NO_ERROR_KEY_GREATER_THAN_ASKED:
- fprintf(stderr, "No asked key in line %lu: %s\n", keyLineInKeyFile, line);
- break;
- case NO_ERROR_ISCOMMENT:
- fprintf(stderr, "Is comment in line %lu: %s\n", keyLineInKeyFile, line);
- default:
- break;
- }
- line = strtok(NULL, newLine);
- }
-
- free(line); line = NULL;
- delete[] buffer; buffer = NULL;
- return errorCode;
-}
-
-int EncKeys::parseLine(const char *line, const ulint maxKeyId) {
- int ret = NO_ERROR_PARSE_OK;
- if (isComment(line))
- ret = NO_ERROR_ISCOMMENT;
- else {
- const char *error_p = NULL;
- int offset;
- pcre *pattern = pcre_compile(
- "([0-9]+);([0-9,a-f,A-F]{32});([0-9,a-f,A-F]{64}|[0-9,a-f,A-F]{48}|[0-9,a-f,A-F]{32})",
- 0, &error_p, &offset, NULL);
- if ( NULL != error_p)
- fprintf(stderr, "Error: %s\nOffset: %d\n", error_p, offset);
-
- int m_len = (int) strlen(line), ovector[MAX_OFFSETS_IN_PCRE_PATTERNS];
- int rc = pcre_exec(pattern, NULL, line, m_len, 0, 0, ovector, MAX_OFFSETS_IN_PCRE_PATTERNS);
- pcre_free(pattern);
- if (4 == rc) {
- char lin[MAX_KEY_LINE_SIZE + 1];
- strncpy( lin, line, MAX_KEY_LINE_SIZE);
- lin[MAX_KEY_LINE_SIZE] = '\0';
- char *substring_start = lin + ovector[2];
- int substr_length = ovector[3] - ovector[2];
- if (3 < substr_length)
- ret = ERROR_ID_TOO_BIG;
- else {
- char buffer[4];
- sprintf(buffer, "%.*s", substr_length, substring_start);
- ulint id = atoi(buffer);
- if (0 == id) ret = ERROR_NOINITIALIZEDKEY;
- else if (KEY_MAX < id) ret = ERROR_ID_TOO_BIG;
- else if (maxKeyId < id) ret = NO_ERROR_KEY_GREATER_THAN_ASKED;
- else {
- oneKey = new keyentry;
- oneKey->id = id;
- substring_start = lin + ovector[4];
- substr_length = ovector[5] - ovector[4];
- oneKey->iv = new char[substr_length + 1];
- sprintf(oneKey->iv, "%.*s", substr_length, substring_start);
- substring_start = lin + ovector[6];
- substr_length = ovector[7] - ovector[6];
- oneKey->key = new char[substr_length + 1];
- sprintf(oneKey->key, "%.*s", substr_length, substring_start);
- }
- }
- }
- else
- ret = ERROR_WRONG_NUMBER_OF_MATCHES;
- }
- return ret;
-}
-
-/**
- Decrypt the key file 'filename' if it is encrypted with the key 'secret'.
- Store the content of the decrypted file in 'buffer'. The buffer has to be freed
- in the calling function.
-*/
-
-char* EncKeys::decryptFile(const char* filename, const char *secret, int *errorCode) {
- *errorCode = NO_ERROR_PARSE_OK;
- fprintf(stderr, "Reading %s\n\n", filename);
- FILE *fp = fopen(filename, "rb");
- if (NULL == fp) {
- fprintf(stderr, errorOpenFile, filename);
- *errorCode = ERROR_OPEN_FILE;
- return NULL;
- }
-
- if (fseek(fp, 0L, SEEK_END)) {
- *errorCode = ERROR_READING_FILE;
- return NULL;
- }
- long file_size = ftell(fp); // get the file size
- if (MAX_KEY_FILE_SIZE < file_size) {
- fprintf(stderr, errorExceedKeyFileSize, filename, MAX_KEY_FILE_SIZE);
- *errorCode = ERROR_KEY_FILE_TOO_BIG;
- fclose(fp);
- return NULL;
- }
- else if (-1L == file_size) {
- fprintf(stderr, errorFileSize, filename);
- *errorCode = ERROR_READING_FILE;
- return NULL;
- }
-
- rewind(fp);
- //Read file into buffer
- uchar *buffer = new uchar[file_size + 1];
- file_size= fread(buffer, 1, file_size, fp);
- buffer[file_size] = '\0';
- fclose(fp);
- //Check for file encryption
- if (0 == memcmp(buffer, strMAGIC, magicSize))
- { //If file is encrypted, decrypt it first.
- unsigned char salt[magicSize];
- unsigned char *key = new unsigned char[keySize32];
- unsigned char *iv = new unsigned char[ivSize16];
- uchar *decrypted = new uchar[file_size];
- memcpy(&salt, buffer + magicSize, magicSize);
- my_bytes_to_key((unsigned char *) salt, secret, key, iv);
- uint32 d_size = 0;
-
- /* This file is always encoded with cbc */
- enum_my_aes_encryption_algorithm org_method= current_aes_dynamic_method;
- my_aes_init_dynamic_encrypt(MY_AES_ALGORITHM_CBC);
- int res = my_aes_decrypt_dynamic((const uchar*)buffer + 2 * magicSize,
- file_size - 2 * magicSize,
- decrypted, &d_size,
- (const uchar*) key, keySize32,
- iv, ivSize16, 0);
- my_aes_init_dynamic_encrypt(org_method);
- if(0 != res) {
- *errorCode = ERROR_FALSE_FILE_KEY;
- delete[] buffer; buffer = NULL;
- fprintf(stderr, errorFalseFileKey, filename);
- }
- else {
- memcpy(buffer, decrypted, d_size);
- buffer[d_size] = '\0';
- }
-
- delete[] decrypted; decrypted = NULL;
- delete[] key; key = NULL;
- delete[] iv; iv = NULL;
- }
- return (char*) buffer;
-}
-
-bool EncKeys::isComment(const char *line) {
- const char *error_p;
- int offset, m_len = (int) strlen(line), ovector[MAX_OFFSETS_IN_PCRE_PATTERNS];
- pcre *pattern = pcre_compile("\\s*#.*", 0, &error_p, &offset, NULL);
- int rc = pcre_exec( pattern, NULL, line, m_len, 0, 0, ovector, MAX_OFFSETS_IN_PCRE_PATTERNS);
- pcre_free(pattern);
- if (0 > rc) return false;
- else return true;
-}
-
-
-void EncKeys::printKeyEntry( ulint id)
-{
-#ifdef UNIV_DEBUG
- keyentry *entry = getKeys(id);
- if( NULL == entry) {
- fprintf(stderr, "No such keyID=%lu\n",id);
- }
- else {
- fprintf(stderr, "Key: id:%3lu \tiv:%lu bytes\tkey:%lu bytes\n", entry->id, strlen(entry->iv)/2, strlen(entry->key)/2);
- }
-#endif //UNIV_DEBUG
-}
diff --git a/storage/xtradb/enc/KeySingleton.cc b/storage/xtradb/enc/KeySingleton.cc
deleted file mode 100644
index b751bd79fe2..00000000000
--- a/storage/xtradb/enc/KeySingleton.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (C) 2014 eperi GmbH. All Rights Reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-/******************************************************************//**
-@file KeySingleton.cc
-Implementation of single pattern to keep keys for encrypting/decrypting pages.
-
-Created 09/13/2014
-***********************************************************************/
-
-
-#include "KeySingleton.h"
-#include <stdlib.h>
-
-
-bool KeySingleton::instanceInited = false;
-KeySingleton KeySingleton::theInstance;
-EncKeys KeySingleton::encKeys;
-
-
-
-KeySingleton & KeySingleton::getInstance() {
-#ifdef UNIV_DEBUG
- if( !instanceInited) {
- fprintf(stderr, "Encryption / decryption keys were not initialized. "
- "You can not read encrypted tables or columns\n");
- }
-#endif /* UNIV_DEBUG */
- return theInstance;
-}
-
-KeySingleton & KeySingleton::getInstance(const char *name, const char *url,
- const int initType, const char *filekey) {
-
- if(instanceInited) return theInstance;
- instanceInited = encKeys.initKeys(name, url, initType, filekey);
- if( !instanceInited) {
- fprintf(stderr, "Could not initialize any of the encryption / decryption keys. "
- "You can not read encrypted tables\n\n");
- fflush(stderr);
- }
-
- return theInstance;
-}
-
-keyentry *KeySingleton::getKeys(int id) {
- return encKeys.getKeys(id);
-}
-
-ibool KeySingleton::hasKey(int id) {
- return encKeys.getKeys(id) != NULL;
-}
-
diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc
index 5024db0d0fb..0b61b31f7f5 100644
--- a/storage/xtradb/fil/fil0crypt.cc
+++ b/storage/xtradb/fil/fil0crypt.cc
@@ -9,10 +9,16 @@
#include "ut0ut.h"
#include "btr0scrub.h"
#include "fsp0fsp.h"
+#include "fil0pagecompress.h"
+#include "fil0pageencryption.h"
#include <my_crypt.h>
#include <my_crypt_key_management.h>
+#include <my_aes.h>
+#include <math.h>
+
+
/** Mutex for keys */
UNIV_INTERN ib_mutex_t fil_crypt_key_mutex;
@@ -173,85 +179,136 @@ fil_space_crypt_cleanup()
Get key bytes for a space/key-version */
static
void
-fil_crypt_get_key(uchar *dst, uint dstlen,
- fil_space_crypt_t* crypt_data, uint version)
+fil_crypt_get_key(byte *dst, uint* key_length,
+ fil_space_crypt_t* crypt_data, uint version, bool page_encrypted)
{
-#ifndef HAVE_EncryptAes128Ctr
- return;
-#else
- mutex_enter(&crypt_data->mutex);
+ unsigned char keybuf[MY_AES_MAX_KEY_LENGTH];
+ unsigned char iv[CRYPT_SCHEME_1_IV_LEN];
+ ulint iv_len = sizeof(iv);
- // 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));
- mutex_exit(&crypt_data->mutex);
- return;
+ if (!page_encrypted) {
+ mutex_enter(&crypt_data->mutex);
+
+ // 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));
+ mutex_exit(&crypt_data->mutex);
+ return;
+ }
}
- }
- // Not found!
- crypt_data->keyserver_requests++;
+ // Not found!
+ crypt_data->keyserver_requests++;
- // Rotate keys to make room for a new
- for (uint i = 1; i < array_elements(crypt_data->keys); i++) {
- crypt_data->keys[i] = crypt_data->keys[i - 1];
- }
+ // Rotate keys to make room for a new
+ for (uint i = 1; i < array_elements(crypt_data->keys); i++) {
+ crypt_data->keys[i] = crypt_data->keys[i - 1];
+ }
+ }
+ else
+ {
+ // load iv
+ fprintf(stderr, "%d... %d\n",iv_len, version);
- // TODO(jonaso): Integrate with real key server
+ int rc = GetCryptoIV(version, (unsigned char*)iv, iv_len);
+ fprintf(stderr, " %d\n",rc);
- // Get new key from key server
- unsigned char keybuf[CRYPT_SCHEME_1_IV_LEN];
- unsigned keylen = sizeof(keybuf);
- int rc = GetCryptoKey(version, keybuf, keylen);
- if (rc != 0) {
+ if (rc != CRYPT_KEY_OK) {
ib_logf(IB_LOG_LEVEL_FATAL,
- "Unable to retrieve key with"
- " version %u return-code: %d. Can't continue!\n",
- version, rc);
+ "IV %d can not be found. Reason=%d", version, rc);
ut_error;
- }
+ }
+ }
+
+ if (HasCryptoKey(version)) {
+ *key_length = GetCryptoKeySize(version);
+
+ int rc = GetCryptoKey(version, (unsigned char*)keybuf, *key_length);
- // Now compute L by encrypting IV using this key
- const unsigned char* src = crypt_data->iv;
- const int srclen = crypt_data->iv_length;
- unsigned char* buf = crypt_data->keys[0].key;
- int buflen = sizeof(crypt_data->keys[0].key);
- rc = my_aes_encrypt_ecb(src, srclen,
- buf, &buflen,
- keybuf, sizeof(keybuf),
- 0,0,0);
- if (rc != CRYPT_OK) {
+ if (rc != CRYPT_KEY_OK) {
ib_logf(IB_LOG_LEVEL_FATAL,
- "Unable to encrypt key-block "
- " src: %p srclen: %d buf: %p buflen: %d."
- " return-code: %d. Can't continue!\n",
- src, srclen, buf, buflen, rc);
+ "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;
}
- crypt_data->keys[0].key_version = version;
- crypt_data->key_count++;
- if (crypt_data->key_count > array_elements(crypt_data->keys)) {
- crypt_data->key_count = array_elements(crypt_data->keys);
+ // do ctr key initialization
+ if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR)
+ {
+ // Now compute L by encrypting IV using this key
+ const unsigned char* src = page_encrypted ? iv : crypt_data->iv;
+ const int srclen = page_encrypted ? iv_len : crypt_data->iv_length;
+ unsigned char* buf = page_encrypted ? keybuf : crypt_data->keys[0].key;
+ uint32 buflen = page_encrypted ? *key_length : sizeof(crypt_data->keys[0].key);
+
+ // call ecb explicit
+ my_aes_encrypt_dynamic_type func = get_aes_encrypt_func(MY_AES_ALGORITHM_ECB);
+ int rc = (*func)(src, srclen,
+ buf, &buflen,
+ (unsigned char*)keybuf, *key_length,
+ NULL, 0,
+ 1);
+
+ if (rc != AES_OK) {
+ ib_logf(IB_LOG_LEVEL_FATAL,
+ "Unable to encrypt key-block "
+ " src: %p srclen: %d buf: %p buflen: %d."
+ " return-code: %d. Can't continue!\n",
+ src, srclen, buf, buflen, rc);
+ ut_error;
+ }
+
+ if (!page_encrypted) {
+ crypt_data->keys[0].key_version = version;
+ crypt_data->key_count++;
+
+ if (crypt_data->key_count > array_elements(crypt_data->keys)) {
+ crypt_data->key_count = array_elements(crypt_data->keys);
+ }
+ }
+
+ // set the key size to the aes block size because this encrypted data is the key
+ *key_length = MY_AES_BLOCK_SIZE;
+ memcpy(dst, buf, buflen);
+ }
+ else
+ {
+ // otherwise keybuf contains the right key
+ memcpy(dst, keybuf, *key_length);
}
- memcpy(dst, crypt_data->keys[0].key,
- sizeof(crypt_data->keys[0].key));
- mutex_exit(&crypt_data->mutex);
-#endif
+ if (!page_encrypted) {
+ mutex_exit(&crypt_data->mutex);
+ }
}
/******************************************************************
Get key bytes for a space/latest(key-version) */
static inline
void
-fil_crypt_get_latest_key(uchar *dst, uint dstlen,
+fil_crypt_get_latest_key(byte *dst, uint* key_length,
fil_space_crypt_t* crypt_data, uint *version)
{
- *version = GetLatestCryptoKeyVersion();
- return fil_crypt_get_key(dst, dstlen, crypt_data, *version);
+ if (srv_encrypt_tables) {
+ // used for key rotation - get the next key id from the key provider
+ int rc = GetLatestCryptoKeyVersion();
+
+ // if no new key was created use the last one
+ if (rc >= 0)
+ {
+ *version = rc;
+ }
+
+ return fil_crypt_get_key(dst, key_length, crypt_data, *version, false);
+ } else {
+ return fil_crypt_get_key(dst, key_length, NULL, *version, true);
+ }
}
/******************************************************************
@@ -260,9 +317,6 @@ UNIV_INTERN
fil_space_crypt_t*
fil_space_create_crypt_data()
{
-#ifndef HAVE_EncryptAes128Ctr
- return 0;
-#else
const uint iv_length = CRYPT_SCHEME_1_IV_LEN;
const uint sz = sizeof(fil_space_crypt_t) + iv_length;
fil_space_crypt_t* crypt_data =
@@ -282,7 +336,6 @@ fil_space_create_crypt_data()
crypt_data->iv_length = iv_length;
my_random_bytes(crypt_data->iv, iv_length);
return crypt_data;
-#endif
}
/******************************************************************
@@ -558,52 +611,120 @@ fil_space_check_encryption_write(
}
/******************************************************************
-
Encrypt a page */
UNIV_INTERN
void
fil_space_encrypt(ulint space, ulint offset, lsn_t lsn,
- const byte* src_frame, ulint zip_size, byte* dst_frame)
+ const byte* src_frame, ulint zip_size, byte* dst_frame, ulint encryption_key)
{
- fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space);
+ fil_space_crypt_t* crypt_data;
ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
- if (crypt_data == NULL || srv_encrypt_tables == FALSE) {
- memcpy(dst_frame, src_frame, page_size);
- return;
- }
+
+ fprintf(stderr, "JAN: page_size %lu\n", page_size);
// get key (L)
uint key_version;
- uchar key[CRYPT_SCHEME_1_IV_LEN];
- fil_crypt_get_latest_key(key, sizeof(key), crypt_data, &key_version);
+ byte key[MY_AES_MAX_KEY_LENGTH];
+ uint key_length;
+
+ if (srv_encrypt_tables) {
+ crypt_data = fil_space_get_crypt_data(space);
+ if (crypt_data == NULL) {
+ //TODO: Is this really needed ?
+ memcpy(dst_frame, src_frame, page_size);
+ return;
+ }
+ fil_crypt_get_latest_key(key, &key_length, crypt_data, &key_version);
+ } else {
+ key_version = encryption_key;
+ fil_crypt_get_latest_key(key, &key_length, NULL, (uint*)&key_version);
+ }
+
+
+ /* Load the iv or counter (depending to the encryption algorithm used) */
+ unsigned char iv[MY_AES_BLOCK_SIZE];
+
+ if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR)
+ {
+ // create counter block (C)
+ mach_write_to_4(iv + 0, space);
+ ulint space_offset = mach_read_from_4(
+ src_frame + FIL_PAGE_OFFSET);
+ mach_write_to_4(iv + 4, space_offset);
+ mach_write_to_8(iv + 8, lsn);
+ }
+ else
+ {
+ // take the iv from the key provider
+
+ int load_iv_rc = GetCryptoIV(key_version, (uchar *) iv, sizeof(iv));
+
+ // if the iv can not be loaded the whole page can not be encrypted
+ if (load_iv_rc != CRYPT_KEY_OK)
+ {
+ ib_logf(IB_LOG_LEVEL_FATAL,
+ "Unable to decrypt data-block. "
+ " Can not load iv for key %d"
+ " return-code: %d. Can't continue!\n",
+ key_version, load_iv_rc);
+
+ ut_error;
+ }
+ }
+
+
+ ibool page_compressed = (mach_read_from_2(src_frame+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED);
+ ibool page_encrypted = fil_space_is_page_encrypted(space);
+
+ ulint compression_alg = mach_read_from_8(src_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
+
+ ulint orig_page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
+ if (orig_page_type==FIL_PAGE_TYPE_FSP_HDR
+ || orig_page_type==FIL_PAGE_TYPE_XDES
+ || orig_page_type== FIL_PAGE_PAGE_ENCRYPTED
+ || orig_page_type== FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
+ memcpy(dst_frame, src_frame, page_size);
+ return;
+ }
// copy page header
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
- // store key version
- mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
- key_version);
- // create counter block (C)
- unsigned char counter[MY_AES_BLOCK_SIZE];
- mach_write_to_4(counter + 0, space);
- mach_write_to_4(counter + 4, offset);
- mach_write_to_8(counter + 8, lsn);
+ if (page_encrypted && !page_compressed) {
+ // key id
+ mach_write_to_2(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
+ key_version);
+ // original page type
+ mach_write_to_2(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 2,
+ orig_page_type);
+ // new page type
+ mach_write_to_2(dst_frame+FIL_PAGE_TYPE, FIL_PAGE_PAGE_ENCRYPTED);
+ } else {
+ // store key version
+ mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
+ key_version);
+ }
// encrypt page data
ulint unencrypted_bytes = FIL_PAGE_DATA + FIL_PAGE_DATA_END;
-
- const uchar* src = (uchar*) src_frame + FIL_PAGE_DATA;
- uchar* dst = (uchar*) dst_frame + FIL_PAGE_DATA;
+ ulint srclen = page_size - unencrypted_bytes;
+ const byte* src = src_frame + FIL_PAGE_DATA;
+ byte* dst = dst_frame + FIL_PAGE_DATA;
uint32 dstlen;
- int rc = my_aes_encrypt_dynamic(src, (page_size - unencrypted_bytes),
- dst, &dstlen,
- key, sizeof(key),
- counter, sizeof(counter),
- 0);
- if (! ((rc == AES_OK) &&
- ((ulint) dstlen == (page_size - unencrypted_bytes))))
- {
+
+ if (page_compressed) {
+ srclen = page_size;
+ }
+
+
+ int rc = (* my_aes_encrypt_dynamic)(src, srclen,
+ dst, &dstlen,
+ (unsigned char*)key, key_length,
+ (unsigned char*)iv, sizeof(iv),
+ 1);
+
+ if (! ((rc == AES_OK) && ((ulint) dstlen == srclen))) {
ib_logf(IB_LOG_LEVEL_FATAL,
"Unable to encrypt data-block "
" src: %p srclen: %ld buf: %p buflen: %d."
@@ -613,42 +734,57 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn,
ut_error;
}
- // copy page trailer
- memcpy(dst_frame + page_size - FIL_PAGE_DATA_END,
- src_frame + page_size - FIL_PAGE_DATA_END,
- FIL_PAGE_DATA_END);
+ if (!page_compressed) {
+ // copy page trailer
+ memcpy(dst_frame + page_size - FIL_PAGE_DATA_END,
+ src_frame + page_size - FIL_PAGE_DATA_END,
+ FIL_PAGE_DATA_END);
- /* handle post encryption checksum */
- ib_uint32_t checksum = 0;
- srv_checksum_algorithm_t algorithm =
- static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
+ /* handle post encryption checksum */
+ ib_uint32_t checksum = 0;
+ srv_checksum_algorithm_t algorithm =
+ static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
- if (zip_size == 0) {
- switch (algorithm) {
- case SRV_CHECKSUM_ALGORITHM_CRC32:
- case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
- checksum = buf_calc_page_crc32(dst_frame);
- break;
- case SRV_CHECKSUM_ALGORITHM_INNODB:
- case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
- checksum = (ib_uint32_t) buf_calc_page_new_checksum(
- dst_frame);
- break;
- case SRV_CHECKSUM_ALGORITHM_NONE:
- case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
- checksum = BUF_NO_CHECKSUM_MAGIC;
- break;
- /* no default so the compiler will emit a warning
- * if new enum is added and not handled here */
+ if (zip_size == 0) {
+ switch (algorithm) {
+ case SRV_CHECKSUM_ALGORITHM_CRC32:
+ case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
+ checksum = buf_calc_page_crc32(dst_frame);
+ break;
+ case SRV_CHECKSUM_ALGORITHM_INNODB:
+ case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
+ checksum = (ib_uint32_t) buf_calc_page_new_checksum(
+ dst_frame);
+ break;
+ case SRV_CHECKSUM_ALGORITHM_NONE:
+ case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
+ checksum = BUF_NO_CHECKSUM_MAGIC;
+ break;
+ /* no default so the compiler will emit a warning
+ * if new enum is added and not handled here */
+ }
+ } else {
+ checksum = page_zip_calc_checksum(dst_frame, zip_size,
+ algorithm);
}
+
+ // store the post-encryption checksum after the key-version
+ mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4,
+ checksum);
} else {
- checksum = page_zip_calc_checksum(dst_frame, zip_size,
- algorithm);
+ /* Page compressed and encrypted tables have different
+ FIL_HEADER */
+ ulint page_len = log10((double)srclen)/log10((double)2);
+ /* Set up the correct page type */
+ mach_write_to_2(dst_frame+FIL_PAGE_TYPE, FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
+ /* Set up the compression algorithm */
+ mach_write_to_2(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+4, orig_page_type);
+ /* Set up the compressed size */
+ mach_write_to_1(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+6, page_len);
+ /* Set up the compression method */
+ mach_write_to_1(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+7, compression_alg);
}
- // store the post-encryption checksum after the key-version
- mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4,
- checksum);
}
/*********************************************************************
@@ -676,21 +812,38 @@ bool
fil_space_decrypt(fil_space_crypt_t* crypt_data,
const byte* src_frame, ulint page_size, byte* dst_frame)
{
+ ulint space_id = mach_read_from_4(src_frame + FIL_PAGE_SPACE_ID);
+ ulint page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
// key version
- uint key_version = mach_read_from_4(
- src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
+ uint key_version;
+ bool page_encrypted = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
+ || page_type == FIL_PAGE_PAGE_ENCRYPTED);
+
+ bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
+ || page_type == FIL_PAGE_PAGE_COMPRESSED);
+
+ ulint orig_page_type=0;
+ fprintf(stderr, "JAN: page type %lu\n", page_type);
+
+ if (page_type == FIL_PAGE_PAGE_ENCRYPTED) {
+ key_version = mach_read_from_2(
+ src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
+ fprintf(stderr, "JAN: key_version %lu\n", key_version);
+ orig_page_type = mach_read_from_2(
+ src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 2);
+ fprintf(stderr, "JAN: decrypt: orig_page_type %lu\n", orig_page_type);
+ } else {
+ key_version = mach_read_from_4(
+ src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
+ }
- if (key_version == 0) {
+ if (key_version == 0 && !page_encrypted) {
+ fprintf(stderr, "JAN: unencrypted\n");
+ //TODO: is this really needed ?
memcpy(dst_frame, src_frame, page_size);
return false; /* page not decrypted */
}
-#ifndef HAVE_EncryptAes128Ctr
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Unable to decrypt data-block as server not compiled with CTR encyption");
- ut_error;
- return false;
-#else
// read space & offset & lsn
ulint space = mach_read_from_4(
src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
@@ -698,32 +851,81 @@ fil_space_decrypt(fil_space_crypt_t* crypt_data,
src_frame + FIL_PAGE_OFFSET);
ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
- ut_a(crypt_data != NULL);
-
- // get key (L)
- byte key[CRYPT_SCHEME_1_IV_LEN];
- fil_crypt_get_key(key, sizeof(key), crypt_data, key_version);
+ fprintf(stderr, "JAN: space %lu, offset %lu lsn %lu\n", space, offset, lsn);
// copy page header
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
- // create counter block
- unsigned char counter[MY_AES_BLOCK_SIZE];
- mach_write_to_4(counter + 0, space);
- mach_write_to_4(counter + 4, offset);
- mach_write_to_8(counter + 8, lsn);
+ if (page_type == FIL_PAGE_PAGE_ENCRYPTED) {
+ // orig page type
+ mach_write_to_2(dst_frame+FIL_PAGE_TYPE, orig_page_type);
+ }
+
+
+ // get key
+ byte key[MY_AES_MAX_KEY_LENGTH];
+ uint key_length;
+ fil_crypt_get_key(key, &key_length, crypt_data, key_version, page_encrypted);
+
+ // get the iv
+ unsigned char iv[MY_AES_BLOCK_SIZE];
+
+ if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR)
+ {
+ // create counter block
+
+ mach_write_to_4(iv + 0, space);
+ mach_write_to_4(iv + 4, offset);
+ mach_write_to_8(iv + 8, lsn);
+ }
+ else
+ {
+ // take the iv from the key provider
+
+ int load_iv_rc = GetCryptoIV(key_version, (uchar *) iv, sizeof(iv));
+
+ // if the iv can not be loaded the whole page can not be decrypted
+ if (load_iv_rc != CRYPT_KEY_OK)
+ {
+ ib_logf(IB_LOG_LEVEL_FATAL,
+ "Unable to decrypt data-block. "
+ " Can not load iv for key %d"
+ " return-code: %d. Can't continue!\n",
+ key_version, load_iv_rc);
+
+ return AES_KEY_CREATION_FAILED;
+ }
+ }
// decrypt page data
ulint unencrypted_bytes = FIL_PAGE_DATA + FIL_PAGE_DATA_END;
const byte* src = src_frame + FIL_PAGE_DATA;
byte* dst = dst_frame + FIL_PAGE_DATA;
- int dstlen;
- int rc = my_aes_decrypt_ctr(src, (page_size - unencrypted_bytes),
- dst, &dstlen, key, sizeof(key),
- counter, sizeof(counter), 0);
- if (! ((rc == AES_OK) &&
- ((ulint) dstlen == (page_size - unencrypted_bytes)))) {
+ uint32 dstlen;
+ ulint srclen = page_size - (FIL_PAGE_DATA + FIL_PAGE_DATA_END);
+
+ ulint compressed_len;
+ ulint compression_method;
+ if (page_compressed) {
+ orig_page_type = mach_read_from_2(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+4);
+ compressed_len = mach_read_from_1(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+6);
+ compression_method = mach_read_from_1(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+7);
+ }
+ if (page_encrypted && !page_compressed) {
+ orig_page_type = mach_read_from_2(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+2);
+ }
+
+ if (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
+ srclen = pow((double)2, (double)((int)compressed_len));
+ }
+ int rc = (* my_aes_decrypt_dynamic)(src, srclen,
+ dst, &dstlen,
+ (unsigned char*)key, key_length,
+ (unsigned char*)iv, sizeof(iv),
+ 1);
+
+ if (! ((rc == AES_OK) && ((ulint) dstlen == srclen))) {
ib_logf(IB_LOG_LEVEL_FATAL,
"Unable to decrypt data-block "
" src: %p srclen: %ld buf: %p buflen: %d."
@@ -733,16 +935,26 @@ fil_space_decrypt(fil_space_crypt_t* crypt_data,
ut_error;
}
- // copy page trailer
- memcpy(dst_frame + page_size - FIL_PAGE_DATA_END,
- src_frame + page_size - FIL_PAGE_DATA_END,
- FIL_PAGE_DATA_END);
+ if (page_type != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
+ fprintf(stderr, "JAN: trailer...\n");
+ // copy page trailer
+ memcpy(dst_frame + page_size - FIL_PAGE_DATA_END,
+ src_frame + page_size - FIL_PAGE_DATA_END,
+ FIL_PAGE_DATA_END);
- // clear key-version & crypt-checksum from dst
- memset(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
+ // clear key-version & crypt-checksum from dst
+ memset(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
+ } else {
+ /* For page compressed tables we set up the FIL_HEADER again */
+ /* setting original page type */
+ mach_write_to_2(dst_frame + FIL_PAGE_TYPE, orig_page_type);
+ /* page_compression uses BUF_NO_CHECKSUM_MAGIC as checksum */
+ mach_write_to_4(dst_frame + FIL_PAGE_SPACE_OR_CHKSUM, BUF_NO_CHECKSUM_MAGIC);
+ /* Set up the flush lsn to be compression algorithm */
+ mach_write_to_8(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, compression_method);
+ }
return true; /* page was decrypted */
-#endif
}
/******************************************************************
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index e45a4b5bbf8..0799e9921bf 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -26,7 +26,6 @@ Created 10/25/1995 Heikki Tuuri
#include "fil0fil.h"
-#include "KeySingleton.h"
#include <debug_sync.h>
#include <my_dbug.h>
@@ -1361,8 +1360,7 @@ fil_space_create(
ut_a(fil_system);
if (fsp_flags_is_page_encrypted(flags)) {
- if (!KeySingleton::getInstance().isAvailable()
- || KeySingleton::getInstance().getKeys(fsp_flags_get_page_encryption_key(flags))==NULL) {
+ if (!HasCryptoKey(fsp_flags_get_page_encryption_key(flags))) {
/* by returning here it should be avoided that
* the server crashes, if someone tries to access an
* encrypted table and the encryption key is not available.
diff --git a/storage/xtradb/fil/fil0pageencryption.cc b/storage/xtradb/fil/fil0pageencryption.cc
index 114064984e3..49c42615e19 100644
--- a/storage/xtradb/fil/fil0pageencryption.cc
+++ b/storage/xtradb/fil/fil0pageencryption.cc
@@ -33,7 +33,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "buf0checksum.h"
#include <my_global.h>
#include <my_aes.h>
-#include <KeySingleton.h>
#include <math.h>
/*
@@ -217,35 +216,28 @@ fil_encrypt_page(
data_size = ((len - FIL_PAGE_DATA - FIL_PAGE_DATA_END) / MY_AES_BLOCK_SIZE) * MY_AES_BLOCK_SIZE;
- const unsigned char rkey[] = {0xbd, 0xe4, 0x72, 0xa2, 0x95, 0x67, 0x5c, 0xa9,
- 0x2e, 0x04, 0x67, 0xea, 0xdb, 0xc0, 0xe0, 0x23,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- uint8 key_len = 16;
+ unsigned char rkey[GetCryptoKeySize(encryption_key)];
+ uint key_len = sizeof(rkey);
- const unsigned char iv[] = {0x2d, 0x1a, 0xf8, 0xd3, 0x97, 0x4e, 0x0b, 0xd3, 0xef, 0xed,
- 0x5a, 0x6f, 0x82, 0x59, 0x4f,0x5e};
+ unsigned char iv[16];
+ uint iv_len = sizeof(iv);
- ulint iv_len = 16;
-
- KeySingleton& keys = KeySingleton::getInstance();
-
- if (!keys.isAvailable()) {
- err = AES_KEY_CREATION_FAILED;
- } else if (keys.getKeys(encryption_key) == NULL) {
+ if (!HasCryptoKey(encryption_key)) {
err = PAGE_ENCRYPTION_KEY_MISSING;
} else {
- char* keyString = keys.getKeys(encryption_key)->key;
- char* ivString = keys.getKeys(encryption_key)->iv;
+ int rc;
+
+ rc = GetCryptoKey(encryption_key, rkey, key_len);
+ if (rc != AES_OK)
+ {
+ err = PAGE_ENCRYPTION_KEY_MISSING;
+ }
- if (keyString == NULL || ivString == NULL) {
- *errorCode = PAGE_ENCRYPTION_WILL_NOT_ENCRYPT;
- *out_len = len;
- return (buf);
+ rc = GetCryptoIV(encryption_key, iv, iv_len);
+ if (rc != AES_OK)
+ {
+ err = PAGE_ENCRYPTION_KEY_MISSING;
}
- key_len = strlen(keyString)/2;
- my_aes_hex2uint(keyString, (unsigned char*)&rkey, key_len);
- my_aes_hex2uint(ivString, (unsigned char*)&iv, 16);
}
/* 1st encryption: data_size bytes starting from FIL_PAGE_DATA */
@@ -255,9 +247,9 @@ fil_encrypt_page(
data_size,
(uchar *) out_buf + FIL_PAGE_DATA,
&write_size,
- (const unsigned char *) &rkey,
+ (const unsigned char *) rkey,
key_len,
- (const unsigned char *) &iv,
+ (const unsigned char *) iv,
iv_len,
1);
@@ -285,9 +277,9 @@ fil_encrypt_page(
64,
(uchar*)tmp_buf,
&write_size,
- (const unsigned char *)&rkey,
+ (const unsigned char *)rkey,
key_len,
- (const unsigned char *)&iv,
+ (const unsigned char *)iv,
iv_len, 1);
ut_ad(write_size == 64);
@@ -449,34 +441,32 @@ fil_decrypt_page(
data_size = ((len - FIL_PAGE_DATA - FIL_PAGE_DATA_END) / MY_AES_BLOCK_SIZE) * MY_AES_BLOCK_SIZE;
- const unsigned char rkey[] = {0xbd, 0xe4, 0x72, 0xa2, 0x95, 0x67, 0x5c, 0xa9,
- 0x2e, 0x04, 0x67, 0xea, 0xdb, 0xc0,0xe0, 0x23,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- uint8 key_len = 16;
- const unsigned char iv[] = {0x2d, 0x1a, 0xf8, 0xd3, 0x97, 0x4e, 0x0b, 0xd3, 0xef, 0xed,
- 0x5a, 0x6f, 0x82, 0x59, 0x4f,0x5e};
- uint8 iv_len = 16;
+ unsigned char rkey[GetCryptoKeySize(page_decryption_key)];
+ uint key_len = sizeof(rkey);
- KeySingleton& keys = KeySingleton::getInstance();
+ unsigned char iv[16];
+ uint iv_len = sizeof(iv);
- if (!keys.isAvailable()) {
- err = PAGE_ENCRYPTION_ERROR;
- } else if (keys.getKeys(page_decryption_key) == NULL) {
+ if (!HasCryptoKey(page_decryption_key)) {
err = PAGE_ENCRYPTION_KEY_MISSING;
} else {
- char* keyString = keys.getKeys(page_decryption_key)->key;
- char* ivString = keys.getKeys(page_decryption_key)->iv;
- key_len = strlen(keyString)/2;
- if (keyString == NULL || ivString == NULL) {
- return err;
+ int rc;
+
+ rc = GetCryptoKey(page_decryption_key, rkey, key_len);
+ if (rc != AES_OK)
+ {
+ err = PAGE_ENCRYPTION_KEY_MISSING;
}
- my_aes_hex2uint(keyString, (unsigned char*)&rkey, key_len);
- my_aes_hex2uint(ivString, (unsigned char*)&iv, 16);
+ rc = GetCryptoIV(page_decryption_key, iv, iv_len);
+ if (rc != AES_OK)
+ {
+ err = PAGE_ENCRYPTION_KEY_MISSING;
+ }
}
+
if (err != AES_OK) {
/* surely key could not be determined. */
fprintf(stderr, "InnoDB: Corruption: Page is marked as encrypted\n"
@@ -514,9 +504,9 @@ fil_decrypt_page(
64,
(uchar *) in_buf + len - offset - 64,
&tmp_write_size,
- (const unsigned char *) &rkey,
+ (const unsigned char *) rkey,
key_len,
- (const unsigned char *) &iv,
+ (const unsigned char *) iv,
iv_len,
1);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index c319f1a1d84..21d7cee0fba 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -107,8 +107,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "page0zip.h"
#include "fil0pagecompress.h"
-#include "KeySingleton.h"
-
#define thd_get_trx_isolation(X) ((enum_tx_isolation)thd_tx_isolation(X))
@@ -213,12 +211,6 @@ static char* innobase_disable_monitor_counter = NULL;
static char* innobase_reset_monitor_counter = NULL;
static char* innobase_reset_all_monitor_counter = NULL;
-/* Encryption for tables and columns */
-static char* innobase_data_encryption_providername = NULL;
-static char* innobase_data_encryption_providerurl = NULL;
-static uint innobase_data_encryption_providertype = 0; // 1 == file, 2 == server
-static char* innobase_data_encryption_filekey = NULL;
-
/* The highest file format being used in the database. The value can be
set by user, however, it will be adjusted to the newer file format if
a table of such format is created/opened. */
@@ -3505,10 +3497,6 @@ innobase_init(
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
- KeySingleton::getInstance(
- innobase_data_encryption_providername, innobase_data_encryption_providerurl,
- innobase_data_encryption_providertype, innobase_data_encryption_filekey);
-
#ifndef DBUG_OFF
static const char test_filename[] = "-@";
char test_tablename[sizeof test_filename
@@ -4173,8 +4161,6 @@ innobase_end(
mysql_mutex_destroy(&pending_checkpoint_mutex);
}
- KeySingleton::getInstance().~KeySingleton();
-
DBUG_RETURN(err);
}
@@ -11883,15 +11869,6 @@ ha_innobase::check_table_options(
" innodb_file_per_table.");
return "PAGE_ENCRYPTION";
}
-
- if (!KeySingleton::getInstance().isAvailable()) {
- push_warning(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_WRONG_CREATE_OPTION,
- "InnoDB: PAGE_ENCRYPTION needs a key provider"
- );
- return "PAGE_ENCRYPTION";
- }
}
/* Check page compression requirements */
@@ -11981,7 +11958,7 @@ ha_innobase::check_table_options(
return "PAGE_ENCRYPTION_KEY";
}
- if (KeySingleton::getInstance().getKeys(options->page_encryption_key)==NULL) {
+ if (!HasCryptoKey(options->page_encryption_key)) {
push_warning_printf(
thd, Sql_condition::WARN_LEVEL_WARN,
HA_WRONG_CREATE_OPTION,
@@ -20333,26 +20310,6 @@ static MYSQL_SYSVAR_ULONG(fatal_semaphore_wait_threshold, srv_fatal_semaphore_wa
UINT_MAX32, /* Maximum setting */
0);
-static MYSQL_SYSVAR_UINT(data_encryption_providertype, innobase_data_encryption_providertype,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Use table or column encryption / decryption. Default is 0 for no use, 1 for keyfile and 2 for keyserver.",
- NULL, NULL, 1, 0, 2, 0);
-
-static MYSQL_SYSVAR_STR(data_encryption_providername, innobase_data_encryption_providername,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Name of keyfile or keyserver.",
- NULL, NULL, NULL);
-
-static MYSQL_SYSVAR_STR(data_encryption_providerurl, innobase_data_encryption_providerurl,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Path or URL for keyfile or keyserver.",
- NULL, NULL, NULL);
-
-static MYSQL_SYSVAR_STR(data_encryption_filekey, innobase_data_encryption_filekey,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Key to encrypt / decrypt the keyfile.",
- NULL, NULL, NULL);
-
static MYSQL_SYSVAR_BOOL(encrypt_tables, srv_encrypt_tables, 0,
"Encrypt tables",
0, 0, 0);
@@ -20669,11 +20626,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(compression_algorithm),
MYSQL_SYSVAR(mtflush_threads),
MYSQL_SYSVAR(use_mtflush),
- /* Table encryption feature */
- MYSQL_SYSVAR(data_encryption_providertype),
- MYSQL_SYSVAR(data_encryption_providername),
- MYSQL_SYSVAR(data_encryption_providerurl),
- MYSQL_SYSVAR(data_encryption_filekey),
/* Encryption feature */
MYSQL_SYSVAR(encrypt_tables),
MYSQL_SYSVAR(encryption_threads),
diff --git a/storage/xtradb/include/EncKeys.h b/storage/xtradb/include/EncKeys.h
deleted file mode 100644
index 43f2920fd7f..00000000000
--- a/storage/xtradb/include/EncKeys.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright (C) 2014 eperi GmbH. All Rights Reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-/******************************************************************//**
-@file EncKeys.h
-A structure and class to keep keys for encryption/decryption.
-
-Created 09/15/2014
-***********************************************************************/
-
-#ifndef ENCKEYS_H_
-#define ENCKEYS_H_
-
-#include "univ.i"
-#include <sys/types.h>
-#include <stdio.h>
-
-
-
-
-struct keyentry {
- ulint id;
- char *iv;
- char *key;
-};
-
-
-class EncKeys
-{
-private:
- static const char *strMAGIC, *newLine;
- static const int magicSize;
-
- enum constants { MAX_OFFSETS_IN_PCRE_PATTERNS = 30};
- enum keyAttributes { KEY_MIN = 1, KEY_MAX = 255, MAX_KEYS = 255,
- MAX_IVLEN = 256, MAX_KEYLEN = 512, ivSize16 = 16, keySize32 = 32 };
- enum keyInitType { KEYINITTYPE_FILE = 1, KEYINITTYPE_SERVER = 2 };
- enum errorAttributes { MAX_KEY_LINE_SIZE = 3 * MAX_KEYLEN, MAX_KEY_FILE_SIZE = 1048576 };
- enum errorCodesLine { NO_ERROR_PARSE_OK = 0, NO_ERROR_ISCOMMENT = 10, NO_ERROR_KEY_GREATER_THAN_ASKED = 20,
- ERROR_NOINITIALIZEDKEY = 30, ERROR_ID_TOO_BIG = 40, ERROR_WRONG_NUMBER_OF_MATCHES = 50,
- ERROR_EQUAL_DOUBLE_KEY = 60, ERROR_UNEQUAL_DOUBLE_KEY = 70 };
-
- static const char *errorNoKeyId, *errorInMatches, *errorExceedKeyFileSize,
- *errorExceedKeySize, *errorEqualDoubleKey, *errorUnequalDoubleKey,
- *errorNoInitializedKey, *errorFalseFileKey,
- *errorNotImplemented, *errorOpenFile, *errorReadingFile, *errorFileSize;
-
- static const char* initialPwd;
- ulint countKeys, keyLineInKeyFile;
- keyentry keys[MAX_KEYS], *oneKey;
-
- void printKeyEntry( ulint id);
- int initKeysThroughFile( const char *name, const char *path, const char *filekey);
- int initKeysThroughServer( const char *name, const char *path, const char *filekey);
- bool isComment( const char *line);
- char * decryptFile( const char* filename, const char *secret, int *errorCode);
- int parseFile( const char* filename, const ulint maxKeyId, const char *secret);
- int parseLine( const char *line, const ulint maxKeyId);
-
-public:
- static const size_t MAX_SECRET_SIZE = 256;
-
- enum errorCodesFile { NO_ERROR_KEY_FILE_PARSE_OK = 0, ERROR_KEY_FILE_PARSE_NULL = 110,
- ERROR_KEY_FILE_TOO_BIG = 120, ERROR_KEY_FILE_EXCEEDS_MAX_NUMBERS_OF_KEYS = 130,
- ERROR_OPEN_FILE = 140, ERROR_READING_FILE = 150, ERROR_FALSE_FILE_KEY = 160,
- ERROR_KEYINITTYPE_SERVER_NOT_IMPLEMENTED = 170, ERROR_ENCRYPTION_SECRET_NULL = 180 };
- EncKeys();
- virtual ~EncKeys();
- bool initKeys( const char *name, const char *url, const int initType, const char *filekey);
- keyentry *getKeys( int id);
- /* made public for unit testing */
- static void parseSecret( const char *filename, char *secret );
-
-};
-
-#endif /* ENCKEYS_H_ */
diff --git a/storage/xtradb/include/KeySingleton.h b/storage/xtradb/include/KeySingleton.h
deleted file mode 100644
index 2b2f3991998..00000000000
--- a/storage/xtradb/include/KeySingleton.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (C) 2014 eperi GmbH. All Rights Reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-/******************************************************************//**
-@file KeySingletonPattern.h
-Implementation of single pattern to keep keys for encrypting/decrypting pages.
-
-Created 09/13/2014
-***********************************************************************/
-
-
-#ifndef KEYSINGLETON_H_
-#define KEYSINGLETON_H_
-
-#include "EncKeys.h"
-
-
-class KeySingleton
-{
-private:
- static bool instanceInited;
- static KeySingleton theInstance;
- static EncKeys encKeys;
-
- // No new instance or object possible
- KeySingleton() {}
-
- // No new instance possible through copy constructor
- KeySingleton( const KeySingleton&) {}
-
- // No new instance possible through copy
- KeySingleton & operator = (const KeySingleton&);
-
-public:
- virtual ~KeySingleton() {encKeys.~EncKeys();}
- static KeySingleton& getInstance();
- // Init the instance for only one time
- static KeySingleton& getInstance(const char *name, const char *url,
- const int initType, const char *filekey);
- keyentry *getKeys(int id);
- ibool hasKey(int id);
- static bool isAvailable() {
- return instanceInited;
- }
-};
-
-#endif /* KEYSINGLETON_H_ */
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index e0004311404..6d9c2d0404e 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -168,6 +168,8 @@ static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2;
/* @} */
/** File page types (values of FIL_PAGE_TYPE) @{ */
+#define FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED 35631 /* page compressed +
+ encrypted page */
#define FIL_PAGE_PAGE_COMPRESSED 34354 /*!< Page compressed page */
#define FIL_PAGE_PAGE_ENCRYPTED 34355 /*!< Page encrypted page */
#define FIL_PAGE_INDEX 17855 /*!< B-tree node */
@@ -1236,7 +1238,9 @@ fil_space_encrypt(
lsn_t lsn, /*!< in: page lsn */
const byte* src_frame,/*!< in: page frame */
ulint size, /*!< in: size of data to encrypt */
- byte* dst_frame); /*!< in: where to encrypt to */
+ byte* dst_frame, /*!< in: where to encrypt to */
+ ulint page_encryption_key); /*!< in: page encryption key id if page
+ encrypted */
/*********************************************************************
Decrypt buffer page */
diff --git a/storage/xtradb/include/fsp0pageencryption.ic b/storage/xtradb/include/fsp0pageencryption.ic
index c78ed40bcc6..7ff002b203e 100644
--- a/storage/xtradb/include/fsp0pageencryption.ic
+++ b/storage/xtradb/include/fsp0pageencryption.ic
@@ -24,7 +24,6 @@ Created 08/28/2014
***********************************************************************/
#include "fsp0fsp.h"
-#include "KeySingleton.h"
#include "fil0pageencryption.h"
@@ -116,6 +115,17 @@ fil_page_is_encrypted(
return(mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_ENCRYPTED);
}
+/*******************************************************************//**
+Find out whether the page is page is first compressed and then encrypted
+@return true if page is page compressed+encrypted, false if not */
+UNIV_INLINE
+ibool
+fil_page_is_compressed_encrypted(
+/*=============================*/
+ const byte *buf) /*!< in: page */
+{
+ return(mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
+}
/*******************************************************************//**
Find out whether the page can be decrypted.
@@ -139,22 +149,16 @@ fil_page_encryption_status(
if (page_type == FIL_PAGE_TYPE_FSP_HDR) {
ulint flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + buf);
if (fsp_flags_is_page_encrypted(flags)) {
- if (!KeySingleton::getInstance().isAvailable() ||
- !KeySingleton::getInstance().hasKey(fsp_flags_get_page_encryption_key(flags))) {
+ if (!HasCryptoKey(fsp_flags_get_page_encryption_key(flags))) {
/* accessing table would surely fail, because no key or no key provider available */
- if (KeySingleton::getInstance().isAvailable() &&
- !KeySingleton::getInstance().hasKey(fsp_flags_get_page_encryption_key(flags))) {
- return PAGE_ENCRYPTION_KEY_MISSING;
- }
- return PAGE_ENCRYPTION_ERROR;
+ return PAGE_ENCRYPTION_KEY_MISSING;
}
}
}
if(page_type == FIL_PAGE_PAGE_ENCRYPTED) {
ulint key = mach_read_from_1(buf + FIL_PAGE_SPACE_OR_CHKSUM);
- if (KeySingleton::getInstance().isAvailable() &&
- !KeySingleton::getInstance().hasKey(key)) {
- return PAGE_ENCRYPTION_KEY_MISSING;
+ if (!HasCryptoKey(key)) {
+ return PAGE_ENCRYPTION_KEY_MISSING;
}
return PAGE_ENCRYPTION_ERROR;
}
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index e2a409011b2..9cb1bd8d7f9 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -3152,6 +3152,7 @@ try_again:
if (ret && len == n) {
/* If page is encrypted we need to decrypt it first */
+ /*
if (fil_page_is_encrypted((byte *)buf)) {
if (fil_decrypt_page(
NULL,
@@ -3163,6 +3164,22 @@ try_again:
return FALSE;
}
}
+ */
+
+ if (fil_page_is_compressed_encrypted((byte *)buf) ||
+ fil_page_is_encrypted((byte *)buf)) {
+
+ byte * dst_frm = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE));
+ // Decrypt the data
+ fil_space_decrypt(
+ (fil_space_crypt_t* ) NULL,
+ (byte *)buf,
+ n,
+ dst_frm);
+ // Copy decrypted buffer back to buf
+ memcpy(buf, dst_frm, n);
+ ut_free(dst_frm);
+ }
/* Note that InnoDB writes files that are not formated
as file spaces and they do not have FIL_PAGE_TYPE
@@ -3185,6 +3202,7 @@ try_again:
if ((ulint) ret == n) {
/* If page is encrypted we need to decrypt it first */
+ /*
if (fil_page_is_encrypted((byte *)buf)) {
if (fil_decrypt_page(
NULL,
@@ -3196,6 +3214,21 @@ try_again:
return FALSE;
}
}
+ */
+ if (fil_page_is_compressed_encrypted((byte *)buf) ||
+ fil_page_is_encrypted((byte *)buf)) {
+
+ byte * dst_frm = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE));
+ // Decrypt the data
+ fil_space_decrypt(
+ (fil_space_crypt_t*) NULL,
+ (byte *)buf,
+ n,
+ dst_frm);
+ // Copy decrypted buffer back to buf
+ memcpy(buf, dst_frm, n);
+ ut_free(dst_frm);
+ }
/* Note that InnoDB writes files that are not formated
as file spaces and they do not have FIL_PAGE_TYPE
@@ -3296,6 +3329,7 @@ try_again:
if (ret && len == n) {
/* If page is encrypted we need to decrypt it first */
+ /*
if (fil_page_is_encrypted((byte *)buf)) {
if (fil_decrypt_page(
NULL,
@@ -3307,6 +3341,20 @@ try_again:
return (FALSE);
}
}
+ */
+ if (fil_page_is_compressed_encrypted((byte *)buf) ||
+ fil_page_is_encrypted((byte *)buf)) {
+ byte * dst_frm = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE));
+ // Decrypt the data
+ fil_space_decrypt(
+ (fil_space_crypt_t* ) NULL,
+ (byte *)buf,
+ n,
+ dst_frm);
+ // Copy decrypted buffer back to buf
+ memcpy(buf, dst_frm, n);
+ ut_free(dst_frm);
+ }
/* Note that InnoDB writes files that are not formated
as file spaces and they do not have FIL_PAGE_TYPE
@@ -3330,6 +3378,7 @@ try_again:
if ((ulint) ret == n) {
/* If the page is encrypted we need to decrypt it first */
+ /*
if (fil_page_is_encrypted((byte *)buf)) {
if (fil_decrypt_page(
NULL,
@@ -3341,6 +3390,23 @@ try_again:
return (FALSE);
}
}
+ */
+
+ if (fil_page_is_compressed_encrypted((byte *)buf) ||
+ fil_page_is_encrypted((byte *)buf)) {
+
+ byte * dst_frm = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE));
+ // Decrypt the data
+ fil_space_decrypt(
+ (fil_space_crypt_t* ) NULL,
+ (byte *)buf,
+ n,
+ dst_frm);
+ // Copy decrypted buffer back to buf
+ memcpy(buf, dst_frm, n);
+ ut_free(dst_frm);
+ }
+
/* Note that InnoDB writes files that are not formated
as file spaces and they do not have FIL_PAGE_TYPE
@@ -4901,6 +4967,10 @@ found:
os_mutex_enter(array->mutex);
}
+// if (srv_encrypt_tables) {
+// page_encryption = TRUE;
+// }
+
/* If the space is page encryption and this is write operation
then we encrypt the page */
if (message1 && type == OS_FILE_WRITE && page_encryption ) {
@@ -4915,28 +4985,18 @@ found:
// if it is not yet allocated.
os_slot_alloc_page_buf2(slot);
os_slot_alloc_tmp_encryption_buf(slot);
-
- tmp = fil_encrypt_page(
+ /* ctr not yet supported in xtradb, lsn is null*/
+ fil_space_encrypt(
fil_node_get_space_id(slot->message1),
+ slot->offset,
+ NULL,
(byte *)buf,
+ slot->len,
slot->page_buf2,
- len,
- page_encryption_key,
- &real_len,
- &ec,
- slot->tmp_encryption_buf);
+ slot->page_encryption_key);
- /* If encryption succeeded, set up the length and buffer */
- if (tmp != buf) {
- len = real_len;
- buf = slot->page_buf2;
- slot->len = real_len;
- slot->page_encryption_success = TRUE;
- } else {
- /* Use original not encrypted page */
- slot->page_encryption_success = FALSE;
- buf = slot->buf;
- }
+ slot->page_encryption_success = TRUE;
+ buf = slot->page_buf2;
/* Take array mutex back */
os_mutex_enter(array->mutex);
@@ -5575,16 +5635,20 @@ os_aio_windows_handle(
}
if (slot->type == OS_FILE_READ) {
- if (fil_page_is_encrypted(slot->buf)) {
+ if (fil_page_is_compressed_encrypted(slot->buf) ||
+ fil_page_is_encrypted(slot->buf)) {
+ ut_ad(slot->message1 != NULL);
os_slot_alloc_page_buf2(slot);
os_slot_alloc_tmp_encryption_buf(slot);
- fil_decrypt_page(
- slot->page_buf2,
+
+ // Decrypt the data
+ fil_space_decrypt(
+ fil_node_get_space_id(slot->message1),
slot->buf,
slot->len,
- slot->write_size,
- NULL,
- slot->tmp_encryption_buf);
+ slot->page_buf2);
+ // Copy decrypted buffer back to buf
+ memcpy(slot->buf, slot->page_buf2, slot->len);
}
if (fil_page_is_compressed(slot->buf)) {
@@ -5702,16 +5766,21 @@ retry:
ut_a(slot->pos < end_pos);
if (slot->type == OS_FILE_READ) {
- if (fil_page_is_encrypted(slot->buf)) {
+ /* If the page is page encrypted we decrypt */
+ if (fil_page_is_compressed_encrypted(slot->buf) ||
+ fil_page_is_encrypted(slot->buf)) {
os_slot_alloc_page_buf2(slot);
os_slot_alloc_tmp_encryption_buf(slot);
- fil_decrypt_page(
- slot->page_buf2,
+ ut_ad(slot->message1 != NULL);
+
+ // Decrypt the data
+ fil_space_decrypt(
+ fil_node_get_space_id(slot->message1),
slot->buf,
slot->len,
- slot->write_size,
- NULL,
- slot->tmp_encryption_buf);
+ slot->page_buf2);
+ // Copy decrypted buffer back to buf
+ memcpy(slot->buf, slot->page_buf2, slot->len);
}
/* If the page is page compressed and this is read,