Hi ,
I am trying to encrypt and decrypt a large file using the Openssl API.
I am doing this by calling EVP_EncryptUpdate / EVP_DecryptUpdate iteratively
for a block size of 1024 and then calling the EVP_EncryptFinal_ex/
EVP_DecryptFinal_ex respectively in the end.
It always fails to decrypt for file sizes greater than 1024 bytes (which is
the size of the block in which I am encrypting / decrypting). If I increase
the blocksize to say 2048 and then it only encrypts files with 2048 bytes or
less.
The error I get is "5790:error:06065064:digital envelope
routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:461:"
I have used the standard methods and I am unable to see any problems with
this code.
Can anybody please help in identifying the problem? I am using Openssl
version 0.9.8e
Thanks in Advance,
Please see the code attached.
Encryption:
------------------
const EVP_CIPHER* cipher;
cipher = EVP_aes_256_cbc();
int blocksize = 32;
EVP_CIPHER_CTX ctx;
int datalength,padlength;
unsigned int iNumLength = ((pInputLength + blocksize - 1) /
blocksize) + 1; // one extra block for padding
pOutLength = iNumLength * (blocksize);
unsigned char pBuff[pOutLength];
memset(pBuff,0,pOutLength * sizeof(unsigned char));
printf("\n pInputLength is %d\n", pInputLength);
printf("\n pBuff Length is %d\n", pOutLength);
EVP_CIPHER_CTX_init(&ctx);
if(!EVP_EncryptInit_ex(&ctx,cipher,NULL,key,NULL))
{
printf("\nEncryptInit failed\n");
ERR_print_errors_fp(stdout);
EVP_CIPHER_CTX_cleanup(&ctx);
return CRYPTO_ENCRYPTION_ENGINE_FAILURE;
}
unsigned int iNumChunks = pInputLength / 1024;
int currentLength = 0;
datalength = 0;
printf("\n iNumChunks is %d\n", iNumChunks);
memset(pBuff,0,pOutLength * sizeof(unsigned char));
for(int i=0;i<iNumChunks;i++)
{
if(!EVP_EncryptUpdate(&ctx,&pBuff[currentLength],&datalength,&pData[currentLength],1024))
{
printf("\nEncrypt failed\n");
ERR_print_errors_fp(stdout);
EVP_CIPHER_CTX_cleanup(&ctx);
return CRYPTO_ENCRYPTION_ENGINE_FAILURE;
}
printf("\n currentLength is %d\n",
currentLength);
printf("\n encrypt datalength 1 is %d\n",
datalength);
fflush(stdout);
currentLength += datalength;
printf("\n currentLength is %d\n",
currentLength);
}
if(pInputLength % 1024 )
{
if(!EVP_EncryptUpdate(&ctx,&pBuff[currentLength],&datalength,&pData[currentLength],pInputLength
% 1024))
{
printf("\nEncrypt failed\n");
ERR_print_errors_fp(stdout);
EVP_CIPHER_CTX_cleanup(&ctx);
return CRYPTO_ENCRYPTION_ENGINE_FAILURE;
}
printf("\n currentLength is %d\n",
currentLength);
currentLength += datalength;
printf("\n currentLength is %d\n",
currentLength);
printf("\n encrypt datalength 2 is %d\n",
datalength);
fflush(stdout);
}
if(!EVP_EncryptFinal_ex(&ctx,&pBuff[currentLength],&datalength))
{
printf("\nEncryptFinal failed\n");
ERR_print_errors_fp(stdout);
EVP_CIPHER_CTX_cleanup(&ctx);
return CRYPTO_ENCRYPTION_ENGINE_FAILURE;
}
printf("\n currentLength is %d\n", currentLength);
printf("\n encrypt datalength is %d\n", datalength);
currentLength += datalength;
pOutLength = currentLength;
printf("\n final currentLength is %d\n", currentLength);
------------------
Decryption:
const EVP_CIPHER* cipher;
cipher = EVP_aes_256_cbc();
blocksize = 32;
EVP_CIPHER_CTX ctx;
int datalength,padlength;
unsigned int iNumLength = ((sDecodedData.size() + blocksize - 1) /
blocksize) + 1; // one extra block for padding
pOutLength = iNumLength * (blocksize);
pOutLength = sDecodedData.size();
unsigned char pBuff[pOutLength];
memset(pBuff,0,pOutLength * sizeof(unsigned char));
printf("\n decrypt pOutLength is %d\n", pOutLength);
EVP_CIPHER_CTX_init(&ctx);
if(!EVP_DecryptInit_ex(&ctx,cipher,NULL,key,NULL))
{
printf("\nDecryptInit failed\n");
ERR_print_errors_fp(stdout);
EVP_CIPHER_CTX_cleanup(&ctx);
return CRYPTO_ENCRYPTION_ENGINE_FAILURE;
}
unsigned int iNumChunks = sDecodedData.size() / 1024;
const unsigned char* pInputData = (const unsigned char*)
sDecodedData.c_str();
int currentLength = 0;
printf("\n iNumChunks is %d\n", iNumChunks);
for(int i=0;i<iNumChunks;i++)
{
if(!EVP_DecryptUpdate(&ctx,&pBuff[currentLength],&datalength,&pInputData[currentLength],1024))
{
printf("\n Decrypt failed\n");
ERR_print_errors_fp(stdout);
EVP_CIPHER_CTX_cleanup(&ctx);
return CRYPTO_ENCRYPTION_ENGINE_FAILURE;
}
printf("\n decrypt datalength 1 is %d\n", datalength);
fflush(stdout);
currentLength += datalength;
}
if(sDecodedData.size() % 1024 )
{
if(!EVP_DecryptUpdate(&ctx,&pBuff[currentLength],&datalength,&pInputData[currentLength],sDecodedData.size()
% 1024))
{
printf("\nEncrypt failed\n");
ERR_print_errors_fp(stdout);
EVP_CIPHER_CTX_cleanup(&ctx);
return CRYPTO_ENCRYPTION_ENGINE_FAILURE;
}
currentLength += datalength;
printf("\n decrypt datalength 2 is %d\n",
datalength);
fflush(stdout);
}
printf("\n decrypt currentLength is %d\n",
currentLength);
fflush(stdout);
if(!EVP_DecryptFinal_ex(&ctx,&pBuff[currentLength],&datalength))
{
printf("\n DecryptFinal failed\n");
ERR_print_errors_fp(stdout);
fflush(stdout);
EVP_CIPHER_CTX_cleanup(&ctx);
return CRYPTO_ENCRYPTION_ENGINE_FAILURE;
}
currentLength += datalength;
//memcpy(pTempBuff,outBuff,(datalength + padlength));
pOutLength = currentLength;
//printf("\n Decrypted Data is %s\n",pBuff);
fflush(stdout);
--------------------------------------
_________________________________________________________________
"Post ads for free - to sell, rent or even buy.www.yello.in"
http://ss1.richmedia.in/recurl.asp?pid=186
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager [EMAIL PROTECTED]