I have a single-threaded client-server application that must perform both encryption and decryption of its network interaction. I plan to use the OpenSSL EVP API and AES-256-CBC.
If you use the SSL_* functions from libssl , then most likely you will never EVP_* APIs EVP_* .
On line 1, do I create EVP_CIPHER_CTX only once and continue to use it until the application terminates?
You create it once per use. That is, since you need to encrypt, you use the same context. If you need to encrypt the second stream, you must use the second context. If you need to decrypt the third stream, you must use the third context.
Also on line 1, can I reuse the same EVP_CIPHER_CTX for encryption and decryption, or should I create 2 of them?
No, see above.
Ciphers will have different states.
On line 2, should I reinstall IV for every packet that I encrypt? Or did I install IV only once, and then let it go on forever?
No. You install IV once, and then forget about it. The context object manages this part of the state for the cipher.
What should I do if I encrypt UDP packets, where the packet can easily disappear or be received out of order: do I think that CBC will not work correctly ...
If you use UDP, then you may find similar problems. You will probably end up inventing TCP.
Encryption alone is usually not enough. You also need to ensure authenticity and integrity. You are not handling data that is not authentic. This is what continues to cause SST / TLS and SSH problems.
For example, here is the guy who wrote the main article on verified encryption regarding IPSec, SSL / TLS and SSH, weighing the Authenticate-Then-Encrypt (EtA) scheme used by SSL / TLS: Last Call: (Encrypt-then -MAC for TLS and DTLS) to the proposed standard :
The technical results in my 2001 article are correct, but the conclusion regarding SSL / TLS is incorrect. I assumed that TLS uses fresh IV and that the MAC was computed in encoded plaintext, i.e. Encode-Mac-Encrypt, while TLS does Mac-Encode-Encrypt, which, as my theoretical example shows, is unsafe.
For authenticity, you must abandon CBC mode and switch to GCM mode. GCM is an authenticated encryption mode that combines confidentiality and authenticity in one mode, so you do not need to combine primitives (like AES / CBC with HMAC).
or is this where I need to drop the IV at the beginning of every packet I sent?
No, you installed IV once, and then forgot about it.
The problem is in all these examples, I'm not sure what to do with each encryption / decryption, and what I should do only once at startup.
- Create it once:
EVP_CIPHER_CTX - Call it once to configure:
EVP_CipherInit EVP_CipherUpdate is as many times as you want: EVP_CipherUpdate- Call it once to clear:
EVP_CipherFinal
OpenSSL has many examples of using the EVP_* interfaces. See Symmetric Encryption and Decryption of EVP, Encryption and Decryption with EVP Authentication , Signing and Verification of EVP .
All examples use the same template: Init , Update and then Final . It does not matter whether its encryption or hashing.
Related: this should interest you: encryption and decryption using EVP . This is sample code from the OpenSSL wiki.
Related: you can find copies of Viega, Messier and Chandra Network Security with OpenSSL online. You might consider finding a copy and getting to know some of its concepts.