On 23/04/12 13:16, MauMau wrote:

Apart from that, let me go back to my original question 4 in my first mail.

----------------------------------------
Q4: Do I have to call EVP_EncryptInit_ex/EVP_DecryptInit_ex for each
block/record? I'm concerned about the overhead of those functions. For
example, I want to make function calls as follows. However, this does not
seem to work.

/* one-time initialization */
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
EVP_CIPHER_CTX_init(&enc_ctx);
EVP_CIPHER_CTX_init(&dec_ctx);
EVP_EncryptInit_ex(&enc_ctx, EVP_aes_256_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(&enc_ctx, 0);
EVP_DecryptInit_ex(&dec_ctx, EVP_aes_256_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(&dec_ctx, 0);

/* encrypt first block */
EVP_EncryptUpdate(&enc_ctx, block1, &outlen, block1, 4096);
/* encrypt second block */
EVP_EncryptUpdate(&enc_ctx, block2, &outlen, block2, 4096);

/* decrypt second block */
EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096);
/* decrypt first block */
EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096);

The above code produces wrong data for block2. ...

I have modified your code to use XTS, which I think will achieve what you want to do:
 - It supports random read and write access to your data
- It is standards based so you don't have to make up your own way of doing things and potentially open yourself up to security issues - You do not have to store a separate key and/or IV for each of the records that you want to encrypt

Some things to note about using XTS:
- XTS is only supported in the latest (1.0.1) version of openssl so you must be using that for this to work - The key length is double the size of a standard AES key of the same strength, i.e. for AES 256 you must supply a 512 bit key - You do not have to use an IV. Instead you supply a so-called "tweak". This needs to be unique for each record (what you have called a "block") that you are working with. However it does not need to be random - it can be a simple unique identifier for the block.

The modified code is as follows:

    char tweak[16]  = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    /* one-time initialization */
    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
    EVP_CIPHER_CTX_init(&enc_ctx);
    EVP_CIPHER_CTX_init(&dec_ctx);
EVP_EncryptInit_ex(&enc_ctx, EVP_aes_256_xts(), NULL, key, NULL); /* KEY MUST BE 512 BITS!!! */
    EVP_CIPHER_CTX_set_padding(&enc_ctx, 0);
    EVP_DecryptInit_ex(&dec_ctx, EVP_aes_256_xts(), NULL, key, NULL);
    EVP_CIPHER_CTX_set_padding(&dec_ctx, 0);

    /* encrypt first block */
    tweak[15] = 1; /* Tweak for block1 */
    EVP_EncryptInit_ex(&enc_ctx, NULL, NULL, NULL, tweak);
    EVP_EncryptUpdate(&enc_ctx, block1, &outlen, block1, 4096);

    /* encrypt second block */
    tweak[15] = 2; /* Tweak for block2 */
    EVP_EncryptInit_ex(&enc_ctx, NULL, NULL, NULL, tweak);
    EVP_EncryptUpdate(&enc_ctx, block2, &outlen, block2, 4096);


    /* decrypt second block */
    tweak[15] = 2; /* Tweak for block2 */
    EVP_DecryptInit_ex(&dec_ctx, NULL, NULL, NULL, tweak);
    EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096);

    /* decrypt first block */
    tweak[15] = 1; /* Tweak for block1 */
    EVP_DecryptInit_ex(&dec_ctx, NULL, NULL, NULL, tweak);
    EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096);


Hope that helps.

Matt


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to