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.