# Generating an IV for ESP 3DES-CBC

I have an application written in C, running in Linux. It uses IPsec (ESP) (manually putting the IPSec packet together) to send certain packets. The algorithm used for encrypting the payload is 3DES-CBC (using Libgcrypt).

So my doubts are regarding the IV that I have to use. For this scheme to be secure:

Is it enough to generate a random IV? If so, what random number generator source should I use for this? (e.g. /dev/random)

The other requirement that I noted while reading RFC 1851 is that the IV should be 64-bit long.

Update:

There are two recommended methods for generating unpredictable IVs. The first method is to apply the forward cipher function, under the same key that is used for the encryption of the plaintext, to a nonce. The nonce must be a data block that is unique to each execution of the encryption operation. For example, the nonce may be a counter, as described in Appendix B, or a message number. The second method is to generate a random data block using a FIPS-approved random number generator.

Tried to find a list of all Linux random number generator implementations that are FIPS-approved but couldn't find much information on this.

-

To generate an IV securely for CBC mode, there are two obvious ways to do it (and both are cited by NIST):

• For each packet, select a nonce (the IPSec sequence number, padded out to 64 bits, works fine), encrypt that in ECB mode, and then use resulting ciphertext block as the IV. An equivalent way to do that is to take your 64 bit nonce, prepend that to the byte plaintext, encrypt the plaintext (and the 64 bit nonce) with a fixed IV, and then transmit the first 64 bits of the ciphertext (not including the fixed IV you used) as the IV, and the rest of the ciphertext as the ciphertext body. It turns out this is equivalent to the first method because of how CBC mode works internally.

• For call a random number generator to select a 64 bit IV, and use that. The text from NIST you cite says the rng has to be FIPS-approved; actually, unless you care about FIPS compliance, any unpredictable rng should work; I don't expect any problems /dev/random

Personally, I suspect you'll find the first option is easier.

The other thing you ought to consider is integrity; there's a surprising amount of mischief someone can cause by modifying the ciphertext, and then having someone attempt to decrypt it. Now, IPSec has an answer to that (including a MAC along with the ciphertext; if someone modifies the ciphertext, the MAC will fail); are you including that?

BTW: the RFC you cite (RFC1851) is rather out-of-date, and won't interoperate with modern versions of IPSec; at the very least, modern versions will expect the padding to have a specific pattern. That doesn't matter if you're implementing both sides of the protocol; however if the other side is a non-ancient IPSec implementation, look at RFC2406 and RFC2451

-
Some comments: 1. The first option seems nice because I would not need a random number generator, but I have doubts about the fixed IV. By saying fixed you mean hard-coded on the client code? Is it alright to be known to everyone? Using the ESP sequence number seems better. 2. I'm considering message integrity, yes. I'm aware of the problems with using ESP encryption only. 3. Thanks for the heads up on the RFC, I'm implementing client code only. On section 3 of the RFC 2451, I noticed that it says "The IV MUST be chosen at random". – Juan Andrés Aug 25 '13 at 6:31
I don't recommend using /dev/random, for a number of reasons (do a search here or on IT Security.SE to see why). Instead, use /dev/urandom or any crypto-quality pseudorandom number genreator. – D.W. Aug 25 '13 at 6:38
EBC $\mapsto$ ECB $\;$ – Ricky Demer Aug 25 '13 at 6:45
@JuanAndrés: with the first option, using a fixed (known) IV to kick the process is just fine, because you won't be actually transmitting it. Instead, it's just part of the formula for creating the IV you will actually be sending. – poncho Aug 25 '13 at 12:04
@JuanAndrés: For details on the "fixed IV trick", see crypto.stackexchange.com/questions/5421/…. Basically, it's just a clever way to perform both the NIST-recommended IV derivation and the actual CBC encryption using a single call to a CBC encryption function. – Ilmari Karonen Aug 25 '13 at 13:10