diff options
author | Sergei Golubchik <serg@mariadb.org> | 2015-05-13 21:57:24 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2015-05-15 18:12:01 +0200 |
commit | 2300fe2e0ed59e36046bb867cc7499bf4c3d7c27 (patch) | |
tree | 9adab44a30ef40e5cf1e1661220a9cf8079cb5b5 /include | |
parent | 632f2307f775d255bab948de2178feb85fcac970 (diff) | |
download | mariadb-git-2300fe2e0ed59e36046bb867cc7499bf4c3d7c27.tar.gz |
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
Diffstat (limited to 'include')
-rw-r--r-- | include/my_crypt.h | 8 | ||||
-rw-r--r-- | include/mysql/plugin.h | 2 | ||||
-rw-r--r-- | include/mysql/plugin_audit.h.pp | 37 | ||||
-rw-r--r-- | include/mysql/plugin_auth.h.pp | 37 | ||||
-rw-r--r-- | include/mysql/plugin_encryption.h.pp | 37 | ||||
-rw-r--r-- | include/mysql/plugin_ftparser.h.pp | 37 | ||||
-rw-r--r-- | include/mysql/plugin_password_validation.h.pp | 37 | ||||
-rw-r--r-- | include/mysql/service_encryption_scheme.h | 133 | ||||
-rw-r--r-- | include/mysql/services.h | 1 | ||||
-rw-r--r-- | include/service_versions.h | 1 |
10 files changed, 325 insertions, 5 deletions
diff --git a/include/my_crypt.h b/include/my_crypt.h index bfde4d3c0f7..655d1641136 100644 --- a/include/my_crypt.h +++ b/include/my_crypt.h @@ -25,10 +25,10 @@ extern "C" { #endif /* return values from my_aes_encrypt/my_aes_decrypt functions */ -#define MY_AES_OK 0 -#define MY_AES_BAD_DATA -1 -#define MY_AES_OPENSSL_ERROR -2 -#define MY_AES_BAD_KEYSIZE -3 +#define MY_AES_OK 0 +#define MY_AES_BAD_DATA -100 +#define MY_AES_OPENSSL_ERROR -101 +#define MY_AES_BAD_KEYSIZE -102 /* The block size for all supported algorithms */ #define MY_AES_BLOCK_SIZE 16 diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 09026514a88..cfa4b13a7ef 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -75,7 +75,7 @@ typedef struct st_mysql_xid MYSQL_XID; #define MYSQL_PLUGIN_INTERFACE_VERSION 0x0104 /* MariaDB plugin interface version */ -#define MARIA_PLUGIN_INTERFACE_VERSION 0x010a +#define MARIA_PLUGIN_INTERFACE_VERSION 0x010b /* The allowable types of plugins diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 7346c4f29b0..669be094542 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -213,6 +213,43 @@ struct encryption_service_st { encrypt_decrypt_func encryption_decrypt_func; }; 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 { long formatID; long gtrid_length; diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 1df73b0a41e..1b795079c22 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -213,6 +213,43 @@ struct encryption_service_st { encrypt_decrypt_func encryption_decrypt_func; }; 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 { long formatID; long gtrid_length; diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp index 2cf344864e4..56cad7ab716 100644 --- a/include/mysql/plugin_encryption.h.pp +++ b/include/mysql/plugin_encryption.h.pp @@ -213,6 +213,43 @@ struct encryption_service_st { encrypt_decrypt_func encryption_decrypt_func; }; 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 { long formatID; long gtrid_length; diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index ee8ebc4299c..3c07800a656 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -213,6 +213,43 @@ struct encryption_service_st { encrypt_decrypt_func encryption_decrypt_func; }; 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 { long formatID; long gtrid_length; diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp index e7dcc44f07a..6b8a886dc25 100644 --- a/include/mysql/plugin_password_validation.h.pp +++ b/include/mysql/plugin_password_validation.h.pp @@ -213,6 +213,43 @@ struct encryption_service_st { encrypt_decrypt_func encryption_decrypt_func; }; 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 { long formatID; long gtrid_length; diff --git a/include/mysql/service_encryption_scheme.h b/include/mysql/service_encryption_scheme.h new file mode 100644 index 00000000000..195c7aa4a5c --- /dev/null +++ b/include/mysql/service_encryption_scheme.h @@ -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 diff --git a/include/mysql/services.h b/include/mysql/services.h index f8f41b19bd9..9d031a9b094 100644 --- a/include/mysql/services.h +++ b/include/mysql/services.h @@ -33,6 +33,7 @@ extern "C" { #include <mysql/service_thd_error_context.h> #include <mysql/service_thd_specifics.h> #include <mysql/service_encryption.h> +#include <mysql/service_encryption_scheme.h> /*#include <mysql/service_wsrep.h>*/ #ifdef __cplusplus diff --git a/include/service_versions.h b/include/service_versions.h index 0f3d8af5723..79b36092a0d 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -36,4 +36,5 @@ #define VERSION_thd_error_context 0x0100 #define VERSION_thd_specifics 0x0100 #define VERSION_encryption 0x0200 +#define VERSION_encryption_scheme 0x0100 |