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

Reply via email to