summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/encryption/r/aria_tiny.result5
-rw-r--r--mysql-test/suite/encryption/t/aria_tiny.test12
-rw-r--r--mysys_ssl/my_crypt.cc112
-rw-r--r--plugin/file_key_management/file_key_management_plugin.cc2
4 files changed, 79 insertions, 52 deletions
diff --git a/mysql-test/suite/encryption/r/aria_tiny.result b/mysql-test/suite/encryption/r/aria_tiny.result
new file mode 100644
index 00000000000..b0f8bac7c32
--- /dev/null
+++ b/mysql-test/suite/encryption/r/aria_tiny.result
@@ -0,0 +1,5 @@
+set global aria_encrypt_tables = 1;
+create table t1 (i int, key(i)) engine=aria;
+insert into t1 values (1);
+drop table t1;
+set global aria_encrypt_tables = 0;
diff --git a/mysql-test/suite/encryption/t/aria_tiny.test b/mysql-test/suite/encryption/t/aria_tiny.test
new file mode 100644
index 00000000000..cad63ed16f1
--- /dev/null
+++ b/mysql-test/suite/encryption/t/aria_tiny.test
@@ -0,0 +1,12 @@
+#
+# MDEV-8022 Assertion `rc == 0' failed in ma_encrypt on dropping an encrypted Aria table
+#
+
+--source include/have_file_key_management_plugin.inc
+
+set global aria_encrypt_tables = 1;
+create table t1 (i int, key(i)) engine=aria;
+insert into t1 values (1);
+drop table t1;
+set global aria_encrypt_tables = 0;
+
diff --git a/mysys_ssl/my_crypt.cc b/mysys_ssl/my_crypt.cc
index ee77a265ec3..0c977eb94bf 100644
--- a/mysys_ssl/my_crypt.cc
+++ b/mysys_ssl/my_crypt.cc
@@ -71,84 +71,94 @@ static int block_crypt(CipherMode cipher, Dir dir,
{
int tail= source_length % MY_AES_BLOCK_SIZE;
-#ifdef HAVE_YASSL
- TaoCrypt::AES ctx(dir, cipher);
-
- if (unlikely(key_length != 16 && key_length != 24 && key_length != 32))
- return MY_AES_BAD_KEYSIZE;
+ DBUG_ASSERT(source_length);
- ctx.SetKey(key, key_length);
- if (iv)
+ if (likely(source_length >= MY_AES_BLOCK_SIZE || !no_padding))
{
- ctx.SetIV(iv);
- DBUG_ASSERT(TaoCrypt::AES::BLOCK_SIZE == iv_length);
- }
- DBUG_ASSERT(TaoCrypt::AES::BLOCK_SIZE == MY_AES_BLOCK_SIZE);
+#ifdef HAVE_YASSL
+ TaoCrypt::AES ctx(dir, cipher);
- ctx.Process(dest, source, source_length - tail);
- *dest_length= source_length - tail;
+ if (unlikely(key_length != 16 && key_length != 24 && key_length != 32))
+ return MY_AES_BAD_KEYSIZE;
- /* unlike OpenSSL, YaSSL doesn't support PKCS#7 padding */
- if (!no_padding)
- {
- if (dir == CRYPT_ENCRYPT)
+ ctx.SetKey(key, key_length);
+ if (iv)
{
- 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;
+ ctx.SetIV(iv);
+ DBUG_ASSERT(TaoCrypt::AES::BLOCK_SIZE <= iv_length);
}
- else
+ 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)
{
- int n= dest[source_length - 1];
- if (tail || n == 0 || n > MY_AES_BLOCK_SIZE)
- return MY_AES_BAD_DATA;
- *dest_length-= n;
+ 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= dest[source_length - 1];
+ 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;
+ int fin;
+ struct MyCTX ctx;
- if (unlikely(!cipher))
- return MY_AES_BAD_KEYSIZE;
+ if (unlikely(!cipher))
+ return MY_AES_BAD_KEYSIZE;
- if (!EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, dir))
- return MY_AES_OPENSSL_ERROR;
+ if (!EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, dir))
+ return MY_AES_OPENSSL_ERROR;
- EVP_CIPHER_CTX_set_padding(&ctx, !no_padding);
+ EVP_CIPHER_CTX_set_padding(&ctx, !no_padding);
- 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);
+ 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_OPENSSL_ERROR;
- if (!EVP_CipherFinal_ex(&ctx, dest + *dest_length, &fin))
- return MY_AES_BAD_DATA;
- *dest_length += fin;
+ /* 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_OPENSSL_ERROR;
+ if (!EVP_CipherFinal_ex(&ctx, dest + *dest_length, &fin))
+ return MY_AES_BAD_DATA;
+ *dest_length += fin;
#endif
+ }
if (no_padding && tail)
{
/*
Not much we can do, block ciphers cannot encrypt data that aren't
a multiple of the block length. At least not without padding.
- What we do here, we XOR the tail with the previous encrypted block.
+ Let's do something CTR-like for the last partial block.
*/
- if (unlikely(source_length < MY_AES_BLOCK_SIZE))
- return MY_AES_BAD_DATA;
+ 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(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= (dir == CRYPT_ENCRYPT ? d : s) - MY_AES_BLOCK_SIZE;
+ const uchar *m= mask;
while (s < e)
*d++ = *s++ ^ *m++;
*dest_length= source_length;
@@ -204,7 +214,7 @@ int my_aes_encrypt_ecb(const uchar* source, uint source_length,
int no_padding)
{
return block_crypt(aes_ecb(key_length), CRYPT_ENCRYPT, source, source_length,
- dest, dest_length, key, key_length, 0, 0, no_padding);
+ dest, dest_length, key, key_length, iv, iv_length, no_padding);
}
int my_aes_decrypt_ecb(const uchar* source, uint source_length,
@@ -214,7 +224,7 @@ int my_aes_decrypt_ecb(const uchar* source, uint source_length,
int no_padding)
{
return block_crypt(aes_ecb(key_length), CRYPT_DECRYPT, source, source_length,
- dest, dest_length, key, key_length, 0, 0, no_padding);
+ dest, dest_length, key, key_length, iv, iv_length, no_padding);
}
int my_aes_encrypt_cbc(const uchar* source, uint source_length,
diff --git a/plugin/file_key_management/file_key_management_plugin.cc b/plugin/file_key_management/file_key_management_plugin.cc
index 08c0c9b74c8..666a5190860 100644
--- a/plugin/file_key_management/file_key_management_plugin.cc
+++ b/plugin/file_key_management/file_key_management_plugin.cc
@@ -50,7 +50,7 @@ static MYSQL_SYSVAR_STR(filekey, filekey,
static MYSQL_SYSVAR_ENUM(encryption_algorithm, encryption_algorithm,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Encryption algorithm to use.",
+ "Encryption algorithm to use, aes_ctr is the recommended one.",
NULL, NULL, 0, &encryption_algorithm_typelib);
static struct st_mysql_sys_var* settings[] = {