# OpenSSL & TLS1.2 with aes-cbc and initialization vector

I'm trying to manually decrypt DTLS traffic using OpenSSL and TLS 1.2. The cipher suite im using is AES256-SHA256 as listed here. Im able to decrypt the packets with the key that the server and the client negotiate during the handshake without issues, but what i don't understand is that i can set the initialization vector to any value or even null and still i can decrypt the packets.

Here is a code snippet from the program that receives the packet:

EVP_CIPHER_CTX *ctc = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, (const unsigned char)"not a real iv");
...
EVP_DecryptFinal_ex(ctx, (unsigned char*)payload + len, &len);


And that decrypts the data fine with the bogus IV.

So apparently either the encryption / decryption is not done in CBC mode. Or does OpenSSL derive the IV by the decryption key somehow from the packet ?

What i am missing or/and not understanding here ? The DTLS rfc did not talk about this either.

Or does OpenSSL derive the IV by the decryption key somehow from the packet ?

Well, yes. Actually, it's not that complicated; for DTLS and AES-CBC mode, the IV is the first 16 bytes of the encrypted region, so it just reads it from there, and starts decrypting from there.

In DTLS, we assume that encrypted packets can be dropped in flight (or received out of order), and so the system cannot assume that the decryptor has seen the previous packets. Everything that is needed to decrypt (except for those parts, such as keys, that were established in the initial negotiation) must be in the UDP packet. When it comes to IV, well, IV's can be sent in the clear; we need to communicate the IV to the decryptor, and so the obvious approach (which DTLS uses) is just include the IV in the UDP packet.

Now, for TLS, this 'missing records or receiving them out of order' is not an issue (as the TCP stack will ensure that, absent someone in the middle tweaking things, we will receive things as sent). So, what TLS 1.0 used to do is make the IV for the next record the same as the last ciphertext block of the previous record. However, it turns out that opens things up to chosen plaintext attacks, hence with TLS 1.1 and on, they also send the explicit IV, just like DTLS has always done.