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