Postfix/TLS - PRNG Pseudo Random Number Generator

One of the crucial points of encryption is the generation of the keys, for which random numbers are required. As of OpenSSL 0.9.5, the seeding of the included PRNG Pseudo Random Number Generator is checked. Starting with Postfix/TLS 0.5.4, an architecture to collect entropy is included.

Included PRNG

OpenSSL features a quite sophisticated PRNG. In order to generate random numbers of lengths of more then 1024bit, a 8192bit (=1kB) pool is kept and used to generate these random numbers. To achieve full complexity for an attacker, it is necessary to have the full range of random numbers available and not restrict the search space used for searching keys, hence an according amount of entropy is necessary.

Obtaining Entropy

To get entropy, unpredictable events are needed. Unfortunately, computers and software tend to be very predictable, so that a lot of effort is necessary to collect unpredictable events. The mathematical techniques are discussed in the excellent book of Schneier "Applied Cryptography".

We use at least one feature: if you have collected a pool of data with entropy in it, you can add up more data without losing the entropy already there, so that we can mix external sources and internal bits to only increase the entropy.

External sources

Only few operating systems provide good entropy collection.

/dev/random and /dev/urandom

Linux offers the /dev/random and /dev/urandom devices, some BSD derivatives as well.

/dev/random will provide high quality random data, but it will block until enough entropy is available, if too much random data is requested to fast. /dev/urandom will fill up the real entropy data with data from an internal PRNG and will never block. For a system with automated startup /dev/urandom should be used. Reading from /dev/urandom will however trigger kernel activity to satisfy the demands. Imagine starting up postfix with a large number of emails in the queue. 50 (default) smtp processes want to start at the same time and access /dev/urandom.

Entropy Gathering Daemon

A replacement for operating systems without good random number collection is the EGD Entropy Gathering Daemon. It will also extract entropy from a lot of sources.

EGD has a command driven interface, there is a command for blocking and one for non-blocking read. Unlike /dev/urandom the non-blocking command will not trigger an internal PRNG to fill up, but will simply return a smaller number of bytes than requested, even 0 if totally drained.

EGD should hence not be used for direct feeding of smtp[d] processes. Again, imagine 50 smtp processes starting delivery at the same time.

To circumvent this problem, I have witten my own daemon, that has a EGD compatible interface but can never run dry, just like /dev/urandom. Check out PRNGD for details.

Intermediate File

Hence, Postfix/TLS maintains its own pool of entropy by means of the tlsmgr daemon. It will collect entropy from an external source at startup and periodically during runtime to ever increase the entropy in the pool. The smtp[d] processes are fed from an PRNG exchange file that is updated in short periods. Upon restart, tlsmgr will also read entropy from this file, so that the large entropy pool is fully utilized.

The single smtp[d] daemons can also access an external source. Their collected entropy is also stirred into the intermediate file, so that a significant amount of entropy is available alltogether.