EVP_EncryptFinal  and EVP_DecryptFinal must be used only one time after the
last update.



-----Messaggio originale-----
Da: owner-openssl-...@openssl.org [mailto:owner-openssl-...@openssl.org] Per
conto di Ladar Levison
Inviato: mercoledì 30 novembre 2011 08:33
A: openssl-dev@openssl.org
Cc: Jussi Peltonen
Oggetto: Re: Problem with EVP_EncryptUpdate/EVP_DecryptUpdate


Someone else might have a better answer, but I suspect your problem is that
your calling Final after every Update, and/or the block size is wrong.

I haven't worked with BF, but at least with AES, the modes dictates the
proper input block size. The job of the Final function is to pad the input
so it conforms to the cipher block requirements. That's why you call it at
the end, after all of your data has been fed into the cipher using the
Update function.

You might want to try padding your overall input to the proper block length.
Then verify that the extra bytes produced at the end of decryption are your
padding characters.

Your email used Decrypt for both operations, but I assume that was a typo.

Check out the man pages for EVP_CIPHER_block_size() and
EVP_EncryptFinal()/EVP_DecryptFinal().

and

http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation



On 11/30/11 12:55 AM, Jussi Peltonen wrote:
> Hello,
>
> I have a problem with the blowfish algorithm. I tried the 
> openssl-users mailing list but did not get any solutions. The 
> discussion is under subject "Blowfish algorithm problem with OpenSSL 
> 1.0.0e (32-bit)".
>
> What is wrong here?
>
> The problem is that EVP_DecryptUpdate function returns too long output
length.
>
> My test program reads 7680 bytes from a file, encrypts the bytes and 
> writes 7744 bytes to another file. Then it reads the 7744 bytes from 
> the file created, decrypts the bytes and writes the buffer to third 
> file. I thouht that the contents of the first and third file would be 
> identical.
>
> This is the output of my test functions:
>
> Encrypt:
> encrypting 7680 bytes
> EVP_DecryptUpdate 1024 bytes
> EVP_DecryptFinal 8 bytes
> EVP_DecryptUpdate 1024 bytes
> EVP_DecryptFinal 8 bytes
> EVP_DecryptUpdate 1024 bytes
> EVP_DecryptFinal 8 bytes
> EVP_DecryptUpdate 1024 bytes
> EVP_DecryptFinal 8 bytes
> EVP_DecryptUpdate 1024 bytes
> EVP_DecryptFinal 8 bytes
> EVP_DecryptUpdate 1024 bytes
> EVP_DecryptFinal 8 bytes
> EVP_DecryptUpdate 1024 bytes
> EVP_DecryptFinal 8 bytes
> EVP_DecryptUpdate 512 bytes
> EVP_DecryptFinal 8 bytes
> encrypted 7744 bytes
>
> Decrypt:
> decrypting 7744 bytes
> EVP_DecryptUpdate 1024 bytes
> EVP_DecryptFinal 0 bytes
> EVP_DecryptUpdate 1032 bytes<= why 1032 instead of 1024?
> EVP_DecryptFinal 0 bytes
> EVP_DecryptUpdate 1032 bytes
> EVP_DecryptFinal 0 bytes
> EVP_DecryptUpdate 1032 bytes
> EVP_DecryptFinal 0 bytes
> EVP_DecryptUpdate 1032 bytes
> EVP_DecryptFinal 0 bytes
> EVP_DecryptUpdate 1032 bytes
> EVP_DecryptFinal 0 bytes
> EVP_DecryptUpdate 1032 bytes
> EVP_DecryptFinal 0 bytes
> EVP_DecryptUpdate 520 bytes
> EVP_DecryptFinal 0 bytes
> decrypted 7736 bytes<= original size 7680
>
> Source code:
> =============
>
> #define IP_SIZE 1024
> #define OP_SIZE 1032
>
> static int
> decrypt (unsigned char *inbuf, int size, unsigned char *outbuf,
>                  int *outsz)
> {
>         int olen, tlen, n, left;
>         unsigned char *inp = inbuf;
>         unsigned char *outp = outbuf;
>         EVP_CIPHER_CTX ctx;
>
>         printf("decrypting %d bytes\n", size);
>
>         EVP_CIPHER_CTX_init (&ctx);
>         EVP_DecryptInit (&ctx, EVP_bf_cbc (), key, iv);
>
>         left = size;
>         *outsz = 0;
>
>         while (left>  0)
>         {
>                 n = (left>  OP_SIZE ? OP_SIZE : left);
>                 olen = 0;
>                 memset((void *)outp, 0, IP_SIZE);
>                 if (EVP_DecryptUpdate (&ctx, outp,&olen, inp, n) != 1)
>                 {
>                         return -1;
>                 }
>                 printf("EVP_DecryptUpdate %d bytes\n", olen);
>
>                 if (EVP_DecryptFinal (&ctx, outp + olen,&tlen) != 1)
>                 {
>                         return -1;
>                 }
>                 printf("EVP_DecryptFinal %d bytes\n", tlen);
>
>                 *outsz = ((*outsz) + olen + tlen);
>                 inp += n;
>                 left -= n;
>                 outp += (olen + tlen);
>         }
>
>         printf("decrypted %d bytes\n", *outsz);
>
>         EVP_CIPHER_CTX_cleanup (&ctx);
>         return 0;
> }
>
> static int
> encrypt (unsigned char *inbuf, int size, unsigned char *outbuf, int 
> *outsz) {
>         int olen, tlen, n, left;
>         unsigned char *inp = inbuf;
>         unsigned char *outp = outbuf;
>         EVP_CIPHER_CTX ctx;
>
>         printf("encrypting %d bytes\n", size);
>
>         EVP_CIPHER_CTX_init (&ctx);
>         EVP_EncryptInit (&ctx, EVP_bf_cbc (), key, iv);
>
>         left = size;
>         *outsz = 0;
>
>         while (left>  0)
>         {
>                 n = (left>  IP_SIZE ? IP_SIZE : left);
>                 olen = 0;
>                 if (EVP_EncryptUpdate (&ctx, outp,&olen, inp, n) != 1)
>                 {
>                         return -1;
>                 }
>                 printf("EVP_DecryptUpdate %d bytes\n", olen);
>
>                 if (EVP_EncryptFinal (&ctx, outp + olen,&tlen) != 1)
>                 {
>                         return -1;
>                 }
>                 printf("EVP_DecryptFinal %d bytes\n", tlen);
>
>                 *outsz = ((*outsz) + olen + tlen);
>                 inp += n;
>                 left -= n;
>                 outp += (olen + tlen);
>         }
>
>         printf("encrypted %d bytes\n", *outsz);
>
>         EVP_CIPHER_CTX_cleanup (&ctx);
>         return 0;
> }
>
>  From the Visual Studio IDE I can see that the libaye32.dll is loaded 
> from the debug folder where I copied it.
>
> libeay32.dll  D:\work\openssl\ssl_test\debug\libeay32.dll     N/A     N/A
Symbols
> loaded.       D:\work\openssl\ssl_test\debug\libeay32.pdb     5
1.00.0.5        25.11.2011
> 11:34 10000000-10113000       [7580] ssl_test.exe: Native
>
> libeay32.dll is of version 1.0.0.5. I have built it from the source code.
>
> Having the libeay32.pdb file in the same folder I'm able to step into
> EVP_DecryptUpdate():
>
> evp_enc.c, lines 426-427:
>
>       if (fix_len)
>               *outl += b;
>
> The "fix_len" flag is not set during the first decrypt block but is 
> set during the rest of the blocks as the output of my test program 
> shows. Because of that increment the output buffer in my program 
> becomes larger that the original data was before it was encrypted.
>
> outp += (olen + tlen);         // olen too big here
>
> Regards,
> Jussi Peltonen


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           majord...@openssl.org

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to