I copied the do_crypt routine (General encryption, decryption function example
using FILE I/O and RC2 with an 80 bit key) from the EVP_EncryptInit(3) man
page and used it to encrypt a 433282 byte file. Function EVP_CipherFinal_ex
fails and ERR_get_error returns `error:0606506D:lib(6):func(101):reason(109)',
i.e. WRONG FINAL BLOCK LENGTH. ctx.buf_len has a value of 2. I thought
EVP_CipherFinal_ex would pad the extra bytes and encrypt them.
I get and out file of 433280 bytes, which using, the same routine to decode,
results in a 433288 byte file. i.e. the last two bytes of the orinigal
file vanish and 8 bytes of garbage get appended. Clearly I have misunderstood
something. Please help.
Here is the code.
I inserted unsigned char before inbuf[1024]
and the lines:
char *errorString = ERR_error_string(ERR_get_error(),0);
printf ("Error check> %s <\n", errorString);
printf("number we have left: %d\n", ctx.buf_len);
after
if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
Douglas Laing - Johannesburg
/* General encryption, decryption function example using FILE I/O and RC2
with an 80 bit key */
#include <openssl/evp.h>
int do_crypt(FILE *in, FILE *out, int do_encrypt)
{
/* Allow enough space in output buffer for additional block
*/
unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
int inlen, outlen;
/* Bogus key and IV: we’d normally set these from
* another source.
*/
unsigned char key[] = "0123456789";
unsigned char iv[] = "12345678";
EVP_CIPHER_CTX ctx;
/* Don’t set key or IV because we will modify the parameters */
EVP_CIPHER_CTX_init(&ctx);
/* int EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); &ctx
initializes cipher contex ctx. */
EVP_CipherInit_ex(&ctx, EVP_rc2_cbc(), NULL, NULL, NULL,
do_encrypt);
/* int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, &ctx
const EVP_CIPHER *type, EVP_rc2_cbc()
ENGINE *impl, NULL
unsigned char *key, NULL
unsigned char *iv, NULL
int enc); do_encryp
EVP_CipherInit_ex(), EVP_CipherUpdate() and EVP_CipherFinal_ex() are
functions that can be used for decryption or encryption. The operation
performed depends on the value of the enc parameter. It should be set
to 1 for encryption, 0 for decryption and -1 to leave the value
unchanged (the actual value of ’enc’ being supplied in a previous
call). */
EVP_CIPHER_CTX_set_key_length(&ctx, 10);
/* sets the key length of the cipher ctx.
If the cipher is a fixed length cipher then attempting to set the key
length to any value other than the fixed value is an error. */
/* We finished modifying parameters so now we can set key and IV */
EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
/* int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, &ctx
const EVP_CIPHER *type, NULL,
ENGINE *impl, NULL
unsigned char *key, key
unsigned char *iv, iv
int enc); do_encryp */
for(;;)
{
inlen = fread(inbuf, 1, 1024, in);
if(inlen <= 0) break;
if(!EVP_CipherUpdate(&ctx, outbuf, &outlen,
inbuf, inlen))
/* int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, &ctx
unsigned char *out, outbuf
int *outl, &outlen
unsigned char *in, inbuf
int inl); inlen */
{
/* Error */
return 0;
}
fwrite(outbuf, 1, outlen, out);
}
if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
/* If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts
the "final" data, that is any data that remains in a partial block. It
uses standard block padding (aka PKCS padding). The encrypted final
data is written to out which should have sufficient space for one
cipher block. The number of bytes written is placed in outl. After this
function is called the encryption operation is finished and no further
calls to EVP_EncryptUpdate() should be made. */
{
/* Error */
char *errorString = ERR_error_string(ERR_get_error(),0);
printf ("Error check> %s <\n", errorString);
printf("number we have left: %d\n", ctx.buf_len);
return 0;
}
fwrite(outbuf, 1, outlen, out);
EVP_CIPHER_CTX_cleanup(&ctx);
/* clears all information from a cipher context
and free up any allocated memory associate with it. It should be called
after all operations using a cipher are complete so sensitive informa-
tion does not remain in memory. */
return 1;
}
- WRONG FINAL BLOCK LENGTH Douglas Laing
- Re: WRONG FINAL BLOCK LENGTH Nils Larsch
- Re: WRONG FINAL BLOCK LENGTH Douglas Laing
