Hi,
I tried to encrypt and decrypt a text using different ciphers. There I found that the decryption failes at EVP_CipherFinal_ex() call. Somebody please point me out what I've done wrong. The code is attached.
Cheers,
Kaushalye
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <axis2_base64.h>
#include <string.h>

#define BUFSIZE 64

void printerror()
{                       unsigned long ErrCode = ERR_get_error();
                        char ErrBuf[120];
                        ERR_error_string(ErrCode, ErrBuf);
                        fprintf(stderr, "Error: [%s]\n", ErrBuf); 
}

int cryptbuf(unsigned char *in_main_buf, unsigned char **out_main_buf, int do_encrypt)
{
        
        unsigned char inbuf[BUFSIZE + 1 ], outbuf[BUFSIZE + EVP_MAX_BLOCK_LENGTH]; /*EVP_MAX_BLOCK_LENGTH = 32 in evp.h*/
        unsigned char *tempbuf, *tempbuf2 ;
        int inlen, outlen, i, in_main_len, out_buf_index;
        EVP_CIPHER_CTX ctx;
        int ret;

        /* Bogus key and IV: Set the correct size, if u change the cipher.
           Check the list given below
         */
        unsigned char key[EVP_MAX_KEY_LENGTH] = "0123456701234567";
        unsigned char iv[EVP_MAX_IV_LENGTH] = "0123456701234567";

        EVP_CIPHER_CTX_init(&ctx);
        /*Uncomment one of followings to encrypt. Make sure u have the correct key and IV size*/
       
        /*EVP_CipherInit_ex(&ctx, EVP_rc2(), NULL, NULL, NULL, do_encrypt);*/
        /*EVP_CipherInit_ex(&ctx, EVP_rc2_cbc(), NULL, NULL, NULL, do_encrypt);*/
        /*EVP_CipherInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, key, iv, do_encrypt);*/
        EVP_CipherInit_ex(&ctx,  EVP_aes_128_cbc(), NULL, NULL, NULL, do_encrypt);
        
        EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);

        printf("Length of the key is %d\n",EVP_CIPHER_key_length(&ctx));       
        printf("Length of the IV is %d\n",EVP_CIPHER_CTX_iv_length(&ctx));       
     
        i = 0;
        out_buf_index = 0;

        for(;;)
        {
                memset(inbuf,0 ,BUFSIZE);/*Reset memory for the inbuf*/
                memcpy(inbuf, in_main_buf + (i * BUFSIZE) , BUFSIZE );/*Copy the first block to the inbuf*/
                inbuf[BUFSIZE] = '\0';

                in_main_len = strlen((const char*)in_main_buf);
                /*inlen = strlen(inbuf);*/

                if(in_main_len <= i*BUFSIZE) break; /*Finish!!! */

                /*If we are in the last block, set inlen according to the in_main_len */
                if(in_main_len <= (i+1)*BUFSIZE)
                {
                    inlen = in_main_len - (i*BUFSIZE);
                }else{
                    inlen = BUFSIZE;
                }

                
                if(do_encrypt == 1){
                    printf("\nEncrypting block[%d] %s", inlen, inbuf);
                }

                memset(outbuf,0 ,BUFSIZE + EVP_MAX_BLOCK_LENGTH);/*Reset memory for the outbuf*/
                if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
                {
                        /* Error */
                        EVP_CIPHER_CTX_cleanup(&ctx);
                        printf("\nERROR: EVP_CIPHER_CTX_cleanup");

                        printerror();
                        return (-1);
                }
                /*TODO: Write the encrypted block to the tempbuf*/ 
                tempbuf2 = malloc(out_buf_index + outlen);
                if(i>0){/*Skip for the i=0 step*/
                    memcpy(tempbuf2, tempbuf, out_buf_index);
                    /*free tempbuf*/
                    free(tempbuf);
                }
                memcpy(tempbuf2 + out_buf_index, outbuf, outlen);
                tempbuf = tempbuf2; /*Assign new tempbuf2 to the old one*/
                out_buf_index = out_buf_index + outlen;/*Update the writing position of the tempbuf*/
                
                i++;
        }/*End of for loop*/
       
        if(do_encrypt == 1){
            printf("\neCipherFinalizing block[%d] %s", strlen((char*)outbuf), outbuf);
        }else{
            printf("\ndCipherFinalizing block[%d]", strlen((char*)outbuf));
        } 
        ret = EVP_CipherFinal_ex(&ctx, outbuf, &outlen); 
        if(!ret)
        {
                /* Error */
                EVP_CIPHER_CTX_cleanup(&ctx);
                printf("\nERROR:EVP_CipherFinal_ex--- EVP_CIPHER_CTX_cleanup");
    
                printerror();
                return (-1);
        }
        /*Alright now we need to write the last drop*/
        tempbuf2 = malloc(out_buf_index + outlen);
        memcpy(tempbuf2, tempbuf, out_buf_index);
        /*free tempbuf*/
        free(tempbuf);

        memcpy(tempbuf2 + out_buf_index, outbuf, outlen);
        tempbuf = tempbuf2; /*Assign new tempbuf2 to the old one*/
        
        out_buf_index = out_buf_index + outlen;/*Update the writing position of the tempbuf*/

        EVP_CIPHER_CTX_cleanup(&ctx);
        /*Assign the temp buf to the out_main_buf*/
        
        *out_main_buf = tempbuf;    
        free(tempbuf2);
        return out_buf_index;
}
 
 

int main()
{

    FILE *out;
    FILE *out2;

    /*The length of each line is 64*/
    unsigned char in_main_buf[] = "Upon successful completion, fread() returns the number of ...AB1"\
                                  "Upon successful completion, fread() returns the number of ...AB2";
                                  /*"This is an additional block :)";*/
    unsigned char *out_main_buf = NULL;
    unsigned char *decrypt_in_buf ; 
    unsigned char *decrypt_out_buf = NULL;

    int crypted_length ;

    crypted_length = cryptbuf(in_main_buf, &out_main_buf, 1); /*Encrypt*/
    if(crypted_length < 0){
        printf("\nERROR");
    }else{
        
        out = fopen("outbuf", "wb");
        fwrite(out_main_buf, 1, crypted_length, out);
        /*fclose(out);*/
    
        printf("\n******************************************************\n");
        memcpy(decrypt_in_buf, out_main_buf  , strlen((char*)out_main_buf));/*Copy the first block to the inbuf*/
        
        crypted_length = cryptbuf(decrypt_in_buf, &decrypt_out_buf, 0);/*Decrypt*/

        if(crypted_length < 0 ){
            printf("\nERROR decrypting");
        }  else{
            printf("\nPlain Text =%s",decrypt_out_buf);

        } 
    }
     
    return 0;

}

/*
Block, Key and IV sizes of each cipher
Cipher : des_ede3_cbc--------------------------
Blk size :8
Key size :24
IVsize :8

Cipher : aes-128-cbc--------------------------
Blk size :16
Key size :16
IV  size :16

Cipher : aes-192-cbc--------------------------
Blk size :16
Key size :24
IV  size :16

Cipher : aes-256-cbc--------------------------
Blk size :16
Key size :32
IV  size :16

Cipher : aes-128-ecb--------------------------
Blk size :16
Key size :16
IV  size :16

Cipher : aes-192-ecb--------------------------
Blk size :16
Key size :24
IV  size :16

Cipher : aes-256-ecb--------------------------
Blk size :16
Key size :32
IV  size :16
*/

Reply via email to