EVP_DecryptFinal succeeds but fails.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

EVP_DecryptFinal succeeds but fails.

roxaz
Hey, EVP_DecryptFinal returns 0 for me, but no data is returned to supplied output buffer, and returned data length is set to 0. What could be the issue? bdec  receives some correct data tho.

        u32 szbdec = 0;
        u8* bdec = new u8[resp.rSize + halfKey];    // half rSize = half of chyper key + chypered bytes

        EVP_CIPHER_CTX ctx;
        EVP_DecryptInit(&ctx, EVP_aes_256_ecb(), key, NULL);
        EVP_CIPHER_CTX_set_padding(&ctx, 0);
        EVP_DecryptUpdate(&ctx, bdec, (int*)&szbdec, resp.rBuff + halfKey, resp.rSize - halfKey);
        //ZeroMemory(resp.rBuff, resp.rSize);
        if(!EVP_DecryptFinal(&ctx, bdec, (int*)&szbdec))
        {
            u32 err = ERR_get_error();
        }
        EVP_CIPHER_CTX_cleanup(&ctx);

-- roxaz
Reply | Threaded
Open this post in threaded view
|

Re: EVP_DecryptFinal succeeds but fails.

Goetz Babin-Ebell
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

roxaz wrote:
| Hey, EVP_DecryptFinal returns 0 for me, but no data is returned to
| supplied output buffer, and returned data length is set to 0. What could
| be the issue? bdec  receives some correct data tho.
|
|         u32 szbdec = 0;
|         u8* bdec = new u8[resp.rSize + halfKey];    // half rSize = half
[...]
|         if(!EVP_DecryptFinal(&ctx, bdec, (int*)&szbdec))

szbdec is an IO parameter.
You have to initialize it to resp.rSize + halfKey
before passing it to EVP_DecryptFinal()

Goetz

- --
DMCA: The greed of the few outweighs the freedom of the many
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFKoC7f2iGqZUF3qPYRAj01AJ91PotqfpUhOM5jty85RV+ApCgBOwCfd2ps
o2P5fEx5AojN19q435ZJCdo=
=k67m
-----END PGP SIGNATURE-----
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: EVP_DecryptFinal succeeds but fails.

Dave Thompson-4
In reply to this post by roxaz
> From: [hidden email] On Behalf Of roxaz
> Sent: Thursday, 03 September, 2009 06:46

> Hey, EVP_DecryptFinal returns 0 for me, but no data is returned
> to supplied output buffer, and returned data length is set to 0.
> What could be the issue? bdec  receives some correct data tho.

"but"? 0 means failure, so returned length == 0 isn't surprising.

Probably your data is not a multiple of the blocksize, aka aligned.
ECB is a block mode and with no padding it can only handle full blocks.
       
>        u32 szbdec = 0;
>        u8* bdec = new u8[resp.rSize + halfKey];    
>             // half rSize = half of chyper key + chypered bytes
       
>        EVP_CIPHER_CTX ctx;
>        EVP_DecryptInit(&ctx, EVP_aes_256_ecb(), key, NULL);
>        EVP_CIPHER_CTX_set_padding(&ctx, 0);
>        EVP_DecryptUpdate(&ctx, bdec, (int*)&szbdec,
> resp.rBuff + halfKey, resp.rSize - halfKey);

Minor: treating szbdec which is actually u32 as int is not portable.
Assuming u32 is 32bits (it's not official, but that's the only sensible
thing to use that name for), there are platforms where int isn't 32bits.
Better to have an actual int variable and use that.

Minor: assuming the data you are passing (rBuff+halfkey for rSize-halfkey)
is correct, your output buffer is larger than needed. The plaintext is
never longer than the ciphertext; without padding it is the same size
(which for block modes must be a multiple of the blocksize); with padding
it may be up to a block shorter (and need not be a multiple). Unless
you intend to (later) combine some other data into the same buffer.

Trivial: "chyper" is not a word

                //ZeroMemory(resp.rBuff, resp.rSize);
                if(!EVP_DecryptFinal(&ctx, bdec, (int*)&szbdec))
                {
                    u32 err = ERR_get_error();
                }

If you looked at that errorcode it probably was 0x0606508A which means
digital envelope routines:EVP_DecryptFinal_ex:data not multiple of block
length
(Aside: u32 is OK here. Even on a platform where the unsigned long _type_
is more than 32bits, the OpenSSL error _values_ still fit in 32bits.)

Even if this worked (with padding, or a stream mode like OFB),
it would overwrite the first plaintext block(s) (assuming there
are any, i.e. the Update call was at least one full block,
or with padding one full block plus some lag) and lose their length.
You want to step through the buffer by the amount gotten on previous
Update call(s), here one but in general may be more than one.



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]