Hi, I'm trying to write simple AES encryption/decryption routines.  I'm
having trouble with the decryption routine, specifically, I get this error:
27013:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad
decrypt:evp_enc.c:461:

I've included my code below; I compile it with:
g++ <filename> -o aes -lssl -lcrypto

As one can see by running it, the encryption/decryption keys are the same,
the IVs are the same, and the ciphertexts are the same.

Thanks for any help!

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/engine.h>
#include <openssl/bio.h>
#include <openssl/evp.h>

#include <stdio.h>

unsigned char *sym_encrypt(char *data, int *len);
char *sym_decrypt(unsigned char *ctext, int len);
void print_buf(unsigned char *buf, const char* str, int len);

int main() {
  SSL_load_error_strings();
  SSL_library_init();
  OpenSSL_add_all_algorithms();

  char data[] = "this is the data";
  int len;
  unsigned char *ciphertext = sym_encrypt(data, &len);
  char *plaintext = sym_decrypt(ciphertext, len);

  printf("%s == %s\n", data, plaintext);

  return 0;
}

unsigned char *sym_encrypt(char *data, int *len) {
  int data_len = strlen(data);

  const char *pass = "password";
    const char *salt = "1234";
    int ic = 1000;
    unsigned char key_material[256];
    PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), (unsigned char *) salt,
strlen(salt), ic, 128, key_material);
    unsigned char *sym_key = key_material;
    unsigned char *iv = key_material + 16;

  // initialize the cipher
    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, sym_key, iv);

  int block_size = EVP_CIPHER_CTX_block_size(&ctx);
    unsigned char *sym_out_buf = (unsigned char *) malloc(strlen(data) +
block_size);

  // encrypt the data with the symmetric key
  print_buf(sym_key, "key", 16);
  print_buf(iv, "iv", 16);

  int out_len, out_total;

  if (!EVP_EncryptUpdate(&ctx, sym_out_buf, &out_total, (const unsigned char
*) data, data_len)) {
    ERR_print_errors_fp(stdout); }
  if (!EVP_EncryptFinal_ex(&ctx, sym_out_buf, &out_len)) {
ERR_print_errors_fp(stdout); }

  out_total += out_len;
  *len = out_total;
  print_buf(sym_out_buf, "ciphertext", out_total);

  return sym_out_buf;
}

char *sym_decrypt(unsigned char *ctext, int len) {
  const char *pass = "password";
    const char *salt = "1234";
    int ic = 1000;
    unsigned char key_material[256];
    PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), (unsigned char *) salt,
strlen(salt), ic, 128, key_material);
    unsigned char *sym_key = key_material;
    unsigned char *iv = key_material + 16;

  // initialize the cipher
    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, sym_key, iv);

    unsigned char *sym_out_buf = (unsigned char *) malloc(len);  // the
output is smaller than the ciphertex

  // encrypt the data with the symmetric key
  int out_len, out_total;

  print_buf(sym_key, "key", 16);
  print_buf(iv, "iv", 16);
  print_buf(ctext, "ciphertext", len);

  if (!EVP_DecryptUpdate(&ctx, sym_out_buf, &out_total, (const unsigned char
*) ctext, len)) {
    ERR_print_errors_fp(stdout); }
  if (!EVP_DecryptFinal_ex(&ctx, sym_out_buf, &out_len)) {
ERR_print_errors_fp(stdout); }

  out_total += out_len;
  sym_out_buf[out_total] = '\0';  // null-terminate it

  return (char *) sym_out_buf;
}

void print_buf(unsigned char *buf, const char *str, int p) {
  int len = (p) ? p : strlen( (char *) buf);
  printf("%s (%d):\n", str, len);
  for (int i = 0; i < len; i++) {
    printf("%02x", buf[i] & 0xFF);
  }
  printf("\n------------------------\n");
}

Reply via email to