Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need multiple EVP_CIPHER_CTX structures?

Tags:

openssl

aes

I have a single-threaded client/server application that needs to do both encryption and decryption of their network communication. I plan on using OpenSSL's EVP API and AES-256-CBC.

Some sample pseudo-code I found from a few examples:

// key is 256 bits (32 bytes) when using EVP_aes_256_*()
// I think iv is the same size as the block size, 128 bits (16 bytes)...is it?
1: EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
2: EVP_CipherInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv, 1); //0=decrypt, 1=encrypt
3: EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, inlen);
4: EVP_CipherFinal_ex(ctx, outbuf + outlen, &tmplen));
5: outlen += tmplen;
6: EVP_CIPHER_CTX_cleanup(ctx);
7: EVP_CIPHER_CTX_free(ctx);

The problem is from all these examples, I'm not sure what needs to be done at every encryption/decryption, and what I should only do once on startup.

Specifically:

  • At line 1, do I create this EVP_CIPHER_CTX just once and keep re-using it until the application ends?
  • Also at line 1, can I re-use the same EVP_CIPHER_CTX for both encryption and decryption, or am I supposed to create 2 of them?
  • At line 2, should the IV be re-set at every packet I'm encrypting? Or do I set the IV just once, and then let it continue forever?
  • What if I'm encrypting UDP packets, where a packet can easily go missing or be received out-of-order: am I correct in thinking CBC wont work, or is this where I need to reset the IV at the start of every packet I send out?
like image 435
Stéphane Avatar asked Jun 22 '14 07:06

Stéphane


1 Answers

Sorry for reviving an old thread, but I noticed the following error in the accepted answer:

At line 1, do I create this EVP_CIPHER_CTX just once and keep re-using it until the application ends?

You create it once per use. That is, as you need to encrypt, you use the same context. If you need to encrypt a second stream, you would use a second context. If you needed to decrypt a third stream, you would use a third context.

Also at line 1, can I re-use the same EVP_CIPHER_CTX for both encryption and decryption, or am I supposed to create 2 of them?

No, see above.

This is not necessary. From the man page for OpenSSL:

New code should use EVP_EncryptInit_ex(), EVP_EncryptFinal_ex(), EVP_DecryptInit_ex(), EVP_DecryptFinal_ex(), EVP_CipherInit_ex() and EVP_CipherFinal_ex() because they can reuse an existing context without allocating and freeing it up on each call.

In other words, you need to re-initialize the context each time before you use it, but you can certainly use the same context over and over again without creating (allocating) a new one.

like image 150
bacchuswng Avatar answered Oct 20 '22 20:10

bacchuswng