Skip to content

Commit

Permalink
New encryption API. Piece-wise encryption.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vuvova committed Sep 4, 2015
1 parent d94a982 commit 66b9a94
Show file tree
Hide file tree
Showing 24 changed files with 896 additions and 647 deletions.
82 changes: 39 additions & 43 deletions include/my_crypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,58 +36,54 @@ extern "C" {
/* The max key length of all supported algorithms */
#define MY_AES_MAX_KEY_LENGTH 32

#ifdef HAVE_EncryptAes128Ctr

int my_aes_encrypt_ctr(const uchar* source, uint source_length,
uchar* dest, uint* dest_length,
const uchar* key, uint key_length,
const uchar* iv, uint iv_length);

#define my_aes_decrypt_ctr my_aes_encrypt_ctr
#define MY_AES_CTX_SIZE 512

enum my_aes_mode {
MY_AES_ECB, MY_AES_CBC
#ifdef HAVE_EncryptAes128Ctr
, MY_AES_CTR
#endif

#ifdef HAVE_EncryptAes128Gcm
, MY_AES_GCM
#endif
};

int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags,
const unsigned char* key, unsigned int klen,
const unsigned char* iv, unsigned int ivlen);
int my_aes_crypt_update(void *ctx, const uchar *src, uint slen,
uchar *dst, uint *dlen);
int my_aes_crypt_finish(void *ctx, uchar *dst, uint *dlen);
int my_aes_crypt(enum my_aes_mode mode, int flags,
const uchar *src, uint slen, uchar *dst, uint *dlen,
const uchar *key, uint klen, const uchar *iv, uint ivlen);

int my_aes_encrypt_gcm(const uchar* source, uint source_length,
uchar* dest, uint* dest_length,
const uchar* key, uint key_length,
const uchar* iv, uint iv_length);

int my_aes_decrypt_gcm(const uchar* source, uint source_length,
uchar* dest, uint* dest_length,
const uchar* key, uint key_length,
const uchar* iv, uint iv_length);
/*
calculate the length of the cyphertext from the length of the plaintext
for different AES encryption modes with padding enabled.
Without padding (ENCRYPTION_FLAG_NOPAD) cyphertext has the same length
as the plaintext
*/
static inline uint my_aes_get_size(enum my_aes_mode mode __attribute__((unused)), uint source_length)
{
#ifdef HAVE_EncryptAes128Ctr
if (mode == MY_AES_CTR)
return source_length;
#ifdef HAVE_EncryptAes128Gcm
if (mode == MY_AES_GCM)
return source_length + MY_AES_BLOCK_SIZE;
#endif
#endif
return (source_length / MY_AES_BLOCK_SIZE + 1) * MY_AES_BLOCK_SIZE;
}

int my_aes_encrypt_cbc(const uchar* source, uint source_length,
uchar* dest, uint* dest_length,
const uchar* key, uint key_length,
const uchar* iv, uint iv_length,
int no_padding);

int my_aes_decrypt_cbc(const uchar* source, uint source_length,
uchar* dest, uint* dest_length,
const uchar* key, uint key_length,
const uchar* iv, uint iv_length,
int no_padding);

int my_aes_encrypt_ecb(const uchar* source, uint source_length,
uchar* dest, uint* dest_length,
const uchar* key, uint key_length,
const uchar* iv, uint iv_length,
int no_padding);

int my_aes_decrypt_ecb(const uchar* source, uint source_length,
uchar* dest, uint* dest_length,
const uchar* key, uint key_length,
const uchar* iv, uint iv_length,
int no_padding);
static inline uint my_aes_ctx_size(enum my_aes_mode mode __attribute__((unused)))
{
return MY_AES_CTX_SIZE;
}

int my_random_bytes(uchar* buf, int num);

uint my_aes_get_size(uint source_length);

#ifdef __cplusplus
}
#endif
Expand Down
49 changes: 37 additions & 12 deletions include/mysql/plugin_audit.h.pp
Original file line number Diff line number Diff line change
Expand Up @@ -181,21 +181,46 @@
void thd_key_delete(MYSQL_THD_KEY_T *key);
void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key);
int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen,
const unsigned char* key, unsigned int klen,
const unsigned char* iv, unsigned int ivlen,
int no_padding, unsigned int key_id,
unsigned int key_version);
struct encryption_service_st {
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
unsigned int (*encryption_key_id_exists_func)(unsigned int);
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
encrypt_decrypt_func encryption_encrypt_func;
encrypt_decrypt_func encryption_decrypt_func;
unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
unsigned char* buffer, unsigned int* length);
unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
int (*encryption_ctx_init_func)(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);
int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen);
int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
};
extern struct encryption_service_st encryption_handler;
static inline unsigned int encryption_key_id_exists(unsigned int id)
{
return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
}
static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
{
unsigned int unused;
return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
}
static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen,
const unsigned char* key, unsigned int klen,
const unsigned char* iv, unsigned int ivlen,
int flags, unsigned int key_id, unsigned int key_version)
{
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
int res1, res2;
unsigned int d1, d2;
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
return res1;
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
*dlen= d1 + d2;
return res1 ? res1 : res2;
}
struct st_encryption_scheme_key {
unsigned int version;
unsigned char key[16];
Expand Down
49 changes: 37 additions & 12 deletions include/mysql/plugin_auth.h.pp
Original file line number Diff line number Diff line change
Expand Up @@ -181,21 +181,46 @@
void thd_key_delete(MYSQL_THD_KEY_T *key);
void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key);
int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen,
const unsigned char* key, unsigned int klen,
const unsigned char* iv, unsigned int ivlen,
int no_padding, unsigned int key_id,
unsigned int key_version);
struct encryption_service_st {
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
unsigned int (*encryption_key_id_exists_func)(unsigned int);
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
encrypt_decrypt_func encryption_encrypt_func;
encrypt_decrypt_func encryption_decrypt_func;
unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
unsigned char* buffer, unsigned int* length);
unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
int (*encryption_ctx_init_func)(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);
int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen);
int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
};
extern struct encryption_service_st encryption_handler;
static inline unsigned int encryption_key_id_exists(unsigned int id)
{
return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
}
static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
{
unsigned int unused;
return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
}
static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen,
const unsigned char* key, unsigned int klen,
const unsigned char* iv, unsigned int ivlen,
int flags, unsigned int key_id, unsigned int key_version)
{
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
int res1, res2;
unsigned int d1, d2;
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
return res1;
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
*dlen= d1 + d2;
return res1 ? res1 : res2;
}
struct st_encryption_scheme_key {
unsigned int version;
unsigned char key[16];
Expand Down
15 changes: 13 additions & 2 deletions include/mysql/plugin_encryption.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ struct st_mariadb_encryption
{
int interface_version; /**< version plugin uses */

/*********** KEY MANAGEMENT ********************************************/

/**
function returning latest key version for a given key id
Expand Down Expand Up @@ -66,8 +68,17 @@ struct st_mariadb_encryption
unsigned int (*get_key)(unsigned int key_id, unsigned int version,
unsigned char *key, unsigned int *key_length);

encrypt_decrypt_func encrypt;
encrypt_decrypt_func decrypt;
/*********** ENCRYPTION ************************************************/

uint (*crypt_ctx_size)(unsigned int key_id, unsigned int key_version);
int (*crypt_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);
int (*crypt_ctx_update)(void *ctx, const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen);
int (*crypt_ctx_finish)(void *ctx, unsigned char* dst, unsigned int* dlen);
uint (*encrypted_length)(unsigned int slen, unsigned int key_id, unsigned int key_version);
};
#endif

60 changes: 46 additions & 14 deletions include/mysql/plugin_encryption.h.pp
Original file line number Diff line number Diff line change
Expand Up @@ -181,21 +181,46 @@
void thd_key_delete(MYSQL_THD_KEY_T *key);
void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key);
int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value);
typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen,
const unsigned char* key, unsigned int klen,
const unsigned char* iv, unsigned int ivlen,
int no_padding, unsigned int key_id,
unsigned int key_version);
struct encryption_service_st {
unsigned int (*encryption_key_get_latest_version_func)(unsigned int);
unsigned int (*encryption_key_id_exists_func)(unsigned int);
unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int);
unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*);
encrypt_decrypt_func encryption_encrypt_func;
encrypt_decrypt_func encryption_decrypt_func;
unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
unsigned char* buffer, unsigned int* length);
unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
int (*encryption_ctx_init_func)(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);
int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen);
int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
};
extern struct encryption_service_st encryption_handler;
static inline unsigned int encryption_key_id_exists(unsigned int id)
{
return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
}
static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
{
unsigned int unused;
return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
}
static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen,
const unsigned char* key, unsigned int klen,
const unsigned char* iv, unsigned int ivlen,
int flags, unsigned int key_id, unsigned int key_version)
{
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
int res1, res2;
unsigned int d1, d2;
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
return res1;
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
*dlen= d1 + d2;
return res1 ? res1 : res2;
}
struct st_encryption_scheme_key {
unsigned int version;
unsigned char key[16];
Expand Down Expand Up @@ -392,6 +417,13 @@
unsigned int (*get_latest_key_version)(unsigned int key_id);
unsigned int (*get_key)(unsigned int key_id, unsigned int version,
unsigned char *key, unsigned int *key_length);
encrypt_decrypt_func encrypt;
encrypt_decrypt_func decrypt;
uint (*crypt_ctx_size)(unsigned int key_id, unsigned int key_version);
int (*crypt_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);
int (*crypt_ctx_update)(void *ctx, const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen);
int (*crypt_ctx_finish)(void *ctx, unsigned char* dst, unsigned int* dlen);
uint (*encrypted_length)(unsigned int slen, unsigned int key_id, unsigned int key_version);
};
Loading

0 comments on commit 66b9a94

Please sign in to comment.