# /dev/random and /dev/urandom radomness seeding in Tails

/dev/random and /dev/urandom are special Linux devices that provide access from
user land to the Linux kernel Pseudo Random Number Generator (PRNG). This
generator is used for almost every security protocol, like TLS/SSL key
generation, choosing TCP sequences, ASLR offsets, and GPG key generation [1]. In
order for this seed to be cryptographically secure, a source with 'good'
entropy must be used. The Linux kernel collects entropy from several sources,
for example keyboard typing, mouse movement, among others.

## Problem

Because of the Tails nature of being amnesic, and run from a (USB) live device,
care must be taken to ensure the system still gets enough entropy and boots with enough randomness. For example by providing a random seed through different means.

Although these problem have been documented since a long time (see [7] and [8]),
there's not much done to tackle the problem. We looked at notes and research from LiveCD OS's and supply them here for completements sake. Whonix has a [wiki
page](https://www.whonix.org/wiki/Dev/Entropy) with some notes, and Qubes has tickets
about this.

The Qubes tickets can be found at footnotes [3],[4],[5] and [6] for more information.

## Current situation

See the related [[design document|contribute/design/random]]

Tails has stopped shipping /var/lib/urandom/random-seed, since it is a fixed known value
for every Tails installation which means its entropy contribution is zero.

Without this random seed, systemd-random-seed load won't write anything to
/dev/urandom (so we rely purely on the kernel and current system entropy to get
/dev/urandom). This new behavior can't be much worse, and the fact it's the new
debootstrap and systemd default behavior tends to be reassuring.

Tails also ships Haveged since a while, and rngd since 2.6. Note that in
Stretch, Haveged will be started very early at boot time (after the apparmor
profiles loading), before any userland application needs randomness. Still there
are concerns about Haveged's reliability to provide cryptographically secure
randomness.

So the situation may not be that bad, but given the Live nature of Tails,
and the fact that good cryptography is a must, we may want to add additional
measures to ensure any Tails system has enough entropy.

## Use cases

We have several use cases, which may require different solutions, depending on
how the Tails OS is installed.

### DVD

This may be the most difficult, since all that the user is running is the plain
ISO we provide. In there, there's no seed at all, and no way for the users to
add one.

On the other hand, that's not the installation method we want to support the
most, and probably not the most used when people want to secure other
communication types than HTTPS (e.g persistence is very usefull for OpenPGP key
storage and usage, chat account configuration, ...).

So we may eventually just document somewhere to users that they MUST NOT use
this type of installation if they want to rely on good cryptograpy for their
communications and key generation, or that they should wait after having
interacting a long (but hard to define) time with the system so that it had time
to collect entropy, and does not rely on Haveged + rngd only.

We could also add some kind of notification to users when entropy gets too low,
or just saying them that the way they use Tails is not compatible with strong
cryptography.

### Intermediary USB

This type of installation is supposed to be used when people are installing
Tails from another OS (except Debian and Ubuntu, where they can use the Tails
installer). In most case, this means having a bit by bit copy of the Tails ISO
on the USB stick, except for Windows where we ask to use the [Universal USB
Installer](http://www.pendrivelinux.com/universal-usb-installer-easy-as-1-2-3/)

In this case the situation is pretty much the same than with the DVD one. No
seed, and adding one is very difficult if not impossible (except with the
Windows installation where we may ask upstream to implement that in the
Universal USB Installer, but well...).

That's also not really the way we push to users to use Tails, so as with DVD
there's maybe no point to fix the situation here, and the same workaround could
may apply.

### Final USB

That's supposed to be the standard way to use Tails.

Note that in this case, there are two situations: using this installation with
persistence enabled, and without.

It is worth noting too that the first time this Tails installation is booted,
most of the time the first step is to configure persistence, which means
creating an encrypted partition. At this step though, there is at the moment
probably very little entropy, so this may weaken the LUKS volume encryption.

### Virtual Machines

That's a way to use Tails, and one of the worste cases: it is of public
knowledge that entropy in VMs is very poor. It's not really clear how the
entropy gathering daemons we have would help, but there are mechanisms now in
libvirt to pass randomness from the host using the Virtio RNG feature (even if
it may not be enough by itself).

## Proposed solutions

### Persist entropy pool seeds [[!tails_ticket 7675]]

We hope to improve this situation for users who enable the persistence storage
option using some randomness from the previous session to help bootstrap with
some "well" generated randomness.

Storing it in the persistent partition will be implemented using a default
hidden persistence setting. But it does not solve the problem for the first time
Tails is booted, which is likely when the encrypted persistence partition is
created.

###  Use the Tails installer to create a better seed [[!tails_ticket 11897]]

Tails installer can be used on Debian and Ubuntu, and is the tool people
running OSX or Windows are told to use to install their final Tails
USB stick with.

Tails installer could store a seed in the FAT filesystem of the system
partition. That would workaround this first boot problem not handled by the
persistence option.

We can't sadly update this seed while running Tails, as mounting RW the system
FAT partition at that moment does not work. So we'll have to update it at the
system shutdown. This will mean remount this partition, write the new random
seed, then unmount it and start the shutdown of the system. Obviously we can
do this only in normal shutdown process, and will have to avoid it in emergency
shutdown mode.

Using this in addition to the persistent seed mentionned above may thus be the
way to go.

This solution is partial since it only works for Tails Installer+USB stick, and
we don't know if and how we will use the Tails installer in the future (see [[!tails_ticket 11679]]).

One drawback: this would break the ability to verify this system partition with
a simple shasum operation.

### Use stronger/more entropy collectors [[!tails_ticket 5650]]

As already stated, Tails run Haveged, and rngd (since 2.6 for the later).

We may want to add other sources though, given there are concerns about Haveged,
and rngd starts only when a hardware RNG is detected, which is not so often the
case.

XXX: It would be nice to have a study (read: a survey of packages, etc) of all the
useful entropy gathering daemons that might be of use on a Tails system.

An evaluation of some of them [has been done
already](https://volumelabs.net/best-random-data-software/)

Possible candidates:

* [entropy gathering daemon](http://egd.sourceforge.net/): not packaged into Debian.
* [twuewand](http://www.finnie.org/software/twuewand/): used by Finnix LiveCD, packaged into Ubuntu only.
* [timer entropy daemon](https://www.vanheusden.com/te/): not packaged into Debian
* randomsound: probably a bad idea in the Tails context as we're discussing a
  Greeter option to deactivate the microphone.

### Block booting till enough entropy has been gathered

One way to ensure Tails is booting with enough entropy would be to block during
the boot if the system is lacking of it.

But this brings questions about how to interact correctly with the users,
as blocking without notifications would be terrible UX. Also Tails boot time is
a bit long already, and this may grow it quite a bit more again.

XXX: So before going on, we need a bit more data about the state of the entropy when
Tails boot, specially now that we have several entropy collector daemons. It may
very well be that this case do not happen anymore. And if it is, we need to know
on average how much time that blocking would last. [Sycamoreone] [[!tails_ticket
11758]]

### Regulary check available entropy and notify if low

An idea that has been mentioned several time is to have a service that
check if the available entropy is high enough, and notify the user if
it's not the case.

## Related tickets

This is about [[!tails_ticket 7642]], [[!tails_ticket 7675]],
[[!tails_ticket 6116]], [[!tails_ticket 11897]] and friends.

## References

* [1] <https://eprint.iacr.org/2006/086.pdf>
* [2] <https://eprint.iacr.org/2013/338.pdf>
* [3] <http://wiki.qubes-os.org/trac/ticket/673>
* [4] <https://github.com/QubesOS/qubes-issues/issues/1311>
* [5] <https://groups.google.com/forum/#!msg/qubes-devel/Q65boPAbqbE/9ZOZUInQCgAJ>
* [6] <https://groups.google.com/forum/#!topic/qubes-devel/5wI8ygbaohk>
* [7] <https://www.av8n.com/computer/htm/secure-random.htm>
* [8] <http://www.av8n.com/computer/htm/fixup-live-cd.htm>
* [9] <https://www.python.org/dev/peps/pep-0506/>
* [10]<https://docs.python.org/2/library/os.html#os.urandom>
