I need to encrypt long lived network data streams using AES-CBC. I was thinking I would call EVP_EncryptInit_ex()
just once and save the EVP_CIPHER_CTX
for subsequent calls to EVP_EncryptUpdate
. Then do likewise on the decrypt end. The first problem I discovered is EVP_DecryptUpdate will always be one block behind. E.g., if I encrypt 32 bytes, the 1st decrypt update will return only 16, even though I know it has decrypted all 32 bytes. I guess this means I need to call EVP_DecryptFinal
after every EVP_DecryptUpdate
, and then EVP_EncryptInit_ex()
to reset the iv before the next update.
A second concern is that I may have many 1000's of these streams, and am trying to minimize the memory footprint. sizeof(EVP_CIPHER_CTX)
is only 168 bytes, but if I query memory usage before and after 1000 calls to EVP_EncryptInit_ex()
, it looks like it allocates an additional 412 bytes per context (this is on top of 20K after first call).
CORRECTION, I see 412 bytes per CTX not 168 + 412
The AES_cbc_encrypt()
interface looks much better for my needs. There is a fixed 260 byte AES_KEY
structure, plus I need to maintain the 16 byte IV myself. However, from what I understand, it does not use the AES-NI Intel hardware acceleration. https://security.stackexchange.com/questions/35036/different-performance-of-openssl-speed-on-the-same-hardware-with-aes-256-evp-an Is there a way to enable AES-NI on the AEC_cbc_encrypt()
interface? Is the 2X memory requirement of EVP not just a side effect of the API, but necessary to get the speed improvement? Is there a good alternative to OpenSSL that uses AES-NI?