Hello, I'm having problems with the EVP_Encrypt/Decrypt interface.
The following program doesn't work as expected. It does simple
data->encrypt->decrypt->in. Specifically, I get some garbage mixed with
the plaintext in the final buffer.

It seems like the EVP_DncryptUpdate decrypts (n-1) blocks of 8 bytes,
which is OK, but the EVP_DncryptFinal doesn't decrypt the remaining
block and returns `bad_decrypt' error - everything is in the comments
below. What am I doing wrong?

======= t_evp.c =============
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>

int main(void)
{
        BIO *bio_err=NULL;
        EVP_CIPHER_CTX ectx;
        u_char enckey[EVP_MAX_KEY_LENGTH];
        u_char password[]="sample password";
        u_char data[]="abcdefghijklmnopqrstuvwxyz1234567890";
        int outl, inl;
        u_char *out, *in;
        int toutl;
        int ret;

        OpenSSL_add_all_algorithms();
        ERR_load_crypto_strings();
        bio_err = BIO_new_fp(stderr,BIO_NOCLOSE);

        /* Make 3DES key out of password */
        EVP_BytesToKey(EVP_des_ede3_cbc(), EVP_sha1(),
                        NULL, password, strlen(password), 1, enckey, NULL);

        /* Initialize encryption */
        EVP_CIPHER_CTX_init(&ectx);
        EVP_EncryptInit( &ectx, EVP_des_ede3_cbc(), enckey, NULL);

        /* Make room for encrypted output and decrypted input */
        out = malloc( strlen(data) + 2*EVP_CIPHER_CTX_block_size(&ectx));
        in = malloc( strlen(data) + 2*EVP_CIPHER_CTX_block_size(&ectx));

        /* Encrypt from data to out */
        /* Length of the data is 36 */
        EVP_EncryptUpdate( &ectx, out, &outl, data, strlen(data));
        toutl = outl;   /* Now outl is 32 */
        EVP_EncryptFinal( &ectx, out, &outl);
        toutl += outl;  /* Now outl is 8 */

        /* Clean up and reinitialize */
        EVP_CIPHER_CTX_cleanup(&ectx);
        EVP_DecryptInit( &ectx, EVP_des_ede3_cbc(), enckey, NULL );

        /* Decrypt from out to in */
        /* toutl is 40 */
        EVP_DecryptUpdate( &ectx, in, &inl, out, toutl);
        /* inl is 32 - correct, but the result in `in' is garbage,
         * and then some plaintext (starting with `qrst...'
         */
        ret = EVP_DecryptFinal( &ectx, in, &inl);
        /* This fails, inl is 0 and error `bad_decrypt' is set */

        if (ret != 1)
        {
                ERR_print_errors(bio_err);
        }


        return 0;
}
======= end t_evp.c =============

-- 
Paweł Krawczyk <http://ceti.pl/~kravietz/>
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to