summaryrefslogtreecommitdiff
path: root/plugin/example_key_management_plugin/example_key_management_plugin.cc
blob: f590fbb55b8d4feeaee2af9a8f525ba6c0bd9a6e (plain)
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;