summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-08-13 15:58:50 +0200
committerSergei Golubchik <serg@mariadb.org>2015-08-30 15:31:52 +0200
commit009e2a1a44479f6f465b46151d39ce099e8eb2fb (patch)
tree8214dd0458aa07f65a8a09cf41a897e4e3da5735
parent0acea15ac7ad73d34560e5dceb5ca84408247a27 (diff)
downloadmariadb-git-009e2a1a44479f6f465b46151d39ce099e8eb2fb.tar.gz
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.
-rw-r--r--include/my_crypt.h82
-rw-r--r--include/mysql/plugin_audit.h.pp49
-rw-r--r--include/mysql/plugin_auth.h.pp49
-rw-r--r--include/mysql/plugin_encryption.h15
-rw-r--r--include/mysql/plugin_encryption.h.pp60
-rw-r--r--include/mysql/plugin_ftparser.h.pp49
-rw-r--r--include/mysql/plugin_password_validation.h.pp49
-rw-r--r--include/mysql/service_encryption.h75
-rw-r--r--mysys/mf_iocache.c2
-rw-r--r--mysys_ssl/my_crypt.cc476
-rw-r--r--plugin/debug_key_management/debug_key_management_plugin.cc3
-rw-r--r--plugin/example_key_management/example_key_management_plugin.cc35
-rw-r--r--plugin/file_key_management/file_key_management_plugin.cc92
-rw-r--r--plugin/file_key_management/parser.cc9
-rw-r--r--sql/encryption.cc65
-rw-r--r--sql/item_strfunc.cc16
-rw-r--r--sql/item_strfunc.h5
-rw-r--r--sql/log_event.cc11
-rw-r--r--sql/log_event.h2
-rw-r--r--sql/mf_iocache_encr.cc16
-rw-r--r--storage/innobase/log/log0crypt.cc42
-rw-r--r--storage/maria/ma_check_standalone.h2
-rw-r--r--storage/xtradb/log/log0crypt.cc40
-rw-r--r--unittest/mysys/aes-t.c69
-rw-r--r--unittest/sql/mf_iocache-t.cc33
25 files changed, 713 insertions, 633 deletions
diff --git a/include/my_crypt.h b/include/my_crypt.h
index 3e6da6aa212..6a62b58f322 100644
--- a/include/my_crypt.h
+++ b/include/my_crypt.h
@@ -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 256
+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, 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
diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp
index 5a10835be56..73265c971db 100644
--- a/include/mysql/plugin_audit.h.pp
+++ b/include/mysql/plugin_audit.h.pp
@@ -181,21 +181,46 @@ int thd_key_create(MYSQL_THD_KEY_T *key);
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);
+ uint (*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);
+ uint (*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(uint id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(uint id, uint version)
+{
+ uint 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;
+ uint 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];
diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp
index 97aca99b257..4d385568482 100644
--- a/include/mysql/plugin_auth.h.pp
+++ b/include/mysql/plugin_auth.h.pp
@@ -181,21 +181,46 @@ int thd_key_create(MYSQL_THD_KEY_T *key);
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);
+ uint (*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);
+ uint (*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(uint id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(uint id, uint version)
+{
+ uint 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;
+ uint 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];
diff --git a/include/mysql/plugin_encryption.h b/include/mysql/plugin_encryption.h
index 90979017101..673599bfaf3 100644
--- a/include/mysql/plugin_encryption.h
+++ b/include/mysql/plugin_encryption.h
@@ -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
@@ -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
diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp
index 36b4eca0473..1f6781821e1 100644
--- a/include/mysql/plugin_encryption.h.pp
+++ b/include/mysql/plugin_encryption.h.pp
@@ -181,21 +181,46 @@ int thd_key_create(MYSQL_THD_KEY_T *key);
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);
+ uint (*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);
+ uint (*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(uint id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(uint id, uint version)
+{
+ uint 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;
+ uint 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];
@@ -392,6 +417,13 @@ struct st_mariadb_encryption
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);
};
diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp
index 29b24c0fafa..6db75c62208 100644
--- a/include/mysql/plugin_ftparser.h.pp
+++ b/include/mysql/plugin_ftparser.h.pp
@@ -181,21 +181,46 @@ int thd_key_create(MYSQL_THD_KEY_T *key);
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);
+ uint (*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);
+ uint (*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(uint id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(uint id, uint version)
+{
+ uint 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;
+ uint 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];
diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp
index 8d3a300f02c..a16537476c4 100644
--- a/include/mysql/plugin_password_validation.h.pp
+++ b/include/mysql/plugin_password_validation.h.pp
@@ -181,21 +181,46 @@ int thd_key_create(MYSQL_THD_KEY_T *key);
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);
+ uint (*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);
+ uint (*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(uint id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(uint id, uint version)
+{
+ uint 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;
+ uint 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];
diff --git a/include/mysql/service_encryption.h b/include/mysql/service_encryption.h
index 2b79e00fa40..b622007a397 100644
--- a/include/mysql/service_encryption.h
+++ b/include/mysql/service_encryption.h
@@ -20,7 +20,7 @@
Functions to support data encryption and encryption key management.
They are normally implemented in an encryption plugin, so this service
- connects encryption *consumers* (storage engines) to the encryption
+ connects encryption *consumers* (e.g. storage engines) to the encryption
*provider* (encryption plugin).
*/
@@ -38,20 +38,23 @@ extern "C" {
/* returned from encryption_key_get() */
#define ENCRYPTION_KEY_BUFFER_TOO_SMALL (100)
-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);
+#define ENCRYPTION_FLAG_ENCRYPT 0
+#define ENCRYPTION_FLAG_DECRYPT 1
+#define ENCRYPTION_FLAG_NOPAD 2
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);
+ uint (*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);
+ uint (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
};
#ifdef MYSQL_DYNAMIC_PLUGIN
@@ -59,23 +62,53 @@ struct encryption_service_st {
extern struct encryption_service_st *encryption_service;
#define encryption_key_get_latest_version(KI) encryption_service->encryption_key_get_latest_version_func(KI)
-#define encryption_key_id_exists(KI) encryption_service->encryption_key_id_exists_func((KI))
-#define encryption_key_version_exists(KI,KV) encryption_service->encryption_key_version_exists_func((KI),(KV))
#define encryption_key_get(KI,KV,K,S) encryption_service->encryption_key_get_func((KI),(KV),(K),(S))
-#define encryption_encrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_service->encryption_encrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV))
-#define encryption_decrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_service->encryption_decrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV))
+#define encryption_ctx_size(KI,KV) encryption_service->encryption_ctx_size_func((KI),(KV))
+#define encryption_ctx_init(CTX,K,KL,IV,IVL,F,KI,KV) encryption_service->encryption_ctx_init_func((CTX),(K),(KL),(IV),(IVL),(F),(KI),(KV))
+#define encryption_ctx_update(CTX,S,SL,D,DL) encryption_service->encryption_ctx_update_func((CTX),(S),(SL),(D),(DL))
+#define encryption_ctx_finish(CTX,D,DL) encryption_service->encryption_ctx_finish_func((CTX),(D),(DL))
+#define encryption_encrypted_length(SL,KI,KV) encryption_service->encryption_encrypted_length_func((SL),(KI),(KV))
#else
extern struct encryption_service_st encryption_handler;
#define encryption_key_get_latest_version(KI) encryption_handler.encryption_key_get_latest_version_func(KI)
-#define encryption_key_id_exists(KI) encryption_handler.encryption_key_id_exists_func((KI))
-#define encryption_key_version_exists(KI,KV) encryption_handler.encryption_key_version_exists_func((KI),(KV))
#define encryption_key_get(KI,KV,K,S) encryption_handler.encryption_key_get_func((KI),(KV),(K),(S))
-#define encryption_encrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_handler.encryption_encrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV))
-#define encryption_decrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_handler.encryption_decrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV))
+#define encryption_ctx_size(KI,KV) encryption_handler.encryption_ctx_size_func((KI),(KV))
+#define encryption_ctx_init(CTX,K,KL,IV,IVL,F,KI,KV) encryption_handler.encryption_ctx_init_func((CTX),(K),(KL),(IV),(IVL),(F),(KI),(KV))
+#define encryption_ctx_update(CTX,S,SL,D,DL) encryption_handler.encryption_ctx_update_func((CTX),(S),(SL),(D),(DL))
+#define encryption_ctx_finish(CTX,D,DL) encryption_handler.encryption_ctx_finish_func((CTX),(D),(DL))
+#define encryption_encrypted_length(SL,KI,KV) encryption_handler.encryption_encrypted_length_func((SL),(KI),(KV))
#endif
+static inline unsigned int encryption_key_id_exists(uint id)
+{
+ return encryption_key_get_latest_version(id) != ENCRYPTION_KEY_VERSION_INVALID;
+}
+
+static inline unsigned int encryption_key_version_exists(uint id, uint version)
+{
+ uint unused;
+ return encryption_key_get(id, version, NULL, &unused) != ENCRYPTION_KEY_VERSION_INVALID;
+}
+
+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_ctx_size(key_id, key_version));
+ int res1, res2;
+ uint d1, d2;
+ if ((res1= encryption_ctx_init(ctx, key, klen, iv, ivlen, flags, key_id, key_version)))
+ return res1;
+ res1= encryption_ctx_update(ctx, src, slen, dst, &d1);
+ res2= encryption_ctx_finish(ctx, dst + d1, &d2);
+ *dlen= d1 + d2;
+ return res1 ? res1 : res2;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 4591557baf0..28e5e72130d 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -265,7 +265,7 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
if (type == SEQ_READ_APPEND)
buffer_block *= 2;
else if (cache_myflags & MY_ENCRYPT)
- buffer_block= 2*my_aes_get_size(buffer_block) + sizeof(IO_CACHE_CRYPT);
+ buffer_block= 2*(buffer_block + MY_AES_BLOCK_SIZE) + sizeof(IO_CACHE_CRYPT);
if (cachesize == min_cache)
flags|= (myf) MY_WME;
diff --git a/mysys_ssl/my_crypt.cc b/mysys_ssl/my_crypt.cc
index dc3c4f63bdb..8d6f7bdb498 100644
--- a/mysys_ssl/my_crypt.cc
+++ b/mysys_ssl/my_crypt.cc
@@ -16,22 +16,9 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <my_global.h>
+#include <string.h>
#include <my_crypt.h>
-#ifdef HAVE_YASSL
-#include "aes.hpp"
-
-typedef TaoCrypt::CipherDir Dir;
-static const Dir CRYPT_ENCRYPT = TaoCrypt::ENCRYPTION;
-static const Dir CRYPT_DECRYPT = TaoCrypt::DECRYPTION;
-
-typedef TaoCrypt::Mode CipherMode;
-static inline CipherMode aes_ecb(uint) { return TaoCrypt::ECB; }
-static inline CipherMode aes_cbc(uint) { return TaoCrypt::CBC; }
-
-typedef TaoCrypt::byte KeyByte;
-
-#else
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/err.h>
@@ -42,173 +29,141 @@ static const Dir CRYPT_DECRYPT = 0;
typedef const EVP_CIPHER *CipherMode;
-#define make_aes_dispatcher(mode) \
- static inline CipherMode aes_ ## mode(uint key_length) \
- { \
- switch (key_length) { \
- case 16: return EVP_aes_128_ ## mode(); \
- case 24: return EVP_aes_192_ ## mode(); \
- case 32: return EVP_aes_256_ ## mode(); \
- default: return 0; \
- } \
- }
-
-make_aes_dispatcher(ecb)
-make_aes_dispatcher(cbc)
-
typedef uchar KeyByte;
-struct MyCTX : EVP_CIPHER_CTX {
- MyCTX() { EVP_CIPHER_CTX_init(this); }
- ~MyCTX() { EVP_CIPHER_CTX_cleanup(this); ERR_remove_state(0); }
-};
-#endif
-
-static int block_crypt(CipherMode cipher, Dir dir,
- const uchar* source, uint source_length,
- uchar* dest, uint* dest_length,
- const KeyByte *key, uint key_length,
- const KeyByte *iv, uint iv_length, int no_padding)
+class MyCTX
{
- int tail= source_length % MY_AES_BLOCK_SIZE;
+public:
+ EVP_CIPHER_CTX ctx;
+ MyCTX() { EVP_CIPHER_CTX_init(&ctx); }
+ virtual ~MyCTX() { EVP_CIPHER_CTX_cleanup(&ctx); ERR_remove_state(0); }
- if (likely(source_length >= MY_AES_BLOCK_SIZE || !no_padding))
+ virtual int init(CipherMode cipher, Dir dir, const KeyByte *key, uint klen,
+ const KeyByte *iv, uint ivlen)
{
-#ifdef HAVE_YASSL
- TaoCrypt::AES ctx(dir, cipher);
-
- if (unlikely(key_length != 16 && key_length != 24 && key_length != 32))
- return MY_AES_BAD_KEYSIZE;
-
- ctx.SetKey(key, key_length);
- if (iv)
- {
- ctx.SetIV(iv);
- DBUG_ASSERT(TaoCrypt::AES::BLOCK_SIZE <= iv_length);
- }
- DBUG_ASSERT(TaoCrypt::AES::BLOCK_SIZE == MY_AES_BLOCK_SIZE);
-
- ctx.Process(dest, source, source_length - tail);
- *dest_length= source_length - tail;
-
- /* unlike OpenSSL, YaSSL doesn't support PKCS#7 padding */
- if (!no_padding)
- {
- if (dir == CRYPT_ENCRYPT)
- {
- uchar buf[MY_AES_BLOCK_SIZE];
- memcpy(buf, source + source_length - tail, tail);
- memset(buf + tail, MY_AES_BLOCK_SIZE - tail, MY_AES_BLOCK_SIZE - tail);
- ctx.Process(dest + *dest_length, buf, MY_AES_BLOCK_SIZE);
- *dest_length+= MY_AES_BLOCK_SIZE;
- }
- else
- {
- int n= source_length ? dest[source_length - 1] : 0;
- if (tail || n == 0 || n > MY_AES_BLOCK_SIZE)
- return MY_AES_BAD_DATA;
- *dest_length-= n;
- }
- }
-
-#else // HAVE_OPENSSL
- int fin;
- struct MyCTX ctx;
-
if (unlikely(!cipher))
return MY_AES_BAD_KEYSIZE;
if (!EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, dir))
return MY_AES_OPENSSL_ERROR;
- EVP_CIPHER_CTX_set_padding(&ctx, !no_padding);
+ DBUG_ASSERT(EVP_CIPHER_CTX_key_length(&ctx) == (int)klen);
+ DBUG_ASSERT(EVP_CIPHER_CTX_iv_length(&ctx) <= (int)ivlen);
- DBUG_ASSERT(EVP_CIPHER_CTX_key_length(&ctx) == (int)key_length);
- DBUG_ASSERT(EVP_CIPHER_CTX_iv_length(&ctx) <= (int)iv_length);
- DBUG_ASSERT(EVP_CIPHER_CTX_block_size(&ctx) == MY_AES_BLOCK_SIZE);
-
- /* use built-in OpenSSL padding, if possible */
- if (!EVP_CipherUpdate(&ctx, dest, (int*)dest_length,
- source, source_length - (no_padding ? tail : 0)))
+ return MY_AES_OK;
+ }
+ virtual int update(const uchar *src, uint slen, uchar *dst, uint *dlen)
+ {
+ if (!EVP_CipherUpdate(&ctx, dst, (int*)dlen, src, slen))
return MY_AES_OPENSSL_ERROR;
- if (!EVP_CipherFinal_ex(&ctx, dest + *dest_length, &fin))
+ return MY_AES_OK;
+ }
+ virtual int finish(uchar *dst, uint *dlen)
+ {
+ if (!EVP_CipherFinal_ex(&ctx, dst, (int*)dlen))
return MY_AES_BAD_DATA;
- *dest_length += fin;
+ return MY_AES_OK;
+ }
+};
-#endif
+class MyCTX_nopad : public MyCTX
+{
+public:
+ uchar tail[MY_AES_BLOCK_SIZE], iv[MY_AES_BLOCK_SIZE];
+ const uchar *key;
+ int klen, ivlen, tail_len;
+
+ MyCTX_nopad() : MyCTX(), tail_len(0) { }
+ ~MyCTX_nopad() { }
+
+ int init(CipherMode cipher, Dir dir, const KeyByte *key, uint klen,
+ const KeyByte *iv, uint ivlen)
+ {
+ compile_time_assert(MY_AES_CTX_SIZE >= sizeof(MyCTX_nopad));
+ this->key= key;
+ this->klen= klen;
+ if (iv)
+ memcpy(this->iv, iv, sizeof(this->iv));
+ this->ivlen= ivlen;
+ int res= MyCTX::init(cipher, dir, key, klen, this->iv, sizeof(this->iv));
+ EVP_CIPHER_CTX_set_padding(&ctx, 0);
+ return res;
}
- if (no_padding)
+ int update(const uchar *src, uint slen, uchar *dst, uint *dlen)
+ {
+ *dlen= 0;
+ if (tail_len)
+ {
+ uint head_len= MY_AES_BLOCK_SIZE - tail_len;
+ if (head_len > slen)
+ {
+ memcpy(tail + tail_len, src, slen);
+ tail_len+= slen;
+ return MY_AES_OK;
+ }
+ memcpy(tail + tail_len, src, head_len);
+ int dst_len;
+ if (!EVP_CipherUpdate(&ctx, dst, &dst_len, tail, MY_AES_BLOCK_SIZE))
+ return MY_AES_OPENSSL_ERROR;
+ src+= head_len;
+ slen-= head_len;
+ dst+= dst_len;
+ *dlen+= dst_len;
+ }
+ tail_len= slen % MY_AES_BLOCK_SIZE;
+ slen-= tail_len;
+ memcpy(tail, src + slen, tail_len);
+ if (slen)
+ {
+ int dst_len;
+ if (!EVP_CipherUpdate(&ctx, dst, &dst_len, src, slen))
+ return MY_AES_OPENSSL_ERROR;
+ *dlen+= dst_len;
+ }
+ return MY_AES_OK;
+ }
+ int finish(uchar *dst, uint *dlen)
{
- if (tail)
+ if (tail_len)
{
/*
Not much we can do, block ciphers cannot encrypt data that aren't
a multiple of the block length. At least not without padding.
Let's do something CTR-like for the last partial block.
*/
-
uchar mask[MY_AES_BLOCK_SIZE];
uint mlen;
- DBUG_ASSERT(iv_length >= sizeof(mask));
- my_aes_encrypt_ecb(iv, sizeof(mask), mask, &mlen,
- key, key_length, 0, 0, 1);
+ DBUG_ASSERT(ivlen >= (int)sizeof(mask));
+ my_aes_crypt(MY_AES_ECB, ENCRYPTION_FLAG_ENCRYPT | ENCRYPTION_FLAG_NOPAD,
+ iv, sizeof(mask), mask, &mlen, key, klen, 0, 0);
DBUG_ASSERT(mlen == sizeof(mask));
- const uchar *s= source + source_length - tail;
- const uchar *e= source + source_length;
- uchar *d= dest + source_length - tail;
- const uchar *m= mask;
- while (s < e)
- *d++ = *s++ ^ *m++;
+ for (int i=0; i < tail_len; i++)
+ dst[i]= tail[i] ^ mask[i];
}
- *dest_length= source_length;
+ *dlen= tail_len;
+ return MY_AES_OK;
}
+};
- return MY_AES_OK;
-}
-
-C_MODE_START
+#define make_aes_dispatcher(mode) \
+ static inline CipherMode aes_ ## mode(uint klen) \
+ { \
+ switch (klen) { \
+ case 16: return EVP_aes_128_ ## mode(); \
+ case 24: return EVP_aes_192_ ## mode(); \
+ case 32: return EVP_aes_256_ ## mode(); \
+ default: return 0; \
+ } \
+ }
+make_aes_dispatcher(ecb)
+make_aes_dispatcher(cbc)
#ifdef HAVE_EncryptAes128Ctr
make_aes_dispatcher(ctr)
-
-/*
- special simplified implementation for CTR, because it's a stream cipher
- (doesn't need padding, always encrypts the specified number of bytes), and
- because encrypting and decrypting code is exactly the same (courtesy of XOR)
-*/
-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)
-{
- CipherMode cipher= aes_ctr(key_length);
- struct MyCTX ctx;
- int fin __attribute__((unused));
-
- if (unlikely(!cipher))
- return MY_AES_BAD_KEYSIZE;
-
- if (!EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, CRYPT_ENCRYPT))
- return MY_AES_OPENSSL_ERROR;
-
- DBUG_ASSERT(EVP_CIPHER_CTX_key_length(&ctx) == (int)key_length);
- DBUG_ASSERT(EVP_CIPHER_CTX_iv_length(&ctx) <= (int)iv_length);
- DBUG_ASSERT(EVP_CIPHER_CTX_block_size(&ctx) == 1);
-
- if (!EVP_CipherUpdate(&ctx, dest, (int*)dest_length, source, source_length))
- return MY_AES_OPENSSL_ERROR;
-
- DBUG_ASSERT(EVP_CipherFinal_ex(&ctx, dest + *dest_length, &fin));
- DBUG_ASSERT(fin == 0);
-
- return MY_AES_OK;
-}
-
#endif /* HAVE_EncryptAes128Ctr */
-
#ifdef HAVE_EncryptAes128Gcm
make_aes_dispatcher(gcm)
@@ -218,145 +173,145 @@ make_aes_dispatcher(gcm)
- IV tail (over 12 bytes) goes to AAD
- the tag is appended to the ciphertext
*/
-int do_gcm(const uchar* source, uint source_length,
- uchar* dest, uint* dest_length,
- const uchar* key, uint key_length,
- const uchar* iv, uint iv_length, Dir dir)
-{
- CipherMode cipher= aes_gcm(key_length);
- struct MyCTX ctx;
- int fin;
- uint real_iv_length;
- if (unlikely(!cipher))
- return MY_AES_BAD_KEYSIZE;
-
- if (!EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, dir))
- return MY_AES_OPENSSL_ERROR;
-
- real_iv_length= EVP_CIPHER_CTX_iv_length(&ctx);
-
- DBUG_ASSERT(EVP_CIPHER_CTX_key_length(&ctx) == (int)key_length);
- DBUG_ASSERT(real_iv_length <= iv_length);
- DBUG_ASSERT(EVP_CIPHER_CTX_block_size(&ctx) == 1);
-
- if (dir == CRYPT_DECRYPT)
+class MyCTX_gcm : public MyCTX
+{
+public:
+ Dir dir;
+ const uchar *aad;
+ int aadlen;
+ MyCTX_gcm() : MyCTX() { }
+ ~MyCTX_gcm() { }
+
+ int init(CipherMode cipher, Dir dir, const KeyByte *key, uint klen,
+ const KeyByte *iv, uint ivlen)
{
- source_length-= MY_AES_BLOCK_SIZE;
- if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, MY_AES_BLOCK_SIZE,
- (void*)(source + source_length)))
- return MY_AES_OPENSSL_ERROR;
+ compile_time_assert(MY_AES_CTX_SIZE >= sizeof(MyCTX_gcm));
+ int res= MyCTX::init(cipher, dir, key, klen, iv, ivlen);
+ this->dir= dir;
+ int real_ivlen= EVP_CIPHER_CTX_iv_length(&ctx);
+ aad= iv + real_ivlen;
+ aadlen= ivlen - real_ivlen;
+ return res;
}
- if (real_iv_length < iv_length)
+ int update(const uchar *src, uint slen, uchar *dst, uint *dlen)
{
- if (!EVP_CipherUpdate(&ctx, NULL, &fin,
- iv + real_iv_length, iv_length - real_iv_length))
+ /*
+ note that this GCM class cannot do streaming decryption, because
+ it needs the tag (which is located at the end of encrypted data)
+ before decrypting the data. it can encrypt data piecewise, like, first
+ half, then the second half, but it must decrypt all at once
+ */
+ if (dir == CRYPT_DECRYPT)
+ {
+ slen-= MY_AES_BLOCK_SIZE;
+ if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, MY_AES_BLOCK_SIZE,
+ (void*)(src + slen)))
+ return MY_AES_OPENSSL_ERROR;
+ }
+ int unused;
+ if (aadlen && !EVP_CipherUpdate(&ctx, NULL, &unused, aad, aadlen))
return MY_AES_OPENSSL_ERROR;
+ aadlen= 0;
+ return MyCTX::update(src, slen, dst, dlen);
}
- if (!EVP_CipherUpdate(&ctx, dest, (int*)dest_length, source, source_length))
- return MY_AES_OPENSSL_ERROR;
-
- if (!EVP_CipherFinal_ex(&ctx, dest + *dest_length, &fin))
- return MY_AES_BAD_DATA;
- DBUG_ASSERT(fin == 0);
-
- if (dir == CRYPT_ENCRYPT)
+ int finish(uchar *dst, uint *dlen)
{
- if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, MY_AES_BLOCK_SIZE,
- dest + *dest_length))
- return MY_AES_OPENSSL_ERROR;
- *dest_length+= MY_AES_BLOCK_SIZE;
- }
+ int fin;
+ if (!EVP_CipherFinal_ex(&ctx, dst, &fin))
+ return MY_AES_BAD_DATA;
+ DBUG_ASSERT(fin == 0);
- return MY_AES_OK;
-}
+ if (dir == CRYPT_ENCRYPT)
+ {
+ if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, MY_AES_BLOCK_SIZE, dst))
+ return MY_AES_OPENSSL_ERROR;
+ *dlen= MY_AES_BLOCK_SIZE;
+ }
+ else
+ *dlen= 0;
+ return MY_AES_OK;
+ }
+};
-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)
-{
- return do_gcm(source, source_length, dest, dest_length,
- key, key_length, iv, iv_length, CRYPT_ENCRYPT);
-}
+#endif
-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)
-{
- return do_gcm(source, source_length, dest, dest_length,
- key, key_length, iv, iv_length, CRYPT_DECRYPT);
-}
+C_MODE_START
+CipherMode (*ciphers[])(uint)= {
+ aes_ecb, aes_cbc
+#ifdef HAVE_EncryptAes128Ctr
+ , aes_ctr
+#ifdef HAVE_EncryptAes128Gcm
+ , aes_gcm
#endif
+#endif
+};
-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)
-{
- return block_crypt(aes_ecb(key_length), CRYPT_ENCRYPT, source, source_length,
- dest, dest_length, key, key_length, iv, iv_length, no_padding);
-}
+Dir dirs[2]= { CRYPT_ENCRYPT, CRYPT_DECRYPT };
-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)
+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)
{
- return block_crypt(aes_ecb(key_length), CRYPT_DECRYPT, source, source_length,
- dest, dest_length, key, key_length, iv, iv_length, no_padding);
+#ifdef HAVE_EncryptAes128Ctr
+#ifdef HAVE_EncryptAes128Gcm
+ if (mode == MY_AES_GCM)
+ if (flags & ENCRYPTION_FLAG_NOPAD)
+ return MY_AES_OPENSSL_ERROR;
+ else
+ new (ctx) MyCTX_gcm();
+ else
+#endif
+ if (mode == MY_AES_CTR)
+ new (ctx) MyCTX();
+ else
+#endif
+ if (flags & ENCRYPTION_FLAG_NOPAD)
+ new (ctx) MyCTX_nopad();
+ else
+ new (ctx) MyCTX();
+ return ((MyCTX*)ctx)->init(ciphers[mode](klen), dirs[flags & 1],
+ key, klen, iv, ivlen);
}
-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_crypt_update(void *ctx, const uchar *src, uint slen,
+ uchar *dst, uint *dlen)
{
- return block_crypt(aes_cbc(key_length), CRYPT_ENCRYPT, source, source_length,
- dest, dest_length, key, key_length, iv, iv_length, no_padding);
+ return ((MyCTX*)ctx)->update(src, slen, dst, dlen);
}
-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_crypt_finish(void *ctx, uchar *dst, uint *dlen)
{
- return block_crypt(aes_cbc(key_length), CRYPT_DECRYPT, source, source_length,
- dest, dest_length, key, key_length, iv, iv_length, no_padding);
+ int res= ((MyCTX*)ctx)->finish(dst, dlen);
+ ((MyCTX*)ctx)->~MyCTX();
+ return res;
}
-C_MODE_END
-
-#if defined(HAVE_YASSL)
-
-#include <random.hpp>
-
-C_MODE_START
-
-int my_random_bytes(uchar* buf, int num)
+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)
{
- TaoCrypt::RandomNumberGenerator rand;
- rand.GenerateBlock((TaoCrypt::byte*) buf, num);
- return MY_AES_OK;
+ void *ctx= alloca(MY_AES_CTX_SIZE);
+ int res1, res2;
+ uint d1, d2;
+ if ((res1= my_aes_crypt_init(ctx, mode, flags, key, klen, iv, ivlen)))
+ return res1;
+ res1= my_aes_crypt_update(ctx, src, slen, dst, &d1);
+ res2= my_aes_crypt_finish(ctx, dst + d1, &d2);
+ *dlen= d1 + d2;
+ return res1 ? res1 : res2;
}
C_MODE_END
-#else /* OpenSSL */
-
#include <openssl/rand.h>
C_MODE_START
-int my_random_bytes(uchar* buf, int num)
+int my_random_bytes(uchar *buf, int num)
{
/*
Unfortunately RAND_bytes manual page does not provide any guarantees
@@ -364,30 +319,11 @@ int my_random_bytes(uchar* buf, int num)
instead of whatever random engine is currently set in OpenSSL. That way
we are guaranteed to have a non-blocking random.
*/
- RAND_METHOD* rand = RAND_SSLeay();
+ RAND_METHOD *rand = RAND_SSLeay();
if (rand == NULL || rand->bytes(buf, num) != 1)
return MY_AES_OPENSSL_ERROR;
return MY_AES_OK;
}
C_MODE_END
-#endif /* HAVE_YASSL */
-
-/**
- Get size of buffer which will be large enough for encrypted data
-
- The buffer should be sufficiently large to fit encrypted data
- independently from the encryption algorithm and mode. With padding up to
- MY_AES_BLOCK_SIZE bytes can be added. With GCM, exactly MY_AES_BLOCK_SIZE
- bytes are added.
-
- The actual length of the encrypted data is returned from the encryption
- function (e.g. from my_aes_encrypt_cbc).
- @return required buffer size
-*/
-
-uint my_aes_get_size(uint source_length)
-{
- return source_length + MY_AES_BLOCK_SIZE;
-}
diff --git a/plugin/debug_key_management/debug_key_management_plugin.cc b/plugin/debug_key_management/debug_key_management_plugin.cc
index 33e0c6ab318..23ff78dece2 100644
--- a/plugin/debug_key_management/debug_key_management_plugin.cc
+++ b/plugin/debug_key_management/debug_key_management_plugin.cc
@@ -74,7 +74,8 @@ struct st_mariadb_encryption debug_key_management_plugin= {
MariaDB_ENCRYPTION_INTERFACE_VERSION,
get_latest_key_version,
get_key,
- 0, 0 // use default encrypt/decrypt functions
+ // use default encrypt/decrypt functions
+ 0, 0, 0, 0, 0
};
/*
diff --git a/plugin/example_key_management/example_key_management_plugin.cc b/plugin/example_key_management/example_key_management_plugin.cc
index 32fa135d33a..fb19710c0ef 100644
--- a/plugin/example_key_management/example_key_management_plugin.cc
+++ b/plugin/example_key_management/example_key_management_plugin.cc
@@ -77,26 +77,24 @@ get_key(unsigned int key_id, unsigned int version,
/*
for the sake of an example, let's use different encryption algorithms/modes
- for different keys.
+ for different keys versions:
*/
-int encrypt(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 keyid, unsigned int key_version)
+static inline enum my_aes_mode mode(unsigned int key_version)
{
- return ((key_version & 1) ? my_aes_encrypt_cbc : my_aes_encrypt_ecb)
- (src, slen, dst, dlen, key, klen, iv, ivlen, no_padding);
+ return key_version & 1 ? MY_AES_ECB : MY_AES_CBC;
}
-int decrypt(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 keyid, unsigned int key_version)
+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 ((key_version & 1) ? my_aes_decrypt_cbc : my_aes_decrypt_ecb)
- (src, slen, dst, dlen, key, klen, iv, ivlen, no_padding);
+ return my_aes_crypt_init(ctx, mode(key_version), flags, key, klen, iv, ivlen);
+}
+
+static unsigned int get_length(unsigned int slen, unsigned int key_id,
+ unsigned int key_version)
+{
+ return my_aes_get_size(mode(key_version), slen);
}
static int example_key_management_plugin_init(void *p)
@@ -119,8 +117,11 @@ struct st_mariadb_encryption example_key_management_plugin= {
MariaDB_ENCRYPTION_INTERFACE_VERSION,
get_latest_key_version,
get_key,
- encrypt,
- decrypt
+ (uint (*)(unsigned int, unsigned int))my_aes_ctx_size,
+ ctx_init,
+ my_aes_crypt_update,
+ my_aes_crypt_finish,
+ get_length
};
/*
diff --git a/plugin/file_key_management/file_key_management_plugin.cc b/plugin/file_key_management/file_key_management_plugin.cc
index 53cb4069a95..970fae9c189 100644
--- a/plugin/file_key_management/file_key_management_plugin.cc
+++ b/plugin/file_key_management/file_key_management_plugin.cc
@@ -113,65 +113,59 @@ static unsigned int get_key_from_key_file(unsigned int key_id,
return 0;
}
-struct st_mariadb_encryption file_key_management_plugin= {
- MariaDB_ENCRYPTION_INTERFACE_VERSION,
- get_latest_version,
- get_key_from_key_file,
- 0,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
-#ifdef HAVE_EncryptAes128Gcm
-/*
- use AES-CTR when cyphertext length must be the same as plaintext length,
- and AES-GCM when cyphertext can be longer than plaintext.
-*/
-static int ctr_gcm_encrypt(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 keyid, unsigned int key_version)
+static inline enum my_aes_mode mode(int flags)
{
- return (no_padding ? my_aes_encrypt_ctr : my_aes_encrypt_gcm)
- (src, slen, dst, dlen, key, klen, iv, ivlen);
+ /*
+ 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 ctr_gcm_decrypt(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 keyid, unsigned int key_version)
+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 (no_padding ? my_aes_decrypt_ctr : my_aes_decrypt_gcm)
- (src, slen, dst, dlen, key, klen, iv, ivlen);
+ return my_aes_crypt_init(ctx, mode(flags), flags, key, klen, iv, ivlen);
+}
+
+static unsigned int get_length(unsigned int slen, unsigned int key_id,
+ unsigned int key_version)
+{
+ return my_aes_get_size(mode(0), slen);
}
-#endif
+
+struct st_mariadb_encryption file_key_management_plugin= {
+ MariaDB_ENCRYPTION_INTERFACE_VERSION,
+ get_latest_version,
+ get_key_from_key_file,
+ (uint (*)(unsigned int, unsigned int))my_aes_ctx_size,
+ ctx_init,
+ my_aes_crypt_update,
+ my_aes_crypt_finish,
+ get_length
+};
static int file_key_management_plugin_init(void *p)
{
Parser parser(filename, filekey);
- switch (encryption_algorithm) {
- case 0: // AES_CBC
- file_key_management_plugin.encrypt=
- (encrypt_decrypt_func)my_aes_encrypt_cbc;
- file_key_management_plugin.decrypt=
- (encrypt_decrypt_func)my_aes_decrypt_cbc;
- break;
-#ifdef HAVE_EncryptAes128Ctr
- case 1: // AES_CTR
-#ifdef HAVE_EncryptAes128Gcm
- file_key_management_plugin.encrypt= ctr_gcm_encrypt;
- file_key_management_plugin.decrypt= ctr_gcm_decrypt;
-#else
- file_key_management_plugin.encrypt=
- (encrypt_decrypt_func)my_aes_encrypt_ctr;
- file_key_management_plugin.decrypt=
- (encrypt_decrypt_func)my_aes_decrypt_ctr;
-#endif
- break;
-#endif
- default:
- return 1; // cannot happen
- }
return parser.parse(&keys);
}
diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc
index 552dd7df970..9204f39326d 100644
--- a/plugin/file_key_management/parser.cc
+++ b/plugin/file_key_management/parser.cc
@@ -336,10 +336,11 @@ char* Parser::read_and_decrypt_file(const char *secret)
bytes_to_key(buffer + OpenSSL_prefix_len, secret, key, iv);
uint32 d_size;
- if (my_aes_decrypt_cbc(buffer + OpenSSL_prefix_len + OpenSSL_salt_len,
- file_size - OpenSSL_prefix_len - OpenSSL_salt_len,
- decrypted, &d_size, key, OpenSSL_key_len,
- iv, OpenSSL_iv_len, 0))
+ if (my_aes_crypt(MY_AES_CBC, ENCRYPTION_FLAG_DECRYPT,
+ buffer + OpenSSL_prefix_len + OpenSSL_salt_len,
+ file_size - OpenSSL_prefix_len - OpenSSL_salt_len,
+ decrypted, &d_size, key, OpenSSL_key_len,
+ iv, OpenSSL_iv_len))
{
my_printf_error(EE_READ, "Cannot decrypt %s. Wrong key?", MYF(ME_NOREFRESH), filename);
diff --git a/sql/encryption.cc b/sql/encryption.cc
index 520eb8b898f..9fa000abf34 100644
--- a/sql/encryption.cc
+++ b/sql/encryption.cc
@@ -25,31 +25,23 @@ void init_io_cache_encryption();
static plugin_ref encryption_manager= 0;
struct encryption_service_st encryption_handler;
-unsigned int has_key_id(uint id)
-{
- return encryption_key_get_latest_version(id) != ENCRYPTION_KEY_VERSION_INVALID;
-}
-
-unsigned int has_key_version(uint id, uint version)
-{
- uint unused;
- return encryption_key_get(id, version, NULL, &unused) != ENCRYPTION_KEY_VERSION_INVALID;
-}
-
uint no_key(uint)
{
return ENCRYPTION_KEY_VERSION_INVALID;
}
-static int no_crypt(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, uint key_id, uint key_version)
+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 1;
+ return my_aes_crypt_init(ctx, MY_AES_CBC, flags, key, klen, iv, ivlen);
}
+static unsigned int get_length(unsigned int slen, unsigned int key_id,
+ unsigned int key_version)
+{
+ return my_aes_get_size(MY_AES_CBC, slen);
+}
int initialize_encryption_plugin(st_plugin_int *plugin)
{
@@ -67,13 +59,21 @@ int initialize_encryption_plugin(st_plugin_int *plugin)
st_mariadb_encryption *handle=
(struct st_mariadb_encryption*) plugin->plugin->info;
- encryption_handler.encryption_encrypt_func=
- handle->encrypt ? handle->encrypt
- : (encrypt_decrypt_func)my_aes_encrypt_cbc;
+ encryption_handler.encryption_ctx_size_func=
+ handle->crypt_ctx_size ? handle->crypt_ctx_size :
+ (uint (*)(unsigned int, unsigned int))my_aes_ctx_size;
+
+ encryption_handler.encryption_ctx_init_func=
+ handle->crypt_ctx_init ? handle->crypt_ctx_init : ctx_init;
+
+ encryption_handler.encryption_ctx_update_func=
+ handle->crypt_ctx_update ? handle->crypt_ctx_update : my_aes_crypt_update;
+
+ encryption_handler.encryption_ctx_finish_func=
+ handle->crypt_ctx_finish ? handle->crypt_ctx_finish : my_aes_crypt_finish;
- encryption_handler.encryption_decrypt_func=
- handle->decrypt ? handle->decrypt
- : (encrypt_decrypt_func)my_aes_decrypt_cbc;
+ encryption_handler.encryption_encrypted_length_func=
+ handle->encrypted_length ? handle->encrypted_length : get_length;
encryption_handler.encryption_key_get_func=
handle->get_key;
@@ -88,10 +88,6 @@ int initialize_encryption_plugin(st_plugin_int *plugin)
int finalize_encryption_plugin(st_plugin_int *plugin)
{
- encryption_handler.encryption_encrypt_func= no_crypt;
- encryption_handler.encryption_decrypt_func= no_crypt;
- encryption_handler.encryption_key_id_exists_func= has_key_id;
- encryption_handler.encryption_key_version_exists_func= has_key_version;
encryption_handler.encryption_key_get_func=
(uint (*)(uint, uint, uchar*, uint*))no_key;
encryption_handler.encryption_key_get_latest_version_func= no_key;
@@ -144,8 +140,9 @@ static uint scheme_get_key(st_encryption_scheme *scheme,
goto ret;
/* Now generate the local key by encrypting IV using the global key */
- rc = my_aes_encrypt_ecb(scheme->iv, sizeof(scheme->iv), key->key, &key_len,
- global_key, global_key_len, NULL, 0, 1);
+ rc = my_aes_crypt(MY_AES_ECB, ENCRYPTION_FLAG_ENCRYPT | ENCRYPTION_FLAG_NOPAD,
+ scheme->iv, sizeof(scheme->iv), key->key, &key_len,
+ global_key, global_key_len, NULL, 0);
DBUG_ASSERT(key_len == sizeof(key->key));
@@ -169,7 +166,7 @@ int do_crypt(const unsigned char* src, unsigned int slen,
struct st_encryption_scheme *scheme,
unsigned int key_version, unsigned int i32_1,
unsigned int i32_2, unsigned long long i64,
- encrypt_decrypt_func crypt)
+ int flag)
{
compile_time_assert(ENCRYPTION_SCHEME_KEY_INVALID ==
(int)ENCRYPTION_KEY_VERSION_INVALID);
@@ -197,8 +194,8 @@ int do_crypt(const unsigned char* src, unsigned int slen,
int4store(iv + 4, i32_2);
int8store(iv + 8, i64);
- return crypt(src, slen, dst, dlen, key.key, sizeof(key.key),
- iv, sizeof(iv), 1, scheme->key_id, key_version);
+ return encryption_crypt(src, slen, dst, dlen, key.key, sizeof(key.key),
+ iv, sizeof(iv), flag, scheme->key_id, key_version);
}
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
@@ -208,7 +205,7 @@ int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
unsigned int i32_2, unsigned long long i64)
{
return do_crypt(src, slen, dst, dlen, scheme, key_version, i32_1,
- i32_2, i64, encryption_handler.encryption_encrypt_func);
+ i32_2, i64, ENCRYPTION_FLAG_NOPAD | ENCRYPTION_FLAG_ENCRYPT);
}
@@ -219,5 +216,5 @@ int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
unsigned int i32_2, unsigned long long i64)
{
return do_crypt(src, slen, dst, dlen, scheme, key_version, i32_1,
- i32_2, i64, encryption_handler.encryption_decrypt_func);
+ i32_2, i64, ENCRYPTION_FLAG_NOPAD | ENCRYPTION_FLAG_DECRYPT);
}
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 035338ff020..2d31a96c715 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -402,16 +402,16 @@ String *Item_aes_crypt::val_str(String *str)
if (sptr && user_key) // we need both arguments to be not NULL
{
null_value=0;
- aes_length=my_aes_get_size(sptr->length()); // Calculate result length
+ aes_length=my_aes_get_size(MY_AES_ECB, sptr->length());
if (!str_value.alloc(aes_length)) // Ensure that memory is free
{
uchar rkey[AES_KEY_LENGTH / 8];
create_key(user_key, rkey);
- if (!crypt((uchar*)sptr->ptr(), sptr->length(),
+ if (!my_aes_crypt(MY_AES_ECB, what, (uchar*)sptr->ptr(), sptr->length(),
(uchar*)str_value.ptr(), &aes_length,
- rkey, AES_KEY_LENGTH / 8, 0, 0, 0))
+ rkey, AES_KEY_LENGTH / 8, 0, 0))
{
str_value.length((uint) aes_length);
return &str_value;
@@ -424,16 +424,16 @@ String *Item_aes_crypt::val_str(String *str)
void Item_func_aes_encrypt::fix_length_and_dec()
{
- max_length=my_aes_get_size(args[0]->max_length);
- crypt= my_aes_encrypt_ecb;
+ max_length=my_aes_get_size(MY_AES_ECB, args[0]->max_length);
+ what= ENCRYPTION_FLAG_ENCRYPT;
}
void Item_func_aes_decrypt::fix_length_and_dec()
{
- max_length=args[0]->max_length;
- maybe_null= 1;
- crypt= my_aes_decrypt_ecb;
+ max_length=args[0]->max_length;
+ maybe_null= 1;
+ what= ENCRYPTION_FLAG_DECRYPT;
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 9a8c79966d0..c6545f733ff 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -142,10 +142,7 @@ class Item_aes_crypt :public Item_str_func
void create_key(String *user_key, uchar* key);
protected:
- int (*crypt)(const uchar* src, uint slen, uchar* dst, uint* dlen,
- const uchar* key, uint klen, const uchar* iv, uint ivlen,
- int no_padding);
-
+ int what;
public:
Item_aes_crypt(Item *a, Item *b) :Item_str_func(a,b) {}
String *val_str(String *);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 786b249db39..4f49a77b4ab 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1136,8 +1136,7 @@ bool Log_event::wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, ulong
bool Log_event::write_footer(IO_CACHE* file)
{
/*
- footer contains the checksum-algorithm descriptor
- followed by the checksum value
+ (optional) footer contains the checksum value
*/
if (need_checksum())
{
@@ -1149,7 +1148,7 @@ bool Log_event::write_footer(IO_CACHE* file)
}
/*
- Log_event::write()
+ Log_event::write_header()
*/
bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
@@ -2775,7 +2774,7 @@ void Query_log_event::pack_info(THD *thd, Protocol *protocol)
/**
Utility function for the next method (Query_log_event::write()) .
*/
-static void write_str_with_code_and_len(uchar **dst, const char *src,
+static void store_str_with_code_and_len(uchar **dst, const char *src,
uint len, uint code)
{
/*
@@ -2871,7 +2870,7 @@ bool Query_log_event::write(IO_CACHE* file)
}
if (catalog_len) // i.e. this var is inited (false for 4.0 events)
{
- write_str_with_code_and_len(&start,
+ store_str_with_code_and_len(&start,
catalog, catalog_len, Q_CATALOG_NZ_CODE);
/*
In 5.0.x where x<4 masters we used to store the end zero here. This was
@@ -2909,7 +2908,7 @@ bool Query_log_event::write(IO_CACHE* file)
{
/* In the TZ sys table, column Name is of length 64 so this should be ok */
DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
- write_str_with_code_and_len(&start,
+ store_str_with_code_and_len(&start,
time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
}
if (lc_time_names_number)
diff --git a/sql/log_event.h b/sql/log_event.h
index 95b68e627ff..528f0aa7476 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -1245,7 +1245,7 @@ public:
write_data_body(file) ||
write_footer(file));
}
- virtual bool write_data_header(IO_CACHE* file)
+ virtual bool write_data_header(IO_CACHE* file __attribute__((unused)))
{ return 0; }
virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
{ return 0; }
diff --git a/sql/mf_iocache_encr.cc b/sql/mf_iocache_encr.cc
index d215636d62a..96658e2e3d0 100644
--- a/sql/mf_iocache_encr.cc
+++ b/sql/mf_iocache_encr.cc
@@ -95,9 +95,10 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count)
elength= wlength - (ebuffer - wbuffer);
set_iv(iv, pos_in_file, crypt_data->inbuf_counter);
- if (encryption_decrypt(ebuffer, elength, info->buffer, &length,
- crypt_data->key, sizeof(crypt_data->key),
- iv, sizeof(iv), 0, keyid, keyver))
+ if (encryption_crypt(ebuffer, elength, info->buffer, &length,
+ crypt_data->key, sizeof(crypt_data->key),
+ iv, sizeof(iv), ENCRYPTION_FLAG_DECRYPT,
+ keyid, keyver))
{
my_errno= 1;
DBUG_RETURN(info->error= -1);
@@ -175,9 +176,10 @@ static int my_b_encr_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
crypt_data->inbuf_counter= crypt_data->counter;
set_iv(iv, info->pos_in_file, crypt_data->inbuf_counter);
- if (encryption_encrypt(Buffer, length, ebuffer, &elength,
- crypt_data->key, sizeof(crypt_data->key),
- iv, sizeof(iv), 0, keyid, keyver))
+ if (encryption_crypt(Buffer, length, ebuffer, &elength,
+ crypt_data->key, sizeof(crypt_data->key),
+ iv, sizeof(iv), ENCRYPTION_FLAG_ENCRYPT,
+ keyid, keyver))
{
my_errno= 1;
DBUG_RETURN(info->error= -1);
@@ -191,7 +193,7 @@ static int my_b_encr_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
buffer_length bytes should *always* produce block_length bytes
*/
DBUG_ASSERT(crypt_data->block_length == 0 || crypt_data->block_length == wlength);
- DBUG_ASSERT(elength <= my_aes_get_size(length));
+ DBUG_ASSERT(elength <= encryption_encrypted_length(length, keyid, keyver));
crypt_data->block_length= wlength;
}
else
diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc
index 79f4ba35b69..2849ec075f6 100644
--- a/storage/innobase/log/log0crypt.cc
+++ b/storage/innobase/log/log0crypt.cc
@@ -125,15 +125,16 @@ log_blocks_crypt(
const byte* block, /*!< in: blocks before encrypt/decrypt*/
ulint size, /*!< in: size of block */
byte* dst_block, /*!< out: blocks after encrypt/decrypt */
- bool is_encrypt) /*!< in: encrypt or decrypt*/
+ int what) /*!< in: encrypt or decrypt*/
{
byte *log_block = (byte*)block;
Crypt_result rc = MY_AES_OK;
uint dst_len;
byte aes_ctr_counter[MY_AES_BLOCK_SIZE];
+ byte is_encrypt= what == ENCRYPTION_FLAG_ENCRYPT;
lsn_t lsn = is_encrypt ? log_sys->lsn : srv_start_lsn;
- const int src_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE;
+ const uint src_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE;
for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE) {
ulint log_block_no = log_block_get_hdr_no(log_block);
lsn_t log_block_start_lsn = log_block_get_start_lsn(
@@ -168,21 +169,13 @@ log_blocks_crypt(
bzero(aes_ctr_counter + 15, 1);
int rc;
- if (is_encrypt) {
- rc = encryption_encrypt(log_block + LOG_BLOCK_HDR_SIZE, src_len,
- dst_block + LOG_BLOCK_HDR_SIZE, &dst_len,
- (unsigned char*)(info->crypt_key), 16,
- aes_ctr_counter, MY_AES_BLOCK_SIZE, 1,
- LOG_DEFAULT_ENCRYPTION_KEY,
- info->key_version);
- } else {
- rc = encryption_decrypt(log_block + LOG_BLOCK_HDR_SIZE, src_len,
- dst_block + LOG_BLOCK_HDR_SIZE, &dst_len,
- (unsigned char*)(info->crypt_key), 16,
- aes_ctr_counter, MY_AES_BLOCK_SIZE, 1,
- LOG_DEFAULT_ENCRYPTION_KEY,
- info->key_version);
- }
+ rc = encryption_crypt(log_block + LOG_BLOCK_HDR_SIZE, src_len,
+ dst_block + LOG_BLOCK_HDR_SIZE, &dst_len,
+ (unsigned char*)(info->crypt_key), 16,
+ aes_ctr_counter, MY_AES_BLOCK_SIZE,
+ what | ENCRYPTION_FLAG_NOPAD,
+ LOG_DEFAULT_ENCRYPTION_KEY,
+ info->key_version);
ut_a(rc == MY_AES_OK);
ut_a(dst_len == src_len);
@@ -224,10 +217,11 @@ init_crypt_key(
}
uint dst_len;
- int rc= my_aes_encrypt_ecb(info->crypt_msg, sizeof(info->crypt_msg), //src, srclen
- info->crypt_key, &dst_len, //dst, &dstlen
- (unsigned char*)&mysqld_key, sizeof(mysqld_key),
- NULL, 0, 1);
+ int rc= my_aes_crypt(MY_AES_ECB, ENCRYPTION_FLAG_NOPAD|ENCRYPTION_FLAG_ENCRYPT,
+ info->crypt_msg, sizeof(info->crypt_msg), //src, srclen
+ info->crypt_key, &dst_len, //dst, &dstlen
+ (unsigned char*)&mysqld_key, sizeof(mysqld_key),
+ NULL, 0);
if (rc != MY_AES_OK || dst_len != MY_AES_BLOCK_SIZE) {
fprintf(stderr,
@@ -281,7 +275,7 @@ log_blocks_encrypt(
const ulint size, /*!< in: size of blocks, must be multiple of a log block */
byte* dst_block) /*!< out: blocks after encryption */
{
- return log_blocks_crypt(block, size, dst_block, true);
+ return log_blocks_crypt(block, size, dst_block, ENCRYPTION_FLAG_ENCRYPT);
}
/*********************************************************************//**
@@ -351,7 +345,7 @@ log_encrypt_before_write(
byte* dst_frame = (byte*)malloc(size);
//encrypt log blocks content
- Crypt_result result = log_blocks_crypt(block, size, dst_frame, true);
+ Crypt_result result = log_blocks_crypt(block, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT);
if (result == MY_AES_OK) {
ut_ad(block[0] == dst_frame[0]);
@@ -377,7 +371,7 @@ log_decrypt_after_read(
byte* dst_frame = (byte*)malloc(size);
// decrypt log blocks content
- Crypt_result result = log_blocks_crypt(frame, size, dst_frame, false);
+ Crypt_result result = log_blocks_crypt(frame, size, dst_frame, ENCRYPTION_FLAG_DECRYPT);
if (result == MY_AES_OK) {
memcpy(frame, dst_frame, size);
diff --git a/storage/maria/ma_check_standalone.h b/storage/maria/ma_check_standalone.h
index c240ca056e7..6626a62c4ef 100644
--- a/storage/maria/ma_check_standalone.h
+++ b/storage/maria/ma_check_standalone.h
@@ -30,7 +30,7 @@ static unsigned int no_key()
struct encryption_service_st encryption_handler=
{
- no_key, 0, 0, 0, 0, 0
+ no_key, 0, 0, 0, 0, 0, 0
};
int encryption_scheme_encrypt(const unsigned char* src __attribute__((unused)),
diff --git a/storage/xtradb/log/log0crypt.cc b/storage/xtradb/log/log0crypt.cc
index 23bde798de1..2849ec075f6 100644
--- a/storage/xtradb/log/log0crypt.cc
+++ b/storage/xtradb/log/log0crypt.cc
@@ -125,12 +125,13 @@ log_blocks_crypt(
const byte* block, /*!< in: blocks before encrypt/decrypt*/
ulint size, /*!< in: size of block */
byte* dst_block, /*!< out: blocks after encrypt/decrypt */
- bool is_encrypt) /*!< in: encrypt or decrypt*/
+ int what) /*!< in: encrypt or decrypt*/
{
byte *log_block = (byte*)block;
Crypt_result rc = MY_AES_OK;
uint dst_len;
byte aes_ctr_counter[MY_AES_BLOCK_SIZE];
+ byte is_encrypt= what == ENCRYPTION_FLAG_ENCRYPT;
lsn_t lsn = is_encrypt ? log_sys->lsn : srv_start_lsn;
const uint src_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE;
@@ -168,21 +169,13 @@ log_blocks_crypt(
bzero(aes_ctr_counter + 15, 1);
int rc;
- if (is_encrypt) {
- rc = encryption_encrypt(log_block + LOG_BLOCK_HDR_SIZE, src_len,
- dst_block + LOG_BLOCK_HDR_SIZE, &dst_len,
- (unsigned char*)(info->crypt_key), 16,
- aes_ctr_counter, MY_AES_BLOCK_SIZE, 1,
- LOG_DEFAULT_ENCRYPTION_KEY,
- info->key_version);
- } else {
- rc = encryption_decrypt(log_block + LOG_BLOCK_HDR_SIZE, src_len,
- dst_block + LOG_BLOCK_HDR_SIZE, &dst_len,
- (unsigned char*)(info->crypt_key), 16,
- aes_ctr_counter, MY_AES_BLOCK_SIZE, 1,
- LOG_DEFAULT_ENCRYPTION_KEY,
- info->key_version);
- }
+ rc = encryption_crypt(log_block + LOG_BLOCK_HDR_SIZE, src_len,
+ dst_block + LOG_BLOCK_HDR_SIZE, &dst_len,
+ (unsigned char*)(info->crypt_key), 16,
+ aes_ctr_counter, MY_AES_BLOCK_SIZE,
+ what | ENCRYPTION_FLAG_NOPAD,
+ LOG_DEFAULT_ENCRYPTION_KEY,
+ info->key_version);
ut_a(rc == MY_AES_OK);
ut_a(dst_len == src_len);
@@ -224,10 +217,11 @@ init_crypt_key(
}
uint dst_len;
- int rc= my_aes_encrypt_ecb(info->crypt_msg, sizeof(info->crypt_msg), //src, srclen
- info->crypt_key, &dst_len, //dst, &dstlen
- (unsigned char*)&mysqld_key, sizeof(mysqld_key),
- NULL, 0, 1);
+ int rc= my_aes_crypt(MY_AES_ECB, ENCRYPTION_FLAG_NOPAD|ENCRYPTION_FLAG_ENCRYPT,
+ info->crypt_msg, sizeof(info->crypt_msg), //src, srclen
+ info->crypt_key, &dst_len, //dst, &dstlen
+ (unsigned char*)&mysqld_key, sizeof(mysqld_key),
+ NULL, 0);
if (rc != MY_AES_OK || dst_len != MY_AES_BLOCK_SIZE) {
fprintf(stderr,
@@ -281,7 +275,7 @@ log_blocks_encrypt(
const ulint size, /*!< in: size of blocks, must be multiple of a log block */
byte* dst_block) /*!< out: blocks after encryption */
{
- return log_blocks_crypt(block, size, dst_block, true);
+ return log_blocks_crypt(block, size, dst_block, ENCRYPTION_FLAG_ENCRYPT);
}
/*********************************************************************//**
@@ -351,7 +345,7 @@ log_encrypt_before_write(
byte* dst_frame = (byte*)malloc(size);
//encrypt log blocks content
- Crypt_result result = log_blocks_crypt(block, size, dst_frame, true);
+ Crypt_result result = log_blocks_crypt(block, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT);
if (result == MY_AES_OK) {
ut_ad(block[0] == dst_frame[0]);
@@ -377,7 +371,7 @@ log_decrypt_after_read(
byte* dst_frame = (byte*)malloc(size);
// decrypt log blocks content
- Crypt_result result = log_blocks_crypt(frame, size, dst_frame, false);
+ Crypt_result result = log_blocks_crypt(frame, size, dst_frame, ENCRYPTION_FLAG_DECRYPT);
if (result == MY_AES_OK) {
memcpy(frame, dst_frame, size);
diff --git a/unittest/mysys/aes-t.c b/unittest/mysys/aes-t.c
index 83cd39ff325..59368236536 100644
--- a/unittest/mysys/aes-t.c
+++ b/unittest/mysys/aes-t.c
@@ -21,49 +21,26 @@
#include <string.h>
#include <ctype.h>
-#define DO_TEST_P(mode, slen, fill, dlen, hash) \
+#define DO_TEST(mode, nopad, slen, fill, dlen, hash) \
do { \
memset(src, fill, src_len= slen); \
- ok(my_aes_encrypt_ ## mode(src, src_len, dst, &dst_len, \
- key, sizeof(key), iv, sizeof(iv), 0) == MY_AES_OK, \
- "encrypt " #mode " %u", src_len); \
- ok(dst_len <= my_aes_get_size(src_len), \
- "my_aes_get_size(%u) >= %u", src_len, dst_len); \
+ ok(my_aes_crypt(mode, nopad | ENCRYPTION_FLAG_ENCRYPT, \
+ src, src_len, dst, &dst_len, \
+ key, sizeof(key), iv, sizeof(iv)) == MY_AES_OK, \
+ "encrypt " #mode " %u %s", src_len, nopad ? "nopad" : "pad"); \
+ if (!nopad) \
+ ok (dst_len == my_aes_get_size(mode, src_len), "my_aes_get_size");\
my_md5(md5, (char*)dst, dst_len); \
ok(dst_len == dlen && memcmp(md5, hash, sizeof(md5)) == 0, "md5"); \
- ok(my_aes_decrypt_ ## mode(dst, dst_len, ddst, &ddst_len, \
- key, sizeof(key), iv, sizeof(iv), 0) == MY_AES_OK, \
+ ok(my_aes_crypt(mode, nopad | ENCRYPTION_FLAG_DECRYPT, \
+ dst, dst_len, ddst, &ddst_len, \
+ key, sizeof(key), iv, sizeof(iv)) == MY_AES_OK, \
"decrypt " #mode " %u", dst_len); \
ok(ddst_len == src_len && memcmp(src, ddst, src_len) == 0, "memcmp"); \
} while(0)
-#define DO_TEST_N(mode, slen, fill, dlen, hash) \
- do { \
- memset(src, fill, src_len= slen); \
- ok(my_aes_encrypt_ ## mode(src, src_len, dst, &dst_len, \
- key, sizeof(key), iv, sizeof(iv), 1) == MY_AES_OK, \
- "encrypt " #mode " %u nopad", src_len); \
- my_md5(md5, (char*)dst, dst_len); \
- ok(dst_len == dlen && memcmp(md5, hash, sizeof(md5)) == 0, "md5"); \
- ok(my_aes_decrypt_ ## mode(dst, dst_len, ddst, &ddst_len, \
- key, sizeof(key), iv, sizeof(iv), 1) == MY_AES_OK, \
- "decrypt " #mode " %u", dst_len); \
- ok(ddst_len == src_len && memcmp(src, ddst, src_len) == 0, "memcmp"); \
- } while(0)
-
-#define DO_TEST_X(mode, slen, fill, dlen, hash) \
- do { \
- memset(src, fill, src_len= slen); \
- ok(my_aes_encrypt_ ## mode(src, src_len, dst, &dst_len, \
- key, sizeof(key), iv, sizeof(iv)) == MY_AES_OK, \
- "encrypt " #mode " %u", src_len); \
- my_md5(md5, (char*)dst, dst_len); \
- ok(dst_len == dlen && memcmp(md5, hash, sizeof(md5)) == 0, "md5"); \
- ok(my_aes_decrypt_ ## mode(dst, dst_len, ddst, &ddst_len, \
- key, sizeof(key), iv, sizeof(iv)) == MY_AES_OK, \
- "decrypt " #mode " %u", dst_len); \
- ok(ddst_len == src_len && memcmp(src, ddst, src_len) == 0, "memcmp"); \
- } while(0)
+#define DO_TEST_P(M,S,F,D,H) DO_TEST(M,0,S,F,D,H)
+#define DO_TEST_N(M,S,F,D,H) DO_TEST(M,ENCRYPTION_FLAG_NOPAD,S,F,D,H)
/* useful macro for debugging */
#define PRINT_MD5() \
@@ -87,17 +64,17 @@ main(int argc __attribute__((unused)),char *argv[])
MY_INIT(argv[0]);
- plan(44);
- DO_TEST_P(ecb, 200, '.', 208, "\xd8\x73\x8e\x3a\xbc\x66\x99\x13\x7f\x90\x23\x52\xee\x97\x6f\x9a");
- DO_TEST_P(ecb, 128, '?', 144, "\x19\x58\x33\x85\x4c\xaa\x7f\x06\xd1\xb2\xec\xd7\xb7\x6a\xa9\x5b");
- DO_TEST_P(cbc, 159, '%', 160, "\x4b\x03\x18\x3d\xf1\xa7\xcd\xa1\x46\xb3\xc6\x8a\x92\xc0\x0f\xc9");
- DO_TEST_P(cbc, 192, '@', 208, "\x54\xc4\x75\x1d\xff\xe0\xf6\x80\xf0\x85\xbb\x8b\xda\x07\x21\x17");
- DO_TEST_N(ecb, 200, '.', 200, "\xbf\xec\x43\xd1\x66\x8d\x01\xad\x3a\x25\xee\xa6\x3d\xc6\xc4\x68");
- DO_TEST_N(ecb, 128, '?', 128, "\x5b\x44\x20\xf3\xd9\xb4\x9d\x74\x5e\xb7\x5a\x0a\xe7\x32\x35\xc3");
- DO_TEST_N(cbc, 159, '%', 159, "\xf3\x6e\x40\x00\x3c\x08\xa0\xb1\x2d\x1f\xcf\xce\x54\xc9\x73\x83");
- DO_TEST_N(cbc, 192, '@', 192, "\x30\xe5\x28\x8c\x4a\x3b\x02\xd7\x56\x40\x59\x25\xac\x58\x09\x22");
- DO_TEST_X(ctr, 200, '.', 200, "\x5a\x77\x19\xea\x67\x50\xe3\xab\x7f\x39\x6f\xc4\xa8\x09\xc5\x88");
- DO_TEST_X(gcm, 128, '?', 144, "\x54\x6a\x7c\xa2\x04\xdc\x6e\x80\x1c\xcd\x5f\x7a\x7b\x08\x9e\x9d");
+ plan(46);
+ DO_TEST_P(MY_AES_ECB, 200, '.', 208, "\xd8\x73\x8e\x3a\xbc\x66\x99\x13\x7f\x90\x23\x52\xee\x97\x6f\x9a");
+ DO_TEST_P(MY_AES_ECB, 128, '?', 144, "\x19\x58\x33\x85\x4c\xaa\x7f\x06\xd1\xb2\xec\xd7\xb7\x6a\xa9\x5b");
+ DO_TEST_P(MY_AES_CBC, 159, '%', 160, "\x4b\x03\x18\x3d\xf1\xa7\xcd\xa1\x46\xb3\xc6\x8a\x92\xc0\x0f\xc9");
+ DO_TEST_P(MY_AES_CBC, 192, '@', 208, "\x54\xc4\x75\x1d\xff\xe0\xf6\x80\xf0\x85\xbb\x8b\xda\x07\x21\x17");
+ DO_TEST_N(MY_AES_ECB, 200, '.', 200, "\xbf\xec\x43\xd1\x66\x8d\x01\xad\x3a\x25\xee\xa6\x3d\xc6\xc4\x68");
+ DO_TEST_N(MY_AES_ECB, 128, '?', 128, "\x5b\x44\x20\xf3\xd9\xb4\x9d\x74\x5e\xb7\x5a\x0a\xe7\x32\x35\xc3");
+ DO_TEST_N(MY_AES_CBC, 159, '%', 159, "\xf3\x6e\x40\x00\x3c\x08\xa0\xb1\x2d\x1f\xcf\xce\x54\xc9\x73\x83");
+ DO_TEST_N(MY_AES_CBC, 192, '@', 192, "\x30\xe5\x28\x8c\x4a\x3b\x02\xd7\x56\x40\x59\x25\xac\x58\x09\x22");
+ DO_TEST_P(MY_AES_CTR, 200, '.', 200, "\x5a\x77\x19\xea\x67\x50\xe3\xab\x7f\x39\x6f\xc4\xa8\x09\xc5\x88");
+ DO_TEST_P(MY_AES_GCM, 128, '?', 144, "\x54\x6a\x7c\xa2\x04\xdc\x6e\x80\x1c\xcd\x5f\x7a\x7b\x08\x9e\x9d");
my_end(0);
return exit_status();
diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc
index eb503d2f8de..c89f8a9f038 100644
--- a/unittest/sql/mf_iocache-t.cc
+++ b/unittest/sql/mf_iocache-t.cc
@@ -49,19 +49,34 @@ uint encryption_key_get_func(uint, uint, uchar* key, uint* size)
return 0;
}
+#ifdef HAVE_EncryptAes128Gcm
+enum my_aes_mode aes_mode= MY_AES_GCM;
+#else
+enum my_aes_mode aes_mode= MY_AES_CBC;
+#endif
+
+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)
+{
+ return my_aes_crypt_init(ctx, aes_mode, flags, key, klen, iv, ivlen);
+}
+
+uint encryption_encrypted_length_func(unsigned int slen, unsigned int key_id, unsigned int key_version)
+{
+ return my_aes_get_size(aes_mode, slen);
+}
+
struct encryption_service_st encryption_handler=
{
encryption_key_get_latest_version_func,
- encryption_key_id_exists_func,
- encryption_key_version_exists_func,
encryption_key_get_func,
-#ifdef HAVE_EncryptAes128Gcm
- (encrypt_decrypt_func)my_aes_encrypt_gcm,
- (encrypt_decrypt_func)my_aes_decrypt_gcm
-#else
- (encrypt_decrypt_func)my_aes_encrypt_cbc,
- (encrypt_decrypt_func)my_aes_decrypt_cbc
-#endif
+ (uint (*)(unsigned int, unsigned int))my_aes_ctx_size,
+ encryption_ctx_init_func,
+ my_aes_crypt_update,
+ my_aes_crypt_finish,
+ encryption_encrypted_length_func
};
void sql_print_information(const char *format, ...)