By Nathan Willis
April 10, 2013
Randomness: it rarely seems like it is in short supply—until
you need it. Quite a few security features on a modern
operating system rely on a supply of random bits: cryptographic key
generation, TCP sequence number selection, and so on. The operating
system can provide random bits by collecting "entropy"—in
essence, measuring an unpredictable process. But there are
instances when the kernel's own entropy supply cannot keep up with
demand, either because demand is too high, or supply is too low. Entropy Broker is
a framework that allows multiple machines to pool their entropy
sources together. It allows client machines that consume more entropy than they can themselves generate
to use entropy donations from server machines that produce more entropy than they need.
How random
For starters, a little terminology. Many people (and software
projects) use the terms randomness and entropy interchangeably; to make the distinction a
little clearer, it might help to think of entropy as a property of a
physical system: clock oscillations vary minutely, the
least-significant digit of the timestamp on an interrupt is
unpredictable, and so on. Measuring that entropy provides input that can
be turned into a sequence of random bits. But rate at which each
source being measured can provide entropy is a property of the system,
too. The clock crystal oscillates at its frequency, interrupts only
arrive when they are needed, and so on.
On a typical Linux system the kernel draws on a small set of
entropy sources in order to fill up the pool of random bytes it delivers
in the /dev/random pseudo-file. The incoming bits of entropy
are "stirred" together using one-way hash functions, in order to make
them less predictable. In theory, the stirring process
greatly reduces the danger that a pattern will occur in the physical
process creating entropy, but one thing stirring cannot do is
increase the speed at which the entropy bits are collected. And it is
when the supply of collected entropy runs low that causes concern.
There are various approaches to solving this supply problem; true
random number generators (RNGs), for example, can provide entropy at
rates orders of magnitude higher than software collection, and there are potential entropy sources outside of
what the kernel relies on, such as reading the low-level noise from microphones or
video cameras.
Nevertheless, when it comes to the availability of random bits,
there are concerns other than how to collect sufficient entropy. For
instance, although /dev/random will block whenever it
temporarily runs short of entropy bits, /dev/urandom will
instead use a pseudo-random number generator. But that pseudo-random
number generator needs to have a different seed value at every reboot,
or it will be predictable. Immediately after boot, when no entropy
has been collected, running the generator with the same seed will
produce the same output. Fixing that problem can be especially
difficult when dealing with virtual machines (consider cloud server images,
for example, which are created from scratch on demand).
Entropy Broker offers a relief option for several of these
scenarios. It defines "clients" as those machines needing a supply of
entropy, and "servers" as machines that collect entropy and contribute
it to the shared pool. A broker process handles mixing the incoming
contributions together and servicing the requests from clients. The
client machines could be high-volume entropy consumers (e.g.,
performing a lot of cryptographic work), or they could lack the entropy
sources found on a normal machine. A diskless workstation, for
example, would have no hard disk interrupt timings (a common entropy source) to
measure; a virtual machine might have no reliable entropy sources at all.
Brokering it
Entropy Broker is maintained by Folkert van Heusden; the current
release is version 2.1, released in December 2012.
At the lowest level, Entropy Broker starts with a suite of separate
"server" programs (most of which can run on any UNIX-like platform,
although a few are Linux-specific) that collect entropy bits from a
specific source (timer jitter, audio or video4linux noise, or even a
hardware RNG). The server processes are configured to send their entropy to a
broker process, which can run on the same machine or on a different
one. The entropy bits that each server collects are hashed, then the
bits and the hash are encrypted with a pre-shared key prior to
transmission; the hash allows the broker to check that the data was
not tampered with during transmission. Both the cipher and the hash
function used are configurable. By default, the broker, servers, and
clients use TCP port 55225 to communicate, which is configurable as
well.
In the broker process, incoming entropy packets are decrypted, and
the entropy bits checked against their hash. If the hash verifies
their integrity, the entropy bits are "stirred" together into a common
pool, using either AES, 3DES, Blowfish, or Camellia. The stirring
process takes the existing pool of entropy and encrypts with the
selected cipher, using the new entropy bits as the key (thus, the new
bits mix up the old bits, thereby stirring them). As is the
case with /dev/random, the broker keeps track of how many
bits of entropy it has in its pool; if it runs out, it sends an "empty
pool" message to its clients and servers. Conversely, if it fills
its entropy pool, the broker sends a "sleep" message to its servers.
The Entropy Broker package includes several "client" programs to
run on machines that want to request entropy from the broker. The
client_linux_kernel program uses entropy from the broker
to fill the kernel's local entropy pool. This is the most
general-purpose solution for Linux systems; it allows both high-demand and
supply-poor machines to fill /dev/random, with no changes
visible to user-space applications. But there are other clients as well. The
client_egd program can mimic the Entropy Gathering
Daemon (EGD) and provide a socket interface, and the
client_file program that can write entropy bits to a
general-purpose file.
When a client needs some entropy, it sends a request message to the
broker asking for a particular number of bits. When enough bits are
available, the broker "unstirs" them from the pool by hashing the pool, then
decrypting the pool with the hash value used as a key (as with
stirring, this process is performed so that the bits extracted come
from the pool as a whole, as opposed to pushing and popping values
from a stack). The hash value is "folded" in half (by XORing the
first and last halves of the hash value together, which protects
against some attacks by further obfuscating the state of the pool),
then it is sent to the client, and the broker decrements its count of
entropy bits available.
At your service
Delivering the accumulated entropy to clients is fairly
straightforward; the throttling options allow the broker to tell
clients when there is not enough entropy to go around as well as to
make more efficient use of hardware RNGs on the servers, which could
very well be capable of producing entropy faster than the clients need
it. But the entropy servers are interesting in their own right, since
collecting entropy is at times a tricky affair. Entropy Broker 2.1
includes twelve servers and one "proxy" server designed to mix
together less reliable entropy sources.
The best option, if it is available, is a hardware RNG device.
Systems with a hardware RNG either in the chipset or connected via
serial port can use server_stream, passing the device name to
the server as the -d argument. For example,
server_stream -I mybroker.example.com -d /dev/ttyS0 -s -X my_preshared_credentials.txt
where mybroker.example.com is the address of the machine running
the broker process, and my_preshared_credentials.txt on the
client machine contains the pre-shared password used to authenticate
with the broker. There are three servers written for hardware RNG
products not covered by server_stream. Systems with an
EntropyKey device can use server_egd, which requires two additional parameters:
-b read_interval (in microseconds) and -a bytes_to_read (per interval). As the name suggests,
server_egd can also use the EGD daemon to collect entropy. The
server_ComScire_R2000KU server is designed to collect entropy data
from the USB ComScire R2000KU RNG device. The
server_smartcard server can collect entropy from compatible ISO 7816
smart cards—although "compatible" in this case means that the
card must accept the GET_CHALLENGE command, which the Entropy
Broker documentation notes is not supported by every card on the market.
Some hardware RNG modules can be used by the kernel directly to fill /dev/random; on these
machines the server_linux_kernel server can make use of the
hardware without special configuration. Naturally, server_linux_kernel can also be
used donate entropy collected by the kernel through the normal
software sources. On a machine that will be used as an entropy
source, though, there are other server options worth exploring, even
when no hard RNG is available—such as the server_audio and
server_v4l servers. The audio server collects Johnson-Nyquist
noise data from an ALSA-compatible sound card. The sound card so
utilized needs to be unused, since an active signal will drown out the
desired noise. The Video4Linux2 server can extract noise from either a
webcam or a TV tuner card. As with the sound card, a TV tuner needs
to be picking up static, not an actual signal. It is less obvious how best
to collect noise from a webcam; the Entropy Broker documentation
points users toward two possibilities: LavaRnd (which requires pointing
the webcam at a constantly-moving random image such as a lava lamp),
and AlphaRad
(which uses a cheap radiation source pulled from a home smoke detector).
A step down from the above hardware sources, the server_usb server can extract
entropy from the response times of attached USB devices (even simple
input devices like keyboards). An x86-compatible system can collect
entropy from server_cycle_count, which implements a variant
of the HAVEGE
algorithm to measure CPU flutter. The final
hardware option is server_timers, which measures jitter in
the length of usleep() timings. All of the servers that collect
entropy from hardware sources use Von
Neumann whitening to normalize the signal before sending it to the broker.
Two other options exist if none of the others suffice. The first,
server_ext_proc, allows one to use any external process as an
entropy input source; the user is on his or her own as to the
viability of that external process. Similarly, server_file
can be used to read entropy bits from a file (the contents of which,
hopefully, are replenished between reads). In either case, the
Entropy Broker network protocol includes a free-form "server type"
field; if the entropy source is less than reliable, at least that fact
is communicated by server_ext_proc and server_file.
The package does include a utility that can theoretically improve
mediocre entropy, eb_proxy_knuth_m. This is a server program
that mixes together two or more entropy streams, via algorithm M from
Donald Knuth's The Art of Computer Programming, Volume 2,
chapter 3.2.2. The same algorithm is also described in Bruce
Schneier's Applied Cryptography, in case it needs
additional credibility.
Altogether, Entropy Broker's server selection covers a wide range
of randomness-collection options. Virtual machines may be able to use
server_timers or server_cycle_count at the "low
end" and contribute to a shared pool of entropy, while systems with
fast hardware RNGs can be pooled together to provide high-quality
entropy to a pool of clients. In between lies the possibility of a
room full of underutilized file servers with built-in motherboard sound
cards. There are clearly a variety of
different topologies that could make use of Entropy Broker, including
sharing a hardware RNG between peers (i.e., one-to-many), or feeding
excess entropy into a common pool lest it go unused (i.e.,
many-to-one). There are some currently unimplemented features
described in the network protocol, such as quotas. In the field,
making sure that Entropy Broker is producing quality output can be
critical, so there are several test utilities provided for plotting
and otherwise measuring the randomness of the broker's shared pool.
Some of Entropy Broker's more interesting servers are Linux-only (the
audio and Video4Linux2 servers, for example), but others should work on
other UNIX-like systems as well.
Of course, ultimately, the entropy used to fill /dev/random
is important insofar as it provides good, unpredictable input to
things like cryptographic key or pad generation. Providing good
randomness is a small piece of the overall security puzzle, but
attacks that exploit /dev/urandom and /dev/random are certainly not
unheard of. For virtual machines or crypto-heavy servers, the need
for quality randomness is magnified. In such cases, a framework
like Entropy Broker is no silver bullet, but it can offer a flexible
solution. Entropy involves a curious paradox on computer systems;
although believed to be constantly increasing, it can still be
hard to deliver on demand.
(
Log in to post comments)