Skip to content

Commit 66b9a94

Browse files
committed
New encryption API. Piece-wise encryption.
Instead of encrypt(src, dst, key, iv) that encrypts all data in one go, now we have encrypt_init(key,iv), encrypt_update(src,dst), and encrypt_finish(dst). This also causes collateral changes in the internal my_crypt.cc encryption functions and in the encryption service. There are wrappers to provide the old all-at-once encryption functionality. But binlog events are often written piecewise, they'll need the new api.
1 parent d94a982 commit 66b9a94

24 files changed

+896
-647
lines changed

include/my_crypt.h

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -36,58 +36,54 @@ extern "C" {
3636
/* The max key length of all supported algorithms */
3737
#define MY_AES_MAX_KEY_LENGTH 32
3838

39-
#ifdef HAVE_EncryptAes128Ctr
40-
41-
int my_aes_encrypt_ctr(const uchar* source, uint source_length,
42-
uchar* dest, uint* dest_length,
43-
const uchar* key, uint key_length,
44-
const uchar* iv, uint iv_length);
45-
46-
#define my_aes_decrypt_ctr my_aes_encrypt_ctr
39+
#define MY_AES_CTX_SIZE 512
4740

41+
enum my_aes_mode {
42+
MY_AES_ECB, MY_AES_CBC
43+
#ifdef HAVE_EncryptAes128Ctr
44+
, MY_AES_CTR
4845
#endif
49-
5046
#ifdef HAVE_EncryptAes128Gcm
47+
, MY_AES_GCM
48+
#endif
49+
};
50+
51+
int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags,
52+
const unsigned char* key, unsigned int klen,
53+
const unsigned char* iv, unsigned int ivlen);
54+
int my_aes_crypt_update(void *ctx, const uchar *src, uint slen,
55+
uchar *dst, uint *dlen);
56+
int my_aes_crypt_finish(void *ctx, uchar *dst, uint *dlen);
57+
int my_aes_crypt(enum my_aes_mode mode, int flags,
58+
const uchar *src, uint slen, uchar *dst, uint *dlen,
59+
const uchar *key, uint klen, const uchar *iv, uint ivlen);
5160

52-
int my_aes_encrypt_gcm(const uchar* source, uint source_length,
53-
uchar* dest, uint* dest_length,
54-
const uchar* key, uint key_length,
55-
const uchar* iv, uint iv_length);
56-
57-
int my_aes_decrypt_gcm(const uchar* source, uint source_length,
58-
uchar* dest, uint* dest_length,
59-
const uchar* key, uint key_length,
60-
const uchar* iv, uint iv_length);
61+
/*
62+
calculate the length of the cyphertext from the length of the plaintext
63+
for different AES encryption modes with padding enabled.
64+
Without padding (ENCRYPTION_FLAG_NOPAD) cyphertext has the same length
65+
as the plaintext
66+
*/
67+
static inline uint my_aes_get_size(enum my_aes_mode mode __attribute__((unused)), uint source_length)
68+
{
69+
#ifdef HAVE_EncryptAes128Ctr
70+
if (mode == MY_AES_CTR)
71+
return source_length;
72+
#ifdef HAVE_EncryptAes128Gcm
73+
if (mode == MY_AES_GCM)
74+
return source_length + MY_AES_BLOCK_SIZE;
75+
#endif
6176
#endif
77+
return (source_length / MY_AES_BLOCK_SIZE + 1) * MY_AES_BLOCK_SIZE;
78+
}
6279

63-
int my_aes_encrypt_cbc(const uchar* source, uint source_length,
64-
uchar* dest, uint* dest_length,
65-
const uchar* key, uint key_length,
66-
const uchar* iv, uint iv_length,
67-
int no_padding);
68-
69-
int my_aes_decrypt_cbc(const uchar* source, uint source_length,
70-
uchar* dest, uint* dest_length,
71-
const uchar* key, uint key_length,
72-
const uchar* iv, uint iv_length,
73-
int no_padding);
74-
75-
int my_aes_encrypt_ecb(const uchar* source, uint source_length,
76-
uchar* dest, uint* dest_length,
77-
const uchar* key, uint key_length,
78-
const uchar* iv, uint iv_length,
79-
int no_padding);
80-
81-
int my_aes_decrypt_ecb(const uchar* source, uint source_length,
82-
uchar* dest, uint* dest_length,
83-
const uchar* key, uint key_length,
84-
const uchar* iv, uint iv_length,
85-
int no_padding);
80+
static inline uint my_aes_ctx_size(enum my_aes_mode mode __attribute__((unused)))
81+
{
82+
return MY_AES_CTX_SIZE;
83+
}
8684

8785
int my_random_bytes(uchar* buf, int num);
8886

89-
uint my_aes_get_size(uint source_length);
90-
9187
#ifdef __cplusplus
9288
}
9389
#endif

include/mysql/plugin_audit.h.pp

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -181,21 +181,46 @@
181181
void thd_key_delete(MYSQL_THD_KEY_T *key);
182182
void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key);
183183
int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
184-
typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen,
185-
unsigned char* dst, unsigned int* dlen,
186-
const unsigned char* key, unsigned int klen,
187-
const unsigned char* iv, unsigned int ivlen,
188-
int no_padding, unsigned int key_id,
189-
unsigned int key_version);
190184
struct encryption_service_st {
191-
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
192-
unsigned int (*encryption_key_id_exists_func)(unsigned int);
193-
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
194-
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
195-
encrypt_decrypt_func encryption_encrypt_func;
196-
encrypt_decrypt_func encryption_decrypt_func;
185+
unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
186+
unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
187+
unsigned char* buffer, unsigned int* length);
188+
unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
189+
int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
190+
const unsigned char* iv, unsigned int ivlen,
191+
int flags, unsigned int key_id,
192+
unsigned int key_version);
193+
int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
194+
unsigned char* dst, unsigned int* dlen);
195+
int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
196+
unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
197197
};
198198
extern struct encryption_service_st encryption_handler;
199+
static inline unsigned int encryption_key_id_exists(unsigned int id)
200+
{
201+
return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
202+
}
203+
static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
204+
{
205+
unsigned int unused;
206+
return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
207+
}
208+
static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
209+
unsigned char* dst, unsigned int* dlen,
210+
const unsigned char* key, unsigned int klen,
211+
const unsigned char* iv, unsigned int ivlen,
212+
int flags, unsigned int key_id, unsigned int key_version)
213+
{
214+
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
215+
int res1, res2;
216+
unsigned int d1, d2;
217+
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
218+
return res1;
219+
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
220+
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
221+
*dlen= d1 + d2;
222+
return res1 ? res1 : res2;
223+
}
199224
struct st_encryption_scheme_key {
200225
unsigned int version;
201226
unsigned char key[16];

include/mysql/plugin_auth.h.pp

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -181,21 +181,46 @@
181181
void thd_key_delete(MYSQL_THD_KEY_T *key);
182182
void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key);
183183
int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
184-
typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen,
185-
unsigned char* dst, unsigned int* dlen,
186-
const unsigned char* key, unsigned int klen,
187-
const unsigned char* iv, unsigned int ivlen,
188-
int no_padding, unsigned int key_id,
189-
unsigned int key_version);
190184
struct encryption_service_st {
191-
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
192-
unsigned int (*encryption_key_id_exists_func)(unsigned int);
193-
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
194-
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
195-
encrypt_decrypt_func encryption_encrypt_func;
196-
encrypt_decrypt_func encryption_decrypt_func;
185+
unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
186+
unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
187+
unsigned char* buffer, unsigned int* length);
188+
unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
189+
int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
190+
const unsigned char* iv, unsigned int ivlen,
191+
int flags, unsigned int key_id,
192+
unsigned int key_version);
193+
int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
194+
unsigned char* dst, unsigned int* dlen);
195+
int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
196+
unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
197197
};
198198
extern struct encryption_service_st encryption_handler;
199+
static inline unsigned int encryption_key_id_exists(unsigned int id)
200+
{
201+
return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
202+
}
203+
static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
204+
{
205+
unsigned int unused;
206+
return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
207+
}
208+
static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
209+
unsigned char* dst, unsigned int* dlen,
210+
const unsigned char* key, unsigned int klen,
211+
const unsigned char* iv, unsigned int ivlen,
212+
int flags, unsigned int key_id, unsigned int key_version)
213+
{
214+
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
215+
int res1, res2;
216+
unsigned int d1, d2;
217+
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
218+
return res1;
219+
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
220+
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
221+
*dlen= d1 + d2;
222+
return res1 ? res1 : res2;
223+
}
199224
struct st_encryption_scheme_key {
200225
unsigned int version;
201226
unsigned char key[16];

include/mysql/plugin_encryption.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ struct st_mariadb_encryption
3636
{
3737
int interface_version; /**< version plugin uses */
3838

39+
/*********** KEY MANAGEMENT ********************************************/
40+
3941
/**
4042
function returning latest key version for a given key id
4143
@@ -66,8 +68,17 @@ struct st_mariadb_encryption
6668
unsigned int (*get_key)(unsigned int key_id, unsigned int version,
6769
unsigned char *key, unsigned int *key_length);
6870

69-
encrypt_decrypt_func encrypt;
70-
encrypt_decrypt_func decrypt;
71+
/*********** ENCRYPTION ************************************************/
72+
73+
uint (*crypt_ctx_size)(unsigned int key_id, unsigned int key_version);
74+
int (*crypt_ctx_init)(void *ctx, const unsigned char* key, unsigned int klen,
75+
const unsigned char* iv, unsigned int ivlen,
76+
int flags, unsigned int key_id,
77+
unsigned int key_version);
78+
int (*crypt_ctx_update)(void *ctx, const unsigned char* src, unsigned int slen,
79+
unsigned char* dst, unsigned int* dlen);
80+
int (*crypt_ctx_finish)(void *ctx, unsigned char* dst, unsigned int* dlen);
81+
uint (*encrypted_length)(unsigned int slen, unsigned int key_id, unsigned int key_version);
7182
};
7283
#endif
7384

include/mysql/plugin_encryption.h.pp

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,21 +181,46 @@
181181
void thd_key_delete(MYSQL_THD_KEY_T *key);
182182
void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key);
183183
int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
184-
typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen,
185-
unsigned char* dst, unsigned int* dlen,
186-
const unsigned char* key, unsigned int klen,
187-
const unsigned char* iv, unsigned int ivlen,
188-
int no_padding, unsigned int key_id,
189-
unsigned int key_version);
190184
struct encryption_service_st {
191-
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
192-
unsigned int (*encryption_key_id_exists_func)(unsigned int);
193-
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
194-
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
195-
encrypt_decrypt_func encryption_encrypt_func;
196-
encrypt_decrypt_func encryption_decrypt_func;
185+
unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
186+
unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
187+
unsigned char* buffer, unsigned int* length);
188+
unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
189+
int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
190+
const unsigned char* iv, unsigned int ivlen,
191+
int flags, unsigned int key_id,
192+
unsigned int key_version);
193+
int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
194+
unsigned char* dst, unsigned int* dlen);
195+
int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
196+
unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
197197
};
198198
extern struct encryption_service_st encryption_handler;
199+
static inline unsigned int encryption_key_id_exists(unsigned int id)
200+
{
201+
return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
202+
}
203+
static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
204+
{
205+
unsigned int unused;
206+
return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
207+
}
208+
static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
209+
unsigned char* dst, unsigned int* dlen,
210+
const unsigned char* key, unsigned int klen,
211+
const unsigned char* iv, unsigned int ivlen,
212+
int flags, unsigned int key_id, unsigned int key_version)
213+
{
214+
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
215+
int res1, res2;
216+
unsigned int d1, d2;
217+
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
218+
return res1;
219+
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
220+
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
221+
*dlen= d1 + d2;
222+
return res1 ? res1 : res2;
223+
}
199224
struct st_encryption_scheme_key {
200225
unsigned int version;
201226
unsigned char key[16];
@@ -392,6 +417,13 @@
392417
unsigned int (*get_latest_key_version)(unsigned int key_id);
393418
unsigned int (*get_key)(unsigned int key_id, unsigned int version,
394419
unsigned char *key, unsigned int *key_length);
395-
encrypt_decrypt_func encrypt;
396-
encrypt_decrypt_func decrypt;
420+
uint (*crypt_ctx_size)(unsigned int key_id, unsigned int key_version);
421+
int (*crypt_ctx_init)(void *ctx, const unsigned char* key, unsigned int klen,
422+
const unsigned char* iv, unsigned int ivlen,
423+
int flags, unsigned int key_id,
424+
unsigned int key_version);
425+
int (*crypt_ctx_update)(void *ctx, const unsigned char* src, unsigned int slen,
426+
unsigned char* dst, unsigned int* dlen);
427+
int (*crypt_ctx_finish)(void *ctx, unsigned char* dst, unsigned int* dlen);
428+
uint (*encrypted_length)(unsigned int slen, unsigned int key_id, unsigned int key_version);
397429
};

0 commit comments

Comments
 (0)