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
*/