1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// Copyright (C) 2014 Google Inc.
#include <my_global.h>
#include <my_pthread.h>
#include <my_aes.h>
#include <mysql/plugin_encryption_key_management.h>
#include <my_md5.h>
#include <my_rnd.h>
/* rotate key randomly between 45 and 90 seconds */
#define KEY_ROTATION_MIN 45
#define KEY_ROTATION_MAX 90
static struct my_rnd_struct seed;
static unsigned int key_version = 0;
static unsigned int next_key_version = 0;
static pthread_mutex_t mutex;
static unsigned int
get_latest_key_version()
{
uint now = time(0);
pthread_mutex_lock(&mutex);
if (now >= next_key_version)
{
key_version = now;
unsigned int interval = KEY_ROTATION_MAX - KEY_ROTATION_MIN;
next_key_version = now + KEY_ROTATION_MIN + my_rnd(&seed) * interval;
}
pthread_mutex_unlock(&mutex);
return key_version;
}
static int
get_key(unsigned int version, unsigned char* dstbuf, unsigned buflen)
{
char *dst = (char*)dstbuf; // md5 function takes char* as argument...
unsigned len = 0;
for (; len + MD5_HASH_SIZE <= buflen; len += MD5_HASH_SIZE)
{
compute_md5_hash(dst, (const char*)&version, sizeof(version));
dst += MD5_HASH_SIZE;
version++;
}
if (len < buflen)
{
memset(dst, 0, buflen - len);
}
return 0;
}
static unsigned int has_key_func(unsigned int keyID)
{
return true;
}
static unsigned int get_key_size(unsigned int keyID)
{
return 16;
}
static int get_iv(unsigned int keyID, unsigned char* dstbuf, unsigned buflen)
{
if (buflen < 16)
{
return CRYPT_BUFFER_TO_SMALL;
}
for (int i=0; i<16; i++)
dstbuf[i] = 0;
return CRYPT_KEY_OK;
}
static int example_key_management_plugin_init(void *p)
{
/* init */
my_rnd_init(&seed, time(0), 0);
get_latest_key_version();
my_aes_init_dynamic_encrypt(MY_AES_ALGORITHM_CTR);
pthread_mutex_init(&mutex, NULL);
return 0;
}
static int example_key_management_plugin_deinit(void *p)
{
pthread_mutex_destroy(&mutex);
return 0;
}
struct st_mariadb_encryption_key_management example_key_management_plugin= {
MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION,
get_latest_key_version,
has_key_func,
get_key_size,
get_key,
get_iv
};
/*
Plugin library descriptor
*/
maria_declare_plugin(example_key_management_plugin)
{
MariaDB_ENCRYPTION_KEY_MANAGEMENT_PLUGIN,
&example_key_management_plugin,
"example_key_management_plugin",
"Jonas Oreland",
"Example key management plugin",
PLUGIN_LICENSE_GPL,
example_key_management_plugin_init,
example_key_management_plugin_deinit,
0x0100 /* 1.0 */,
NULL, /* status variables */
NULL, /* system variables */
"1.0",
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
}
maria_declare_plugin_end;
|