Abstract EVP cipher context creation

The EVP_CIPHER_CTX is now created inside a wrapper function to add support
for OpenSSL 1.1. Also fixed improper use of the EVP_CIPHER_CTX internals
in binlogrouter.
This commit is contained in:
Markus Mäkelä
2017-06-27 00:54:19 +03:00
parent 469b432ebe
commit a47d4c40f5
4 changed files with 83 additions and 22 deletions

View File

@ -0,0 +1,25 @@
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2020-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <maxscale/cdefs.h>
#include <openssl/evp.h>
MXS_BEGIN_DECLS
EVP_CIPHER_CTX* mxs_evp_cipher_ctx_alloc();
void mxs_evp_cipher_ctx_free(EVP_CIPHER_CTX* ctx);
MXS_END_DECLS

View File

@ -1,4 +1,4 @@
add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c config_runtime.c dcb.c filter.c filter.cc externcmd.c paths.c hashtable.c hint.c housekeeper.c load_utils.c log_manager.cc maxscale_pcre2.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.cc poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c ssl.c mysql_utils.c mysql_binlog.c modulecmd.c) add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c config_runtime.c dcb.c filter.c filter.cc externcmd.c paths.c hashtable.c hint.c housekeeper.c load_utils.c log_manager.cc maxscale_pcre2.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.cc poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c ssl.c mysql_utils.c mysql_binlog.c modulecmd.c encryption.c)
if(WITH_JEMALLOC) if(WITH_JEMALLOC)
target_link_libraries(maxscale-common ${JEMALLOC_LIBRARIES}) target_link_libraries(maxscale-common ${JEMALLOC_LIBRARIES})

37
server/core/encryption.c Normal file
View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2020-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <maxscale/cdefs.h>
#include <maxscale/alloc.h>
#include <maxscale/encryption.h>
EVP_CIPHER_CTX* mxs_evp_cipher_ctx_alloc()
{
#ifdef OPENSSL_1_1
return EVP_CIPHER_CTX_new();
#else
EVP_CIPHER_CTX* rval = (EVP_CIPHER_CTX*)MXS_MALLOC(sizeof(*rval));
EVP_CIPHER_CTX_init(rval);
return rval;
#endif
}
void mxs_evp_cipher_ctx_free(EVP_CIPHER_CTX* ctx)
{
#ifdef OPENSSL_1_1
EVP_CIPHER_CTX_free(ctx);
#else
MXS_FREE(ctx);
#endif
}

View File

@ -72,6 +72,7 @@
#include <maxscale/alloc.h> #include <maxscale/alloc.h>
#include <inttypes.h> #include <inttypes.h>
#include <maxscale/secrets.h> #include <maxscale/secrets.h>
#include <maxscale/encryption.h>
/** /**
* AES_CTR handling * AES_CTR handling
@ -2796,7 +2797,6 @@ static GWBUF *blr_aes_crypt(ROUTER_INSTANCE *router,
uint8_t *iv, uint8_t *iv,
int action) int action)
{ {
EVP_CIPHER_CTX ctx;
uint8_t *key = router->encryption.key_value; uint8_t *key = router->encryption.key_value;
unsigned int key_len = router->encryption.key_len; unsigned int key_len = router->encryption.key_len;
int outlen; int outlen;
@ -2819,10 +2819,10 @@ static GWBUF *blr_aes_crypt(ROUTER_INSTANCE *router,
out_ptr = GWBUF_DATA(outbuf); out_ptr = GWBUF_DATA(outbuf);
EVP_CIPHER_CTX_init(&ctx); EVP_CIPHER_CTX *ctx = mxs_evp_cipher_ctx_alloc();
/* Set the encryption algorithm accordingly to key_len and encryption mode */ /* Set the encryption algorithm accordingly to key_len and encryption mode */
if (!EVP_CipherInit_ex(&ctx, if (!EVP_CipherInit_ex(ctx,
ciphers[router->encryption.encryption_algorithm](router->encryption.key_len), ciphers[router->encryption.encryption_algorithm](router->encryption.key_len),
NULL, NULL,
key, key,
@ -2830,23 +2830,23 @@ static GWBUF *blr_aes_crypt(ROUTER_INSTANCE *router,
action)) action))
{ {
MXS_ERROR("Error in EVP_CipherInit_ex for algo %d", router->encryption.encryption_algorithm); MXS_ERROR("Error in EVP_CipherInit_ex for algo %d", router->encryption.encryption_algorithm);
EVP_CIPHER_CTX_cleanup(&ctx); mxs_evp_cipher_ctx_free(ctx);
MXS_FREE(outbuf); MXS_FREE(outbuf);
return NULL; return NULL;
} }
/* Set no padding */ /* Set no padding */
EVP_CIPHER_CTX_set_padding(&ctx, 0); EVP_CIPHER_CTX_set_padding(ctx, 0);
/* Encryt/Decrypt the input data */ /* Encryt/Decrypt the input data */
if (!EVP_CipherUpdate(&ctx, if (!EVP_CipherUpdate(ctx,
out_ptr + 4, out_ptr + 4,
&outlen, &outlen,
buffer, buffer,
size)) size))
{ {
MXS_ERROR("Error in EVP_CipherUpdate"); MXS_ERROR("Error in EVP_CipherUpdate");
EVP_CIPHER_CTX_cleanup(&ctx); mxs_evp_cipher_ctx_free(ctx);
MXS_FREE(outbuf); MXS_FREE(outbuf);
return NULL; return NULL;
} }
@ -2857,7 +2857,7 @@ static GWBUF *blr_aes_crypt(ROUTER_INSTANCE *router,
if (router->encryption.encryption_algorithm != BLR_AES_CBC) if (router->encryption.encryption_algorithm != BLR_AES_CBC)
{ {
/* Call Final_ex */ /* Call Final_ex */
if (!EVP_CipherFinal_ex(&ctx, if (!EVP_CipherFinal_ex(ctx,
(out_ptr + 4 + outlen), (out_ptr + 4 + outlen),
(int*)&flen)) (int*)&flen))
{ {
@ -2871,12 +2871,12 @@ static GWBUF *blr_aes_crypt(ROUTER_INSTANCE *router,
* If some bytes (ctx.buf_len) are still available in ctx.buf * If some bytes (ctx.buf_len) are still available in ctx.buf
* handle them with ECB and XOR * handle them with ECB and XOR
*/ */
if (ctx.buf_len) if (size - outlen > 0)
{ {
if (!blr_aes_create_tail_for_cbc(out_ptr + 4 + outlen, if (!blr_aes_create_tail_for_cbc(out_ptr + 4 + outlen,
ctx.buf, buffer + outlen,
ctx.buf_len, size - outlen,
ctx.oiv, iv,
router->encryption.key_value, router->encryption.key_value,
router->encryption.key_len)) router->encryption.key_len))
{ {
@ -2892,7 +2892,7 @@ static GWBUF *blr_aes_crypt(ROUTER_INSTANCE *router,
outbuf = NULL; outbuf = NULL;
} }
EVP_CIPHER_CTX_cleanup(&ctx); mxs_evp_cipher_ctx_free(ctx);
return outbuf; return outbuf;
} }
@ -3070,14 +3070,13 @@ static int blr_aes_create_tail_for_cbc(uint8_t *output,
uint8_t *key, uint8_t *key,
unsigned int key_len) unsigned int key_len)
{ {
EVP_CIPHER_CTX t_ctx;
uint8_t mask[AES_BLOCK_SIZE]; uint8_t mask[AES_BLOCK_SIZE];
int mlen = 0; int mlen = 0;
EVP_CIPHER_CTX_init(&t_ctx); EVP_CIPHER_CTX* t_ctx = mxs_evp_cipher_ctx_alloc();
/* Initialise with AES_ECB and NULL iv */ /* Initialise with AES_ECB and NULL iv */
if (!EVP_CipherInit_ex(&t_ctx, if (!EVP_CipherInit_ex(t_ctx,
ciphers[BLR_AES_ECB](key_len), ciphers[BLR_AES_ECB](key_len),
NULL, NULL,
key, key,
@ -3085,22 +3084,22 @@ static int blr_aes_create_tail_for_cbc(uint8_t *output,
BINLOG_FLAG_ENCRYPT)) BINLOG_FLAG_ENCRYPT))
{ {
MXS_ERROR("Error in EVP_CipherInit_ex CBC for last block (ECB)"); MXS_ERROR("Error in EVP_CipherInit_ex CBC for last block (ECB)");
EVP_CIPHER_CTX_cleanup(&t_ctx); mxs_evp_cipher_ctx_free(t_ctx);
return 0; return 0;
} }
/* Set no padding */ /* Set no padding */
EVP_CIPHER_CTX_set_padding(&t_ctx, 0); EVP_CIPHER_CTX_set_padding(t_ctx, 0);
/* Do the enc/dec of the IV (the one from previous stage) */ /* Do the enc/dec of the IV (the one from previous stage) */
if (!EVP_CipherUpdate(&t_ctx, if (!EVP_CipherUpdate(t_ctx,
mask, mask,
&mlen, &mlen,
iv, iv,
sizeof(mask))) sizeof(mask)))
{ {
MXS_ERROR("Error in EVP_CipherUpdate ECB"); MXS_ERROR("Error in EVP_CipherUpdate ECB");
EVP_CIPHER_CTX_cleanup(&t_ctx); mxs_evp_cipher_ctx_free(t_ctx);
return 0; return 0;
} }
@ -3115,7 +3114,7 @@ static int blr_aes_create_tail_for_cbc(uint8_t *output,
output[i] = input[i] ^ mask[i]; output[i] = input[i] ^ mask[i];
} }
EVP_CIPHER_CTX_cleanup(&t_ctx); mxs_evp_cipher_ctx_free(t_ctx);
return 1; return 1;
} }