summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Widenius <monty@mariadb.org>2014-12-20 15:44:23 +0200
committerMichael Widenius <monty@mariadb.org>2014-12-20 15:44:23 +0200
commit406b31e628145f6af0fa567c0e42b8391e5173bb (patch)
treeaff311e03c5bb078fe67b090bd8a0e602beed547
parent634428b37fd039b862c8277a0c7b0b5f56e765fc (diff)
downloadmariadb-git-bb-10.1-eperi.tar.gz
Fixes for encryption from eperibb-10.1-eperi
-rw-r--r--include/keyfile.h38
-rw-r--r--include/my_aes.h13
-rw-r--r--include/my_crypt_key_management.h28
-rw-r--r--include/mysql/plugin.h3
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_encryption-32k-master.opt2
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_encryption.opt2
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_encryption_compression.opt2
-rw-r--r--mysys_ssl/my_aes.cc92
-rw-r--r--mysys_ssl/my_crypt_key_management.cc36
-rw-r--r--mysys_ssl/my_crypt_key_management_impl.cc18
-rw-r--r--plugin/example_key_management_plugin/example_key_management_plugin.cc32
-rw-r--r--plugin/file_key_management_plugin/CMakeLists.txt4
-rw-r--r--plugin/file_key_management_plugin/EncKeys.cc137
-rw-r--r--plugin/file_key_management_plugin/EncKeys.h17
-rw-r--r--plugin/file_key_management_plugin/KeySingleton.cc7
-rw-r--r--plugin/file_key_management_plugin/KeySingleton.h5
-rw-r--r--plugin/file_key_management_plugin/file_key_management_plugin.cc171
-rw-r--r--sql/sql_plugin.cc74
-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
45 files changed, 1193 insertions, 1468 deletions
diff --git a/include/keyfile.h b/include/keyfile.h
deleted file mode 100644
index d55c79086d4..00000000000
--- a/include/keyfile.h
+++ /dev/null
@@ -1,38 +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 */
-
-/******************************************************************/
-#ifndef KEYFILE_H
-#define KEYFILE_H
-#include<stdio.h>
-
-struct keyentry {
- int id;
- char *iv;
- char *key;
-};
-
-int
-parseFile(FILE * fp, struct keyentry **allKeys, const int k_len, const char *secret);
-
-int
-parseLine(const char *line, struct keyentry *entry, const int k_len);
-
-int
-isComment(char *line);
-
-char*
-trim(char *in);
-#endif
diff --git a/include/my_aes.h b/include/my_aes.h
index 4c40894e116..8ec36add4d1 100644
--- a/include/my_aes.h
+++ b/include/my_aes.h
@@ -32,9 +32,17 @@ typedef int Crypt_result;
#define AES_BAD_KEYSIZE -5
#define AES_KEY_CREATION_FAILED -10
+#define CRYPT_KEY_OK 0
+#define CRYPT_BUFFER_TO_SMALL -11;
+#define CRYPT_KEY_UNKNOWN -48;
+
/* The max block sizes of all supported algorithms */
#define MY_AES_BLOCK_SIZE 16
+/* The max key length of all supported algorithms */
+#define MY_AES_MAX_KEY_LENGTH 32
+
+
#include "rijndael.h"
C_MODE_START
@@ -54,8 +62,7 @@ C_MODE_START
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
- @param noPadding [in] if set to true, no padding is used, input data size must
- be a mulitple of the AES block size
+ @param noPadding [in] if set, algorithm specific padding behaviour is used
Method used defined by calling my_aes_init_dynamic_encrypt() at startup.
@@ -85,7 +92,7 @@ extern my_aes_encrypt_dynamic_type my_aes_encrypt_dynamic;
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
- @param noPadding [in] if set to true, no padding is used, input data size must be a mulitple of the AES block size
+ @param noPadding [in] if set, algorithm specific padding behaviour is used
@return
!= 0 error
diff --git a/include/my_crypt_key_management.h b/include/my_crypt_key_management.h
index 619ac6c11fb..99643d654e1 100644
--- a/include/my_crypt_key_management.h
+++ b/include/my_crypt_key_management.h
@@ -21,7 +21,17 @@ C_MODE_START
/**
* function returning latest key version
*/
-typedef unsigned int (* GetLatestCryptoKeyVersionFunc_t)();
+typedef int (* GetLatestCryptoKeyVersionFunc_t)();
+
+/**
+ * function returning if the key exists
+ */
+typedef unsigned int (* HasKeyVersionFunc_t)(unsigned int version);
+
+/**
+ * function returning the key size
+ */
+typedef int (* GetKeySizeFunc_t)(unsigned int version);
/**
* function returning a key for a key version
@@ -30,11 +40,21 @@ typedef int (* GetCryptoKeyFunc_t)(unsigned int version,
unsigned char* key,
unsigned keybufsize);
+/**
+ * function returning an iv for a key version
+ */
+typedef int (* GetCryptoIVFunc_t)(unsigned int version,
+ unsigned char* iv,
+ unsigned ivbufsize);
+
struct CryptoKeyFuncs_t
{
GetLatestCryptoKeyVersionFunc_t getLatestCryptoKeyVersionFunc;
+ HasKeyVersionFunc_t hasCryptoKeyFunc;
+ GetKeySizeFunc_t getCryptoKeySize;
GetCryptoKeyFunc_t getCryptoKeyFunc;
+ GetCryptoIVFunc_t getCryptoIVFunc;
};
/**
@@ -47,9 +67,13 @@ InstallCryptoKeyFunctions(const struct CryptoKeyFuncs_t* cryptoKeyFuncs);
* Functions to interact with key management
*/
-unsigned int GetLatestCryptoKeyVersion();
+int GetLatestCryptoKeyVersion();
+unsigned int HasCryptoKey(unsigned int version);
+int GetCryptoKeySize(unsigned int version);
int GetCryptoKey(unsigned int version, unsigned char* key_buffer,
unsigned int size);
+int GetCryptoIV(unsigned int version, unsigned char* key_buffer,
+ unsigned int size);
C_MODE_END
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index 07f3c26ba74..b610daabb06 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -89,7 +89,8 @@ typedef struct st_mysql_xid MYSQL_XID;
#define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */
#define MYSQL_AUTHENTICATION_PLUGIN 7 /* The authentication plugin type */
#define MYSQL_VALIDATE_PASSWORD_PLUGIN 8 /* validate password plugin type */
-#define MYSQL_MAX_PLUGIN_TYPE_NUM 9 /* The number of plugin types */
+#define MYSQL_KEY_MANAGEMENT_PLUGIN 9 /* The number of plugin types */
+#define MYSQL_MAX_PLUGIN_TYPE_NUM 10 /* The number of plugin types */
/* We use the following strings to define licenses for plugins */
#define PLUGIN_LICENSE_PROPRIETARY 0
diff --git a/mysql-test/suite/innodb/t/innodb-page_encryption-32k-master.opt b/mysql-test/suite/innodb/t/innodb-page_encryption-32k-master.opt
index 0c479718e27..a2d8b7ab11a 100644
--- a/mysql-test/suite/innodb/t/innodb-page_encryption-32k-master.opt
+++ b/mysql-test/suite/innodb/t/innodb-page_encryption-32k-master.opt
@@ -1 +1 @@
---default_storage_engine=InnoDB --innodb-buffer-pool-size=24M --innodb_data_encryption_providertype=1 --innodb_data_encryption_providername=keys.txt --innodb_data_encryption_providerurl=$MYSQL_TEST_DIR/suite/innodb/include
+--default_storage_engine=InnoDB --innodb-buffer-pool-size=24M --file_key_management_plugin_filename=$MYSQL_TEST_DIR/suite/innodb/include/keys.txt \ No newline at end of file
diff --git a/mysql-test/suite/innodb/t/innodb-page_encryption.opt b/mysql-test/suite/innodb/t/innodb-page_encryption.opt
index 8f9ce8c88ed..ca1d5d1ef18 100644
--- a/mysql-test/suite/innodb/t/innodb-page_encryption.opt
+++ b/mysql-test/suite/innodb/t/innodb-page_encryption.opt
@@ -1 +1 @@
---innodb_data_encryption_providertype=1 --innodb_data_encryption_providername=keys.txt --innodb_data_encryption_providerurl=$MYSQL_TEST_DIR/suite/innodb/include \ No newline at end of file
+--enable-file_key_management_plugin --file_key_management_plugin_filename=$MYSQL_TEST_DIR/suite/innodb/include/keys.txt
diff --git a/mysql-test/suite/innodb/t/innodb-page_encryption_compression.opt b/mysql-test/suite/innodb/t/innodb-page_encryption_compression.opt
index 8f9ce8c88ed..da28287f7a4 100644
--- a/mysql-test/suite/innodb/t/innodb-page_encryption_compression.opt
+++ b/mysql-test/suite/innodb/t/innodb-page_encryption_compression.opt
@@ -1 +1 @@
---innodb_data_encryption_providertype=1 --innodb_data_encryption_providername=keys.txt --innodb_data_encryption_providerurl=$MYSQL_TEST_DIR/suite/innodb/include \ No newline at end of file
+--enable-file_key_management_plugin --file_key_management_plugin_filename=$MYSQL_TEST_DIR/suite/innodb/include/keys.txt \ No newline at end of file
diff --git a/mysys_ssl/my_aes.cc b/mysys_ssl/my_aes.cc
index 22ea3d164ba..20bd03551c2 100644
--- a/mysys_ssl/my_aes.cc
+++ b/mysys_ssl/my_aes.cc
@@ -139,7 +139,7 @@ void my_aes_hex2uint(const char* in, unsigned char *out, int dest_length)
void my_bytes_to_key(const unsigned char *salt, const char *secret, unsigned char *key,
unsigned char *iv)
{
- #ifdef HAVE_YASSL
+#ifdef HAVE_YASSL
/* the yassl function has no support for SHA1. Reason unknown. */
int keyLen = 32;
int ivLen = 16;
@@ -188,7 +188,7 @@ void my_bytes_to_key(const unsigned char *salt, const char *secret, unsigned cha
ivLeft -= store;
}
}
-#elif HAVE_OPENSSL
+#elif defined(HAVE_OPENSSL)
const EVP_CIPHER *type = EVP_aes_256_cbc();
const EVP_MD *digest = EVP_sha1();
EVP_BytesToKey(type, digest, salt, (uchar*) secret, strlen(secret), 1, key, iv);
@@ -208,8 +208,9 @@ void my_bytes_to_key(const unsigned char *salt, const char *secret, unsigned cha
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
- @param noPadding [in] if set to true, no padding is used, input data size must
- be a multiple of the AES block size
+ @param noPadding [in] if set to true, no padding is used. if the input length is not a
+ multiple of the AES block size, trailing bytes are only copied to destination buffer.
+ This allows currently the same interface for CBC, ECB and CTR encryption.
@return
!= 0 error
0 no error
@@ -221,8 +222,8 @@ static int my_aes_encrypt_cbc(const uchar* source, uint32 source_length,
const unsigned char* iv, uint8 iv_length,
uint noPadding)
{
- if (noPadding && (source_length % MY_AES_BLOCK_SIZE) !=0)
- return AES_BAD_DATA;
+ uint8 remaining_bytes = (noPadding == 0) ? 0 : source_length % MY_AES_BLOCK_SIZE;
+ source_length = source_length - remaining_bytes;
#ifdef HAVE_YASSL
TaoCrypt::AES_CBC_Encryption enc;
@@ -254,7 +255,10 @@ static int my_aes_encrypt_cbc(const uchar* source, uint32 source_length,
}
if (noPadding) {
- *dest_length = MY_AES_BLOCK_SIZE * (num_blocks);
+ if (remaining_bytes!=0) {
+ memcpy(dest + source_length, source + source_length, remaining_bytes);
+ }
+ *dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes;
return AES_OK;
}
@@ -305,7 +309,11 @@ static int my_aes_encrypt_cbc(const uchar* source, uint32 source_length,
return AES_BAD_DATA; /* Error */
if (! EVP_EncryptFinal_ex(&ctx.ctx, (unsigned char *) dest + u_len, &f_len))
return AES_BAD_DATA; /* Error */
- *dest_length = (unsigned long int) (u_len + f_len);
+
+ if (remaining_bytes!=0) {
+ memcpy(dest + source_length, source + source_length, remaining_bytes);
+ }
+ *dest_length = (unsigned long int) (u_len + f_len + remaining_bytes);
return AES_OK;
#else
@@ -328,8 +336,9 @@ static int my_aes_encrypt_cbc(const uchar* source, uint32 source_length,
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
- @param noPadding [in] if set to true, no padding is used, input data size must
- be a multiple of the AES block size
+ @param noPadding [in] if set to true, no padding is used. if the input length is not a
+ multiple of the AES block size, trailing bytes are only copied to destination buffer.
+ This allows currently the same interface for CBC, ECB and CTR encryption.
@return
!= 0 error
0 no error
@@ -341,8 +350,8 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length,
const unsigned char* iv, uint8 iv_length,
uint noPadding)
{
- if (noPadding && (source_length % MY_AES_BLOCK_SIZE) !=0)
- return AES_BAD_DATA;
+ uint8 remaining_bytes = (noPadding == 0) ? 0 : source_length % MY_AES_BLOCK_SIZE;
+ source_length = source_length - remaining_bytes;
#ifdef HAVE_YASSL
TaoCrypt::AES_ECB_Encryption enc;
@@ -374,7 +383,10 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length,
}
if (noPadding) {
- *dest_length = MY_AES_BLOCK_SIZE * (num_blocks);
+ if (remaining_bytes!=0) {
+ memcpy(dest + source_length, source + source_length, remaining_bytes);
+ }
+ *dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes;
return AES_OK;
}
@@ -425,7 +437,11 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length,
return AES_BAD_DATA; /* Error */
if (! EVP_EncryptFinal_ex(&ctx.ctx, (unsigned char *) dest + u_len, &f_len))
return AES_BAD_DATA; /* Error */
- *dest_length = (unsigned long int) (u_len + f_len);
+
+ if (remaining_bytes!=0) {
+ memcpy(dest + source_length, source + source_length, remaining_bytes);
+ }
+ *dest_length = (unsigned long int) (u_len + f_len + remaining_bytes);
return AES_OK;
#else
@@ -449,7 +465,9 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length,
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
- @param noPadding [in] if set to true, no padding is used, input data size must be a mulitple of the AES block size
+ @param noPadding [in] if set to true, no padding is used. if the input length is not a
+ multiple of the AES block size, trailing bytes are only copied to destination buffer.
+ This allows currently the same interface for CBC, ECB and CTR encryption.
@return
!= 0 error
@@ -462,8 +480,9 @@ static int my_aes_decrypt_cbc(const uchar* source, uint32 source_length,
const unsigned char* iv, uint8 iv_length,
uint noPadding)
{
- if (noPadding && (source_length % MY_AES_BLOCK_SIZE) !=0)
- return AES_BAD_DATA;
+ uint8 remaining_bytes = (noPadding == 0) ? 0 : source_length % MY_AES_BLOCK_SIZE;
+ source_length = source_length - remaining_bytes;
+
#ifdef HAVE_YASSL
TaoCrypt::AES_CBC_Decryption dec;
@@ -504,7 +523,10 @@ static int my_aes_decrypt_cbc(const uchar* source, uint32 source_length,
if (noPadding) {
memcpy(dest, block, MY_AES_BLOCK_SIZE);
- *dest_length = MY_AES_BLOCK_SIZE * num_blocks;
+ if (remaining_bytes!=0) {
+ memcpy(dest + source_length, source + source_length, remaining_bytes);
+ }
+ *dest_length = MY_AES_BLOCK_SIZE * num_blocks + remaining_bytes;
return AES_OK;
}
@@ -554,7 +576,10 @@ static int my_aes_decrypt_cbc(const uchar* source, uint32 source_length,
*dest_length = (unsigned long int) u_len;
return AES_BAD_DATA;
}
- *dest_length = (unsigned long int) (u_len + f_len);
+ if (remaining_bytes!=0) {
+ memcpy(dest + source_length, source + source_length, remaining_bytes);
+ }
+ *dest_length = (unsigned long int) (u_len + f_len) + remaining_bytes;
#endif
return AES_OK;
}
@@ -572,7 +597,9 @@ static int my_aes_decrypt_cbc(const uchar* source, uint32 source_length,
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
- @param noPadding [in] if set to true, no padding is used, input data size must be a mulitple of the AES block size
+ @param noPadding [in] if set to true, no padding is used. if the input length is not a
+ multiple of the AES block size, trailing bytes are only copied to destination buffer.
+ This allows currently the same interface for CBC, ECB and CTR encryption.
@return
!= 0 error
@@ -585,8 +612,9 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length,
const unsigned char* iv, uint8 iv_length,
uint noPadding)
{
- if (noPadding && (source_length % MY_AES_BLOCK_SIZE) !=0)
- return AES_BAD_DATA;
+ uint8 remaining_bytes = (noPadding == 0) ? 0 : source_length % MY_AES_BLOCK_SIZE;
+ source_length = source_length - remaining_bytes;
+
#ifdef HAVE_YASSL
TaoCrypt::AES_ECB_Decryption dec;
@@ -627,7 +655,10 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length,
if (noPadding) {
memcpy(dest, block, MY_AES_BLOCK_SIZE);
- *dest_length = MY_AES_BLOCK_SIZE * num_blocks;
+ if (remaining_bytes!=0) {
+ memcpy(dest + source_length, source + source_length, remaining_bytes);
+ }
+ *dest_length = MY_AES_BLOCK_SIZE * num_blocks + remaining_bytes;
return AES_OK;
}
@@ -677,7 +708,11 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length,
*dest_length = (unsigned long int) u_len;
return AES_BAD_DATA;
}
- *dest_length = (unsigned long int) (u_len + f_len);
+ if (remaining_bytes!=0) {
+ memcpy(dest + source_length, source + source_length, remaining_bytes);
+ }
+ *dest_length = (unsigned long int) (u_len + f_len) + remaining_bytes;
+
#endif
return AES_OK;
}
@@ -687,7 +722,7 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length,
/**
- Encryption interface that doesn't do anyting (for testing)
+ Encryption interface that doesn't do anything (for testing)
SYNOPSIS
my_aes_encrypt_none()
@@ -699,8 +734,7 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length,
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
- @param noPadding [in] if set to true, no padding is used, input data size must
- be a multiple of the AES block size
+ @param noPadding [in] unused
@return
!= 0 error
0 no error
@@ -719,7 +753,7 @@ static int my_aes_encrypt_none(const uchar* source, uint32 source_length,
/**
- Decryption interface that doesn't do anyting (for testing)
+ Decryption interface that doesn't do anything (for testing)
SYNOPSIS
my_aes_decrypt_none()
@@ -731,7 +765,7 @@ static int my_aes_encrypt_none(const uchar* source, uint32 source_length,
@param key_length [in] Length of the key. 16, 24 or 32
@param iv [in] Iv to be used for encryption
@param iv_length [in] Length of the iv. should be 16.
- @param noPadding [in] if set to true, no padding is used, input data size must be a multiple of the AES block size
+ @param noPadding [in] unused
@return
!= 0 error
diff --git a/mysys_ssl/my_crypt_key_management.cc b/mysys_ssl/my_crypt_key_management.cc
index 9e39642bcdc..94199403b4a 100644
--- a/mysys_ssl/my_crypt_key_management.cc
+++ b/mysys_ssl/my_crypt_key_management.cc
@@ -18,9 +18,13 @@ unsigned int opt_danger_danger_dbug_crypto_key_version = 0;
/**
* Default functions
*/
-unsigned int GetLatestCryptoKeyVersionImpl();
+int GetLatestCryptoKeyVersionImpl();
+unsigned int HasCryptoKeyImpl(unsigned int version);
+int GetCryptoKeySizeImpl(unsigned int version);
int GetCryptoKeyImpl(unsigned int version, unsigned char* key_buffer,
unsigned int size);
+int GetCryptoIVImpl(unsigned int version, unsigned char* key_buffer,
+ unsigned int size);
/**
* Function pointers for
@@ -30,11 +34,14 @@ int GetCryptoKeyImpl(unsigned int version, unsigned char* key_buffer,
static
struct CryptoKeyFuncs_t cryptoKeyFuncs = {
GetLatestCryptoKeyVersionImpl,
- GetCryptoKeyImpl
+ HasCryptoKeyImpl,
+ GetCryptoKeySizeImpl,
+ GetCryptoKeyImpl,
+ GetCryptoIVImpl
};
extern "C"
-unsigned int GetLatestCryptoKeyVersion() {
+int GetLatestCryptoKeyVersion() {
#ifndef DBUG_OFF
if (opt_danger_danger_use_dbug_keys) {
mysql_rwlock_rdlock(&LOCK_dbug_crypto_key_version);
@@ -48,6 +55,16 @@ unsigned int GetLatestCryptoKeyVersion() {
}
extern "C"
+unsigned int HasCryptoKey(unsigned int version) {
+ return (* cryptoKeyFuncs.hasCryptoKeyFunc)(version);
+}
+
+extern "C"
+int GetCryptoKeySize(unsigned int version) {
+ return (* cryptoKeyFuncs.getCryptoKeySize)(version);
+}
+
+extern "C"
int GetCryptoKey(unsigned int version, unsigned char* key, unsigned int size) {
#ifndef DBUG_OFF
if (opt_danger_danger_use_dbug_keys) {
@@ -67,16 +84,27 @@ int GetCryptoKey(unsigned int version, unsigned char* key, unsigned int size) {
}
extern "C"
+int GetCryptoIV(unsigned int version, unsigned char* key, unsigned int size) {
+ return (* cryptoKeyFuncs.getCryptoIVFunc)(version, key, size);
+}
+
+extern "C"
void
InstallCryptoKeyFunctions(const struct CryptoKeyFuncs_t* _cryptoKeyFuncs)
{
if (_cryptoKeyFuncs == NULL)
{
- /* restore defaults when called with NULL argument */
+ /* restore defaults wHashhen called with NULL argument */
cryptoKeyFuncs.getLatestCryptoKeyVersionFunc =
GetLatestCryptoKeyVersionImpl;
+ cryptoKeyFuncs.hasCryptoKeyFunc =
+ HasCryptoKeyImpl;
+ cryptoKeyFuncs.getCryptoKeySize =
+ GetCryptoKeySizeImpl;
cryptoKeyFuncs.getCryptoKeyFunc =
GetCryptoKeyImpl;
+ cryptoKeyFuncs.getCryptoIVFunc =
+ GetCryptoIVImpl;
}
else
{
diff --git a/mysys_ssl/my_crypt_key_management_impl.cc b/mysys_ssl/my_crypt_key_management_impl.cc
index 23c87c9208a..ece4b72c372 100644
--- a/mysys_ssl/my_crypt_key_management_impl.cc
+++ b/mysys_ssl/my_crypt_key_management_impl.cc
@@ -1,7 +1,17 @@
#include <my_global.h>
// TODO Not yet implemented.
-unsigned int GetLatestCryptoKeyVersionImpl()
+int GetLatestCryptoKeyVersionImpl()
+{
+ abort();
+}
+
+unsigned int HasCryptoKeyImpl(unsigned int version)
+{
+ abort();
+}
+
+int GetCryptoKeySizeImpl(unsigned int version)
{
abort();
}
@@ -11,3 +21,9 @@ int GetCryptoKeyImpl(unsigned int version, unsigned char* key,
{
abort();
}
+
+int GetCryptoIVImpl(unsigned int version, unsigned char* key,
+ unsigned int key_size)
+{
+ abort();
+}
diff --git a/plugin/example_key_management_plugin/example_key_management_plugin.cc b/plugin/example_key_management_plugin/example_key_management_plugin.cc
index 19fac2ca38c..5785d264c60 100644
--- a/plugin/example_key_management_plugin/example_key_management_plugin.cc
+++ b/plugin/example_key_management_plugin/example_key_management_plugin.cc
@@ -2,6 +2,7 @@
#include <mysql_version.h>
#include <my_global.h>
+#include <my_aes.h>
#include <my_crypt_key_management.h>
#include <my_md5.h>
@@ -15,7 +16,7 @@ static unsigned int next_key_version = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static
-unsigned int
+int
get_latest_key_version()
{
uint now = time(0);
@@ -50,15 +51,44 @@ get_key(unsigned int version, unsigned char* dstbuf, unsigned buflen)
return 0;
}
+static unsigned int has_key_func(unsigned int keyID)
+{
+ return true;
+}
+
+static int get_key_size(unsigned int keyID)
+{
+ return 16;
+}
+
+static int get_iv(unsigned int keyID, unsigned char* dstbuf, unsigned buflen)
+{
+ if (buflen < 16)
+ {
+ return CRYPT_BUFFER_TO_SMALL;
+ }
+
+ for (int i=0; i<16; i++)
+ dstbuf[i] = 0;
+
+ return CRYPT_KEY_OK;
+}
+
+
static int example_key_management_plugin_init(void *p)
{
/* init */
seed = time(0);
get_latest_key_version();
+ my_aes_init_dynamic_encrypt(MY_AES_ALGORITHM_CTR);
+
struct CryptoKeyFuncs_t func;
func.getLatestCryptoKeyVersionFunc = get_latest_key_version;
+ func.hasCryptoKeyFunc = has_key_func;
+ func.getCryptoKeySize = get_key_size;
func.getCryptoKeyFunc = get_key;
+ func.getCryptoIVFunc = get_iv;
InstallCryptoKeyFunctions(&func);
return 0;
}
diff --git a/plugin/file_key_management_plugin/CMakeLists.txt b/plugin/file_key_management_plugin/CMakeLists.txt
index a4eb490c9a7..49196448e2b 100644
--- a/plugin/file_key_management_plugin/CMakeLists.txt
+++ b/plugin/file_key_management_plugin/CMakeLists.txt
@@ -1,3 +1,3 @@
-SET(FILE_KEY_MANAGEMENT_PLUGIN_SOURCES file_key_management_plugin.cc )
+SET(FILE_KEY_MANAGEMENT_PLUGIN_SOURCES file_key_management_plugin.cc EncKeys.cc KeySingleton.cc)
-MYSQL_ADD_PLUGIN(FILE_KEY_MANAGEMENT_PLUGIN ${FILE_KEY_MANAGEMENT_PLUGIN_SOURCES} MANDATORY)
+MYSQL_ADD_PLUGIN(FILE_KEY_MANAGEMENT_PLUGIN ${FILE_KEY_MANAGEMENT_PLUGIN_SOURCES} DEFAULT)
diff --git a/plugin/file_key_management_plugin/EncKeys.cc b/plugin/file_key_management_plugin/EncKeys.cc
index cabdf7911a0..c43d261926a 100644
--- a/plugin/file_key_management_plugin/EncKeys.cc
+++ b/plugin/file_key_management_plugin/EncKeys.cc
@@ -23,37 +23,43 @@ Example
[mysqld]
...
-innodb_data_encryption_providertype = 1
-innodb_data_encryption_providername = keys.enc
-innodb_data_encryption_providerurl = /home/mdb/
-innodb_data_encryption_filekey = secret
+file_key_management_plugin_filename = /home/mdb/keys.enc
+file_key_management_plugin_filekey = secret
+file_key_management_plugin_encryption_method = aes_cbc
+
...
+Optional configuration value file_key_management_plugin_encryption_method determines the method used for encryption.
+Supported are aes_cbc, aes_ecb or aes_ctr. aes_cbc is default.
+The plug-in sets the default aes encryption/decryption method to the given method.
+
+The keys are read from a file.
+The filename is set up via the file_key_management_plugin_filename configuration value.
+file_key_management_plugin_filename is used to configure the absolute path to this file.
-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)
+file_key_management_plugin_filename = \\\\unc\\keys.enc (windows share)
+file_key_management_plugin_filename = e:/tmp/keys.enc (windows path)
+file_key_management_plugin_filename = /tmp/keys.enc (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.
+Example:
+1;F5502320F8429037B8DAEF761B189D12;770A8A65DA156D24EE2A093277530142
+
+1 is the key identifier which can be used for table creation, a 16 byte IV follows, and finally a 16 byte AES key.
+255 entries are supported.
The key file should be encrypted and the key to decrypt the file can be given with the
-innodb_data_encryption_filekey parameter.
+optional file_key_management_plugin_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.
+as absolute path 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
+file_key_management_plugin_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
@@ -67,6 +73,7 @@ openssl enc –aes-256-cbc –md sha1 –k <initialPwd> –in secret –out secr
#include "EncKeys.h"
#include <my_global.h>
+
#include <my_aes.h>
#include <memory.h>
#include <my_sys.h>
@@ -119,59 +126,34 @@ EncKeys::~EncKeys() {
}
}
-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;
-}
+bool EncKeys::initKeys(const char *filename, const char *filekey) {
+ if (filename==NULL)
+ return ERROR_OPEN_FILE;
-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)
+
+ char *secret = (char*) malloc(MAX_SECRET_SIZE +1 * 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
{
- //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(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;
+ int ret = parseFile((const char *)filename, 254, secret);
+ free(secret);
+ return (ret==NO_ERROR_KEY_FILE_PARSE_OK);
}
/*
@@ -181,7 +163,6 @@ void EncKeys::parseSecret( const char *secretfile, char *secret ) {
int maxSize = (MAX_SECRET_SIZE +16 + magicSize*2) ;
char* buf = (char*)malloc((maxSize) * sizeof(char));
char* _initPwd = (char*)malloc((strlen(initialPwd)+1) * sizeof(char));
-
FILE *fp = fopen(secretfile, "rb");
fseek(fp, 0L, SEEK_END);
long file_size = ftell(fp);
@@ -201,8 +182,9 @@ void EncKeys::parseSecret( const char *secretfile, char *secret ) {
_initPwd[strlen(initialPwd)]= '\0';
my_bytes_to_key((unsigned char *) salt, _initPwd, key, iv);
uint32 d_size = 0;
- int res = my_aes_decrypt_cbc((const char*)buf + 2 * magicSize, bytes_to_read - 2 * magicSize,
- secret, &d_size, key, keySize32, iv, ivSize16, 0);
+ my_aes_decrypt_dynamic_type func = get_aes_decrypt_func(MY_AES_ALGORITHM_CBC);
+ int res = (* func)((const uchar*)buf + 2 * magicSize, bytes_to_read - 2 * magicSize,
+ (uchar*)secret, &d_size, (const uchar*)key, keySize32, iv, ivSize16, 0);
if (d_size>EncKeys::MAX_SECRET_SIZE) {
d_size = EncKeys::MAX_SECRET_SIZE;
}
@@ -237,10 +219,10 @@ keyentry *EncKeys::getKeys(int id) {
* 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 EncKeys::parseFile(const char* filename, const uint32 maxKeyId, const char *secret) {
int errorCode = 0;
char *buffer = decryptFile(filename, secret, &errorCode);
- ulint id = 0;
+ uint32 id = 0;
if (NO_ERROR_PARSE_OK != errorCode) return errorCode;
else errorCode = NO_ERROR_KEY_FILE_PARSE_OK;
@@ -258,17 +240,17 @@ int EncKeys::parseFile(const char* filename, const ulint maxKeyId, const char *s
break;
case ERROR_ID_TOO_BIG:
fprintf(stderr, errorExceedKeySize, KEY_MAX, keyLineInKeyFile);
- fprintf(stderr, " --> %s\n", line);
+ 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);
+ 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);
+ fprintf(stderr, " -----> %s\n", line);
errorCode = ERROR_KEY_FILE_PARSE_NULL;
break;
case NO_ERROR_KEY_GREATER_THAN_ASKED:
@@ -287,7 +269,7 @@ int EncKeys::parseFile(const char* filename, const ulint maxKeyId, const char *s
return errorCode;
}
-int EncKeys::parseLine(const char *line, const ulint maxKeyId) {
+int EncKeys::parseLine(const char *line, const uint32 maxKeyId) {
int ret = NO_ERROR_PARSE_OK;
if (isComment(line))
ret = NO_ERROR_ISCOMMENT;
@@ -314,7 +296,7 @@ int EncKeys::parseLine(const char *line, const ulint maxKeyId) {
else {
char buffer[4];
sprintf(buffer, "%.*s", substr_length, substring_start);
- ulint id = atoi(buffer);
+ uint32 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;
@@ -381,12 +363,13 @@ char* EncKeys::decryptFile(const char* filename, const char *secret, int *errorC
unsigned char salt[magicSize];
unsigned char *key = new unsigned char[keySize32];
unsigned char *iv = new unsigned char[ivSize16];
- char *decrypted = new char[file_size];
+ 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;
- int res = my_aes_decrypt_cbc((const char*)buffer + 2 * magicSize, file_size - 2 * magicSize,
- decrypted, &d_size, key, keySize32, iv, ivSize16, 0);
+ my_aes_decrypt_dynamic_type func = get_aes_decrypt_func(MY_AES_ALGORITHM_CBC);
+ int res = (* func)((const uchar*)buffer + 2 * magicSize, file_size - 2 * magicSize,
+ decrypted, &d_size, (const uchar*) key, keySize32, iv, ivSize16, 0);
if(0 != res) {
*errorCode = ERROR_FALSE_FILE_KEY;
delete[] buffer; buffer = NULL;
@@ -415,7 +398,7 @@ bool EncKeys::isComment(const char *line) {
}
-void EncKeys::printKeyEntry( ulint id)
+void EncKeys::printKeyEntry( uint32 id)
{
#ifdef UNIV_DEBUG
keyentry *entry = getKeys(id);
diff --git a/plugin/file_key_management_plugin/EncKeys.h b/plugin/file_key_management_plugin/EncKeys.h
index ec05c8667df..c2b56047a6e 100644
--- a/plugin/file_key_management_plugin/EncKeys.h
+++ b/plugin/file_key_management_plugin/EncKeys.h
@@ -23,15 +23,16 @@ Created 09/15/2014
#ifndef ENCKEYS_H_
#define ENCKEYS_H_
-#include "my_global.h"
+#include <my_global.h>
#include <sys/types.h>
#include <stdio.h>
+
struct keyentry {
- ulint id;
+ uint32 id;
char *iv;
char *key;
};
@@ -58,16 +59,14 @@ private:
*errorNotImplemented, *errorOpenFile, *errorReadingFile, *errorFileSize;
static const char* initialPwd;
- ulint countKeys, keyLineInKeyFile;
+ uint32 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);
+ void printKeyEntry( uint32 id);
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);
+ int parseFile( const char* filename, const uint32 maxKeyId, const char *secret);
+ int parseLine( const char *line, const uint32 maxKeyId);
public:
static const size_t MAX_SECRET_SIZE = 256;
@@ -78,7 +77,7 @@ public:
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);
+ bool initKeys( const char *filename, const char *filekey);
keyentry *getKeys( int id);
/* made public for unit testing */
static void parseSecret( const char *filename, char *secret );
diff --git a/plugin/file_key_management_plugin/KeySingleton.cc b/plugin/file_key_management_plugin/KeySingleton.cc
index fc633b4f63c..891fe4335f9 100644
--- a/plugin/file_key_management_plugin/KeySingleton.cc
+++ b/plugin/file_key_management_plugin/KeySingleton.cc
@@ -41,11 +41,10 @@ KeySingleton & KeySingleton::getInstance() {
return theInstance;
}
-KeySingleton & KeySingleton::getInstance(const char *name, const char *url,
- const int initType, const char *filekey) {
+KeySingleton & KeySingleton::getInstance(const char *filename, const char *filekey) {
if(instanceInited) return theInstance;
- instanceInited = encKeys.initKeys(name, url, initType, filekey);
+ instanceInited = encKeys.initKeys(filename, filekey);
if( !instanceInited) {
fprintf(stderr, "Could not initialize any of the encryption / decryption keys. "
"You can not read encrypted tables\n\n");
@@ -59,7 +58,7 @@ keyentry *KeySingleton::getKeys(int id) {
return encKeys.getKeys(id);
}
-ibool KeySingleton::hasKey(int id) {
+bool KeySingleton::hasKey(int id) {
return encKeys.getKeys(id) != NULL;
}
diff --git a/plugin/file_key_management_plugin/KeySingleton.h b/plugin/file_key_management_plugin/KeySingleton.h
index 2b2f3991998..d66ff44df27 100644
--- a/plugin/file_key_management_plugin/KeySingleton.h
+++ b/plugin/file_key_management_plugin/KeySingleton.h
@@ -47,10 +47,9 @@ 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);
+ static KeySingleton& getInstance(const char *filename, const char *filekey);
keyentry *getKeys(int id);
- ibool hasKey(int id);
+ bool hasKey(int id);
static bool isAvailable() {
return instanceInited;
}
diff --git a/plugin/file_key_management_plugin/file_key_management_plugin.cc b/plugin/file_key_management_plugin/file_key_management_plugin.cc
index 4fc853d172c..ce0d3aea208 100644
--- a/plugin/file_key_management_plugin/file_key_management_plugin.cc
+++ b/plugin/file_key_management_plugin/file_key_management_plugin.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2012, eperi GmbH.
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
@@ -17,23 +17,176 @@
#include <my_global.h>
#include <mysql_version.h>
#include <my_aes.h>
+#include <my_crypt_key_management.h>
+#include <string.h>
+#include "sql_class.h"
+
+//#include "file_key_management_plugin.h"
+#include "KeySingleton.h"
+#include "EncKeys.h"
+
+
+/* Encryption for tables and columns */
+static char* filename = NULL;
+static char* filekey = NULL;
+static char* encryption_method = NULL;
+
+static MYSQL_SYSVAR_STR(encryption_method, encryption_method,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Name of the encryption method. This can be aes_cbc (default) or aes_ctr (requires OpenSSL on Linux).",
+ NULL, NULL, "aes_cbc");
+
+static MYSQL_SYSVAR_STR(filename, filename,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Path and name of the key file.",
+ NULL, NULL, NULL);
+
+static MYSQL_SYSVAR_STR(filekey, filekey,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Key to encrypt / decrypt the keyfile.",
+ NULL, NULL, NULL);
+
+static struct st_mysql_sys_var* settings[] = {
+ MYSQL_SYSVAR(encryption_method),
+ MYSQL_SYSVAR(filename),
+ MYSQL_SYSVAR(filekey),
+ NULL
+};
+
+
+
+/**
+ * This method is using with the id 0 if exists. This method is used by innobase/xtradb for the key
+ * rotation feature of encrypting log files.
+ */
+static int get_highest_key_used_in_key_file()
+{
+ if (KeySingleton::getInstance().hasKey(0))
+ {
+ return 0;
+ }
+ else
+ return CRYPT_KEY_UNKNOWN;
+}
+
+static unsigned int has_key_from_key_file(unsigned int keyID)
+{
+ keyentry* entry = KeySingleton::getInstance().getKeys(keyID);
+
+ return entry != NULL;
+}
+
+static int get_key_size_from_key_file(unsigned int keyID)
+{
+ keyentry* entry = KeySingleton::getInstance().getKeys(keyID);
+
+ if (entry != NULL)
+ {
+ char* keyString = entry->key;
+ size_t key_len = strlen(keyString)/2;
+
+ return key_len;
+ }
+ else
+ {
+ return CRYPT_KEY_UNKNOWN;
+ }
+}
+
+static int get_key_from_key_file(unsigned int keyID, unsigned char* dstbuf, unsigned buflen)
+{
+ keyentry* entry = KeySingleton::getInstance().getKeys((int)keyID);
+
+ if (entry != NULL)
+ {
+ char* keyString = entry->key;
+ size_t key_len = strlen(keyString)/2;
+
+ if (buflen < key_len)
+ {
+ return CRYPT_BUFFER_TO_SMALL;
+ }
+
+ my_aes_hex2uint(keyString, (unsigned char*)dstbuf, key_len);
+
+ return CRYPT_KEY_OK;
+ }
+ else
+ {
+ return CRYPT_KEY_UNKNOWN;
+ }
+}
+
+static int get_iv_from_key_file(unsigned int keyID, unsigned char* dstbuf, unsigned buflen)
+{
+ keyentry* entry = KeySingleton::getInstance().getKeys((int)keyID);
+
+ if (entry != NULL)
+ {
+ char* ivString = entry->iv;
+ size_t iv_len = strlen(ivString)/2;
+
+ if (buflen < iv_len)
+ {
+ return CRYPT_BUFFER_TO_SMALL;
+ }
+
+ my_aes_hex2uint(ivString, (unsigned char*)dstbuf, iv_len);
+
+ return CRYPT_KEY_OK;
+ }
+ else
+ {
+ return CRYPT_KEY_UNKNOWN;
+ }
+}
+
static int file_key_management_plugin_init(void *p)
{
/* init */
- printf("TO_BE_REMOVED: Loading file_key_management_plugin_init\n");
+ printf("@DE: Loading file_key_management_plugin_init \n");
+
+ /* Setting encryption method */
+ if (encryption_method != NULL && strcmp("aes_ctr", encryption_method) == 0)
+ {
+ my_aes_init_dynamic_encrypt(MY_AES_ALGORITHM_CTR);
+ } else if (encryption_method != NULL && strcmp("aes_ecb", encryption_method) == 0)
+ {
+ my_aes_init_dynamic_encrypt(MY_AES_ALGORITHM_ECB);
+ }
+ else
+ {
+ my_aes_init_dynamic_encrypt(MY_AES_ALGORITHM_CBC);
+ }
+
- /* Setting to MY_AES_METHOD_CBC for page encryption */
- my_aes_init_dynamic_encrypt(MY_AES_ALGORITHM_CBC);
+ /* Initializing the key provider */
+ struct CryptoKeyFuncs_t func;
+ func.getLatestCryptoKeyVersionFunc = get_highest_key_used_in_key_file;
+ func.hasCryptoKeyFunc = has_key_from_key_file;
+ func.getCryptoKeySize = get_key_size_from_key_file;
+ func.getCryptoKeyFunc = get_key_from_key_file;
+ func.getCryptoIVFunc = get_iv_from_key_file;
+
+ InstallCryptoKeyFunctions(&func);
+
+ if (filename == NULL || strcmp("", filename) == 0)
+ {
+ sql_print_error("Parameter file_key_management_plugin_filename is required");
+
+ return 1;
+ }
+
+ KeySingleton::getInstance(filename, filekey);
return 0;
}
static int file_key_management_plugin_deinit(void *p)
{
- /**
- * don't uninstall...
- */
+ KeySingleton::getInstance().~KeySingleton();
+
return 0;
}
@@ -46,7 +199,7 @@ struct st_mysql_daemon file_key_management_plugin= {
*/
maria_declare_plugin(file_key_management_plugin)
{
- MYSQL_DAEMON_PLUGIN,
+ MYSQL_KEY_MANAGEMENT_PLUGIN,
&file_key_management_plugin,
"file_key_management_plugin",
"Denis Endro eperi GmbH",
@@ -56,7 +209,7 @@ maria_declare_plugin(file_key_management_plugin)
file_key_management_plugin_deinit, /* Plugin Deinit */
0x0100 /* 1.0 */,
NULL, /* status variables */
- NULL, /* system variables */
+ settings,
"1.0",
MariaDB_PLUGIN_MATURITY_UNKNOWN
}
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 66b0b810717..874e3943e10 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1229,7 +1229,17 @@ static void reap_plugins(void)
list= reap;
while ((plugin= *(--list)))
- plugin_deinitialize(plugin, true);
+ {
+ if (plugin->plugin->type != MYSQL_KEY_MANAGEMENT_PLUGIN)
+ plugin_deinitialize(plugin, true);
+ }
+
+ list= reap;
+ while ((plugin= *(--list)))
+ {
+ if (plugin->plugin->type == MYSQL_KEY_MANAGEMENT_PLUGIN)
+ plugin_deinitialize(plugin, true);
+ }
mysql_mutex_lock(&LOCK_plugin);
@@ -1529,6 +1539,65 @@ int plugin_init(int *argc, char **argv, int flags)
/*
First we register builtin plugins
*/
+ mandatory = false;
+ for (builtins= mysql_optional_plugins; *builtins; builtins++)
+ {
+ for (plugin= *builtins; plugin->info; plugin++)
+ {
+ if (opt_ignore_builtin_innodb &&
+ !my_strnncoll(&my_charset_latin1, (const uchar*) plugin->name,
+ 6, (const uchar*) "InnoDB", 6))
+ continue;
+
+ if (plugin->type != MYSQL_KEY_MANAGEMENT_PLUGIN)
+ continue;
+
+ bzero(&tmp, sizeof(tmp));
+ tmp.plugin= plugin;
+ tmp.name.str= (char *)plugin->name;
+ tmp.name.length= strlen(plugin->name);
+ tmp.state= 0;
+ tmp.load_option= mandatory ? PLUGIN_FORCE : PLUGIN_ON;
+
+ for (i=0; i < array_elements(override_plugin_load_policy); i++)
+ {
+ if (!my_strcasecmp(&my_charset_latin1, plugin->name,
+ override_plugin_load_policy[i].plugin_name))
+ {
+ tmp.load_option= override_plugin_load_policy[i].override;
+ break;
+ }
+ }
+
+ free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
+ tmp.state= PLUGIN_IS_UNINITIALIZED;
+ if (register_builtin(plugin, &tmp, &plugin_ptr))
+ goto err_unlock;
+
+ is_myisam= !my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM");
+
+ if (plugin_initialize(&tmp_root, plugin_ptr, argc, argv, !is_myisam &&
+ (flags & PLUGIN_INIT_SKIP_INITIALIZATION)))
+ {
+ if (plugin_ptr->load_option == PLUGIN_FORCE)
+ goto err_unlock;
+ plugin_ptr->state= PLUGIN_IS_DISABLED;
+ }
+
+ if (is_myisam)
+ {
+ DBUG_ASSERT(!global_system_variables.table_plugin);
+ global_system_variables.table_plugin=
+ intern_plugin_lock(NULL, plugin_int_to_ref(plugin_ptr));
+ DBUG_ASSERT(plugin_ptr->ref_count == 1);
+ }
+ }
+ }
+
+ /*
+ First we register builtin plugins
+ */
+ mandatory = true;
for (builtins= mysql_mandatory_plugins; *builtins || mandatory; builtins++)
{
if (!*builtins)
@@ -1545,6 +1614,9 @@ int plugin_init(int *argc, char **argv, int flags)
6, (const uchar*) "InnoDB", 6))
continue;
+ if (plugin->type == MYSQL_KEY_MANAGEMENT_PLUGIN)
+ continue;
+
bzero(&tmp, sizeof(tmp));
tmp.plugin= plugin;
tmp.name.str= (char *)plugin->name;
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,