diff options
-rw-r--r-- | mysql-test/suite/encryption/r/aria_tiny.result | 5 | ||||
-rw-r--r-- | mysql-test/suite/encryption/t/aria_tiny.test | 12 | ||||
-rw-r--r-- | mysys_ssl/my_crypt.cc | 112 | ||||
-rw-r--r-- | plugin/file_key_management/file_key_management_plugin.cc | 2 |
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[] = { |