0

Its not duplicate since I was not asking how to encrypt, but I was asking whats wrong in my encryption. Dont like this Question you are free to delete it. I dont care.

I am trying to encrypt one simple hello text file.

Here is my code to encrypt the data.

int encrypt(EVP_CIPHER_CTX *ctx, FILE *ifp,FILE *ofp)
{
        int bytes_read, bytes_written, enc_bytes,tlen;
        unsigned char indata[AES_BLOCK_SIZE];
        unsigned char encdata[AES_BLOCK_SIZE];
        unsigned char outdata[AES_BLOCK_SIZE];
        while (1) {
            bytes_read = fread(indata, 1, AES_BLOCK_SIZE, ifp);

            if (EVP_EncryptUpdate (ctx, encdata, &enc_bytes, indata, bytes_read) != 1)
            {   
                    printf ("error in encrypt update\n");
                    return -1; 
            }   
            printf ("INPUT\n");
            print_memory(indata, bytes_read);
            if (EVP_EncryptFinal (ctx, encdata + enc_bytes, &tlen) != 1)
            {   
                    printf ("error in encrypt final\n");
                    return -1; 
            }   

            printf ("OUTPUT\n");
            print_memory(encdata,enc_bytes+tlen);
            bytes_written = fwrite(encdata, 1,enc_bytes + tlen, ofp);
            if (bytes_read < AES_BLOCK_SIZE)
                    break;
    }   

Here is key and ivec, I have used for initialization

unsigned char ckey[] =  {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};
unsigned char ivec[] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};


EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init (&ctx);
EVP_EncryptInit (&ctx, EVP_bf_cbc (), ckey, ivec);

Here is the output encrypted data in hex 24 47 50 58 93 0B 04 9C D5 54 65 93 D1 6B AD 5A

but when i try to decode the data using openSSL cmd I get following error

anshul:~/> openssl aes-128-cbc  -d  -in  otext  -K 000102030405060708090A0B0C0D0E0F -iv 000102030405060708090A0B0C0D0E0F -nosalt
bad decrypt
3075450556:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:529:

This is the same error I get if I use wrong ivec or key. So I do have wild guess that there is something different in c program key or ivec and openssl cmd key or ivek

Anshul
  • 360
  • 3
  • 15
  • 1
    Unless I completely forgot basic crypto, that EVP_EncryptFinal shouldn't be in the while-loop. And EVP_EncryptInit appears to be nowhere at all, so I'm not sure what you're even starting with. – WhozCraig May 10 '15 at 13:03
  • encrypt init is out of encrypt function. see in initialization code i have pasted. the code is taken from openSSL examples so there was evpfinal function was called in loop – Anshul May 10 '15 at 13:08
  • may be I am wrong with evpFinal, I took code from here https://www.openssl.org/docs/crypto/EVP_EncryptInit.html#EXAMPLES – Anshul May 10 '15 at 13:11
  • but error is not because of that since loop does not run more then once in my text file. my text file contain just "hello text" – Anshul May 10 '15 at 13:13
  • I have also tried debugging openSSL code and putting breakpoint at EVP_EncryptInit to check what ivek and K are meant for openSSL. openssl aes-128-cbc -in text -K 000102030405060708090A0B0C0D0E0F -iv 000102030405060708090A0B0C0D0E0F -nosalt ; but no luck, code does not stop there – Anshul May 10 '15 at 13:18
  • sorry to bother you guys, I got answer to my problem, It was different algo. I had to use EVP_aes_128_cbc, in both place cmd line and code – Anshul May 10 '15 at 13:30

1 Answers1

0

I am trying to encrypt one simple hello text file...
I took code from http://openssl.org/docs/crypto/EVP_EncryptInit.html#EXAMPLES...

Here's the example from the OpenSSL wiki on EVP Authenticated Encryption and Decryption. It uses GCM mode because you often want/need confidentiality and authenticity assurances, and not just confidentiality.

OpenSSL routines work on byte strings in memory. So you will have to read the file and present a byte string to the OpenSSL functions.

int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *aad,
    int aad_len, unsigned char *key, unsigned char *iv,
    unsigned char *ciphertext, unsigned char *tag)
{
    EVP_CIPHER_CTX *ctx;

    int len, ciphertext_len;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

    /* Initialise the encryption operation. */
    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        handleErrors();

    /* Set IV length if default 12 bytes (96 bits) is not appropriate */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL))
        handleErrors();

    /* Initialise key and IV */
    if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors();

    /* Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
        handleErrors();

    /* Provide the message to be encrypted, and obtain the encrypted output.
     * EVP_EncryptUpdate can be called multiple times if necessary
     */
    if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        handleErrors();
    ciphertext_len = len;

    /* Finalise the encryption. Normally ciphertext bytes may be written at
     * this stage, but this does not occur in GCM mode
     */
    if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
    ciphertext_len += len;

    /* Get the tag */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
        handleErrors();

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

And the decryption routine:

int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *aad,
    int aad_len, unsigned char *tag, unsigned char *key, unsigned char *iv,
    unsigned char *plaintext)
{
    EVP_CIPHER_CTX *ctx;
    int len, plaintext_len, ret;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

    /* Initialise the decryption operation. */
    if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        handleErrors();

    /* Set IV length. Not necessary if this is 12 bytes (96 bits) */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL))
        handleErrors();

    /* Initialise key and IV */
    if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors();

    /* Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
        handleErrors();

    /* Provide the message to be decrypted, and obtain the plaintext output.
     * EVP_DecryptUpdate can be called multiple times if necessary
     */
    if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        handleErrors();
    plaintext_len = len;

    /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
        handleErrors();

    /* Finalise the decryption. A positive return value indicates success,
     * anything else is a failure - the plaintext is not trustworthy.
     */
    ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    if(ret > 0)
    {
        /* Success */
        plaintext_len += len;
        return plaintext_len;
    }
    else
    {
        /* Verify failed */
        return -1;
    }
}

anshul:~/> openssl aes-128-cbc -d -in ...

For GCM mode, this won't work. GCM has not been cut-in for the OpenSSL encrypt and decrypt subcommands. See AES-GCM failing from Command Line Interface on the OpenSSL mailing list.

And in case you are wondering, that's not a valid reason to use a different mode, like CBC or OFB. Use GCM mode.

jww
  • 97,681
  • 90
  • 411
  • 885