Hello,

Thanks a lot for your valuable advice. I'm looking into the CBC with IVs based on block numbers, CTR, and XTS. I'm refering to the pages below:

Block cipher modes of operation
http://en.wikipedia.org/wiki/Block_cipher_mode

Disk encryption theory
http://en.wikipedia.org/wiki/Disk_encryption_theory

I'll continue the investigation a little more.

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 said I'm afraid of the overhead of EVP_EncryptInit_ex/EVP_DecryptInit_ex calls. Then, I looked through the source code of those functions and knew that my concern seems correct.

If I call those functions specifying the same cipher, key and IV as the previous call, those functions call EVP_CIPHER_CTX_cleanup to clean up the cipher context, re-allocate some memory for the cipher context, and performs key and IV initialization. Those processing may be too much for each block/record encryption/decryption.

According to the source code, I think I can pass NULL for cipher, key and IV to use those specified in the previous call, eliminating most of the processing overhead. Is this usage correct? The following code worked successfully, producing the correct data:

----------------------------------------
/* 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_EncryptInit_ex(&enc_ctx, NULL, NULL, NULL, NULL);
EVP_EncryptUpdate(&enc_ctx, block2, &outlen, block2, 4096);

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


Regards
MauMau

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

Reply via email to