# Random session key + predictable IV

I'm using Blowfish in a toy Diffie-Hellman communications scheme. Random session keys are generated for each connection.

In this case I can simply feed a null array to the IV right? The same plaintext would never be encrypted with the same keystream.

-
Using null can be confusing. null is commonly used for references, not for values. A zero valued byte array or just zero IV is more clear. –  owlstead Oct 14 '13 at 0:21

If you use CBC mode and your communication protocol looks like SSL, then you may have trouble. In SSL 3.0 and TLS 1.0, the IV for each record is the last block from the previous IV; this implies that an attacker who can both inject some data of his own in the stream, and observe the outcome, may know the IV for the next record and choose his data accordingly. This is the basis for the BEAST attack: that attack context turned out to be realistic when the client is a Web browser.

In all generality, a decent communication protocol should provide both confidentiality and integrity, which means that your data should use a MAC. Combining symmetric encryption and MAC properly is known to be tricky and a good method is to use an encryption mode such as GCM or EAX which does both jobs. A nice point here is that these two modes don't require a random IV, only a non-repeating IV.

This leads to a communication protocol where the initial key exchange (say, your Diffie-Hellman) produces an initial shared secret, which is expanded into two symmetric keys, for the two directions of communications (this "expansion" can be as simple as hashing the initial shared secret with SHA-256, and splitting the 256-bit result into two 128-bit halves). Then both client and server send a sequence of "messages" to each other, using as IV the sequence number of each message (first message from client to server uses as IV the value 1, second message uses the value 2, and so on).

Note that GCM and EAX rely on AES. You can adapt them to any 128-bit block cipher. Usage of block ciphers with 64-bit blocks, like 3DES or Blowfish, is not recommended nowadays, because security of many encryption modes tends to break down when encrypting $2^{n/2}$ blocks with the same key, when blocks have size $n$ bits. For 64-bit blocks, the threshold is around 30 gigabytes, which is not that much.

If your protocol is single-record (after the key exchange, each party sends a single message, which is encrypted in one go, avoiding any BEAST-like issue), then a fixed IV is acceptable, since the key will be used for a single encryption run. However, it would be equally acceptable to derive from the shared DH secret a symmetric key for encryption and the IV; this is what SSL/TLS does (or at least did prior to version TLS-1.1): see the standard, section 6.3.

-
My thing uses OFB and treats the data as one ginormous stream, without the notion of "records" as in TLS. Obviously, integrity may be an issue, and I'll look into schemes like GCM. I can't find functions for GCM in the libcrypto docs though. –  user54609 Oct 13 '13 at 23:39
Integrity means that the receiver end should not begin to process some incoming data until it has verified the MAC value (until that moment, it cannot know whether the data was altered or not), which implies that either the receiver buffers the whole lot in RAM or on disk, or the data stream indeed consists of a sequence of records, where a record is "a unit of data which has its own MAC". –  Thomas Pornin Oct 13 '13 at 23:42
My system as it is does not verify integrity at all. This is really bad, I know it. I'm not sure how exactly it may lead to attacks though. Also, how long should a MAC ideally be? SHA-256 seems to be a bit overheady for things like, kilobyte-sized records. –  user54609 Oct 13 '13 at 23:44
"If your protocol is single-record (...), then a fixed IV is acceptable" as long as each party has their own encryption key. $\:$ Otherwise, the parties could not use the same IV (as each other) on the same key. $\hspace{.37 in}$ –  Ricky Demer Oct 14 '13 at 0:23

Generating a random session key for each connection is the usual approach.
Even if you do that, you will still need to satisfy the standard IV requirements.

However, if you instead generate a random session key for each to-be-encrypted plaintext,
then you can use a fixed IV, such as whatever results from feeding "a null array to the IV".

-
How do you differentiate between "each to-be-encrypted plaintext"? I'm using OFB mode FYI. –  user54609 Oct 13 '13 at 22:54
It's a new "to-be-encrypted plaintext" whenever a party starts encrypting. $\;$ –  Ricky Demer Oct 13 '13 at 23:00
The key is only scheduled once per connection. Does this mean I can use the same IV over and over with different keys? –  user54609 Oct 13 '13 at 23:02
What does it mean for a key to be scheduled? $\:$ (I know about "key schedules" in block ciphers, but you seem to be using the term differently.) $\;\;\;$ –  Ricky Demer Oct 13 '13 at 23:10
One key is used for one side of a connection. The key initialization function is called once for each side. –  user54609 Oct 27 '13 at 11:10