0

i'm try to get a bowfish function working for simple char buffers. The program fails when I try to decrypt an encrypted buffer and fails on the EVP_CipherFinal_ex() call.

#include <string.h> 
#include <openssl/evp.h> 
#include <openssl/buffer.h> 
#include <openssl/blowfish.h>
#include <openssl/evp.h>

int do_crypt(unsigned char *inbuf, int inlen, unsigned char *outbuf, int *outlen, int do_encrypt) { 
     outbuf=(unsigned char*) malloc(inlen+EVP_MAX_BLOCK_LENGTH); 
     int tmplen=0; 
     unsigned char key[] = "0123456789"; 
     unsigned char iv[] = "12345678"; 

     EVP_CIPHER_CTX ctx; 
     EVP_CIPHER_CTX_init(&ctx); 
     EVP_CipherInit_ex(&ctx, EVP_bf_cbc(), NULL, NULL, NULL, do_encrypt); 
     EVP_CIPHER_CTX_set_key_length(&ctx, 10); 
     EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt); 

     if(!EVP_CipherUpdate(&ctx, outbuf, outlen, inbuf, inlen)) { 
         /* Error */ 
         printf("* update failed *\n"); 
         EVP_CIPHER_CTX_cleanup(&ctx); 
         return 0; 
     } 

     int db=*outlen; 

     if(!EVP_CipherFinal_ex(&ctx, outbuf+db, &tmplen)) { 
         /* Error */ 
          ERR_print_errors_fp(stderr); 
         printf("* finalise failed *\n"); 
         EVP_CIPHER_CTX_cleanup(&ctx); 
         return 0; 
     } 


     (*outlen)=db+tmplen; 

     EVP_CIPHER_CTX_cleanup(&ctx); 

     return 1; 
} 
int main(int argc, char **argv) { 
     char *plain="ENCRYPT DECRYPT this string"; 
     int plain_len=strlen(plain); 
     unsigned char *cipher; 
     int cipher_len; 

     printf("***** ENCRYPT *****\n"); 
     if (!do_crypt((unsigned char*) plain, strlen(plain), cipher, &cipher_len, 1)) { 
         printf("failed to encrypt\n"); 
         return 1; 
     } 

     char *decrypt; 
     int decrypt_len; 
     printf("***** DECRYPT *****\n"); 
     if(!do_crypt(  cipher ,cipher_len , decrypt, &decrypt_len, 0)) { 
         printf("failed to decrypt\n"); 
         return 1; 
     }
 printf("decrypt=\"%s\"\n",decrypt); 
 printf("decrypt_len=%d\n",decrypt_len); 
     return 0; 
} 

any help would be much appreciated.

Flan Alflani
  • 2,065
  • 3
  • 15
  • 17
  • And *how* do it fail? What errors do you get? What is the expected output of your program, and what is the actual output? – Some programmer dude Jul 12 '14 at 21:41
  • @JoachimPileborg Segmentation fault '140536099350160:error:06065064:lib(6):func(101):reason(100):evp_enc.c:539:' – Flan Alflani Jul 12 '14 at 21:42
  • There's also an example of how to use the `EVP_*` interfaces for encryption and decryption on the OpenSSL wiki. See [EVP Symmetric Encryption and Decryption](http://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption). – jww Jul 13 '14 at 00:18
  • If anyone is interested i found a solution [here](http://stackoverflow.com/questions/5727646/what-is-the-length-parameter-of-aes-evp-decrypt)! thank you all – Flan Alflani Jul 16 '14 at 03:18

1 Answers1

1

You have two problems: The first is that you should not cast the result of malloc in C. This is the most likely reason EVP_CipherUpdate crashes.

The second error is that arguments in C are passed by value, meaning they are copied and the functions only have copies of the arguments passed by the caller. This means that in the do_crypt function when you assign to the argument output you are only assigning to the local copy inside the function, the variable cipher in the main function will not be changed.

The last problem can be solved by imitating pass by reference by passing a pointer to the pointer, and use the address-of operator & and the dereference * operator:

/*                                     Note extra indirection */
/*                                                          | */
/*                                                          v */
int do_crypt(unsigned char *inbuf, int inlen, unsigned char **outbuf, int *outlen, int do_encrypt) {
    ...
    *output = malloc(...);
    ...
    if(!EVP_CipherUpdate(&ctx, *outbuf, outlen, inbuf, inlen)) { ... }
    ...
 }

You then call it like

do_crypt((unsigned char*) plain, strlen(plain), &cipher, &cipher_len, 1)
Community
  • 1
  • 1
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • the problem is when i try to decrypt the the char buffers and i try what you suggested however did not work and rise so many errors. – Flan Alflani Jul 12 '14 at 22:09
  • @FlanAlflani Try fixing those errors (and possible warnings). If you don't know how to fix all errors, post a new question with the modified code and include the complete the complete and unedited error and warning logs. Also remember that in the function you have to think about [operator precedence](http://en.cppreference.com/w/c/language/operator_precedence) when adding the dereference oprator. For example you have e.g. `outbuf+db` in your original code, which you should change to `(*output)+db`. – Some programmer dude Jul 12 '14 at 22:15
  • @FlanAlflani But I really fail to see where you could get errors. The only thing I see is a warning from the `malloc` call if you don't follow the link in my answer and read about why you should not cast `malloc` and how to fix those warnings. – Some programmer dude Jul 12 '14 at 22:17