summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2018-11-12 12:05:42 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2018-11-14 10:19:10 +0200
commit2eba5d6eabdd3f82bcc9859bb9333e1909ec0852 (patch)
tree3d8d8be35cc31520b438ae29b04b64c3b1198ed8
parent59c82dde09984d10f16417c9c82cd759f81d770c (diff)
downloadmariadb-git-bb-10.1-MDEV-17229.tar.gz
MDEV-17229: Encryption threads ignore innodb_default_encryption_key_idbb-10.1-MDEV-17229
Background MariaDB identifies encryption keys using a positive 32-bit integer. This makes it easier to identify the key you want to use for particular tables, through the ENCRYPTION_KEY_ID table option. You can set the default key using the innodb_default_encryption_key_id system variable. If no value is set system default (1) is used. Syntax SET [GLOBAL|SESSION] innodb-default-encryption-key-id=<key_id>; Used default encryption key_id can't be set to value that does not exists in the encryption plugin. e.g. SET GLOBAL innodb_default_encryption_key_id = 999; ERROR 42000: Variable 'innodb_default_encryption_key_id' can't be set to the value of '999' SHOW WARNINGS; Level Code Message Warning 1210 innodb_default_encryption_key_id=999 not available in the encryption plugin Error 1231 Variable 'innodb_default_encryption_key_id' can't be set to the value of '999' If variable is set on configuration file (my.cnf or similar) server will refuse to start if used key_id is not found in the encryption plugin. This can be seen on server error log e.g. [ERROR] innodb_default_encryption_key_id=999 is unavailable in the encryption plugin [ERROR] Plugin 'InnoDB' init function returned error. [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed. If user creates a table that is not encrypted e.g: create table t1(a int) encrypted=no engine=innodb; and default encryption key_id is not same as system default (1), a warning is issued and system default is used. SET GLOBAL innodb-default-encryption-key-id=1; CREATE TABLE t1 (a int) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=10; Warnings: Warning 140 InnoDB: Ignored ENCRYPTION_KEY_ID=10 when encryption is disabled Currently set default encryption key_id does not effect tables that are created using specific encryption key_id e.g. create table t1(a int) engine=innodb encrypted=yes encryption_key_id=4; Instead specified key_id (in above case 4) is used. Tables using encryption but no specific encryption key_id e.g. create table t1(a int) engine=innodb encrypted=yes; will use currently set default encryption key_id for that session or if no key_id defined the set global encryption key_id or system default. Tables using default table options e.g create table t1(a int) engine=innodb; will use currently set global encryption key_id when encryption threads does key rotation from unencrypted to encrypted state. Changes innodb-checksum-algorithm innodb-encryption-alter innodb-redo-badkey innodb-redo-nokeys These test require small changes as now we do not allow default key_id that is not found from encryption plugin and tables using no encryption produce warning when nondefault encryption key_id is used. fil_crypt_start_encrypting_space() Use global default encryption key_id when creating encryption meta data. innodb_default_encryption_key_id_validate() New function to validate that used key_id is found from encryption plugin. innodb_default_encryption_key_id() New accessessor function for default encryption key_id. innobase_init() Do not allow server startup using encryption key_id that is not found from encryption plugin.
-rw-r--r--mysql-test/suite/encryption/r/innodb-encryption-alter.result35
-rw-r--r--mysql-test/suite/encryption/r/innodb_encryption_default_key.result54
-rw-r--r--mysql-test/suite/encryption/t/innodb-encryption-alter.test12
-rw-r--r--mysql-test/suite/encryption/t/innodb-redo-badkey.opt2
-rw-r--r--mysql-test/suite/encryption/t/innodb-redo-badkey.test2
-rw-r--r--mysql-test/suite/encryption/t/innodb-redo-nokeys.opt2
-rw-r--r--mysql-test/suite/encryption/t/innodb-redo-nokeys.test2
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption_default_key.opt2
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption_default_key.test79
-rw-r--r--storage/innobase/fil/fil0crypt.cc5
-rw-r--r--storage/innobase/handler/ha_innodb.cc70
-rw-r--r--storage/innobase/include/ha_prototypes.h3
-rw-r--r--storage/xtradb/fil/fil0crypt.cc5
-rw-r--r--storage/xtradb/handler/ha_innodb.cc70
-rw-r--r--storage/xtradb/include/ha_prototypes.h3
15 files changed, 308 insertions, 38 deletions
diff --git a/mysql-test/suite/encryption/r/innodb-encryption-alter.result b/mysql-test/suite/encryption/r/innodb-encryption-alter.result
index 5245d1da7d0..e1ff9eacfbe 100644
--- a/mysql-test/suite/encryption/r/innodb-encryption-alter.result
+++ b/mysql-test/suite/encryption/r/innodb-encryption-alter.result
@@ -4,23 +4,28 @@ SET GLOBAL innodb_encrypt_tables = ON;
SET GLOBAL innodb_encryption_threads = 4;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=4;
Warnings:
-Warning 140 InnoDB: Ignored ENCRYPTION_KEY_ID 4 when encryption is disabled
+Warning 140 InnoDB: Ignored ENCRYPTION_KEY_ID=4 when encryption is disabled
DROP TABLE t1;
set innodb_default_encryption_key_id = 99;
+ERROR 42000: Variable 'innodb_default_encryption_key_id' can't be set to the value of '99'
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB;
-ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options")
-SHOW WARNINGS;
-Level Code Message
-Warning 140 InnoDB: ENCRYPTION_KEY_ID 99 not available
-Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options")
-Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `c` varchar(256) DEFAULT NULL,
+ PRIMARY KEY (`pk`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES;
-ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options")
-SHOW WARNINGS;
-Level Code Message
-Warning 140 InnoDB: ENCRYPTION_KEY_ID 99 not available
-Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options")
-Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `c` varchar(256) DEFAULT NULL,
+ PRIMARY KEY (`pk`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 `ENCRYPTED`=YES
+DROP TABLE t1;
set innodb_default_encryption_key_id = 4;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES;
SHOW CREATE TABLE t1;
@@ -39,16 +44,14 @@ t1 CREATE TABLE `t1` (
`c` varchar(256) DEFAULT NULL,
PRIMARY KEY (`pk`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 `ENCRYPTION_KEY_ID`=4
+set innodb_default_encryption_key_id = 1;
CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=1;
-Warnings:
-Warning 140 InnoDB: Ignored ENCRYPTION_KEY_ID 1 when encryption is disabled
ALTER TABLE t1 ENCRYPTION_KEY_ID=99;
ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID'
SHOW WARNINGS;
Level Code Message
Warning 140 InnoDB: ENCRYPTION_KEY_ID 99 not available
Error 1478 Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID'
-set innodb_default_encryption_key_id = 1;
drop table t1,t2;
SET GLOBAL innodb_encrypt_tables=OFF;
CREATE TABLE t1 (a int not null primary key) engine=innodb;
diff --git a/mysql-test/suite/encryption/r/innodb_encryption_default_key.result b/mysql-test/suite/encryption/r/innodb_encryption_default_key.result
new file mode 100644
index 00000000000..6ad1f621cb7
--- /dev/null
+++ b/mysql-test/suite/encryption/r/innodb_encryption_default_key.result
@@ -0,0 +1,54 @@
+call mtr.add_suppression("innodb_default_encryption_key_id=999 is unavailable in the encryption plugin");
+call mtr.add_suppression("Plugin 'InnoDB' init function returned error.");
+call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed.");
+SET GLOBAL innodb_file_format = `Barracuda`;
+SET GLOBAL innodb_file_per_table = ON;
+create table t1 (a int not null primary key) engine=InnoDB;
+create table t2 (a int not null primary key) encrypted=yes engine=InnoDB;
+SET GLOBAL innodb_default_encryption_key_id = -1;
+ERROR 42000: Variable 'innodb_default_encryption_key_id' can't be set to the value of '-1'
+SHOW WARNINGS;
+Level Code Message
+Error 1231 Variable 'innodb_default_encryption_key_id' can't be set to the value of '-1'
+SET GLOBAL innodb_default_encryption_key_id = 4294967296;
+ERROR 42000: Variable 'innodb_default_encryption_key_id' can't be set to the value of '4294967296'
+SHOW WARNINGS;
+Level Code Message
+Error 1231 Variable 'innodb_default_encryption_key_id' can't be set to the value of '4294967296'
+SET GLOBAL innodb_default_encryption_key_id = 'k';
+ERROR 42000: Incorrect argument type to variable 'innodb_default_encryption_key_id'
+SHOW WARNINGS;
+Level Code Message
+Error 1232 Incorrect argument type to variable 'innodb_default_encryption_key_id'
+SET GLOBAL innodb_default_encryption_key_id = 999;
+ERROR 42000: Variable 'innodb_default_encryption_key_id' can't be set to the value of '999'
+SHOW WARNINGS;
+Level Code Message
+Warning 1210 innodb_default_encryption_key_id=999 not available in the encryption plugin
+Error 1231 Variable 'innodb_default_encryption_key_id' can't be set to the value of '999'
+SET GLOBAL innodb_default_encryption_key_id = 4;
+SET GLOBAL innodb_encryption_threads = 4;
+SET GLOBAL innodb_encrypt_tables = ON;
+SET SESSION innodb_default_encryption_key_id = 2;
+create table t3 (a int not null primary key) engine=InnoDB;
+create table t4 (a int not null primary key) encrypted=yes engine=InnoDB;
+SET SESSION innodb_default_encryption_key_id = 10;
+create table t5 (a int not null primary key) engine=InnoDB;
+create table t6 (a int not null primary key) encrypted=yes engine=InnoDB;
+SELECT NAME,CURRENT_KEY_ID,MIN_KEY_VERSION FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 ORDER BY NAME;
+NAME CURRENT_KEY_ID MIN_KEY_VERSION
+SELECT NAME,CURRENT_KEY_ID,MIN_KEY_VERSION FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 ORDER BY NAME;
+NAME CURRENT_KEY_ID MIN_KEY_VERSION
+./ibdata1 4 1
+mysql/innodb_index_stats 4 1
+mysql/innodb_table_stats 4 1
+test/t1 4 1
+test/t2 1 1
+test/t3 2 1
+test/t4 2 1
+test/t5 10 1
+test/t6 10 1
+# Success!
+DROP TABLE t1, t2, t3, t4, t5, t6;
+# Restart mysqld --innodb_default_encryption_key_id=999
+# Restart mysqld --innodb_default_encryption_key_id=1
diff --git a/mysql-test/suite/encryption/t/innodb-encryption-alter.test b/mysql-test/suite/encryption/t/innodb-encryption-alter.test
index 9465226dd96..fdd2dd86805 100644
--- a/mysql-test/suite/encryption/t/innodb-encryption-alter.test
+++ b/mysql-test/suite/encryption/t/innodb-encryption-alter.test
@@ -19,25 +19,25 @@ SET GLOBAL innodb_encryption_threads = 4;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=4;
DROP TABLE t1;
+--error ER_WRONG_VALUE_FOR_VAR
set innodb_default_encryption_key_id = 99;
---error 1005
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB;
-SHOW WARNINGS;
---error 1005
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES;
-SHOW WARNINGS;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
set innodb_default_encryption_key_id = 4;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES;
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB;
SHOW CREATE TABLE t1;
+set innodb_default_encryption_key_id = 1;
CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=1;
--error ER_ILLEGAL_HA_CREATE_OPTION
ALTER TABLE t1 ENCRYPTION_KEY_ID=99;
SHOW WARNINGS;
-set innodb_default_encryption_key_id = 1;
-
--disable_warnings
--disable_query_log
diff --git a/mysql-test/suite/encryption/t/innodb-redo-badkey.opt b/mysql-test/suite/encryption/t/innodb-redo-badkey.opt
index 343128e8803..2b07bbb4b73 100644
--- a/mysql-test/suite/encryption/t/innodb-redo-badkey.opt
+++ b/mysql-test/suite/encryption/t/innodb-redo-badkey.opt
@@ -1,5 +1,5 @@
--innodb-change-buffering=all
---innodb-encrypt-tables=on
+--innodb-encrypt-tables=off
--innodb-tablespaces-encryption
--innodb-encryption-threads=2
--innodb-default-encryption-key-id=4
diff --git a/mysql-test/suite/encryption/t/innodb-redo-badkey.test b/mysql-test/suite/encryption/t/innodb-redo-badkey.test
index 69de4f0f921..75e765ca941 100644
--- a/mysql-test/suite/encryption/t/innodb-redo-badkey.test
+++ b/mysql-test/suite/encryption/t/innodb-redo-badkey.test
@@ -16,7 +16,7 @@ call mtr.add_suppression("InnoDB: Plugin initialization aborted ");
call mtr.add_suppression("InnoDB: ############### CORRUPT LOG RECORD FOUND ##################");
--echo # Restart mysqld --file-key-management-filename=keys2.txt
--- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
+-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt --innodb-default-encryption-key-id=20 --innodb-encrypt-tables=ON
-- source include/restart_mysqld.inc
--echo # Wait max 10 min for key encryption threads to encrypt all spaces
diff --git a/mysql-test/suite/encryption/t/innodb-redo-nokeys.opt b/mysql-test/suite/encryption/t/innodb-redo-nokeys.opt
index 21afc19fc5d..b72e464c480 100644
--- a/mysql-test/suite/encryption/t/innodb-redo-nokeys.opt
+++ b/mysql-test/suite/encryption/t/innodb-redo-nokeys.opt
@@ -1,3 +1,3 @@
--innodb-change-buffering=none
--innodb-encrypt-tables=on
---innodb-default-encryption-key-id=20
+--innodb-default-encryption-key-id=1
diff --git a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test
index 68d831fcd17..5882b9de5c5 100644
--- a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test
+++ b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test
@@ -12,7 +12,7 @@ call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE faile
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[1234]\\.ibd' cannot be decrypted\\.");
--echo # Restart mysqld --file-key-management-filename=keys2.txt
--- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
+-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt --innodb-default-encryption-key-id=20
-- source include/restart_mysqld.inc
--disable_warnings
diff --git a/mysql-test/suite/encryption/t/innodb_encryption_default_key.opt b/mysql-test/suite/encryption/t/innodb_encryption_default_key.opt
new file mode 100644
index 00000000000..5a60c7ba21c
--- /dev/null
+++ b/mysql-test/suite/encryption/t/innodb_encryption_default_key.opt
@@ -0,0 +1,2 @@
+--innodb-tablespaces-encryption
+--innodb-encrypt-tables=OFF
diff --git a/mysql-test/suite/encryption/t/innodb_encryption_default_key.test b/mysql-test/suite/encryption/t/innodb_encryption_default_key.test
new file mode 100644
index 00000000000..0f077707f98
--- /dev/null
+++ b/mysql-test/suite/encryption/t/innodb_encryption_default_key.test
@@ -0,0 +1,79 @@
+-- source include/have_innodb.inc
+-- source include/have_file_key_management_plugin.inc
+-- source include/not_embedded.inc
+
+call mtr.add_suppression("innodb_default_encryption_key_id=999 is unavailable in the encryption plugin");
+call mtr.add_suppression("Plugin 'InnoDB' init function returned error.");
+call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed.");
+
+--disable_query_log
+let $innodb_file_format_orig = `SELECT @@innodb_file_format`;
+let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`;
+--enable_query_log
+
+--disable_warnings
+SET GLOBAL innodb_file_format = `Barracuda`;
+SET GLOBAL innodb_file_per_table = ON;
+--enable_warnings
+
+create table t1 (a int not null primary key) engine=InnoDB;
+create table t2 (a int not null primary key) encrypted=yes engine=InnoDB;
+
+#
+# Test limits
+#
+--error ER_WRONG_VALUE_FOR_VAR
+SET GLOBAL innodb_default_encryption_key_id = -1;
+SHOW WARNINGS;
+--error ER_WRONG_VALUE_FOR_VAR
+SET GLOBAL innodb_default_encryption_key_id = 4294967296;
+SHOW WARNINGS;
+--error ER_WRONG_TYPE_FOR_VAR
+SET GLOBAL innodb_default_encryption_key_id = 'k';
+SHOW WARNINGS;
+
+# Do not allow setting default key to key_id that is not found
+--error ER_WRONG_VALUE_FOR_VAR
+SET GLOBAL innodb_default_encryption_key_id = 999;
+SHOW WARNINGS;
+
+SET GLOBAL innodb_default_encryption_key_id = 4;
+SET GLOBAL innodb_encryption_threads = 4;
+SET GLOBAL innodb_encrypt_tables = ON;
+
+--connect (con11,localhost,root,,test)
+SET SESSION innodb_default_encryption_key_id = 2;
+create table t3 (a int not null primary key) engine=InnoDB;
+create table t4 (a int not null primary key) encrypted=yes engine=InnoDB;
+--disconnect con11
+
+--connect (con12,localhost,root,,test)
+SET SESSION innodb_default_encryption_key_id = 10;
+create table t5 (a int not null primary key) engine=InnoDB;
+create table t6 (a int not null primary key) encrypted=yes engine=InnoDB;
+--disconnect con12
+
+--connection default
+--let $tables_count= `select count(*) from information_schema.tables where engine = 'InnoDB'`
+--let $wait_condition=SELECT COUNT(*) = $tables_count + 1 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND ROTATING_OR_FLUSHING = 0;
+--source include/wait_condition.inc
+
+SELECT NAME,CURRENT_KEY_ID,MIN_KEY_VERSION FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 ORDER BY NAME;
+SELECT NAME,CURRENT_KEY_ID,MIN_KEY_VERSION FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 ORDER BY NAME;
+
+--echo # Success!
+
+DROP TABLE t1, t2, t3, t4, t5, t6;
+
+#
+# Try to restart server with key_id that is not found from encryption plugin
+#
+--echo # Restart mysqld --innodb_default_encryption_key_id=999
+-- let $restart_parameters=--innodb_default_encryption_key_id=999
+--error 1
+-- source include/restart_mysqld.inc
+
+--echo # Restart mysqld --innodb_default_encryption_key_id=1
+-- let $restart_parameters=--innodb_default_encryption_key_id=1
+--error 1
+-- source include/restart_mysqld.inc
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 7859fe67d40..3e66bfee884 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -1063,8 +1063,9 @@ fil_crypt_start_encrypting_space(
* risk of finding encrypted pages without having
* crypt data in page 0 */
- /* 1 - create crypt data */
- crypt_data = fil_space_create_crypt_data(FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+ /* 1 - create crypt data using default encryption key_id */
+ crypt_data = fil_space_create_crypt_data(FIL_ENCRYPTION_DEFAULT,
+ innodb_default_encryption_key_id());
if (crypt_data == NULL) {
mutex_exit(&fil_crypt_threads_mutex);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index a0e6a385b37..d0ef42f7d82 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -685,11 +685,64 @@ static int mysql_tmpfile_path(const char *path, const char *prefix)
static void innodb_remember_check_sysvar_funcs();
mysql_var_check_func check_sysvar_enum;
+/** Validate passed-in "value" is a valid encryption key_id
+found from encryption plugin.
+This function is registered as a callback with MySQL.
+@param[in,out] thd thread handle
+@param[in] var pointer to system variable
+@param[out] save immediate result for validate
+@param[in] value incoming string
+@return 0 for valid key_id */
+static
+int
+innodb_default_encryption_key_id_validate(
+ THD* thd,
+ struct st_mysql_sys_var* var,
+ void* save,
+ struct st_mysql_value* value)
+{
+ long long key_id_buf;
+ uint key_id;
+
+ if (value->val_int(value, &key_id_buf)) {
+ /* The value is NULL. That is invalid. */
+ return 1;
+ }
+
+ if (key_id_buf < 1 || key_id_buf > UINT_MAX32) {
+ /* Out of range */
+ return 1;
+ }
+
+ *reinterpret_cast<uint*>(save) = key_id = static_cast<uint>(key_id_buf);
+
+ /* Default encryption key_id must be found from encryption
+ plugin keys. */
+ if (key_id != FIL_DEFAULT_ENCRYPTION_KEY
+ && !encryption_key_id_exists(key_id)) {
+ push_warning_printf(
+ thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "innodb_default_encryption_key_id=%u not available in the encryption plugin",
+ key_id);
+ return 1;
+ }
+
+ return 0;
+}
+
static MYSQL_THDVAR_UINT(default_encryption_key_id, PLUGIN_VAR_RQCMDARG,
"Default encryption key id used for table encryption.",
- NULL, NULL,
+ innodb_default_encryption_key_id_validate,
+ NULL,
FIL_DEFAULT_ENCRYPTION_KEY, 1, UINT_MAX32, 0);
+/** @return innodb_default_encryption_key_id */
+UNIV_INTERN uint innodb_default_encryption_key_id()
+{
+ return(THDVAR(NULL, default_encryption_key_id));
+}
+
/**
Structure for CREATE TABLE options (table options).
It needs to be called ha_table_option_struct.
@@ -3428,6 +3481,7 @@ innobase_init(
char *default_path;
uint format_id;
ulong num_pll_degree;
+ uint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton*) p;
@@ -3592,6 +3646,14 @@ innobase_init(
goto error;
}
+ key_id = THDVAR(NULL, default_encryption_key_id);
+ if (key_id != FIL_DEFAULT_ENCRYPTION_KEY
+ && !encryption_key_id_exists(key_id)) {
+ sql_print_error("innodb_default_encryption_key_id=%u is "
+ "unavailable in the encryption plugin", key_id);
+ goto error;
+ }
+
os_innodb_umask = (ulint) my_umask;
/* First calculate the default path for innodb_data_home_dir etc.,
@@ -11937,12 +11999,12 @@ ha_innobase::check_table_options(
}
/* Ignore nondefault key_id if encryption is set off */
- if (encrypt == FIL_ENCRYPTION_OFF &&
- options->encryption_key_id != THDVAR(thd, default_encryption_key_id)) {
+ if (encrypt == FIL_ENCRYPTION_OFF
+ && options->encryption_key_id != THDVAR(thd, default_encryption_key_id)) {
push_warning_printf(
thd, Sql_condition::WARN_LEVEL_WARN,
HA_WRONG_CREATE_OPTION,
- "InnoDB: Ignored ENCRYPTION_KEY_ID %u when encryption is disabled",
+ "InnoDB: Ignored ENCRYPTION_KEY_ID=%u when encryption is disabled",
(uint)options->encryption_key_id
);
options->encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index be423c8bd01..84d5652ce64 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -348,6 +348,9 @@ thd_supports_xa(
THD* thd); /*!< in: thread handle, or NULL to query
the global innodb_supports_xa */
+/** @return innodb_default_encryption_key_id */
+UNIV_INTERN uint innodb_default_encryption_key_id();
+
/** Get status of innodb_tmpdir.
@param[in] thd thread handle, or NULL to query
the global innodb_tmpdir.
diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc
index 7859fe67d40..3e66bfee884 100644
--- a/storage/xtradb/fil/fil0crypt.cc
+++ b/storage/xtradb/fil/fil0crypt.cc
@@ -1063,8 +1063,9 @@ fil_crypt_start_encrypting_space(
* risk of finding encrypted pages without having
* crypt data in page 0 */
- /* 1 - create crypt data */
- crypt_data = fil_space_create_crypt_data(FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+ /* 1 - create crypt data using default encryption key_id */
+ crypt_data = fil_space_create_crypt_data(FIL_ENCRYPTION_DEFAULT,
+ innodb_default_encryption_key_id());
if (crypt_data == NULL) {
mutex_exit(&fil_crypt_threads_mutex);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index d01977f072b..c9da3e19623 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -686,11 +686,64 @@ ib_cb_t innodb_api_cb[] = {
static void innodb_remember_check_sysvar_funcs();
mysql_var_check_func check_sysvar_enum;
+/** Validate passed-in "value" is a valid encryption key_id
+found from encryption plugin.
+This function is registered as a callback with MySQL.
+@param[in,out] thd thread handle
+@param[in] var pointer to system variable
+@param[out] save immediate result for validate
+@param[in] value incoming string
+@return 0 for valid key_id */
+static
+int
+innodb_default_encryption_key_id_validate(
+ THD* thd,
+ struct st_mysql_sys_var* var,
+ void* save,
+ struct st_mysql_value* value)
+{
+ long long key_id_buf;
+ uint key_id;
+
+ if (value->val_int(value, &key_id_buf)) {
+ /* The value is NULL. That is invalid. */
+ return 1;
+ }
+
+ if (key_id_buf < 1 || key_id_buf > UINT_MAX32) {
+ /* Out of range */
+ return 1;
+ }
+
+ *reinterpret_cast<uint*>(save) = key_id = static_cast<uint>(key_id_buf);
+
+ /* Default encryption key_id must be found from encryption
+ plugin keys. */
+ if (key_id != FIL_DEFAULT_ENCRYPTION_KEY
+ && !encryption_key_id_exists(key_id)) {
+ push_warning_printf(
+ thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "innodb_default_encryption_key_id=%u not available in the encryption plugin",
+ key_id);
+ return 1;
+ }
+
+ return 0;
+}
+
static MYSQL_THDVAR_UINT(default_encryption_key_id, PLUGIN_VAR_RQCMDARG,
"Default encryption key id used for table encryption.",
- NULL, NULL,
+ innodb_default_encryption_key_id_validate,
+ NULL,
FIL_DEFAULT_ENCRYPTION_KEY, 1, UINT_MAX32, 0);
+/** @return innodb_default_encryption_key_id */
+UNIV_INTERN uint innodb_default_encryption_key_id()
+{
+ return(THDVAR(NULL, default_encryption_key_id));
+}
+
/**
Structure for CREATE TABLE options (table options).
It needs to be called ha_table_option_struct.
@@ -3839,6 +3892,7 @@ innobase_init(
char *default_path;
uint format_id;
ulong num_pll_degree;
+ uint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton*) p;
@@ -4042,6 +4096,14 @@ innobase_init(
goto error;
}
+ key_id = THDVAR(NULL, default_encryption_key_id);
+ if (key_id != FIL_DEFAULT_ENCRYPTION_KEY
+ && !encryption_key_id_exists(key_id)) {
+ sql_print_error("innodb_default_encryption_key_id=%u is "
+ "unavailable in the encryption plugin", key_id);
+ goto error;
+ }
+
os_innodb_umask = (ulint) my_umask;
/* First calculate the default path for innodb_data_home_dir etc.,
@@ -12504,12 +12566,12 @@ ha_innobase::check_table_options(
}
/* Ignore nondefault key_id if encryption is set off */
- if (encrypt == FIL_ENCRYPTION_OFF &&
- options->encryption_key_id != THDVAR(thd, default_encryption_key_id)) {
+ if (encrypt == FIL_ENCRYPTION_OFF
+ && options->encryption_key_id != THDVAR(thd, default_encryption_key_id)) {
push_warning_printf(
thd, Sql_condition::WARN_LEVEL_WARN,
HA_WRONG_CREATE_OPTION,
- "InnoDB: Ignored ENCRYPTION_KEY_ID %u when encryption is disabled",
+ "InnoDB: Ignored ENCRYPTION_KEY_ID=%u when encryption is disabled",
(uint)options->encryption_key_id
);
options->encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 3f3c4f28ced..60b36440a8b 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -366,6 +366,9 @@ thd_supports_xa(
THD* thd); /*!< in: thread handle, or NULL to query
the global innodb_supports_xa */
+/** @return innodb_default_encryption_key_id */
+UNIV_INTERN uint innodb_default_encryption_key_id();
+
/** Get status of innodb_tmpdir.
@param[in] thd thread handle, or NULL to query
the global innodb_tmpdir.