Skip to content

Commit 2300fe2

Browse files
committed
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
1 parent 632f230 commit 2300fe2

26 files changed

+612
-466
lines changed

include/my_crypt.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ extern "C" {
2525
#endif
2626

2727
/* return values from my_aes_encrypt/my_aes_decrypt functions */
28-
#define MY_AES_OK 0
29-
#define MY_AES_BAD_DATA -1
30-
#define MY_AES_OPENSSL_ERROR -2
31-
#define MY_AES_BAD_KEYSIZE -3
28+
#define MY_AES_OK 0
29+
#define MY_AES_BAD_DATA -100
30+
#define MY_AES_OPENSSL_ERROR -101
31+
#define MY_AES_BAD_KEYSIZE -102
3232

3333
/* The block size for all supported algorithms */
3434
#define MY_AES_BLOCK_SIZE 16

include/mysql/plugin.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ typedef struct st_mysql_xid MYSQL_XID;
7575
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0104
7676

7777
/* MariaDB plugin interface version */
78-
#define MARIA_PLUGIN_INTERFACE_VERSION 0x010a
78+
#define MARIA_PLUGIN_INTERFACE_VERSION 0x010b
7979

8080
/*
8181
The allowable types of plugins

include/mysql/plugin_audit.h.pp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,43 @@
213213
encrypt_decrypt_func encryption_decrypt_func;
214214
};
215215
extern struct encryption_service_st encryption_handler;
216+
#include <mysql/service_encryption_scheme.h>
217+
struct st_encryption_scheme_key {
218+
unsigned int version;
219+
unsigned char key[16];
220+
};
221+
struct st_encryption_scheme {
222+
unsigned char iv[16];
223+
struct st_encryption_scheme_key key[3];
224+
unsigned int keyserver_requests;
225+
unsigned int key_id;
226+
unsigned int type;
227+
void (*locker)(struct st_encryption_scheme *self, int release);
228+
};
229+
extern struct encryption_scheme_service_st {
230+
int (*encryption_scheme_encrypt_func)
231+
(const unsigned char* src, unsigned int slen,
232+
unsigned char* dst, unsigned int* dlen,
233+
struct st_encryption_scheme *scheme,
234+
unsigned int key_version, unsigned int i32_1,
235+
unsigned int i32_2, unsigned long long i64);
236+
int (*encryption_scheme_decrypt_func)
237+
(const unsigned char* src, unsigned int slen,
238+
unsigned char* dst, unsigned int* dlen,
239+
struct st_encryption_scheme *scheme,
240+
unsigned int key_version, unsigned int i32_1,
241+
unsigned int i32_2, unsigned long long i64);
242+
} *encryption_scheme_service;
243+
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
244+
unsigned char* dst, unsigned int* dlen,
245+
struct st_encryption_scheme *scheme,
246+
unsigned int key_version, unsigned int i32_1,
247+
unsigned int i32_2, unsigned long long i64);
248+
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
249+
unsigned char* dst, unsigned int* dlen,
250+
struct st_encryption_scheme *scheme,
251+
unsigned int key_version, unsigned int i32_1,
252+
unsigned int i32_2, unsigned long long i64);
216253
struct st_mysql_xid {
217254
long formatID;
218255
long gtrid_length;

include/mysql/plugin_auth.h.pp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,43 @@
213213
encrypt_decrypt_func encryption_decrypt_func;
214214
};
215215
extern struct encryption_service_st encryption_handler;
216+
#include <mysql/service_encryption_scheme.h>
217+
struct st_encryption_scheme_key {
218+
unsigned int version;
219+
unsigned char key[16];
220+
};
221+
struct st_encryption_scheme {
222+
unsigned char iv[16];
223+
struct st_encryption_scheme_key key[3];
224+
unsigned int keyserver_requests;
225+
unsigned int key_id;
226+
unsigned int type;
227+
void (*locker)(struct st_encryption_scheme *self, int release);
228+
};
229+
extern struct encryption_scheme_service_st {
230+
int (*encryption_scheme_encrypt_func)
231+
(const unsigned char* src, unsigned int slen,
232+
unsigned char* dst, unsigned int* dlen,
233+
struct st_encryption_scheme *scheme,
234+
unsigned int key_version, unsigned int i32_1,
235+
unsigned int i32_2, unsigned long long i64);
236+
int (*encryption_scheme_decrypt_func)
237+
(const unsigned char* src, unsigned int slen,
238+
unsigned char* dst, unsigned int* dlen,
239+
struct st_encryption_scheme *scheme,
240+
unsigned int key_version, unsigned int i32_1,
241+
unsigned int i32_2, unsigned long long i64);
242+
} *encryption_scheme_service;
243+
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
244+
unsigned char* dst, unsigned int* dlen,
245+
struct st_encryption_scheme *scheme,
246+
unsigned int key_version, unsigned int i32_1,
247+
unsigned int i32_2, unsigned long long i64);
248+
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
249+
unsigned char* dst, unsigned int* dlen,
250+
struct st_encryption_scheme *scheme,
251+
unsigned int key_version, unsigned int i32_1,
252+
unsigned int i32_2, unsigned long long i64);
216253
struct st_mysql_xid {
217254
long formatID;
218255
long gtrid_length;

include/mysql/plugin_encryption.h.pp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,43 @@
213213
encrypt_decrypt_func encryption_decrypt_func;
214214
};
215215
extern struct encryption_service_st encryption_handler;
216+
#include <mysql/service_encryption_scheme.h>
217+
struct st_encryption_scheme_key {
218+
unsigned int version;
219+
unsigned char key[16];
220+
};
221+
struct st_encryption_scheme {
222+
unsigned char iv[16];
223+
struct st_encryption_scheme_key key[3];
224+
unsigned int keyserver_requests;
225+
unsigned int key_id;
226+
unsigned int type;
227+
void (*locker)(struct st_encryption_scheme *self, int release);
228+
};
229+
extern struct encryption_scheme_service_st {
230+
int (*encryption_scheme_encrypt_func)
231+
(const unsigned char* src, unsigned int slen,
232+
unsigned char* dst, unsigned int* dlen,
233+
struct st_encryption_scheme *scheme,
234+
unsigned int key_version, unsigned int i32_1,
235+
unsigned int i32_2, unsigned long long i64);
236+
int (*encryption_scheme_decrypt_func)
237+
(const unsigned char* src, unsigned int slen,
238+
unsigned char* dst, unsigned int* dlen,
239+
struct st_encryption_scheme *scheme,
240+
unsigned int key_version, unsigned int i32_1,
241+
unsigned int i32_2, unsigned long long i64);
242+
} *encryption_scheme_service;
243+
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
244+
unsigned char* dst, unsigned int* dlen,
245+
struct st_encryption_scheme *scheme,
246+
unsigned int key_version, unsigned int i32_1,
247+
unsigned int i32_2, unsigned long long i64);
248+
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
249+
unsigned char* dst, unsigned int* dlen,
250+
struct st_encryption_scheme *scheme,
251+
unsigned int key_version, unsigned int i32_1,
252+
unsigned int i32_2, unsigned long long i64);
216253
struct st_mysql_xid {
217254
long formatID;
218255
long gtrid_length;

include/mysql/plugin_ftparser.h.pp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,43 @@
213213
encrypt_decrypt_func encryption_decrypt_func;
214214
};
215215
extern struct encryption_service_st encryption_handler;
216+
#include <mysql/service_encryption_scheme.h>
217+
struct st_encryption_scheme_key {
218+
unsigned int version;
219+
unsigned char key[16];
220+
};
221+
struct st_encryption_scheme {
222+
unsigned char iv[16];
223+
struct st_encryption_scheme_key key[3];
224+
unsigned int keyserver_requests;
225+
unsigned int key_id;
226+
unsigned int type;
227+
void (*locker)(struct st_encryption_scheme *self, int release);
228+
};
229+
extern struct encryption_scheme_service_st {
230+
int (*encryption_scheme_encrypt_func)
231+
(const unsigned char* src, unsigned int slen,
232+
unsigned char* dst, unsigned int* dlen,
233+
struct st_encryption_scheme *scheme,
234+
unsigned int key_version, unsigned int i32_1,
235+
unsigned int i32_2, unsigned long long i64);
236+
int (*encryption_scheme_decrypt_func)
237+
(const unsigned char* src, unsigned int slen,
238+
unsigned char* dst, unsigned int* dlen,
239+
struct st_encryption_scheme *scheme,
240+
unsigned int key_version, unsigned int i32_1,
241+
unsigned int i32_2, unsigned long long i64);
242+
} *encryption_scheme_service;
243+
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
244+
unsigned char* dst, unsigned int* dlen,
245+
struct st_encryption_scheme *scheme,
246+
unsigned int key_version, unsigned int i32_1,
247+
unsigned int i32_2, unsigned long long i64);
248+
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
249+
unsigned char* dst, unsigned int* dlen,
250+
struct st_encryption_scheme *scheme,
251+
unsigned int key_version, unsigned int i32_1,
252+
unsigned int i32_2, unsigned long long i64);
216253
struct st_mysql_xid {
217254
long formatID;
218255
long gtrid_length;

include/mysql/plugin_password_validation.h.pp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,43 @@
213213
encrypt_decrypt_func encryption_decrypt_func;
214214
};
215215
extern struct encryption_service_st encryption_handler;
216+
#include <mysql/service_encryption_scheme.h>
217+
struct st_encryption_scheme_key {
218+
unsigned int version;
219+
unsigned char key[16];
220+
};
221+
struct st_encryption_scheme {
222+
unsigned char iv[16];
223+
struct st_encryption_scheme_key key[3];
224+
unsigned int keyserver_requests;
225+
unsigned int key_id;
226+
unsigned int type;
227+
void (*locker)(struct st_encryption_scheme *self, int release);
228+
};
229+
extern struct encryption_scheme_service_st {
230+
int (*encryption_scheme_encrypt_func)
231+
(const unsigned char* src, unsigned int slen,
232+
unsigned char* dst, unsigned int* dlen,
233+
struct st_encryption_scheme *scheme,
234+
unsigned int key_version, unsigned int i32_1,
235+
unsigned int i32_2, unsigned long long i64);
236+
int (*encryption_scheme_decrypt_func)
237+
(const unsigned char* src, unsigned int slen,
238+
unsigned char* dst, unsigned int* dlen,
239+
struct st_encryption_scheme *scheme,
240+
unsigned int key_version, unsigned int i32_1,
241+
unsigned int i32_2, unsigned long long i64);
242+
} *encryption_scheme_service;
243+
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
244+
unsigned char* dst, unsigned int* dlen,
245+
struct st_encryption_scheme *scheme,
246+
unsigned int key_version, unsigned int i32_1,
247+
unsigned int i32_2, unsigned long long i64);
248+
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
249+
unsigned char* dst, unsigned int* dlen,
250+
struct st_encryption_scheme *scheme,
251+
unsigned int key_version, unsigned int i32_1,
252+
unsigned int i32_2, unsigned long long i64);
216253
struct st_mysql_xid {
217254
long formatID;
218255
long gtrid_length;
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#ifndef MYSQL_SERVICE_ENCRYPTION_SCHEME_INCLUDED
2+
/* Copyright (c) 2015, MariaDB
3+
4+
This program is free software; you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation; version 2 of the License.
7+
8+
This program is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
GNU General Public License for more details.
12+
13+
You should have received a copy of the GNU General Public License
14+
along with this program; if not, write to the Free Software
15+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16+
17+
/**
18+
@file
19+
encryption scheme service
20+
21+
A higher-level access to encryption service.
22+
23+
This is a helper service that storage engines use to encrypt tables on disk.
24+
It requests keys from the plugin, generates temporary or local keys
25+
from the global (as returned by the plugin) keys, etc.
26+
27+
To use the service:
28+
29+
* st_encryption_scheme object is created per space. A "space" can be
30+
a table space in XtraDB/InnoDB, a file in Aria, etc. The whole
31+
space is encrypted with the one key id.
32+
33+
* The service does not take the key and the IV as parameters for
34+
encryption or decryption. Instead it takes two 32-bit integers and
35+
one 64-bit integer (and requests the key from an encryption
36+
plugin, if needed).
37+
38+
* The service requests the global key from the encryption plugin
39+
automatically as needed. Three last keys are cached in the
40+
st_encryption_scheme. Number of key requests (number of cache
41+
misses) are counted in st_encryption_scheme::keyserver_requests
42+
43+
* If an st_encryption_scheme can be used concurrently by different
44+
threads, it needs to be able to lock itself when accessing the key
45+
cache. Set the st_encryption_scheme::locker appropriately. If
46+
non-zero, it will be invoked by encrypt/decrypt functions to lock
47+
and unlock the scheme when needed.
48+
49+
* Implementation details (in particular, key derivation) are defined
50+
by the scheme type. Currently only schema type 1 is supported.
51+
52+
In the schema type 1, every "space" (table space in XtraDB/InnoDB,
53+
file in Aria) is encrypted with a different space-local key:
54+
55+
* Every space has a 16-byte unique identifier (typically it's
56+
generated randomly and stored in the space). The caller should
57+
put it into st_encryption_scheme::iv.
58+
59+
* Space-local key is generated by encrypting this identifier with
60+
the global encryption key (of the given id and version) using AES_ECB.
61+
62+
* Encryption/decryption parameters for a page are typically the
63+
4-byte space id, 4-byte page position (offset, page number, etc),
64+
and the 8-byte LSN. This guarantees that they'll be different for
65+
any two pages (of the same or different tablespaces) and also that
66+
they'll change for the same page when it's modified. They don't need
67+
to be secret (they create the IV, not the encryption key).
68+
*/
69+
70+
#ifdef __cplusplus
71+
extern "C" {
72+
#endif
73+
74+
#define ENCRYPTION_SCHEME_KEY_INVALID -1
75+
#define ENCRYPTION_SCHEME_BLOCK_LENGTH 16
76+
77+
struct st_encryption_scheme_key {
78+
unsigned int version;
79+
unsigned char key[ENCRYPTION_SCHEME_BLOCK_LENGTH];
80+
};
81+
82+
struct st_encryption_scheme {
83+
unsigned char iv[ENCRYPTION_SCHEME_BLOCK_LENGTH];
84+
struct st_encryption_scheme_key key[3];
85+
unsigned int keyserver_requests;
86+
unsigned int key_id;
87+
unsigned int type;
88+
89+
void (*locker)(struct st_encryption_scheme *self, int release);
90+
};
91+
92+
extern struct encryption_scheme_service_st {
93+
int (*encryption_scheme_encrypt_func)
94+
(const unsigned char* src, unsigned int slen,
95+
unsigned char* dst, unsigned int* dlen,
96+
struct st_encryption_scheme *scheme,
97+
unsigned int key_version, unsigned int i32_1,
98+
unsigned int i32_2, unsigned long long i64);
99+
int (*encryption_scheme_decrypt_func)
100+
(const unsigned char* src, unsigned int slen,
101+
unsigned char* dst, unsigned int* dlen,
102+
struct st_encryption_scheme *scheme,
103+
unsigned int key_version, unsigned int i32_1,
104+
unsigned int i32_2, unsigned long long i64);
105+
} *encryption_scheme_service;
106+
107+
#ifdef MYSQL_DYNAMIC_PLUGIN
108+
109+
#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)
110+
#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)
111+
112+
#else
113+
114+
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
115+
unsigned char* dst, unsigned int* dlen,
116+
struct st_encryption_scheme *scheme,
117+
unsigned int key_version, unsigned int i32_1,
118+
unsigned int i32_2, unsigned long long i64);
119+
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
120+
unsigned char* dst, unsigned int* dlen,
121+
struct st_encryption_scheme *scheme,
122+
unsigned int key_version, unsigned int i32_1,
123+
unsigned int i32_2, unsigned long long i64);
124+
125+
#endif
126+
127+
128+
#ifdef __cplusplus
129+
}
130+
#endif
131+
132+
#define MYSQL_SERVICE_ENCRYPTION_SCHEME_INCLUDED
133+
#endif

include/mysql/services.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extern "C" {
3333
#include <mysql/service_thd_error_context.h>
3434
#include <mysql/service_thd_specifics.h>
3535
#include <mysql/service_encryption.h>
36+
#include <mysql/service_encryption_scheme.h>
3637
/*#include <mysql/service_wsrep.h>*/
3738

3839
#ifdef __cplusplus

include/service_versions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@
3636
#define VERSION_thd_error_context 0x0100
3737
#define VERSION_thd_specifics 0x0100
3838
#define VERSION_encryption 0x0200
39+
#define VERSION_encryption_scheme 0x0100
3940

0 commit comments

Comments
 (0)