Linux – Adding Random Number Entropy for GPG Keys

gpglinuxrandom

In the following video: Linux HOWTO: Secure Your Data with PGP, Part 2, you are shown how to create a key pair with gpg. At about 1:50, the instructor says the following:

While the key is being generated, it is a good idea to move your mouse around a little bit to give it a bit more random number entropy for the creation of the keypair.

This seems to me like a myth, especially since command-line tools shouldn't usually be affected by the cursor. On the other hand, I have no clue how Linux's random number generator works, whether it is shared by the GUI or independent from it. Is there any stock in what he claims, or this an example of cargo cult programming?

Best Answer

There is a grain of truth to this, in fact more truth than myth, but nonetheless the statement reflects a fundamental misunderstanding of what's going on. Yes, moving the mouse while generating a key with GPG can be a good idea. Yes, moving the mouse contributes some entropy that makes random numbers random. No, moving the mouse does not make the key more secure.

All good random generators suitable for cryptography, and Linux's is in that category, have two components:

  • An entropy source, which is non-deterministic. The purpose of the entropy is to bootstrap the random number generator with unpredictable data. The entropy source must be non-deterministic: otherwise, an adversary could reproduce the same computation.
  • A pseudorandom number generator, which produces unpredictable random numbers in a deterministic fashion from a changing internal state.

Entropy has to come from a source that is external to the computer. The user is one source of entropy. What the user does is mostly not random, but the fine timing of keystrokes and mouse movements is so unpredictable as to be slightly random — not very random, but little by little, it accumulates. Other potential sources of entropy include the timing of network packets and camera or microphone white noise. Different kernel versions and configurations may use a different set of sources. Some computers have dedicated hardware RNG circuits based on radioactive decay or, less impressively, unstable electronic circuits. These dedicated sources are especially useful in embedded devices and servers which can have pretty predictable behavior on their first boot, without a user to do weird things.

Linux provides random numbers to programs via two devices: /dev/random and /dev/urandom. Reading from either device returns cryptographic-quality. Both devices use the same internal RNG state and the same algorithm to transform the state and produce random bytes. They have peculiar limitations which makes neither of them the right thing:

  • /dev/urandom can return predictable data if the system has not yet accumulated sufficient entropy.
  • /dev/random calculates the amount of available entropy and blocks if there isn't enough. This sounds good, except that the calculation is based on theoretical considerations that make the amount of available entropy decrease linearly with each output bit. Thus /dev/random tends to block very quickly.

Linux systems save the internal RNG state to disk and restore it at boot time. Therefore entropy carries over from one boot to the next. The only time when a Linux system may lack entropy is when it's freshly installed. Once there is sufficient entropy in the system, entropy does not decrease; only Linux's flawed calculation decreases. For more explanations of this consideration, read /dev/urandom is suitable to generate a cryptographic key, by a professional cryptographer. See aso Can you explain the entropy estimate used in random.c.

Moving the mouse adds more entropy to the system. But gpg can only read from /dev/random, not /dev/urandom (a way to solve this problem is to make /dev/random the same 1:9 device as /dev/urandom), so it is never at risk of receiving not-random-enough random numbers. If you don't move the mouse, the key is as random as can be; but what can happen is that gpg may get blocked in a read from /dev/random, waiting for the kernel's entropy counter to rise.