Commit a3e68b4a authored by Jan Lindström's avatar Jan Lindström

MDEV-7772: SIGSEGV on my_aes_encrypt_cbc when -DWITH_SSL=bundled

Two problems:
- Read/Write outside of buffer at memcpy() because of incorrect parameters
. OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == iv_length); // ECB does not use IV, thus incorrect assertion

Added:
  mysql-test/include/encryption_algorithms.combinations to run tests with methods cbc, ecb and ctr in
  those systems where they are available (see suite.pm).
parent 5e6f1236
[cbc]
encryption-algorithm=aes_cbc
[ecb]
encryption-algorithm=aes_ecb
[ctr]
encryption-algorithm=aes_ctr
-- source encryption_algorithms.inc
if (`select count(*) = 0 from information_schema.plugins if (`select count(*) = 0 from information_schema.plugins
where plugin_name = 'example_key_management_plugin' and plugin_status='active'`) where plugin_name = 'example_key_management_plugin' and plugin_status='active'`)
{ {
......
-- source encryption_algorithms.inc
if (`select count(*) = 0 from information_schema.plugins if (`select count(*) = 0 from information_schema.plugins
where plugin_name = 'file_key_management_plugin' and plugin_status='active'`) where plugin_name = 'file_key_management_plugin' and plugin_status='active'`)
{ {
......
--plugin-load-add=$FILE_KEY_MANAGEMENT_PLUGIN_SO --plugin-load-add=$FILE_KEY_MANAGEMENT_PLUGIN_SO
--loose-file-key-management-plugin --loose-file-key-management-plugin
--loose-file-key-management-plugin-filename=$MYSQL_TEST_DIR/std_data/keys.txt --loose-file-key-management-plugin-filename=$MYSQL_TEST_DIR/std_data/keys.txt
--encryption-algorithm=aes_cbc
...@@ -66,7 +66,7 @@ sub skip_combinations { ...@@ -66,7 +66,7 @@ sub skip_combinations {
unless $::mysqld_variables{'version-ssl-library'} =~ /OpenSSL (\S+)/ unless $::mysqld_variables{'version-ssl-library'} =~ /OpenSSL (\S+)/
and $1 ge "1.0.1"; and $1 ge "1.0.1";
$skip{'include/have_openssl_ctr.inc'} = 'no or too old openssl' $skip{'include/encryption_algorithms.combinations'} = [ 'ctr' ]
unless $::mysqld_variables{'version-ssl-library'} =~ /OpenSSL (\S+)/ unless $::mysqld_variables{'version-ssl-library'} =~ /OpenSSL (\S+)/
and $1 ge "1.0.1"; and $1 ge "1.0.1";
......
--encryption-algorithm=aes_cbc
--innodb-encrypt-log --innodb-encrypt-log
-- source include/have_innodb.inc -- source include/have_innodb.inc
-- source include/have_openssl_ctr.inc
-- source include/have_example_key_management_plugin.inc -- source include/have_example_key_management_plugin.inc
# embedded does not support restart # embedded does not support restart
......
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
--innodb-encryption-rotate-key-age=15 --innodb-encryption-rotate-key-age=15
--innodb-encryption-threads=4 --innodb-encryption-threads=4
--innodb-tablespaces-encryption --innodb-tablespaces-encryption
--encryption-algorithm=aes_ctr
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
# #
-- source include/have_innodb.inc -- source include/have_innodb.inc
-- source include/have_example_key_management_plugin.inc -- source include/have_example_key_management_plugin.inc
-- source include/have_openssl_ctr.inc
# embedded does not support restart # embedded does not support restart
-- source include/not_embedded.inc -- source include/not_embedded.inc
......
-- source include/have_innodb.inc -- source include/have_innodb.inc
-- source include/have_example_key_management_plugin.inc -- source include/have_example_key_management_plugin.inc
-- source include/have_openssl_ctr.inc
--source include/not_embedded.inc --source include/not_embedded.inc
--disable_query_log --disable_query_log
......
...@@ -256,11 +256,11 @@ static int my_aes_encrypt_cbc(const uchar* source, uint32 source_length, ...@@ -256,11 +256,11 @@ static int my_aes_encrypt_cbc(const uchar* source, uint32 source_length,
if (noPadding) { if (noPadding) {
if (remaining_bytes!=0) { if (remaining_bytes!=0) {
memcpy(dest + source_length, source + source_length, remaining_bytes); /* Note that we moved the original pointers above */
memcpy(dest, source, remaining_bytes);
} }
*dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes; *dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes;
return AES_OK; return AES_OK;
} }
/* Encode the rest. We always have incomplete block */ /* Encode the rest. We always have incomplete block */
...@@ -384,11 +384,11 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length, ...@@ -384,11 +384,11 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length,
if (noPadding) { if (noPadding) {
if (remaining_bytes!=0) { if (remaining_bytes!=0) {
memcpy(dest + source_length, source + source_length, remaining_bytes); /* Note that we moved the original pointers above */
memcpy(dest, source, remaining_bytes);
} }
*dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes; *dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes;
return AES_OK; return AES_OK;
} }
/* Encode the rest. We always have incomplete block */ /* Encode the rest. We always have incomplete block */
...@@ -430,7 +430,8 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length, ...@@ -430,7 +430,8 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length,
} }
EVP_CIPHER_CTX_key_length(&ctx.ctx); EVP_CIPHER_CTX_key_length(&ctx.ctx);
OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx.ctx) == key_length); OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx.ctx) == key_length);
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == iv_length); // ECB does not use IV
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == 0);
OPENSSL_assert(EVP_CIPHER_CTX_block_size(&ctx.ctx) == 16); OPENSSL_assert(EVP_CIPHER_CTX_block_size(&ctx.ctx) == 16);
if (! EVP_EncryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len, if (! EVP_EncryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len,
(unsigned const char *) source, source_length)) (unsigned const char *) source, source_length))
...@@ -438,9 +439,9 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length, ...@@ -438,9 +439,9 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length,
if (! EVP_EncryptFinal_ex(&ctx.ctx, (unsigned char *) dest + u_len, &f_len)) if (! EVP_EncryptFinal_ex(&ctx.ctx, (unsigned char *) dest + u_len, &f_len))
return AES_BAD_DATA; /* Error */ return AES_BAD_DATA; /* Error */
if (remaining_bytes!=0) { if (remaining_bytes!=0)
memcpy(dest + source_length, source + source_length, remaining_bytes); memcpy(dest + source_length, source + source_length, remaining_bytes);
}
*dest_length = (unsigned long int) (u_len + f_len + remaining_bytes); *dest_length = (unsigned long int) (u_len + f_len + remaining_bytes);
return AES_OK; return AES_OK;
...@@ -524,7 +525,8 @@ static int my_aes_decrypt_cbc(const uchar* source, uint32 source_length, ...@@ -524,7 +525,8 @@ static int my_aes_decrypt_cbc(const uchar* source, uint32 source_length,
if (noPadding) { if (noPadding) {
memcpy(dest, block, MY_AES_BLOCK_SIZE); memcpy(dest, block, MY_AES_BLOCK_SIZE);
if (remaining_bytes!=0) { if (remaining_bytes!=0) {
memcpy(dest + source_length, source + source_length, remaining_bytes); /* Note that we have moved dest and source */
memcpy(dest + MY_AES_BLOCK_SIZE, source + MY_AES_BLOCK_SIZE, remaining_bytes);
} }
*dest_length = MY_AES_BLOCK_SIZE * num_blocks + remaining_bytes; *dest_length = MY_AES_BLOCK_SIZE * num_blocks + remaining_bytes;
return AES_OK; return AES_OK;
...@@ -656,7 +658,8 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length, ...@@ -656,7 +658,8 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length,
if (noPadding) { if (noPadding) {
memcpy(dest, block, MY_AES_BLOCK_SIZE); memcpy(dest, block, MY_AES_BLOCK_SIZE);
if (remaining_bytes!=0) { if (remaining_bytes!=0) {
memcpy(dest + source_length, source + source_length, remaining_bytes); /* Note that we have moved dest and source */
memcpy(dest + MY_AES_BLOCK_SIZE, source + MY_AES_BLOCK_SIZE, remaining_bytes);
} }
*dest_length = MY_AES_BLOCK_SIZE * num_blocks + remaining_bytes; *dest_length = MY_AES_BLOCK_SIZE * num_blocks + remaining_bytes;
return AES_OK; return AES_OK;
...@@ -699,7 +702,8 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length, ...@@ -699,7 +702,8 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length,
EVP_CIPHER_CTX_set_padding(&ctx.ctx, 0); EVP_CIPHER_CTX_set_padding(&ctx.ctx, 0);
} }
OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx.ctx) == key_length); OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx.ctx) == key_length);
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == iv_length); // ECB does not use IV
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == 0);
OPENSSL_assert(EVP_CIPHER_CTX_block_size(&ctx.ctx) == 16); OPENSSL_assert(EVP_CIPHER_CTX_block_size(&ctx.ctx) == 16);
if (! EVP_DecryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len, if (! EVP_DecryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len,
(unsigned char *)source, source_length)) (unsigned char *)source, source_length))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment