[openssl-dev] EVP possibly leaking bytes

Nonce Word openssldev at gmail.com
Wed Mar 16 16:36:15 UTC 2016


Using the guide posted here:
https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption

I was getting a fairly large amount of bytes "still reachable", so I
decided to throw in all of the options to free up whatever was left over.

Originally, all that was suggested in the wiki was to EVP_cleanup() and
ERR_free_strings(). But by adding in CRYPTO_cleanup_all_ex_data(),
ERR_remove_thread_state(0), ENGINE_cleanup(), and CONF_modules_unload(0), I
was able to significantly cut down on the bytes still reachable.

Full leak check below. The code is the exact same as in the wiki, but with
the additions mentioned above.

root at openssl:~# valgrind ./test --leak-check=full --tool=memcheck -v
==31040== Memcheck, a memory error detector
==31040== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==31040== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==31040== Command: ./test --leak-check=full --tool=memcheck -v
==31040==
--31040-- WARNING: Serious error when reading debug info
--31040-- When reading debug info from /lib/x86_64-linux-gnu/ld-2.21.so:
--31040-- Ignoring non-Dwarf2/3/4 block in .debug_info
--31040-- WARNING: Serious error when reading debug info
--31040-- When reading debug info from /lib/x86_64-linux-gnu/ld-2.21.so:
--31040-- Last block truncated in .debug_info; ignoring
--31040-- WARNING: Serious error when reading debug info
--31040-- When reading debug info from /lib/x86_64-linux-gnu/ld-2.21.so:
--31040-- parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4
--31040-- WARNING: Serious error when reading debug info
--31040-- When reading debug info from /lib/x86_64-linux-gnu/libc-2.21.so:
--31040-- Ignoring non-Dwarf2/3/4 block in .debug_info
--31040-- WARNING: Serious error when reading debug info
--31040-- When reading debug info from /lib/x86_64-linux-gnu/libc-2.21.so:
--31040-- Last block truncated in .debug_info; ignoring
--31040-- WARNING: Serious error when reading debug info
--31040-- When reading debug info from /lib/x86_64-linux-gnu/libc-2.21.so:
--31040-- parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4
--31040-- WARNING: Serious error when reading debug info
--31040-- When reading debug info from /lib/x86_64-linux-gnu/libdl-2.21.so:
--31040-- Ignoring non-Dwarf2/3/4 block in .debug_info
--31040-- WARNING: Serious error when reading debug info
--31040-- When reading debug info from /lib/x86_64-linux-gnu/libdl-2.21.so:
--31040-- Last block truncated in .debug_info; ignoring
--31040-- WARNING: Serious error when reading debug info
--31040-- When reading debug info from /lib/x86_64-linux-gnu/libdl-2.21.so:
--31040-- parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4
Ciphertext is:
0000 - e0 6f 63 a7 11 e8 b7 aa-9f 94 40 10 7d 46 80 a1   .oc....... at .}F..
0010 - 17 99 43 80 ea 31 d2 a2-99 b9 53 02 d4 39 b9 70   ..C..1....S..9.p
0020 - 2c 8e 65 a9 92 36 ec 92-07 04 91 5c f1 a9 8a 44   ,.e..6.....\...D
Decrypted text is:
The quick brown fox jumps over the lazy dog
==31040==
==31040== HEAP SUMMARY:
==31040==     in use at exit: 240 bytes in 8 blocks
==31040==   total heap usage: 3,295 allocs, 3,287 frees, 121,451 bytes
allocated
==31040==
==31040== LEAK SUMMARY:
==31040==    definitely lost: 0 bytes in 0 blocks
==31040==    indirectly lost: 0 bytes in 0 blocks
==31040==      possibly lost: 0 bytes in 0 blocks
==31040==    still reachable: 240 bytes in 8 blocks
==31040==         suppressed: 0 bytes in 0 blocks
==31040== Rerun with --leak-check=full to see details of leaked memory
==31040==
==31040== For counts of detected and suppressed errors, rerun with: -v
==31040== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Code:

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/engine.h>
#include <string.h>

void handleErrors(void)
{
  ERR_print_errors_fp(stderr);
  abort();
}

int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char
*key,
  unsigned char *iv, unsigned char *plaintext)
{
  EVP_CIPHER_CTX *ctx;

  int len;

  int plaintext_len;

  /* Create and initialise the context */
  if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

  /* Initialise the decryption operation. IMPORTANT - ensure you use a key
   * and IV size appropriate for your cipher
   * In this example we are using 256 bit AES (i.e. a 256 bit key). The
   * IV size for *most* modes is the same as the block size. For AES this
   * is 128 bits */
  if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
    handleErrors();

  /* Provide the message to be decrypted, and obtain the plaintext output.
   * EVP_DecryptUpdate can be called multiple times if necessary
   */
  if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext,
ciphertext_len))
    handleErrors();
  plaintext_len = len;

  /* Finalise the decryption. Further plaintext bytes may be written at
   * this stage.
   */
  if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
  plaintext_len += len;

  /* Clean up */
  EVP_CIPHER_CTX_free(ctx);

  return plaintext_len;
}

int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
  unsigned char *iv, unsigned char *ciphertext)
{
  EVP_CIPHER_CTX *ctx;

  int len;

  int ciphertext_len;

  /* Create and initialise the context */
  if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

  /* Initialise the encryption operation. IMPORTANT - ensure you use a key
   * and IV size appropriate for your cipher
   * In this example we are using 256 bit AES (i.e. a 256 bit key). The
   * IV size for *most* modes is the same as the block size. For AES this
   * is 128 bits */
  if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
    handleErrors();

  /* Provide the message to be encrypted, and obtain the encrypted output.
   * EVP_EncryptUpdate can be called multiple times if necessary
   */
  if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext,
plaintext_len))
    handleErrors();
  ciphertext_len = len;

  /* Finalise the encryption. Further ciphertext bytes may be written at
   * this stage.
   */
  if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
  ciphertext_len += len;

  /* Clean up */
  EVP_CIPHER_CTX_free(ctx);

  return ciphertext_len;
}

int main (void)
{
  /* Set up the key and iv. Do I need to say to not hard code these in a
   * real application? :-)
   */

  /* A 256 bit key */
  unsigned char *key = (unsigned char *)"01234567890123456789012345678901";

  /* A 128 bit IV */
  unsigned char *iv = (unsigned char *)"01234567890123456";

  /* Message to be encrypted */
  unsigned char *plaintext =
                (unsigned char *)"The quick brown fox jumps over the lazy
dog";

  /* Buffer for ciphertext. Ensure the buffer is long enough for the
   * ciphertext which may be longer than the plaintext, dependant on the
   * algorithm and mode
   */
  unsigned char ciphertext[128];

  /* Buffer for the decrypted text */
  unsigned char decryptedtext[128];

  int decryptedtext_len, ciphertext_len;

  /* Initialise the library */
  ERR_load_crypto_strings();
  OpenSSL_add_all_algorithms();
  OPENSSL_config(NULL);

  /* Encrypt the plaintext */
  ciphertext_len = encrypt (plaintext, strlen ((char *)plaintext), key, iv,
                            ciphertext);

  /* Do something useful with the ciphertext here */
  printf("Ciphertext is:\n");
  BIO_dump_fp (stdout, (const char *)ciphertext, ciphertext_len);

  /* Decrypt the ciphertext */
  decryptedtext_len = decrypt(ciphertext, ciphertext_len, key, iv,
    decryptedtext);

  /* Add a NULL terminator. We are expecting printable text */
  decryptedtext[decryptedtext_len] = '\0';

  /* Show the decrypted text */
  printf("Decrypted text is:\n");
  printf("%s\n", decryptedtext);

  /* Clean up */
  EVP_cleanup();
  ERR_free_strings();
  ENGINE_cleanup();
  CONF_modules_unload(0);
  CRYPTO_cleanup_all_ex_data();
  ERR_remove_thread_state(0);

  return 0;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mta.openssl.org/pipermail/openssl-dev/attachments/20160316/ccb20f7b/attachment-0001.html>


More information about the openssl-dev mailing list