c - Getting wrong plain text after decrypting (AES) and decoding (Base64) -


i have written small test program takes string of plain text, encrypts using aes, , encodes base 64. portion seems fine, when try decode , decrypt data, wrong information.

my code below. i'm quite new c, presume making rookie mistake wrongly using pointer or reference somewhere. have tried find problem myself in evp_decryptfinal_ex function, can't seem find bug(s). note! please ignore use of iv , key, test code.

code:

#define _gnu_source #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <openssl/evp.h> #include <openssl/bio.h> #include <openssl/pem.h>  // base 64 encoding char* base64encode(const unsigned char *message, const size_t length) {     bio *bio;     bio *b64;     file* stream;      int encodedsize = 4*ceil((double)length/3);     char *buffer = (char*)malloc(encodedsize+1);      stream = fmemopen(buffer, encodedsize+1, "w");     b64 = bio_new(bio_f_base64());     bio = bio_new_fp(stream, bio_noclose);     bio = bio_push(b64, bio);     bio_set_flags(bio, bio_flags_base64_no_nl);     bio_write(bio, message, length);     (void)bio_flush(bio);     bio_free_all(bio);     fclose(stream);      return buffer; }   // base 64 decoding int calcdecodelength(const char *b64input) {     int len = strlen(b64input);     int padding = 0;      // check trailing '=''s padding     if (b64input[len-1] == '=' && b64input[len-2] == '=') {         padding = 2;     } else if (b64input[len-1] == '=') {         padding = 1;     }     return (int)len*0.75 - padding; }  int base64decode(const char *b64message, unsigned char **buffer) {     bio *bio;     bio *b64;     int decodelen = calcdecodelength(b64message);      *buffer = (unsigned char*)malloc(decodelen+1);     file* stream = fmemopen((char*)b64message, strlen(b64message), "r");      b64 = bio_new(bio_f_base64());     bio = bio_new_fp(stream, bio_noclose);     bio = bio_push(b64, bio);     bio_set_flags(bio, bio_flags_base64_no_nl);     size_t length = bio_read(bio, *buffer, strlen(b64message));     (*buffer)[length] = '\0';      bio_free_all(bio);     fclose(stream);      return decodelen; }   // aes encryption int encryptaes(const char *plaintext, char *ciphertext, const char *key) {     unsigned char iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };      int plaintextlength = 0;     int ciphertextlength = 0;     int blocklength = 0;     static const int max_padding_length = 16;      evp_cipher_ctx encryptctx;     evp_cipher_ctx_init(&encryptctx);      plaintextlength = strlen(plaintext);     ciphertext = (unsigned char *) malloc(plaintextlength + max_padding_length);      // initialise encryption aes256 (cbc mode) using key , iv     evp_encryptinit_ex(&encryptctx, evp_aes_256_cbc(), null, key, iv);      // encrypt plaintext ciphertext, update ciphertextlength length of generated ciphertext     if (!evp_encryptupdate(&encryptctx, ciphertext, &blocklength, (unsigned char *) plaintext, plaintextlength) ) {         printf("error in evp_encryptupdate \n");         return 1;     }     ciphertextlength += blocklength;      // encrypt "final" data remaining in partial block     if (!evp_encryptfinal_ex(&encryptctx, ciphertext + ciphertextlength, &blocklength)) {         printf("error in evp_encryptfinal_ex \n");         return 1;     }     ciphertextlength += blocklength;      evp_cipher_ctx_cleanup(&encryptctx);     return ciphertextlength; }   // aes decryption int decryptaes(const char *ciphertext, char *decipheredplaintext, int ciphertextlength, const char *key) {     unsigned char iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };      int plaintextlength = 0;     int blocklength = 0;      decipheredplaintext = (unsigned char *) malloc(ciphertextlength + 1);      evp_cipher_ctx decryptctx;     evp_cipher_ctx_init(&decryptctx);      // initialise decryption aes256 (cbc mode) using key , iv     evp_decryptinit_ex(&decryptctx, evp_aes_256_cbc(), null, key, iv);      // decrypt ciphertext plaintext, update plaintextlength     if (!evp_decryptupdate(&decryptctx, decipheredplaintext, &blocklength, ciphertext, ciphertextlength)) {         printf("error in evp_decryptupdate\n");         return 1;     }     plaintextlength += blocklength;      // decrypt "final" data remaining in partial block     if (!evp_decryptfinal_ex(&decryptctx, decipheredplaintext + plaintextlength, &blocklength)) {         printf("error in evp_decryptfinal_ex\n");         return 1;     }     plaintextlength += blocklength;      evp_cipher_ctx_cleanup(&decryptctx);     return plaintextlength; }   int main(int argc, char **argv) {     unsigned char key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };     const char *plaintext = "cipher cipher cipher cipher cipher text! 187? 1$5 78@2 14 .tӒ��틪�ձ1z.$�?�u���<y";     printf("original plain text\t[%s]\n", plaintext);  ////////////// // encryption //////////////     // encrypt plain text using aes     unsigned char ciphertext[180];     int ciphertextlength = encryptaes(plaintext, ciphertext, key);     printf("cipher length\t\t[%d]\n", ciphertextlength);      // base64 encode buffer     char* encodedciphertext = base64encode(ciphertext, ciphertextlength);     printf("base64 is\t\t[%s]\n", encodedciphertext);  ////////////// // decryption //////////////     // decode base64 string     unsigned char* decodedciphertext;     int decodedciphertextlength = base64decode(encodedciphertext, &decodedciphertext);     printf("decoded cipher length\t[%d]\n", decodedciphertextlength);      // decrypt cipher text     unsigned char decryptedplaintext[180];     int decryptedplaintextlength = decryptaes(decodedciphertext, decryptedplaintext, decodedciphertextlength, key);     printf("decrypted plain text\t[%s]\n", decryptedplaintext);      // compare before , after     if (strcmp(plaintext, (char *) decryptedplaintext) == 0) {         printf("decrypted data matches input data.\n");     } else {         printf("decrypted data not match input data.\n");     }      return 0; } 

command:

gcc aestest2.c -lcrypto -std=c99 -lm 

output:

original plain text     [cipher cipher cipher cipher cipher text! 187? 1$5 78@2 14 .tӒ��틪�ձ1z.$�?�u���<y] cipher length           [112] base64               [aqaaaaaaaacieylbpgaaaoh04wx/fwaadgaaaaaaaaajaaaaaaaaap504wx/fwaaaaaaaaaaaadgfilbpgaaabb14wx/fwaalwwp2z4aaaaodemf/38aaaaaaaabaaaa2lgg2z4aaabxb0aaaaaaaa==] decoded cipher length   [112] error in evp_decryptfinal_ex decrypted plain text    [�t��] decrypted data not match input data. 

any seasoned c developer appreciated. many thanks.

you declare buffers in main(), , pass references them down en/decrypt functions.

in en/decrypt functions overwrite buffer's address received main() result returned malloc(). data calculated written freshly allocated memory. reference latter lost when returning 2 en/decrypt functions, leaving memory leak.

due buffers in main() hadn't been touched @ all.

you easyly prove setting them 0 before calling en/decrypt functions , printing them out after having returned en/decrypt functions.


Comments

Popular posts from this blog

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

html - How to style widget with post count different than without post count -

url rewriting - How to redirect a http POST with urlrewritefilter -