I'am using the Open SSL in my program, to encrypt and decrypt the data using aes ciphers. At the moment there is a little memory leak, so i'm looking for a way to fix that. In my encrypt decrypt routines, i have the contexts free like so
EVP_CIPHER_CTX_free(ctx);
And created by:
EVP_CIPHER_CTX_new
This was on the OpenSSL wiki page in the examples
But! On the MAN page, there is a suggestion for using EVP_CIPHER_CTX_cleanup
and EVP_CIPHER_CTX_init
functions. So basically what should be correct to use, is the EVP_CIPHER_CTX_new
/EVP_CIPHER_CTX_free
is somehow deprecated? And is there any big difference between EVP_CIPHER_CTX_new
/EVP_CIPHER_CTX_free
and EVP_CIPHER_CTX_init
/ EVP_CIPHER_CTX_cleanup
?
if(!(ctx = EVP_CIPHER_CTX_new())) return -1;
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
{
EVP_CIPHER_CTX_free(ctx);
return -1;
}
if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
{
EVP_CIPHER_CTX_free(ctx);
return -1;
}
ciphertext_len = len;
if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) { EVP_CIPHER_CTX_free(ctx); return -1; }
ciphertext_len += len;
EVP_CIPHER_CTX_free(ctx);
First of all if you want a precise answer, you should always specify which version of OpenSSL you are using. FYI 1.0.2 is current Long Term Support version, while 1.1.0 is the newest (in Sept 2016).
If you read the 1.1.0 man pages you will notice:
EVP_CIPHER_CTX was made opaque in OpenSSL 1.1.0. As a result, EVP_CIPHER_CTX_reset() appeared and EVP_CIPHER_CTX_cleanup() disappeared. EVP_CIPHER_CTX_init() remains as an alias for EVP_CIPHER_CTX_reset().
Short answer is: you should use EVP_CIPHER_CTX_new
to initialize and EVP_CIPHER_CTX_free
do free the memory, regardless of the version, here's why.
Allocating:
1.0.2 man pages say:
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
and 1.1.0 man pages say:
EVP_CIPHER_CTX *ctx;
ctx = EVP_CIPHER_CTX_new();
If you look at the code of EVP_CIPHER_CTX_init in 1.0.2
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
{
memset(ctx, 0, sizeof(EVP_CIPHER_CTX));
/* ctx->cipher=NULL; */
}
while EVP_CIPHER_CTX_new is:
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
{
EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
if (ctx)
EVP_CIPHER_CTX_init(ctx);
return ctx;
}
so you you are still better off initializing the context, like in 1.1.0 example:
EVP_CIPHER_CTX *ctx;
ctx = EVP_CIPHER_CTX_new();
for 1.1.0 the same applies.
For freeing the memory:
1.0.2 man pages:
EVP_CIPHER_CTX_cleanup(&ctx);
1.1.0 man pages:
EVP_CIPHER_CTX_free(ctx);
But if you check the code you can see that for 1.0.2:
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
{
if (ctx) {
EVP_CIPHER_CTX_cleanup(ctx);
OPENSSL_free(ctx);
}
}
So you should use EVP_CIPHER_CTX_free
for deallocating.
If you just want to reset the context for another operation then EVP_CIPHER_CTX_cleanup
(1.0.2) and EVP_CIPHER_CTX_reset
(1.1.0) are your friends.
If you are curious about malloc
memset
and calloc
, here's a good explanation
You should not use EVP_EncryptInit
anymore. That function did automatically create a specific context, but it didn't support the crypto engines that were later added. EVP_EncryptInit_ex
however explicitly states that:
ctx
must be initialized before calling this function.
so you are required to use EVP_CIPHER_CTX_new
here I suppose.
EVP_CIPHER_CTX_free
is another matter, it seems to have been deprecated, I don't see any mention of it on the manual pages of OpenSSL. It is good practice (and required for NIST certified functionality) to delete key material and other state of a cipher after use. Otherwise an attacker may scan the memory or use an overflow at a later stage.
The name of EVP_CIPHER_CTX_free
only indicates that the CTX memory should be released. But freeing of memory does not imply that it is scrubbed of sensitive information first; it's just returned to the system, which is under no obligation to overwrite it either. EVP_CIPHER_CTX_cleanup
on the other hand does explicitly scrub such information before freeing the memory (or it does at least make a decent attempt to do so, I presume). So you need to call this function after you've supplied your key material.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With