mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Identical key derivation code in XtraDB/InnoDB/Aria
* Extract it into the "encryption_scheme" service. * Make these engines to use the service, remove duplicate code. * Change MY_AES_xxx error codes, to return them safely from encryption_scheme_encrypt/decrypt without conflicting with ENCRYPTION_SCHEME_KEY_INVALID error
This commit is contained in:
@ -25,10 +25,10 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* return values from my_aes_encrypt/my_aes_decrypt functions */
|
/* return values from my_aes_encrypt/my_aes_decrypt functions */
|
||||||
#define MY_AES_OK 0
|
#define MY_AES_OK 0
|
||||||
#define MY_AES_BAD_DATA -1
|
#define MY_AES_BAD_DATA -100
|
||||||
#define MY_AES_OPENSSL_ERROR -2
|
#define MY_AES_OPENSSL_ERROR -101
|
||||||
#define MY_AES_BAD_KEYSIZE -3
|
#define MY_AES_BAD_KEYSIZE -102
|
||||||
|
|
||||||
/* The block size for all supported algorithms */
|
/* The block size for all supported algorithms */
|
||||||
#define MY_AES_BLOCK_SIZE 16
|
#define MY_AES_BLOCK_SIZE 16
|
||||||
|
@ -75,7 +75,7 @@ typedef struct st_mysql_xid MYSQL_XID;
|
|||||||
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0104
|
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0104
|
||||||
|
|
||||||
/* MariaDB plugin interface version */
|
/* MariaDB plugin interface version */
|
||||||
#define MARIA_PLUGIN_INTERFACE_VERSION 0x010a
|
#define MARIA_PLUGIN_INTERFACE_VERSION 0x010b
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The allowable types of plugins
|
The allowable types of plugins
|
||||||
|
@ -213,6 +213,43 @@ struct encryption_service_st {
|
|||||||
encrypt_decrypt_func encryption_decrypt_func;
|
encrypt_decrypt_func encryption_decrypt_func;
|
||||||
};
|
};
|
||||||
extern struct encryption_service_st encryption_handler;
|
extern struct encryption_service_st encryption_handler;
|
||||||
|
#include <mysql/service_encryption_scheme.h>
|
||||||
|
struct st_encryption_scheme_key {
|
||||||
|
unsigned int version;
|
||||||
|
unsigned char key[16];
|
||||||
|
};
|
||||||
|
struct st_encryption_scheme {
|
||||||
|
unsigned char iv[16];
|
||||||
|
struct st_encryption_scheme_key key[3];
|
||||||
|
unsigned int keyserver_requests;
|
||||||
|
unsigned int key_id;
|
||||||
|
unsigned int type;
|
||||||
|
void (*locker)(struct st_encryption_scheme *self, int release);
|
||||||
|
};
|
||||||
|
extern struct encryption_scheme_service_st {
|
||||||
|
int (*encryption_scheme_encrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int (*encryption_scheme_decrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
} *encryption_scheme_service;
|
||||||
|
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
struct st_mysql_xid {
|
struct st_mysql_xid {
|
||||||
long formatID;
|
long formatID;
|
||||||
long gtrid_length;
|
long gtrid_length;
|
||||||
|
@ -213,6 +213,43 @@ struct encryption_service_st {
|
|||||||
encrypt_decrypt_func encryption_decrypt_func;
|
encrypt_decrypt_func encryption_decrypt_func;
|
||||||
};
|
};
|
||||||
extern struct encryption_service_st encryption_handler;
|
extern struct encryption_service_st encryption_handler;
|
||||||
|
#include <mysql/service_encryption_scheme.h>
|
||||||
|
struct st_encryption_scheme_key {
|
||||||
|
unsigned int version;
|
||||||
|
unsigned char key[16];
|
||||||
|
};
|
||||||
|
struct st_encryption_scheme {
|
||||||
|
unsigned char iv[16];
|
||||||
|
struct st_encryption_scheme_key key[3];
|
||||||
|
unsigned int keyserver_requests;
|
||||||
|
unsigned int key_id;
|
||||||
|
unsigned int type;
|
||||||
|
void (*locker)(struct st_encryption_scheme *self, int release);
|
||||||
|
};
|
||||||
|
extern struct encryption_scheme_service_st {
|
||||||
|
int (*encryption_scheme_encrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int (*encryption_scheme_decrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
} *encryption_scheme_service;
|
||||||
|
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
struct st_mysql_xid {
|
struct st_mysql_xid {
|
||||||
long formatID;
|
long formatID;
|
||||||
long gtrid_length;
|
long gtrid_length;
|
||||||
|
@ -213,6 +213,43 @@ struct encryption_service_st {
|
|||||||
encrypt_decrypt_func encryption_decrypt_func;
|
encrypt_decrypt_func encryption_decrypt_func;
|
||||||
};
|
};
|
||||||
extern struct encryption_service_st encryption_handler;
|
extern struct encryption_service_st encryption_handler;
|
||||||
|
#include <mysql/service_encryption_scheme.h>
|
||||||
|
struct st_encryption_scheme_key {
|
||||||
|
unsigned int version;
|
||||||
|
unsigned char key[16];
|
||||||
|
};
|
||||||
|
struct st_encryption_scheme {
|
||||||
|
unsigned char iv[16];
|
||||||
|
struct st_encryption_scheme_key key[3];
|
||||||
|
unsigned int keyserver_requests;
|
||||||
|
unsigned int key_id;
|
||||||
|
unsigned int type;
|
||||||
|
void (*locker)(struct st_encryption_scheme *self, int release);
|
||||||
|
};
|
||||||
|
extern struct encryption_scheme_service_st {
|
||||||
|
int (*encryption_scheme_encrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int (*encryption_scheme_decrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
} *encryption_scheme_service;
|
||||||
|
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
struct st_mysql_xid {
|
struct st_mysql_xid {
|
||||||
long formatID;
|
long formatID;
|
||||||
long gtrid_length;
|
long gtrid_length;
|
||||||
|
@ -213,6 +213,43 @@ struct encryption_service_st {
|
|||||||
encrypt_decrypt_func encryption_decrypt_func;
|
encrypt_decrypt_func encryption_decrypt_func;
|
||||||
};
|
};
|
||||||
extern struct encryption_service_st encryption_handler;
|
extern struct encryption_service_st encryption_handler;
|
||||||
|
#include <mysql/service_encryption_scheme.h>
|
||||||
|
struct st_encryption_scheme_key {
|
||||||
|
unsigned int version;
|
||||||
|
unsigned char key[16];
|
||||||
|
};
|
||||||
|
struct st_encryption_scheme {
|
||||||
|
unsigned char iv[16];
|
||||||
|
struct st_encryption_scheme_key key[3];
|
||||||
|
unsigned int keyserver_requests;
|
||||||
|
unsigned int key_id;
|
||||||
|
unsigned int type;
|
||||||
|
void (*locker)(struct st_encryption_scheme *self, int release);
|
||||||
|
};
|
||||||
|
extern struct encryption_scheme_service_st {
|
||||||
|
int (*encryption_scheme_encrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int (*encryption_scheme_decrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
} *encryption_scheme_service;
|
||||||
|
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
struct st_mysql_xid {
|
struct st_mysql_xid {
|
||||||
long formatID;
|
long formatID;
|
||||||
long gtrid_length;
|
long gtrid_length;
|
||||||
|
@ -213,6 +213,43 @@ struct encryption_service_st {
|
|||||||
encrypt_decrypt_func encryption_decrypt_func;
|
encrypt_decrypt_func encryption_decrypt_func;
|
||||||
};
|
};
|
||||||
extern struct encryption_service_st encryption_handler;
|
extern struct encryption_service_st encryption_handler;
|
||||||
|
#include <mysql/service_encryption_scheme.h>
|
||||||
|
struct st_encryption_scheme_key {
|
||||||
|
unsigned int version;
|
||||||
|
unsigned char key[16];
|
||||||
|
};
|
||||||
|
struct st_encryption_scheme {
|
||||||
|
unsigned char iv[16];
|
||||||
|
struct st_encryption_scheme_key key[3];
|
||||||
|
unsigned int keyserver_requests;
|
||||||
|
unsigned int key_id;
|
||||||
|
unsigned int type;
|
||||||
|
void (*locker)(struct st_encryption_scheme *self, int release);
|
||||||
|
};
|
||||||
|
extern struct encryption_scheme_service_st {
|
||||||
|
int (*encryption_scheme_encrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int (*encryption_scheme_decrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
} *encryption_scheme_service;
|
||||||
|
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
struct st_mysql_xid {
|
struct st_mysql_xid {
|
||||||
long formatID;
|
long formatID;
|
||||||
long gtrid_length;
|
long gtrid_length;
|
||||||
|
133
include/mysql/service_encryption_scheme.h
Normal file
133
include/mysql/service_encryption_scheme.h
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#ifndef MYSQL_SERVICE_ENCRYPTION_SCHEME_INCLUDED
|
||||||
|
/* Copyright (c) 2015, MariaDB
|
||||||
|
|
||||||
|
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
|
||||||
|
encryption scheme service
|
||||||
|
|
||||||
|
A higher-level access to encryption service.
|
||||||
|
|
||||||
|
This is a helper service that storage engines use to encrypt tables on disk.
|
||||||
|
It requests keys from the plugin, generates temporary or local keys
|
||||||
|
from the global (as returned by the plugin) keys, etc.
|
||||||
|
|
||||||
|
To use the service:
|
||||||
|
|
||||||
|
* st_encryption_scheme object is created per space. A "space" can be
|
||||||
|
a table space in XtraDB/InnoDB, a file in Aria, etc. The whole
|
||||||
|
space is encrypted with the one key id.
|
||||||
|
|
||||||
|
* The service does not take the key and the IV as parameters for
|
||||||
|
encryption or decryption. Instead it takes two 32-bit integers and
|
||||||
|
one 64-bit integer (and requests the key from an encryption
|
||||||
|
plugin, if needed).
|
||||||
|
|
||||||
|
* The service requests the global key from the encryption plugin
|
||||||
|
automatically as needed. Three last keys are cached in the
|
||||||
|
st_encryption_scheme. Number of key requests (number of cache
|
||||||
|
misses) are counted in st_encryption_scheme::keyserver_requests
|
||||||
|
|
||||||
|
* If an st_encryption_scheme can be used concurrently by different
|
||||||
|
threads, it needs to be able to lock itself when accessing the key
|
||||||
|
cache. Set the st_encryption_scheme::locker appropriately. If
|
||||||
|
non-zero, it will be invoked by encrypt/decrypt functions to lock
|
||||||
|
and unlock the scheme when needed.
|
||||||
|
|
||||||
|
* Implementation details (in particular, key derivation) are defined
|
||||||
|
by the scheme type. Currently only schema type 1 is supported.
|
||||||
|
|
||||||
|
In the schema type 1, every "space" (table space in XtraDB/InnoDB,
|
||||||
|
file in Aria) is encrypted with a different space-local key:
|
||||||
|
|
||||||
|
* Every space has a 16-byte unique identifier (typically it's
|
||||||
|
generated randomly and stored in the space). The caller should
|
||||||
|
put it into st_encryption_scheme::iv.
|
||||||
|
|
||||||
|
* Space-local key is generated by encrypting this identifier with
|
||||||
|
the global encryption key (of the given id and version) using AES_ECB.
|
||||||
|
|
||||||
|
* Encryption/decryption parameters for a page are typically the
|
||||||
|
4-byte space id, 4-byte page position (offset, page number, etc),
|
||||||
|
and the 8-byte LSN. This guarantees that they'll be different for
|
||||||
|
any two pages (of the same or different tablespaces) and also that
|
||||||
|
they'll change for the same page when it's modified. They don't need
|
||||||
|
to be secret (they create the IV, not the encryption key).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ENCRYPTION_SCHEME_KEY_INVALID -1
|
||||||
|
#define ENCRYPTION_SCHEME_BLOCK_LENGTH 16
|
||||||
|
|
||||||
|
struct st_encryption_scheme_key {
|
||||||
|
unsigned int version;
|
||||||
|
unsigned char key[ENCRYPTION_SCHEME_BLOCK_LENGTH];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct st_encryption_scheme {
|
||||||
|
unsigned char iv[ENCRYPTION_SCHEME_BLOCK_LENGTH];
|
||||||
|
struct st_encryption_scheme_key key[3];
|
||||||
|
unsigned int keyserver_requests;
|
||||||
|
unsigned int key_id;
|
||||||
|
unsigned int type;
|
||||||
|
|
||||||
|
void (*locker)(struct st_encryption_scheme *self, int release);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct encryption_scheme_service_st {
|
||||||
|
int (*encryption_scheme_encrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int (*encryption_scheme_decrypt_func)
|
||||||
|
(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
} *encryption_scheme_service;
|
||||||
|
|
||||||
|
#ifdef MYSQL_DYNAMIC_PLUGIN
|
||||||
|
|
||||||
|
#define encryption_scheme_encrypt(S,SL,D,DL,SCH,KV,I32,J32,I64) encryption_scheme_service->encryption_scheme_encrypt_func(S,SL,D,DL,SCH,KV,I32,J32,I64)
|
||||||
|
#define encryption_scheme_decrypt(S,SL,D,DL,SCH,KV,I32,J32,I64) encryption_scheme_service->encryption_scheme_decrypt_func(S,SL,D,DL,SCH,KV,I32,J32,I64)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MYSQL_SERVICE_ENCRYPTION_SCHEME_INCLUDED
|
||||||
|
#endif
|
@ -33,6 +33,7 @@ extern "C" {
|
|||||||
#include <mysql/service_thd_error_context.h>
|
#include <mysql/service_thd_error_context.h>
|
||||||
#include <mysql/service_thd_specifics.h>
|
#include <mysql/service_thd_specifics.h>
|
||||||
#include <mysql/service_encryption.h>
|
#include <mysql/service_encryption.h>
|
||||||
|
#include <mysql/service_encryption_scheme.h>
|
||||||
/*#include <mysql/service_wsrep.h>*/
|
/*#include <mysql/service_wsrep.h>*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -36,4 +36,5 @@
|
|||||||
#define VERSION_thd_error_context 0x0100
|
#define VERSION_thd_error_context 0x0100
|
||||||
#define VERSION_thd_specifics 0x0100
|
#define VERSION_thd_specifics 0x0100
|
||||||
#define VERSION_encryption 0x0200
|
#define VERSION_encryption 0x0200
|
||||||
|
#define VERSION_encryption_scheme 0x0100
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ SET(MYSQLSERVICES_SOURCES
|
|||||||
my_md5_service.c
|
my_md5_service.c
|
||||||
wsrep_service.c
|
wsrep_service.c
|
||||||
encryption_service.c
|
encryption_service.c
|
||||||
|
encryption_scheme_service.c
|
||||||
kill_statement_service.c
|
kill_statement_service.c
|
||||||
logger_service.c)
|
logger_service.c)
|
||||||
|
|
||||||
|
17
libservices/encryption_scheme_service.c
Normal file
17
libservices/encryption_scheme_service.c
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* Copyright (c) 2015 MariaDB
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
#include <service_versions.h>
|
||||||
|
SERVICE_VERSION encryption_scheme_service= (void*)VERSION_encryption_scheme;
|
@ -5,7 +5,7 @@ plugin_version 1.0
|
|||||||
plugin_status ACTIVE
|
plugin_status ACTIVE
|
||||||
plugin_type DAEMON
|
plugin_type DAEMON
|
||||||
plugin_library handlersocket.so
|
plugin_library handlersocket.so
|
||||||
plugin_library_version 1.10
|
plugin_library_version 1.11
|
||||||
plugin_author higuchi dot akira at dena dot jp
|
plugin_author higuchi dot akira at dena dot jp
|
||||||
plugin_description Direct access into InnoDB
|
plugin_description Direct access into InnoDB
|
||||||
plugin_license BSD
|
plugin_license BSD
|
||||||
|
@ -15,7 +15,7 @@ PLUGIN_STATUS ACTIVE
|
|||||||
PLUGIN_TYPE STORAGE ENGINE
|
PLUGIN_TYPE STORAGE ENGINE
|
||||||
PLUGIN_TYPE_VERSION #
|
PLUGIN_TYPE_VERSION #
|
||||||
PLUGIN_LIBRARY ha_example.so
|
PLUGIN_LIBRARY ha_example.so
|
||||||
PLUGIN_LIBRARY_VERSION 1.10
|
PLUGIN_LIBRARY_VERSION 1.11
|
||||||
PLUGIN_AUTHOR Brian Aker, MySQL AB
|
PLUGIN_AUTHOR Brian Aker, MySQL AB
|
||||||
PLUGIN_DESCRIPTION Example storage engine
|
PLUGIN_DESCRIPTION Example storage engine
|
||||||
PLUGIN_LICENSE GPL
|
PLUGIN_LICENSE GPL
|
||||||
@ -28,7 +28,7 @@ PLUGIN_STATUS ACTIVE
|
|||||||
PLUGIN_TYPE DAEMON
|
PLUGIN_TYPE DAEMON
|
||||||
PLUGIN_TYPE_VERSION #
|
PLUGIN_TYPE_VERSION #
|
||||||
PLUGIN_LIBRARY ha_example.so
|
PLUGIN_LIBRARY ha_example.so
|
||||||
PLUGIN_LIBRARY_VERSION 1.10
|
PLUGIN_LIBRARY_VERSION 1.11
|
||||||
PLUGIN_AUTHOR Sergei Golubchik
|
PLUGIN_AUTHOR Sergei Golubchik
|
||||||
PLUGIN_DESCRIPTION Unusable Daemon
|
PLUGIN_DESCRIPTION Unusable Daemon
|
||||||
PLUGIN_LICENSE GPL
|
PLUGIN_LICENSE GPL
|
||||||
@ -67,7 +67,7 @@ PLUGIN_STATUS DELETED
|
|||||||
PLUGIN_TYPE STORAGE ENGINE
|
PLUGIN_TYPE STORAGE ENGINE
|
||||||
PLUGIN_TYPE_VERSION #
|
PLUGIN_TYPE_VERSION #
|
||||||
PLUGIN_LIBRARY ha_example.so
|
PLUGIN_LIBRARY ha_example.so
|
||||||
PLUGIN_LIBRARY_VERSION 1.10
|
PLUGIN_LIBRARY_VERSION 1.11
|
||||||
PLUGIN_AUTHOR Brian Aker, MySQL AB
|
PLUGIN_AUTHOR Brian Aker, MySQL AB
|
||||||
PLUGIN_DESCRIPTION Example storage engine
|
PLUGIN_DESCRIPTION Example storage engine
|
||||||
PLUGIN_LICENSE GPL
|
PLUGIN_LICENSE GPL
|
||||||
|
@ -4,8 +4,8 @@ Variable_name Value
|
|||||||
Opened_plugin_libraries 0
|
Opened_plugin_libraries 0
|
||||||
select * from information_schema.all_plugins where plugin_library='ha_example.so';
|
select * from information_schema.all_plugins where plugin_library='ha_example.so';
|
||||||
PLUGIN_NAME PLUGIN_VERSION PLUGIN_STATUS PLUGIN_TYPE PLUGIN_TYPE_VERSION PLUGIN_LIBRARY PLUGIN_LIBRARY_VERSION PLUGIN_AUTHOR PLUGIN_DESCRIPTION PLUGIN_LICENSE LOAD_OPTION PLUGIN_MATURITY PLUGIN_AUTH_VERSION
|
PLUGIN_NAME PLUGIN_VERSION PLUGIN_STATUS PLUGIN_TYPE PLUGIN_TYPE_VERSION PLUGIN_LIBRARY PLUGIN_LIBRARY_VERSION PLUGIN_AUTHOR PLUGIN_DESCRIPTION PLUGIN_LICENSE LOAD_OPTION PLUGIN_MATURITY PLUGIN_AUTH_VERSION
|
||||||
EXAMPLE 0.1 NOT INSTALLED STORAGE ENGINE MYSQL_VERSION_ID ha_example.so 1.10 Brian Aker, MySQL AB Example storage engine GPL OFF Experimental 0.1
|
EXAMPLE 0.1 NOT INSTALLED STORAGE ENGINE MYSQL_VERSION_ID ha_example.so 1.11 Brian Aker, MySQL AB Example storage engine GPL OFF Experimental 0.1
|
||||||
UNUSABLE 3.14 NOT INSTALLED DAEMON MYSQL_VERSION_ID ha_example.so 1.10 Sergei Golubchik Unusable Daemon GPL OFF Experimental 3.14.15.926
|
UNUSABLE 3.14 NOT INSTALLED DAEMON MYSQL_VERSION_ID ha_example.so 1.11 Sergei Golubchik Unusable Daemon GPL OFF Experimental 3.14.15.926
|
||||||
show status like '%libraries%';
|
show status like '%libraries%';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
Opened_plugin_libraries 1
|
Opened_plugin_libraries 1
|
||||||
|
@ -6,7 +6,7 @@ PLUGIN_STATUS ACTIVE
|
|||||||
PLUGIN_TYPE PASSWORD VALIDATION
|
PLUGIN_TYPE PASSWORD VALIDATION
|
||||||
PLUGIN_TYPE_VERSION 1.0
|
PLUGIN_TYPE_VERSION 1.0
|
||||||
PLUGIN_LIBRARY simple_password_check.so
|
PLUGIN_LIBRARY simple_password_check.so
|
||||||
PLUGIN_LIBRARY_VERSION 1.10
|
PLUGIN_LIBRARY_VERSION 1.11
|
||||||
PLUGIN_AUTHOR Sergei Golubchik
|
PLUGIN_AUTHOR Sergei Golubchik
|
||||||
PLUGIN_DESCRIPTION Simple password strength checks
|
PLUGIN_DESCRIPTION Simple password strength checks
|
||||||
PLUGIN_LICENSE GPL
|
PLUGIN_LICENSE GPL
|
||||||
|
@ -103,3 +103,110 @@ int finalize_encryption_plugin(st_plugin_int *plugin)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
Encryption Scheme service
|
||||||
|
******************************************************************/
|
||||||
|
static uint scheme_get_key(st_encryption_scheme *scheme,
|
||||||
|
st_encryption_scheme_key *key)
|
||||||
|
{
|
||||||
|
if (scheme->locker)
|
||||||
|
scheme->locker(scheme, 0);
|
||||||
|
|
||||||
|
// Check if we already have key
|
||||||
|
for (uint i = 0; i < array_elements(scheme->key); i++)
|
||||||
|
{
|
||||||
|
if (scheme->key[i].version == 0) // no more keys
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (scheme->key[i].version == key->version)
|
||||||
|
{
|
||||||
|
*key= scheme->key[i];
|
||||||
|
if (scheme->locker)
|
||||||
|
scheme->locker(scheme, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found!
|
||||||
|
scheme->keyserver_requests++;
|
||||||
|
|
||||||
|
uchar global_key[MY_AES_MAX_KEY_LENGTH];
|
||||||
|
uint global_key_len= sizeof(global_key), key_len;
|
||||||
|
|
||||||
|
uint rc = encryption_key_get(scheme->key_id, key->version,
|
||||||
|
global_key, & global_key_len);
|
||||||
|
if (rc)
|
||||||
|
goto ret;
|
||||||
|
|
||||||
|
/* Now generate the local key by encrypting IV using the global key */
|
||||||
|
rc = my_aes_encrypt_ecb(scheme->iv, sizeof(scheme->iv), key->key, &key_len,
|
||||||
|
global_key, global_key_len, NULL, 0, 1);
|
||||||
|
|
||||||
|
DBUG_ASSERT(key_len == sizeof(key->key));
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
goto ret;
|
||||||
|
|
||||||
|
// Rotate keys to make room for a new
|
||||||
|
for (uint i = array_elements(scheme->key) - 1; i; i--)
|
||||||
|
scheme->key[i] = scheme->key[i - 1];
|
||||||
|
|
||||||
|
scheme->key[0]= *key;
|
||||||
|
|
||||||
|
ret:
|
||||||
|
if (scheme->locker)
|
||||||
|
scheme->locker(scheme, 1);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_crypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64,
|
||||||
|
encrypt_decrypt_func crypt)
|
||||||
|
{
|
||||||
|
compile_time_assert(ENCRYPTION_SCHEME_KEY_INVALID ==
|
||||||
|
(int)ENCRYPTION_KEY_VERSION_INVALID);
|
||||||
|
|
||||||
|
DBUG_ASSERT(scheme->type == 1);
|
||||||
|
|
||||||
|
if (key_version == ENCRYPTION_KEY_VERSION_INVALID ||
|
||||||
|
key_version == ENCRYPTION_KEY_NOT_ENCRYPTED)
|
||||||
|
return ENCRYPTION_SCHEME_KEY_INVALID;
|
||||||
|
|
||||||
|
st_encryption_scheme_key key;
|
||||||
|
key.version= key_version;
|
||||||
|
uint rc= scheme_get_key(scheme, &key);
|
||||||
|
if (rc)
|
||||||
|
return (int)rc;
|
||||||
|
|
||||||
|
unsigned char iv[4 + 4 + 8];
|
||||||
|
int4store(iv + 0, i32_1);
|
||||||
|
int4store(iv + 4, i32_2);
|
||||||
|
int8store(iv + 8, i64);
|
||||||
|
|
||||||
|
return crypt(src, slen, dst, dlen, key.key, sizeof(key.key),
|
||||||
|
iv, sizeof(iv), 1, scheme->key_id, key_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64)
|
||||||
|
{
|
||||||
|
return do_crypt(src, slen, dst, dlen, scheme, key_version, i32_1,
|
||||||
|
i32_2, i64, encryption_handler.encryption_encrypt_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
|
||||||
|
unsigned char* dst, unsigned int* dlen,
|
||||||
|
struct st_encryption_scheme *scheme,
|
||||||
|
unsigned int key_version, unsigned int i32_1,
|
||||||
|
unsigned int i32_2, unsigned long long i64)
|
||||||
|
{
|
||||||
|
return do_crypt(src, slen, dst, dlen, scheme, key_version, i32_1,
|
||||||
|
i32_2, i64, encryption_handler.encryption_decrypt_func);
|
||||||
|
}
|
||||||
|
@ -147,6 +147,12 @@ static struct thd_specifics_service_st thd_specifics_handler=
|
|||||||
thd_setspecific
|
thd_setspecific
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct encryption_scheme_service_st encryption_scheme_handler=
|
||||||
|
{
|
||||||
|
encryption_scheme_encrypt,
|
||||||
|
encryption_scheme_decrypt
|
||||||
|
};
|
||||||
|
|
||||||
static struct st_service_ref list_of_services[]=
|
static struct st_service_ref list_of_services[]=
|
||||||
{
|
{
|
||||||
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
|
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
|
||||||
@ -162,6 +168,7 @@ static struct st_service_ref list_of_services[]=
|
|||||||
{ "thd_autoinc_service", VERSION_thd_autoinc, &thd_autoinc_handler },
|
{ "thd_autoinc_service", VERSION_thd_autoinc, &thd_autoinc_handler },
|
||||||
{ "wsrep_service", VERSION_wsrep, &wsrep_handler },
|
{ "wsrep_service", VERSION_wsrep, &wsrep_handler },
|
||||||
{ "encryption_service", VERSION_encryption, &encryption_handler },
|
{ "encryption_service", VERSION_encryption, &encryption_handler },
|
||||||
|
{ "encryption_scheme_service", VERSION_encryption_scheme, &encryption_scheme_handler },
|
||||||
{ "thd_specifics_service", VERSION_thd_specifics, &thd_specifics_handler },
|
{ "thd_specifics_service", VERSION_thd_specifics, &thd_specifics_handler },
|
||||||
{ "thd_error_context_service", VERSION_thd_error_context, &thd_error_conext_handler },
|
{ "thd_error_context_service", VERSION_thd_error_context, &thd_error_conext_handler },
|
||||||
};
|
};
|
||||||
|
@ -149,82 +149,6 @@ fil_space_crypt_cleanup()
|
|||||||
os_event_free(fil_crypt_throttle_sleep_event);
|
os_event_free(fil_crypt_throttle_sleep_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
Get key bytes for a space/key-version */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
fil_crypt_get_key(
|
|
||||||
/*==============*/
|
|
||||||
byte* dst, /*<! out: Key */
|
|
||||||
uint* key_length, /*<! out: Key length */
|
|
||||||
fil_space_crypt_t* crypt_data, /*<! in: crypt data */
|
|
||||||
uint version) /*<! in: Key version */
|
|
||||||
{
|
|
||||||
unsigned char keybuf[MY_AES_MAX_KEY_LENGTH];
|
|
||||||
|
|
||||||
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,
|
|
||||||
crypt_data->keys[i].key_length);
|
|
||||||
*key_length = crypt_data->keys[i].key_length;
|
|
||||||
mutex_exit(&crypt_data->mutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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];
|
|
||||||
}
|
|
||||||
|
|
||||||
*key_length = sizeof(keybuf);
|
|
||||||
uint rc = encryption_key_get(crypt_data->key_id, version, keybuf, key_length);
|
|
||||||
if (rc) {
|
|
||||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
|
||||||
"Key id %u version %u can not be found. Reason=%u",
|
|
||||||
crypt_data->key_id, version, rc);
|
|
||||||
ut_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now compute L by encrypting IV using this key. Note
|
|
||||||
that we use random IV from crypt data. */
|
|
||||||
const unsigned char* src = crypt_data->iv;
|
|
||||||
const int srclen = crypt_data->iv_length;
|
|
||||||
unsigned char* buf = crypt_data->keys[0].key;
|
|
||||||
uint32 buflen = CRYPT_SCHEME_1_IV_LEN;
|
|
||||||
|
|
||||||
/* We use AES_ECB to encrypt IV */
|
|
||||||
rc = my_aes_encrypt_ecb(src, srclen, buf, &buflen,
|
|
||||||
keybuf, *key_length, NULL, 0, 1);
|
|
||||||
|
|
||||||
if (rc != MY_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
crypt_data->keys[0].key_version = version;
|
|
||||||
crypt_data->key_count++;
|
|
||||||
*key_length = buflen;
|
|
||||||
crypt_data->keys[0].key_length = buflen;
|
|
||||||
|
|
||||||
if (crypt_data->key_count > array_elements(crypt_data->keys)) {
|
|
||||||
crypt_data->key_count = array_elements(crypt_data->keys);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dst, buf, buflen);
|
|
||||||
mutex_exit(&crypt_data->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
Get the latest(key-version), waking the encrypt thread, if needed */
|
Get the latest(key-version), waking the encrypt thread, if needed */
|
||||||
static inline
|
static inline
|
||||||
@ -244,27 +168,17 @@ fil_crypt_get_latest_key_version(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
Get key bytes for a space/latest(key-version) */
|
Mutex helper for crypt_data->scheme */
|
||||||
static inline
|
static void crypt_data_scheme_locker(st_encryption_scheme *scheme, int exit)
|
||||||
void
|
|
||||||
fil_crypt_get_latest_key(
|
|
||||||
/*=====================*/
|
|
||||||
byte* dst, /*!< out: Key */
|
|
||||||
uint* key_length, /*!< out: Key length */
|
|
||||||
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
|
||||||
uint* version) /*!< in: Key version */
|
|
||||||
{
|
{
|
||||||
// used for key rotation - get the next key id from the key provider
|
fil_space_crypt_t* crypt_data =
|
||||||
uint rc = *version = fil_crypt_get_latest_key_version(crypt_data);
|
static_cast<fil_space_crypt_t*>(scheme);
|
||||||
|
|
||||||
if (rc == ENCRYPTION_KEY_VERSION_INVALID) {
|
if (exit) {
|
||||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
mutex_exit(&crypt_data->mutex);
|
||||||
"Unknown key id %u. Can't continue!\n",
|
} else {
|
||||||
crypt_data->key_id);
|
mutex_enter(&crypt_data->mutex);
|
||||||
ut_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fil_crypt_get_key(dst, key_length, crypt_data, *version);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
@ -277,8 +191,7 @@ fil_space_create_crypt_data(
|
|||||||
fil_encryption_t encrypt_mode, /*!< in: encryption mode */
|
fil_encryption_t encrypt_mode, /*!< in: encryption mode */
|
||||||
uint key_id) /*!< in: encryption key id */
|
uint key_id) /*!< in: encryption key id */
|
||||||
{
|
{
|
||||||
const uint iv_length = CRYPT_SCHEME_1_IV_LEN;
|
const uint sz = sizeof(fil_space_crypt_t);
|
||||||
const uint sz = sizeof(fil_space_crypt_t) + iv_length;
|
|
||||||
fil_space_crypt_t* crypt_data =
|
fil_space_crypt_t* crypt_data =
|
||||||
static_cast<fil_space_crypt_t*>(malloc(sz));
|
static_cast<fil_space_crypt_t*>(malloc(sz));
|
||||||
|
|
||||||
@ -290,14 +203,14 @@ fil_space_create_crypt_data(
|
|||||||
crypt_data->min_key_version = 0;
|
crypt_data->min_key_version = 0;
|
||||||
} else {
|
} else {
|
||||||
crypt_data->type = CRYPT_SCHEME_1;
|
crypt_data->type = CRYPT_SCHEME_1;
|
||||||
crypt_data->key_id = key_id;
|
crypt_data->key_id = key_id;
|
||||||
crypt_data->min_key_version = encryption_key_get_latest_version(key_id);
|
crypt_data->min_key_version = encryption_key_get_latest_version(key_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_create(fil_crypt_data_mutex_key,
|
mutex_create(fil_crypt_data_mutex_key,
|
||||||
&crypt_data->mutex, SYNC_NO_ORDER_CHECK);
|
&crypt_data->mutex, SYNC_NO_ORDER_CHECK);
|
||||||
crypt_data->iv_length = iv_length;
|
crypt_data->locker = crypt_data_scheme_locker;
|
||||||
my_random_bytes(crypt_data->iv, iv_length);
|
my_random_bytes(crypt_data->iv, sizeof(crypt_data->iv));
|
||||||
crypt_data->encryption = FIL_SPACE_ENCRYPTION_DEFAULT;
|
crypt_data->encryption = FIL_SPACE_ENCRYPTION_DEFAULT;
|
||||||
return crypt_data;
|
return crypt_data;
|
||||||
}
|
}
|
||||||
@ -317,12 +230,9 @@ fil_space_crypt_compare(
|
|||||||
ut_a(crypt_data2->type == CRYPT_SCHEME_UNENCRYPTED ||
|
ut_a(crypt_data2->type == CRYPT_SCHEME_UNENCRYPTED ||
|
||||||
crypt_data2->type == CRYPT_SCHEME_1);
|
crypt_data2->type == CRYPT_SCHEME_1);
|
||||||
|
|
||||||
ut_a(crypt_data1->iv_length == CRYPT_SCHEME_1_IV_LEN);
|
|
||||||
ut_a(crypt_data2->iv_length == CRYPT_SCHEME_1_IV_LEN);
|
|
||||||
|
|
||||||
/* no support for changing iv (yet?) */
|
/* no support for changing iv (yet?) */
|
||||||
ut_a(memcmp(crypt_data1->iv, crypt_data2->iv,
|
ut_a(memcmp(crypt_data1->iv, crypt_data2->iv,
|
||||||
crypt_data1->iv_length) == 0);
|
sizeof(crypt_data1->iv)) == 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -378,9 +288,10 @@ fil_space_read_crypt_data(
|
|||||||
ut_error;
|
ut_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fil_space_crypt_t* crypt_data;
|
||||||
ulint iv_length = mach_read_from_1(page + offset + MAGIC_SZ + 1);
|
ulint iv_length = mach_read_from_1(page + offset + MAGIC_SZ + 1);
|
||||||
|
|
||||||
if (! (iv_length == CRYPT_SCHEME_1_IV_LEN)) {
|
if (! (iv_length == sizeof(crypt_data->iv))) {
|
||||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||||
"Found non sensible iv length: %lu for space %lu "
|
"Found non sensible iv length: %lu for space %lu "
|
||||||
" offset: %lu type: %lu bytes: "
|
" offset: %lu type: %lu bytes: "
|
||||||
@ -405,8 +316,7 @@ fil_space_read_crypt_data(
|
|||||||
page + offset + MAGIC_SZ + 2 + iv_length + 8);
|
page + offset + MAGIC_SZ + 2 + iv_length + 8);
|
||||||
|
|
||||||
const uint sz = sizeof(fil_space_crypt_t) + iv_length;
|
const uint sz = sizeof(fil_space_crypt_t) + iv_length;
|
||||||
fil_space_crypt_t* crypt_data = static_cast<fil_space_crypt_t*>(
|
crypt_data = static_cast<fil_space_crypt_t*>(malloc(sz));
|
||||||
malloc(sz));
|
|
||||||
memset(crypt_data, 0, sz);
|
memset(crypt_data, 0, sz);
|
||||||
|
|
||||||
crypt_data->type = type;
|
crypt_data->type = type;
|
||||||
@ -416,7 +326,7 @@ fil_space_read_crypt_data(
|
|||||||
crypt_data->encryption = encryption;
|
crypt_data->encryption = encryption;
|
||||||
mutex_create(fil_crypt_data_mutex_key,
|
mutex_create(fil_crypt_data_mutex_key,
|
||||||
&crypt_data->mutex, SYNC_NO_ORDER_CHECK);
|
&crypt_data->mutex, SYNC_NO_ORDER_CHECK);
|
||||||
crypt_data->iv_length = iv_length;
|
crypt_data->locker = crypt_data_scheme_locker;
|
||||||
memcpy(crypt_data->iv, page + offset + MAGIC_SZ + 2, iv_length);
|
memcpy(crypt_data->iv, page + offset + MAGIC_SZ + 2, iv_length);
|
||||||
|
|
||||||
return crypt_data;
|
return crypt_data;
|
||||||
@ -453,7 +363,7 @@ fil_space_write_crypt_data_low(
|
|||||||
ut_a(offset > 0 && offset < UNIV_PAGE_SIZE);
|
ut_a(offset > 0 && offset < UNIV_PAGE_SIZE);
|
||||||
ulint space_id = mach_read_from_4(
|
ulint space_id = mach_read_from_4(
|
||||||
page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||||
const uint len = crypt_data->iv_length;
|
const uint len = sizeof(crypt_data->iv);
|
||||||
const uint min_key_version = crypt_data->min_key_version;
|
const uint min_key_version = crypt_data->min_key_version;
|
||||||
const uint key_id = crypt_data->key_id;
|
const uint key_id = crypt_data->key_id;
|
||||||
const fil_encryption_t encryption = crypt_data->encryption;
|
const fil_encryption_t encryption = crypt_data->encryption;
|
||||||
@ -662,9 +572,6 @@ fil_space_encrypt(
|
|||||||
fil_space_crypt_t* crypt_data = NULL;
|
fil_space_crypt_t* crypt_data = NULL;
|
||||||
ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
|
ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
|
||||||
uint key_version;
|
uint key_version;
|
||||||
unsigned char key[MY_AES_MAX_KEY_LENGTH];
|
|
||||||
uint key_length = MY_AES_MAX_KEY_LENGTH;
|
|
||||||
unsigned char iv[MY_AES_BLOCK_SIZE];
|
|
||||||
|
|
||||||
ulint orig_page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
|
ulint orig_page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
|
||||||
|
|
||||||
@ -686,12 +593,14 @@ fil_space_encrypt(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_crypt_get_latest_key(key, &key_length, crypt_data, &key_version);
|
key_version = fil_crypt_get_latest_key_version(crypt_data);
|
||||||
|
|
||||||
/* create iv/counter */
|
if (key_version == ENCRYPTION_KEY_VERSION_INVALID) {
|
||||||
mach_write_to_4(iv + 0, space);
|
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||||
mach_write_to_4(iv + 4, offset);
|
"Unknown key id %u. Can't continue!\n",
|
||||||
mach_write_to_8(iv + 8, lsn);
|
crypt_data->key_id);
|
||||||
|
ut_error;
|
||||||
|
}
|
||||||
|
|
||||||
ibool page_compressed = (mach_read_from_2(src_frame+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED);
|
ibool page_compressed = (mach_read_from_2(src_frame+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED);
|
||||||
|
|
||||||
@ -719,9 +628,9 @@ fil_space_encrypt(
|
|||||||
dst+=2;
|
dst+=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = encryption_encrypt(src, srclen, dst, &dstlen,
|
int rc = encryption_scheme_encrypt(src, srclen, dst, &dstlen,
|
||||||
key, key_length, iv, sizeof(iv), 1,
|
crypt_data, key_version,
|
||||||
crypt_data->key_id, key_version);
|
space, offset, lsn);
|
||||||
|
|
||||||
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
|
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
|
||||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||||
@ -837,17 +746,6 @@ fil_space_decrypt(
|
|||||||
/* Copy FIL page header, it is not encrypted */
|
/* Copy FIL page header, it is not encrypted */
|
||||||
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
|
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
|
||||||
|
|
||||||
/* Get key */
|
|
||||||
byte key[MY_AES_MAX_KEY_LENGTH];
|
|
||||||
uint key_length;
|
|
||||||
unsigned char iv[MY_AES_BLOCK_SIZE];
|
|
||||||
fil_crypt_get_key(key, &key_length, crypt_data, key_version);
|
|
||||||
|
|
||||||
/* create iv/counter */
|
|
||||||
mach_write_to_4(iv + 0, space);
|
|
||||||
mach_write_to_4(iv + 4, offset);
|
|
||||||
mach_write_to_8(iv + 8, lsn);
|
|
||||||
|
|
||||||
/* Calculate the offset where decryption starts */
|
/* Calculate the offset where decryption starts */
|
||||||
const byte* src = src_frame + FIL_PAGE_DATA;
|
const byte* src = src_frame + FIL_PAGE_DATA;
|
||||||
byte* dst = dst_frame + FIL_PAGE_DATA;
|
byte* dst = dst_frame + FIL_PAGE_DATA;
|
||||||
@ -865,9 +763,9 @@ fil_space_decrypt(
|
|||||||
srclen = compressed_len;
|
srclen = compressed_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = encryption_decrypt(src, srclen, dst, &dstlen, key, key_length,
|
int rc = encryption_scheme_decrypt(src, srclen, dst, &dstlen,
|
||||||
iv, sizeof(iv), 1,
|
crypt_data, key_version,
|
||||||
crypt_data->key_id, key_version);
|
space, offset, lsn);
|
||||||
|
|
||||||
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
|
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
|
||||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||||
|
@ -11729,8 +11729,7 @@ ha_innobase::create(
|
|||||||
|
|
||||||
/* If there is old crypt data, copy IV */
|
/* If there is old crypt data, copy IV */
|
||||||
if (old_crypt_data) {
|
if (old_crypt_data) {
|
||||||
memcpy(crypt_data->iv, old_crypt_data->iv, old_crypt_data->iv_length);
|
memcpy(crypt_data->iv, old_crypt_data->iv, sizeof(crypt_data->iv));
|
||||||
crypt_data->iv_length = old_crypt_data->iv_length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
@ -80,13 +80,8 @@ struct fil_space_rotate_state_t
|
|||||||
} scrubbing;
|
} scrubbing;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fil_space_crypt_struct
|
struct fil_space_crypt_struct : st_encryption_scheme
|
||||||
{
|
{
|
||||||
ulint type; // CRYPT_SCHEME
|
|
||||||
uint keyserver_requests; // no of key requests to key server
|
|
||||||
uint key_count; // No of initalized key-structs
|
|
||||||
uint key_id; // Key id for this space
|
|
||||||
key_struct keys[3]; // cached L = AES_ECB(KEY, IV)
|
|
||||||
uint min_key_version; // min key version for this space
|
uint min_key_version; // min key version for this space
|
||||||
ulint page0_offset; // byte offset on page 0 for crypt data
|
ulint page0_offset; // byte offset on page 0 for crypt data
|
||||||
fil_encryption_t encryption; // Encryption setup
|
fil_encryption_t encryption; // Encryption setup
|
||||||
@ -94,9 +89,6 @@ struct fil_space_crypt_struct
|
|||||||
ib_mutex_t mutex; // mutex protecting following variables
|
ib_mutex_t mutex; // mutex protecting following variables
|
||||||
bool closing; // is tablespace being closed
|
bool closing; // is tablespace being closed
|
||||||
fil_space_rotate_state_t rotate_state;
|
fil_space_rotate_state_t rotate_state;
|
||||||
|
|
||||||
uint iv_length; // length of IV
|
|
||||||
byte iv[1]; // IV-data
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* structure containing encryption specification */
|
/* structure containing encryption specification */
|
||||||
|
@ -33,6 +33,33 @@ struct encryption_service_st encryption_handler=
|
|||||||
no_key, 0, 0, 0, 0, 0
|
no_key, 0, 0, 0, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int encryption_scheme_encrypt(const unsigned char* src __attribute__((unused)),
|
||||||
|
unsigned int slen __attribute__((unused)),
|
||||||
|
unsigned char* dst __attribute__((unused)),
|
||||||
|
unsigned int* dlen __attribute__((unused)),
|
||||||
|
struct st_encryption_scheme *scheme __attribute__((unused)),
|
||||||
|
unsigned int key_version __attribute__((unused)),
|
||||||
|
unsigned int i32_1 __attribute__((unused)),
|
||||||
|
unsigned int i32_2 __attribute__((unused)),
|
||||||
|
unsigned long long i64 __attribute__((unused)))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int encryption_scheme_decrypt(const unsigned char* src __attribute__((unused)),
|
||||||
|
unsigned int slen __attribute__((unused)),
|
||||||
|
unsigned char* dst __attribute__((unused)),
|
||||||
|
unsigned int* dlen __attribute__((unused)),
|
||||||
|
struct st_encryption_scheme *scheme __attribute__((unused)),
|
||||||
|
unsigned int key_version __attribute__((unused)),
|
||||||
|
unsigned int i32_1 __attribute__((unused)),
|
||||||
|
unsigned int i32_2 __attribute__((unused)),
|
||||||
|
unsigned long long i64 __attribute__((unused)))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* only those that included myisamchk.h may need and can use the below */
|
/* only those that included myisamchk.h may need and can use the below */
|
||||||
#ifdef _myisamchk_h
|
#ifdef _myisamchk_h
|
||||||
/*
|
/*
|
||||||
|
@ -39,14 +39,9 @@ struct st_crypt_key
|
|||||||
|
|
||||||
struct st_maria_crypt_data
|
struct st_maria_crypt_data
|
||||||
{
|
{
|
||||||
uchar type;
|
struct st_encryption_scheme scheme;
|
||||||
uint keyid;
|
uint space;
|
||||||
mysql_mutex_t lock; /* protecting keys */
|
mysql_mutex_t lock; /* protecting keys */
|
||||||
uint keyserver_requests; /* # of key requests to key server */
|
|
||||||
uint key_count; /* # of initalized key-structs */
|
|
||||||
struct st_crypt_key keys[3]; /* cached L = AES_ECB(KEY, IV) */
|
|
||||||
uchar iv_length;
|
|
||||||
uchar iv[1]; /* variable size */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint
|
uint
|
||||||
@ -77,19 +72,27 @@ ma_crypt_get_file_length()
|
|||||||
return 2 + CRYPT_SCHEME_1_IV_LEN + CRYPT_SCHEME_1_ID_LEN;
|
return 2 + CRYPT_SCHEME_1_IV_LEN + CRYPT_SCHEME_1_ID_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void crypt_data_scheme_locker(struct st_encryption_scheme *scheme,
|
||||||
|
int unlock)
|
||||||
|
{
|
||||||
|
MARIA_CRYPT_DATA *crypt_data = (MARIA_CRYPT_DATA*)scheme;
|
||||||
|
if (unlock)
|
||||||
|
mysql_mutex_unlock(&crypt_data->lock);
|
||||||
|
else
|
||||||
|
mysql_mutex_lock(&crypt_data->lock);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ma_crypt_create(MARIA_SHARE* share)
|
ma_crypt_create(MARIA_SHARE* share)
|
||||||
{
|
{
|
||||||
const uint iv_length= CRYPT_SCHEME_1_IV_LEN + CRYPT_SCHEME_1_ID_LEN;
|
MARIA_CRYPT_DATA *crypt_data=
|
||||||
const uint sz= sizeof(MARIA_CRYPT_DATA) + iv_length;
|
(MARIA_CRYPT_DATA*)my_malloc(sizeof(MARIA_CRYPT_DATA), MYF(MY_ZEROFILL));
|
||||||
MARIA_CRYPT_DATA *crypt_data= (MARIA_CRYPT_DATA*)my_malloc(sz, MYF(0));
|
crypt_data->scheme.type= CRYPT_SCHEME_1;
|
||||||
bzero(crypt_data, sz);
|
crypt_data->scheme.locker= crypt_data_scheme_locker;
|
||||||
crypt_data->type= CRYPT_SCHEME_1;
|
|
||||||
crypt_data->key_count= 0;
|
|
||||||
mysql_mutex_init(key_CRYPT_DATA_lock, &crypt_data->lock, MY_MUTEX_INIT_FAST);
|
mysql_mutex_init(key_CRYPT_DATA_lock, &crypt_data->lock, MY_MUTEX_INIT_FAST);
|
||||||
crypt_data->keyid= HARD_CODED_ENCRYPTION_KEY_ID;
|
crypt_data->scheme.key_id= HARD_CODED_ENCRYPTION_KEY_ID;
|
||||||
crypt_data->iv_length= iv_length;
|
my_random_bytes(crypt_data->scheme.iv, sizeof(crypt_data->scheme.iv));
|
||||||
my_random_bytes(crypt_data->iv, iv_length);
|
my_random_bytes((uchar*)&crypt_data->space, sizeof(crypt_data->space));
|
||||||
share->crypt_data= crypt_data;
|
share->crypt_data= crypt_data;
|
||||||
share->crypt_page_header_space= CRYPT_SCHEME_1_KEY_VERSION_SIZE;
|
share->crypt_page_header_space= CRYPT_SCHEME_1_KEY_VERSION_SIZE;
|
||||||
return 0;
|
return 0;
|
||||||
@ -109,19 +112,18 @@ ma_crypt_free(MARIA_SHARE* share)
|
|||||||
int
|
int
|
||||||
ma_crypt_write(MARIA_SHARE* share, File file)
|
ma_crypt_write(MARIA_SHARE* share, File file)
|
||||||
{
|
{
|
||||||
uchar buff[2];
|
|
||||||
MARIA_CRYPT_DATA *crypt_data= share->crypt_data;
|
MARIA_CRYPT_DATA *crypt_data= share->crypt_data;
|
||||||
|
uchar buff[2 + 4 + sizeof(crypt_data->scheme.iv)];
|
||||||
if (crypt_data == 0)
|
if (crypt_data == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
buff[0]= crypt_data->type;
|
buff[0]= crypt_data->scheme.type;
|
||||||
buff[1]= crypt_data->iv_length;
|
buff[1]= sizeof(buff) - 2;
|
||||||
|
|
||||||
if (mysql_file_write(file, buff, 2, MYF(MY_NABP)))
|
int4store(buff + 2, crypt_data->space);
|
||||||
return 1;
|
memcpy(buff + 6, crypt_data->scheme.iv, sizeof(crypt_data->scheme.iv));
|
||||||
|
|
||||||
if (mysql_file_write(file, crypt_data->iv, crypt_data->iv_length,
|
if (mysql_file_write(file, buff, sizeof(buff), MYF(MY_NABP)))
|
||||||
MYF(MY_NABP)))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -132,29 +134,10 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff)
|
|||||||
{
|
{
|
||||||
uchar type= buff[0];
|
uchar type= buff[0];
|
||||||
uchar iv_length= buff[1];
|
uchar iv_length= buff[1];
|
||||||
if (share->crypt_data == NULL)
|
|
||||||
{
|
|
||||||
/* opening a table */
|
|
||||||
const uint sz= sizeof(MARIA_CRYPT_DATA) + iv_length;
|
|
||||||
MARIA_CRYPT_DATA *crypt_data= (MARIA_CRYPT_DATA*)my_malloc(sz, MYF(0));
|
|
||||||
|
|
||||||
crypt_data->type= type;
|
|
||||||
crypt_data->key_count= 0;
|
|
||||||
mysql_mutex_init(key_CRYPT_DATA_lock, &crypt_data->lock,
|
|
||||||
MY_MUTEX_INIT_FAST);
|
|
||||||
crypt_data->keyid= HARD_CODED_ENCRYPTION_KEY_ID;
|
|
||||||
crypt_data->iv_length= iv_length;
|
|
||||||
memcpy(crypt_data->iv, buff + 2, iv_length);
|
|
||||||
share->crypt_data= crypt_data;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* creating a table */
|
|
||||||
assert(type == share->crypt_data->type);
|
|
||||||
assert(iv_length == share->crypt_data->iv_length);
|
|
||||||
}
|
|
||||||
/* currently only supported type */
|
/* currently only supported type */
|
||||||
if (type != CRYPT_SCHEME_1)
|
if (type != CRYPT_SCHEME_1 ||
|
||||||
|
iv_length != sizeof(((MARIA_CRYPT_DATA*)1)->scheme.iv) + 4)
|
||||||
{
|
{
|
||||||
my_printf_error(HA_ERR_UNSUPPORTED,
|
my_printf_error(HA_ERR_UNSUPPORTED,
|
||||||
"Unsupported crypt scheme! type: %d iv_length: %d\n",
|
"Unsupported crypt scheme! type: %d iv_length: %d\n",
|
||||||
@ -163,6 +146,22 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (share->crypt_data == NULL)
|
||||||
|
{
|
||||||
|
/* opening a table */
|
||||||
|
MARIA_CRYPT_DATA *crypt_data=
|
||||||
|
(MARIA_CRYPT_DATA*)my_malloc(sizeof(MARIA_CRYPT_DATA), MYF(MY_ZEROFILL));
|
||||||
|
|
||||||
|
crypt_data->scheme.type= type;
|
||||||
|
mysql_mutex_init(key_CRYPT_DATA_lock, &crypt_data->lock,
|
||||||
|
MY_MUTEX_INIT_FAST);
|
||||||
|
crypt_data->scheme.locker= crypt_data_scheme_locker;
|
||||||
|
crypt_data->scheme.key_id= HARD_CODED_ENCRYPTION_KEY_ID;
|
||||||
|
crypt_data->space= uint4korr(buff + 2);
|
||||||
|
memcpy(crypt_data->scheme.iv, buff + 6, sizeof(crypt_data->scheme.iv));
|
||||||
|
share->crypt_data= crypt_data;
|
||||||
|
}
|
||||||
|
|
||||||
share->crypt_page_header_space= CRYPT_SCHEME_1_KEY_VERSION_SIZE;
|
share->crypt_page_header_space= CRYPT_SCHEME_1_KEY_VERSION_SIZE;
|
||||||
return buff + 2 + iv_length;
|
return buff + 2 + iv_length;
|
||||||
}
|
}
|
||||||
@ -425,100 +424,6 @@ void ma_crypt_set_index_pagecache_callbacks(PAGECACHE_FILE *file,
|
|||||||
file->post_write_hook= ma_crypt_post_write_hook;
|
file->post_write_hook= ma_crypt_post_write_hook;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
get key bytes for a table and key-version
|
|
||||||
*/
|
|
||||||
static int ma_crypt_get_key(uchar *dst, uint dstlen,
|
|
||||||
MARIA_CRYPT_DATA *crypt_data, uint version)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
uint i;
|
|
||||||
uchar keybuf[CRYPT_SCHEME_1_IV_LEN];
|
|
||||||
uint keylen= sizeof(keybuf);
|
|
||||||
|
|
||||||
DBUG_ASSERT(dstlen == sizeof(crypt_data->keys[0].key));
|
|
||||||
|
|
||||||
mysql_mutex_lock(&crypt_data->lock);
|
|
||||||
|
|
||||||
/* Check if we already have key */
|
|
||||||
for (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));
|
|
||||||
mysql_mutex_unlock(&crypt_data->lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not found! */
|
|
||||||
crypt_data->keyserver_requests++;
|
|
||||||
|
|
||||||
/* Rotate keys to make room for a new */
|
|
||||||
for (i= 1; i < array_elements(crypt_data->keys); i++)
|
|
||||||
crypt_data->keys[i]= crypt_data->keys[i - 1];
|
|
||||||
|
|
||||||
/* Get new key from key server */
|
|
||||||
rc= encryption_key_get(crypt_data->keyid, version, keybuf, &keylen);
|
|
||||||
if (rc != 0)
|
|
||||||
{
|
|
||||||
my_printf_error(HA_ERR_GENERIC,
|
|
||||||
"Key id %u version %u can not be found. Reason=%u",
|
|
||||||
MYF(ME_FATALERROR|ME_NOREFRESH),
|
|
||||||
crypt_data->keyid, version, rc );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now compute L by encrypting IV using this key */
|
|
||||||
{
|
|
||||||
const uchar* src= crypt_data->iv;
|
|
||||||
const int srclen= CRYPT_SCHEME_1_IV_LEN;
|
|
||||||
uchar* buf= crypt_data->keys[0].key;
|
|
||||||
uint buflen= sizeof(crypt_data->keys[0].key);
|
|
||||||
rc = my_aes_encrypt_ecb(src, srclen, buf, &buflen,
|
|
||||||
keybuf, keylen, NULL, 0, 1);
|
|
||||||
if (rc != MY_AES_OK)
|
|
||||||
{
|
|
||||||
my_printf_error(HA_ERR_GENERIC,
|
|
||||||
"Unable to encrypt key-block "
|
|
||||||
" src: %p srclen: %d buf: %p buflen: %d."
|
|
||||||
" return-code: %d. Can't continue!",
|
|
||||||
MYF(ME_FATALERROR|ME_NOREFRESH),
|
|
||||||
src, srclen, buf, buflen, rc);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
memcpy(dst, crypt_data->keys[0].key, sizeof(crypt_data->keys[0].key));
|
|
||||||
mysql_mutex_unlock(&crypt_data->lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
Get key bytes for a table and latest key-version */
|
|
||||||
static int ma_crypt_get_latest_key(uchar *dst, uint dstlen,
|
|
||||||
MARIA_CRYPT_DATA* crypt_data, uint *version)
|
|
||||||
{
|
|
||||||
uint rc = *version = encryption_key_get_latest_version(crypt_data->keyid);
|
|
||||||
if (rc == ENCRYPTION_KEY_VERSION_INVALID)
|
|
||||||
{
|
|
||||||
my_printf_error(HA_ERR_GENERIC,
|
|
||||||
"Unknown key id %u. Can't continue!",
|
|
||||||
MYF(ME_FATALERROR|ME_NOREFRESH),
|
|
||||||
crypt_data->keyid);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return ma_crypt_get_key(dst, dstlen, crypt_data, *version);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define COUNTER_LEN MY_AES_BLOCK_SIZE
|
|
||||||
|
|
||||||
static int ma_encrypt(MARIA_CRYPT_DATA *crypt_data,
|
static int ma_encrypt(MARIA_CRYPT_DATA *crypt_data,
|
||||||
const uchar *src, uchar *dst, uint size,
|
const uchar *src, uchar *dst, uint size,
|
||||||
uint pageno, LSN lsn,
|
uint pageno, LSN lsn,
|
||||||
@ -526,22 +431,18 @@ static int ma_encrypt(MARIA_CRYPT_DATA *crypt_data,
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
uint32 dstlen;
|
uint32 dstlen;
|
||||||
uchar counter[COUNTER_LEN];
|
|
||||||
uchar key[CRYPT_SCHEME_1_IV_LEN];
|
|
||||||
|
|
||||||
// get key (L) and key_version
|
*key_version = encryption_key_get_latest_version(crypt_data->scheme.key_id);
|
||||||
if (ma_crypt_get_latest_key(key, sizeof(key), crypt_data, key_version))
|
if (*key_version == ENCRYPTION_KEY_VERSION_INVALID)
|
||||||
|
{
|
||||||
|
my_printf_error(HA_ERR_GENERIC, "Unknown key id %u. Can't continue!",
|
||||||
|
MYF(ME_FATALERROR|ME_NOREFRESH), crypt_data->scheme.key_id);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* create counter block */
|
rc= encryption_scheme_encrypt(src, size, dst, &dstlen,
|
||||||
memcpy(counter + 0, crypt_data->iv + CRYPT_SCHEME_1_IV_LEN, 4);
|
&crypt_data->scheme, *key_version,
|
||||||
int4store(counter + 4, pageno);
|
crypt_data->space, pageno, lsn);
|
||||||
int8store(counter + 8, lsn);
|
|
||||||
|
|
||||||
rc= encryption_encrypt(src, size, dst, &dstlen,
|
|
||||||
crypt_data->iv, CRYPT_SCHEME_1_IV_LEN,
|
|
||||||
counter, sizeof(counter), 1,
|
|
||||||
crypt_data->keyid, *key_version);
|
|
||||||
|
|
||||||
DBUG_ASSERT(rc == MY_AES_OK);
|
DBUG_ASSERT(rc == MY_AES_OK);
|
||||||
DBUG_ASSERT(dstlen == size);
|
DBUG_ASSERT(dstlen == size);
|
||||||
@ -564,22 +465,10 @@ static int ma_decrypt(MARIA_CRYPT_DATA *crypt_data,
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
uint32 dstlen;
|
uint32 dstlen;
|
||||||
uchar counter[COUNTER_LEN];
|
|
||||||
uchar key[CRYPT_SCHEME_1_IV_LEN];
|
|
||||||
|
|
||||||
// get key (L) and key_version
|
rc= encryption_scheme_decrypt(src, size, dst, &dstlen,
|
||||||
if (ma_crypt_get_key(key, sizeof(key), crypt_data, key_version))
|
&crypt_data->scheme, key_version,
|
||||||
return 1;
|
crypt_data->space, pageno, lsn);
|
||||||
|
|
||||||
/* create counter block */
|
|
||||||
memcpy(counter + 0, crypt_data->iv + CRYPT_SCHEME_1_IV_LEN, 4);
|
|
||||||
int4store(counter + 4, pageno);
|
|
||||||
int8store(counter + 8, lsn);
|
|
||||||
|
|
||||||
rc =encryption_decrypt(src, size, dst, &dstlen,
|
|
||||||
crypt_data->iv, CRYPT_SCHEME_1_IV_LEN,
|
|
||||||
counter, sizeof(counter), 1, crypt_data->keyid,
|
|
||||||
key_version);
|
|
||||||
|
|
||||||
DBUG_ASSERT(rc == MY_AES_OK);
|
DBUG_ASSERT(rc == MY_AES_OK);
|
||||||
DBUG_ASSERT(dstlen == size);
|
DBUG_ASSERT(dstlen == size);
|
||||||
|
@ -149,82 +149,6 @@ fil_space_crypt_cleanup()
|
|||||||
os_event_free(fil_crypt_throttle_sleep_event);
|
os_event_free(fil_crypt_throttle_sleep_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
Get key bytes for a space/key-version */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
fil_crypt_get_key(
|
|
||||||
/*==============*/
|
|
||||||
byte* dst, /*<! out: Key */
|
|
||||||
uint* key_length, /*<! out: Key length */
|
|
||||||
fil_space_crypt_t* crypt_data, /*<! in: crypt data */
|
|
||||||
uint version) /*<! in: Key version */
|
|
||||||
{
|
|
||||||
unsigned char keybuf[MY_AES_MAX_KEY_LENGTH];
|
|
||||||
|
|
||||||
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,
|
|
||||||
crypt_data->keys[i].key_length);
|
|
||||||
*key_length = crypt_data->keys[i].key_length;
|
|
||||||
mutex_exit(&crypt_data->mutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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];
|
|
||||||
}
|
|
||||||
|
|
||||||
*key_length = sizeof(keybuf);
|
|
||||||
uint rc = encryption_key_get(crypt_data->key_id, version, keybuf, key_length);
|
|
||||||
if (rc) {
|
|
||||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
|
||||||
"Key id %u version %u can not be found. Reason=%u",
|
|
||||||
crypt_data->key_id, version, rc);
|
|
||||||
ut_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now compute L by encrypting IV using this key. Note
|
|
||||||
that we use random IV from crypt data. */
|
|
||||||
const unsigned char* src = crypt_data->iv;
|
|
||||||
const int srclen = crypt_data->iv_length;
|
|
||||||
unsigned char* buf = crypt_data->keys[0].key;
|
|
||||||
uint32 buflen = CRYPT_SCHEME_1_IV_LEN;
|
|
||||||
|
|
||||||
/* We use AES_ECB to encrypt IV */
|
|
||||||
rc = my_aes_encrypt_ecb(src, srclen, buf, &buflen,
|
|
||||||
keybuf, *key_length, NULL, 0, 1);
|
|
||||||
|
|
||||||
if (rc != MY_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
crypt_data->keys[0].key_version = version;
|
|
||||||
crypt_data->key_count++;
|
|
||||||
*key_length = buflen;
|
|
||||||
crypt_data->keys[0].key_length = buflen;
|
|
||||||
|
|
||||||
if (crypt_data->key_count > array_elements(crypt_data->keys)) {
|
|
||||||
crypt_data->key_count = array_elements(crypt_data->keys);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dst, buf, buflen);
|
|
||||||
mutex_exit(&crypt_data->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
Get the latest(key-version), waking the encrypt thread, if needed */
|
Get the latest(key-version), waking the encrypt thread, if needed */
|
||||||
static inline
|
static inline
|
||||||
@ -244,27 +168,17 @@ fil_crypt_get_latest_key_version(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
Get key bytes for a space/latest(key-version) */
|
Mutex helper for crypt_data->scheme */
|
||||||
static inline
|
static void crypt_data_scheme_locker(st_encryption_scheme *scheme, int exit)
|
||||||
void
|
|
||||||
fil_crypt_get_latest_key(
|
|
||||||
/*=====================*/
|
|
||||||
byte* dst, /*!< out: Key */
|
|
||||||
uint* key_length, /*!< out: Key length */
|
|
||||||
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
|
||||||
uint* version) /*!< in: Key version */
|
|
||||||
{
|
{
|
||||||
// used for key rotation - get the next key id from the key provider
|
fil_space_crypt_t* crypt_data =
|
||||||
uint rc = *version = fil_crypt_get_latest_key_version(crypt_data);
|
static_cast<fil_space_crypt_t*>(scheme);
|
||||||
|
|
||||||
if (rc == ENCRYPTION_KEY_VERSION_INVALID) {
|
if (exit) {
|
||||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
mutex_exit(&crypt_data->mutex);
|
||||||
"Unknown key id %u. Can't continue!\n",
|
} else {
|
||||||
crypt_data->key_id);
|
mutex_enter(&crypt_data->mutex);
|
||||||
ut_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fil_crypt_get_key(dst, key_length, crypt_data, *version);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
@ -277,8 +191,7 @@ fil_space_create_crypt_data(
|
|||||||
fil_encryption_t encrypt_mode, /*!< in: encryption mode */
|
fil_encryption_t encrypt_mode, /*!< in: encryption mode */
|
||||||
uint key_id) /*!< in: encryption key id */
|
uint key_id) /*!< in: encryption key id */
|
||||||
{
|
{
|
||||||
const uint iv_length = CRYPT_SCHEME_1_IV_LEN;
|
const uint sz = sizeof(fil_space_crypt_t);
|
||||||
const uint sz = sizeof(fil_space_crypt_t) + iv_length;
|
|
||||||
fil_space_crypt_t* crypt_data =
|
fil_space_crypt_t* crypt_data =
|
||||||
static_cast<fil_space_crypt_t*>(malloc(sz));
|
static_cast<fil_space_crypt_t*>(malloc(sz));
|
||||||
|
|
||||||
@ -290,14 +203,14 @@ fil_space_create_crypt_data(
|
|||||||
crypt_data->min_key_version = 0;
|
crypt_data->min_key_version = 0;
|
||||||
} else {
|
} else {
|
||||||
crypt_data->type = CRYPT_SCHEME_1;
|
crypt_data->type = CRYPT_SCHEME_1;
|
||||||
crypt_data->key_id = key_id;
|
crypt_data->key_id = key_id;
|
||||||
crypt_data->min_key_version = encryption_key_get_latest_version(key_id);
|
crypt_data->min_key_version = encryption_key_get_latest_version(key_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_create(fil_crypt_data_mutex_key,
|
mutex_create(fil_crypt_data_mutex_key,
|
||||||
&crypt_data->mutex, SYNC_NO_ORDER_CHECK);
|
&crypt_data->mutex, SYNC_NO_ORDER_CHECK);
|
||||||
crypt_data->iv_length = iv_length;
|
crypt_data->locker = crypt_data_scheme_locker;
|
||||||
my_random_bytes(crypt_data->iv, iv_length);
|
my_random_bytes(crypt_data->iv, sizeof(crypt_data->iv));
|
||||||
crypt_data->encryption = FIL_SPACE_ENCRYPTION_DEFAULT;
|
crypt_data->encryption = FIL_SPACE_ENCRYPTION_DEFAULT;
|
||||||
return crypt_data;
|
return crypt_data;
|
||||||
}
|
}
|
||||||
@ -317,12 +230,9 @@ fil_space_crypt_compare(
|
|||||||
ut_a(crypt_data2->type == CRYPT_SCHEME_UNENCRYPTED ||
|
ut_a(crypt_data2->type == CRYPT_SCHEME_UNENCRYPTED ||
|
||||||
crypt_data2->type == CRYPT_SCHEME_1);
|
crypt_data2->type == CRYPT_SCHEME_1);
|
||||||
|
|
||||||
ut_a(crypt_data1->iv_length == CRYPT_SCHEME_1_IV_LEN);
|
|
||||||
ut_a(crypt_data2->iv_length == CRYPT_SCHEME_1_IV_LEN);
|
|
||||||
|
|
||||||
/* no support for changing iv (yet?) */
|
/* no support for changing iv (yet?) */
|
||||||
ut_a(memcmp(crypt_data1->iv, crypt_data2->iv,
|
ut_a(memcmp(crypt_data1->iv, crypt_data2->iv,
|
||||||
crypt_data1->iv_length) == 0);
|
sizeof(crypt_data1->iv)) == 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -378,9 +288,10 @@ fil_space_read_crypt_data(
|
|||||||
ut_error;
|
ut_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fil_space_crypt_t* crypt_data;
|
||||||
ulint iv_length = mach_read_from_1(page + offset + MAGIC_SZ + 1);
|
ulint iv_length = mach_read_from_1(page + offset + MAGIC_SZ + 1);
|
||||||
|
|
||||||
if (! (iv_length == CRYPT_SCHEME_1_IV_LEN)) {
|
if (! (iv_length == sizeof(crypt_data->iv))) {
|
||||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||||
"Found non sensible iv length: %lu for space %lu "
|
"Found non sensible iv length: %lu for space %lu "
|
||||||
" offset: %lu type: %lu bytes: "
|
" offset: %lu type: %lu bytes: "
|
||||||
@ -405,8 +316,7 @@ fil_space_read_crypt_data(
|
|||||||
page + offset + MAGIC_SZ + 2 + iv_length + 8);
|
page + offset + MAGIC_SZ + 2 + iv_length + 8);
|
||||||
|
|
||||||
const uint sz = sizeof(fil_space_crypt_t) + iv_length;
|
const uint sz = sizeof(fil_space_crypt_t) + iv_length;
|
||||||
fil_space_crypt_t* crypt_data = static_cast<fil_space_crypt_t*>(
|
crypt_data = static_cast<fil_space_crypt_t*>(malloc(sz));
|
||||||
malloc(sz));
|
|
||||||
memset(crypt_data, 0, sz);
|
memset(crypt_data, 0, sz);
|
||||||
|
|
||||||
crypt_data->type = type;
|
crypt_data->type = type;
|
||||||
@ -416,7 +326,7 @@ fil_space_read_crypt_data(
|
|||||||
crypt_data->encryption = encryption;
|
crypt_data->encryption = encryption;
|
||||||
mutex_create(fil_crypt_data_mutex_key,
|
mutex_create(fil_crypt_data_mutex_key,
|
||||||
&crypt_data->mutex, SYNC_NO_ORDER_CHECK);
|
&crypt_data->mutex, SYNC_NO_ORDER_CHECK);
|
||||||
crypt_data->iv_length = iv_length;
|
crypt_data->locker = crypt_data_scheme_locker;
|
||||||
memcpy(crypt_data->iv, page + offset + MAGIC_SZ + 2, iv_length);
|
memcpy(crypt_data->iv, page + offset + MAGIC_SZ + 2, iv_length);
|
||||||
|
|
||||||
return crypt_data;
|
return crypt_data;
|
||||||
@ -453,7 +363,7 @@ fil_space_write_crypt_data_low(
|
|||||||
ut_a(offset > 0 && offset < UNIV_PAGE_SIZE);
|
ut_a(offset > 0 && offset < UNIV_PAGE_SIZE);
|
||||||
ulint space_id = mach_read_from_4(
|
ulint space_id = mach_read_from_4(
|
||||||
page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||||
const uint len = crypt_data->iv_length;
|
const uint len = sizeof(crypt_data->iv);
|
||||||
const uint min_key_version = crypt_data->min_key_version;
|
const uint min_key_version = crypt_data->min_key_version;
|
||||||
const uint key_id = crypt_data->key_id;
|
const uint key_id = crypt_data->key_id;
|
||||||
const fil_encryption_t encryption = crypt_data->encryption;
|
const fil_encryption_t encryption = crypt_data->encryption;
|
||||||
@ -662,9 +572,6 @@ fil_space_encrypt(
|
|||||||
fil_space_crypt_t* crypt_data = NULL;
|
fil_space_crypt_t* crypt_data = NULL;
|
||||||
ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
|
ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
|
||||||
uint key_version;
|
uint key_version;
|
||||||
unsigned char key[MY_AES_MAX_KEY_LENGTH];
|
|
||||||
uint key_length = MY_AES_MAX_KEY_LENGTH;
|
|
||||||
unsigned char iv[MY_AES_BLOCK_SIZE];
|
|
||||||
|
|
||||||
ulint orig_page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
|
ulint orig_page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
|
||||||
|
|
||||||
@ -686,12 +593,14 @@ fil_space_encrypt(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_crypt_get_latest_key(key, &key_length, crypt_data, &key_version);
|
key_version = fil_crypt_get_latest_key_version(crypt_data);
|
||||||
|
|
||||||
/* create iv/counter */
|
if (key_version == ENCRYPTION_KEY_VERSION_INVALID) {
|
||||||
mach_write_to_4(iv + 0, space);
|
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||||
mach_write_to_4(iv + 4, offset);
|
"Unknown key id %u. Can't continue!\n",
|
||||||
mach_write_to_8(iv + 8, lsn);
|
crypt_data->key_id);
|
||||||
|
ut_error;
|
||||||
|
}
|
||||||
|
|
||||||
ibool page_compressed = (mach_read_from_2(src_frame+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED);
|
ibool page_compressed = (mach_read_from_2(src_frame+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED);
|
||||||
|
|
||||||
@ -719,9 +628,9 @@ fil_space_encrypt(
|
|||||||
dst+=2;
|
dst+=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = encryption_encrypt(src, srclen, dst, &dstlen,
|
int rc = encryption_scheme_encrypt(src, srclen, dst, &dstlen,
|
||||||
key, key_length, iv, sizeof(iv), 1,
|
crypt_data, key_version,
|
||||||
crypt_data->key_id, key_version);
|
space, offset, lsn);
|
||||||
|
|
||||||
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
|
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
|
||||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||||
@ -837,17 +746,6 @@ fil_space_decrypt(
|
|||||||
/* Copy FIL page header, it is not encrypted */
|
/* Copy FIL page header, it is not encrypted */
|
||||||
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
|
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
|
||||||
|
|
||||||
/* Get key */
|
|
||||||
byte key[MY_AES_MAX_KEY_LENGTH];
|
|
||||||
uint key_length;
|
|
||||||
unsigned char iv[MY_AES_BLOCK_SIZE];
|
|
||||||
fil_crypt_get_key(key, &key_length, crypt_data, key_version);
|
|
||||||
|
|
||||||
/* create iv/counter */
|
|
||||||
mach_write_to_4(iv + 0, space);
|
|
||||||
mach_write_to_4(iv + 4, offset);
|
|
||||||
mach_write_to_8(iv + 8, lsn);
|
|
||||||
|
|
||||||
/* Calculate the offset where decryption starts */
|
/* Calculate the offset where decryption starts */
|
||||||
const byte* src = src_frame + FIL_PAGE_DATA;
|
const byte* src = src_frame + FIL_PAGE_DATA;
|
||||||
byte* dst = dst_frame + FIL_PAGE_DATA;
|
byte* dst = dst_frame + FIL_PAGE_DATA;
|
||||||
@ -865,9 +763,9 @@ fil_space_decrypt(
|
|||||||
srclen = compressed_len;
|
srclen = compressed_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = encryption_decrypt(src, srclen, dst, &dstlen, key, key_length,
|
int rc = encryption_scheme_decrypt(src, srclen, dst, &dstlen,
|
||||||
iv, sizeof(iv), 1,
|
crypt_data, key_version,
|
||||||
crypt_data->key_id, key_version);
|
space, offset, lsn);
|
||||||
|
|
||||||
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
|
if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) {
|
||||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||||
|
@ -12242,8 +12242,7 @@ ha_innobase::create(
|
|||||||
|
|
||||||
/* If there is old crypt data, copy IV */
|
/* If there is old crypt data, copy IV */
|
||||||
if (old_crypt_data) {
|
if (old_crypt_data) {
|
||||||
memcpy(crypt_data->iv, old_crypt_data->iv, old_crypt_data->iv_length);
|
memcpy(crypt_data->iv, old_crypt_data->iv, sizeof(crypt_data->iv));
|
||||||
crypt_data->iv_length = old_crypt_data->iv_length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
@ -80,13 +80,8 @@ struct fil_space_rotate_state_t
|
|||||||
} scrubbing;
|
} scrubbing;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fil_space_crypt_struct
|
struct fil_space_crypt_struct : st_encryption_scheme
|
||||||
{
|
{
|
||||||
ulint type; // CRYPT_SCHEME
|
|
||||||
uint keyserver_requests; // no of key requests to key server
|
|
||||||
uint key_count; // No of initalized key-structs
|
|
||||||
uint key_id; // Key id for this space
|
|
||||||
key_struct keys[3]; // cached L = AES_ECB(KEY, IV)
|
|
||||||
uint min_key_version; // min key version for this space
|
uint min_key_version; // min key version for this space
|
||||||
ulint page0_offset; // byte offset on page 0 for crypt data
|
ulint page0_offset; // byte offset on page 0 for crypt data
|
||||||
fil_encryption_t encryption; // Encryption setup
|
fil_encryption_t encryption; // Encryption setup
|
||||||
@ -94,9 +89,6 @@ struct fil_space_crypt_struct
|
|||||||
ib_mutex_t mutex; // mutex protecting following variables
|
ib_mutex_t mutex; // mutex protecting following variables
|
||||||
bool closing; // is tablespace being closed
|
bool closing; // is tablespace being closed
|
||||||
fil_space_rotate_state_t rotate_state;
|
fil_space_rotate_state_t rotate_state;
|
||||||
|
|
||||||
uint iv_length; // length of IV
|
|
||||||
byte iv[1]; // IV-data
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* structure containing encryption specification */
|
/* structure containing encryption specification */
|
||||||
|
Reference in New Issue
Block a user