summaryrefslogtreecommitdiffstats
path: root/plugin/file_key_management/file_key_management_plugin.cc
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/file_key_management/file_key_management_plugin.cc')
-rw-r--r--plugin/file_key_management/file_key_management_plugin.cc207
1 files changed, 207 insertions, 0 deletions
diff --git a/plugin/file_key_management/file_key_management_plugin.cc b/plugin/file_key_management/file_key_management_plugin.cc
new file mode 100644
index 00000000..927045ce
--- /dev/null
+++ b/plugin/file_key_management/file_key_management_plugin.cc
@@ -0,0 +1,207 @@
+/* Copyright (c) 2002, 2012, eperi GmbH.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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-1335 USA */
+
+#include <my_global.h>
+#include <typelib.h>
+#include "parser.h"
+#include <mysql/plugin_encryption.h>
+#include <string.h>
+
+static char* filename;
+static char* filekey;
+static unsigned long encryption_algorithm;
+
+static const char *encryption_algorithm_names[]=
+{
+ "aes_cbc",
+#ifdef HAVE_EncryptAes128Ctr
+ "aes_ctr",
+#endif
+ 0
+};
+
+static TYPELIB encryption_algorithm_typelib=
+{
+ array_elements(encryption_algorithm_names)-1,"",
+ encryption_algorithm_names, NULL
+};
+
+
+static MYSQL_SYSVAR_STR(filename, filename,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Path and name of the key file.",
+ NULL, NULL, "");
+
+static MYSQL_SYSVAR_STR(filekey, filekey,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Key to encrypt / decrypt the keyfile.",
+ NULL, NULL, "");
+
+#ifdef HAVE_EncryptAes128Ctr
+#define recommendation ", aes_ctr is the recommended one"
+#else
+#define recommendation ""
+#endif
+static MYSQL_SYSVAR_ENUM(encryption_algorithm, encryption_algorithm,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Encryption algorithm to use" recommendation ".",
+ NULL, NULL, 0, &encryption_algorithm_typelib);
+
+static struct st_mysql_sys_var* settings[] = {
+ MYSQL_SYSVAR(filename),
+ MYSQL_SYSVAR(filekey),
+ MYSQL_SYSVAR(encryption_algorithm),
+ NULL
+};
+
+std::map<unsigned int,keyentry> keys;
+
+static keyentry *get_key(unsigned int key_id)
+{
+ keyentry &key= keys[key_id];
+ if (key.id == 0)
+ return 0;
+ return &key;
+}
+
+/* the version is always the same, no automatic key rotation */
+static unsigned int get_latest_version(uint key_id)
+{
+ return get_key(key_id) ? 1 : ENCRYPTION_KEY_VERSION_INVALID;
+}
+
+static unsigned int get_key_from_key_file(unsigned int key_id,
+ unsigned int key_version, unsigned char* dstbuf, unsigned *buflen)
+{
+ if (key_version != 1)
+ return ENCRYPTION_KEY_VERSION_INVALID;
+
+ keyentry* entry = get_key(key_id);
+
+ if (entry == NULL)
+ return ENCRYPTION_KEY_VERSION_INVALID;
+
+ if (*buflen < entry->length)
+ {
+ *buflen= entry->length;
+ return ENCRYPTION_KEY_BUFFER_TOO_SMALL;
+ }
+
+ *buflen= entry->length;
+ if (dstbuf)
+ memcpy(dstbuf, entry->key, entry->length);
+
+ return 0;
+}
+
+// let's simplify the condition below
+#ifndef HAVE_EncryptAes128Gcm
+#define MY_AES_GCM MY_AES_CTR
+#ifndef HAVE_EncryptAes128Ctr
+#define MY_AES_CTR MY_AES_CBC
+#endif
+#endif
+
+static inline enum my_aes_mode mode(int flags)
+{
+ /*
+ If encryption_algorithm is AES_CTR then
+ if no-padding, use AES_CTR
+ else use AES_GCM (like CTR but appends a "checksum" block)
+ else
+ use AES_CBC
+ */
+ if (encryption_algorithm)
+ if (flags & ENCRYPTION_FLAG_NOPAD)
+ return MY_AES_CTR;
+ else
+ return MY_AES_GCM;
+ else
+ return MY_AES_CBC;
+}
+
+static int ctx_init(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen, int flags,
+ unsigned int key_id, unsigned int key_version)
+{
+ return my_aes_crypt_init(ctx, mode(flags), flags, key, klen, iv, ivlen);
+}
+
+static int ctx_update(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen)
+{
+ return my_aes_crypt_update(ctx, src, slen, dst, dlen);
+}
+
+
+static int ctx_finish(void *ctx, unsigned char *dst, unsigned int *dlen)
+{
+ return my_aes_crypt_finish(ctx, dst, dlen);
+}
+
+static unsigned int get_length(unsigned int slen, unsigned int key_id,
+ unsigned int key_version)
+{
+ return my_aes_get_size(mode(0), slen);
+}
+
+static uint ctx_size(uint, uint)
+{
+ return my_aes_ctx_size(mode(0));
+}
+
+struct st_mariadb_encryption file_key_management_plugin= {
+ MariaDB_ENCRYPTION_INTERFACE_VERSION,
+ get_latest_version,
+ get_key_from_key_file,
+ ctx_size,
+ ctx_init,
+ ctx_update,
+ ctx_finish,
+ get_length
+};
+
+static int file_key_management_plugin_init(void *p)
+{
+ Parser parser(filename, filekey);
+ return parser.parse(&keys);
+}
+
+static int file_key_management_plugin_deinit(void *p)
+{
+ keys.clear();
+ return 0;
+}
+
+/*
+ Plugin library descriptor
+*/
+maria_declare_plugin(file_key_management)
+{
+ MariaDB_ENCRYPTION_PLUGIN,
+ &file_key_management_plugin,
+ "file_key_management",
+ "Denis Endro eperi GmbH",
+ "File-based key management plugin",
+ PLUGIN_LICENSE_GPL,
+ file_key_management_plugin_init,
+ file_key_management_plugin_deinit,
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ settings,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_STABLE
+}
+maria_declare_plugin_end;