Home / Ciberseguridad / The randomness that encrypts your messages does not fall from the sky

The randomness that encrypts your messages does not fall from the sky

Chip de silicio emitiendo dados luminosos y ruido digital que se convierte en una llave cifrada

You open your banking app, the address bar turns green and in under a second a 256-bit session key has been negotiated that not even the owner of the Wi-Fi network can decrypt. All that machinery —RSA, elliptic curves, AES, SHA-3— rests on an uncomfortable premise: at some point the machine needed a number nobody could predict. That number is pure randomness, and manufacturing it inside a chip is far harder than it looks.

A computer is the opposite of randomness

A processor is deterministic by design: give it the same inputs and the same state and it always produces the same output. A program that generates “random” numbers is really a mathematical function (PRNG, pseudorandom number generator): it starts from a seed and spits out a sequence that looks like noise but is perfectly calculated. The de facto standard since the 1990s is Mersenne Twister (MT19937), a generator with 19,937 bits of internal state spread across 624 32-bit words. It is extremely fast, statistically excellent and perfect for simulating particles or shuffling a playlist. For cryptography it is a disaster: observe 624 consecutive outputs and you can rebuild the entire state and predict every future number.

That is why security uses a CSPRNG (cryptographically secure pseudorandom number generator) instead. The difference is not statistical quality but the threat model: a CSPRNG must pass the next-bit test (given all previous output, the next bit must be unpredictable) and provide backtracking resistance: if an attacker steals the current state, they still must not be able to derive keys generated earlier.

When randomness fails, everything fails

The history of modern cryptography is full of disasters caused not by breaking AES but by badly generating a handful of bits:

  • Netscape, 1994. Its SSL seeded the generator with the system time and the process ID. Ian Goldberg and David Wagner needed a few hours to predict every session key.
  • Debian, 2006-2008. A patch to silence Valgrind warnings removed the calls feeding OpenSSL’s generator. For almost two years, keys generated on Debian had only about 32,767 real possibilities. It was found in May 2008: half the internet had to regenerate certificates and SSH keys.
  • PlayStation 3, 2010. Sony signed with ECDSA using a constant k value. A signature satisfies s = k⁻¹(z + r·d), where d is the private key; with two signatures sharing k, the system of two equations leaves d in plain sight. The fail0verflow group recovered the console’s master key and with it the whole signing ecosystem.
  • Android, 2013. A bug in SecureRandom made several bitcoin wallets seed their generator with the same sequence. With the ECDSA k repeated, private keys were computed from the outside and roughly 55 bitcoins vanished.

Out of this came a practice that is now the norm: deterministic ECDSA (RFC 6979), which derives k with an HMAC of the private key and the message, removing the dependency on randomness in signing altogether.

How entropy is manufactured inside the kernel

Entropy is measured in bits and does not mean “amount of data” but real uncertainty: how many bits an attacker is missing to guess the value. The Linux kernel harvests it from physical sources that no attacker can reproduce without being on the machine:

  • Timer jitter: the nanoseconds that vary between two identical interrupts. The jitterentropy subsystem measures the spread of short loops; the result depends on chip temperature, cache state and branch prediction, impossible to replicate from outside.
  • Event timing: the latency of a network packet, the exact instant a finger touches the screen or a disk head finishes a read.
  • Hardware: the RDRAND and RDSEED instructions (Intel since Ivy Bridge, AMD since Zen), ring oscillators with thermal noise inside the silicon itself, the TPM 2.0 TRNG, or the virtio-rng source a hypervisor exposes to virtual machines.

Since Linux 5.17 (2022) the design is much simpler than it used to be: a single 256-bit input_pool mixes all those sources with BLAKE2s, a fast, constant-time hash function —no data-dependent branches, so no timing leaks—. That pool is the key that starts a generator based on ChaCha20, the 256-bit stream cipher with a 16-byte nonce. Instead of “counting” entropy, the kernel verifies that the seed is unpredictable, and from there the CSPRNG is infinite: it is remixed periodically, so anyone reading today’s state cannot rewind to yesterday’s keys. The same idea gave /dev/random its reputation for blocking: it no longer does —as of Linux 5.6 it only blocks until the CRNG has been initialised once— and that first instant is precisely the dangerous window.

From noise to your session key

In a TLS 1.3 handshake, the browser and the server generate an ephemeral X25519 key pair (a Diffie-Hellman exchange over the Curve25519 curve) using numbers taken from that CRNG; from there they derive session keys with HKDF. The whole system is sound as long as the entropy is. And it often is not: in 2012 the Mining Your Ps and Qs study scanned more than twelve million hosts on the internet and found shared prime factors in 0.2% of RSA certificates, plus repeated nonces in millions of DSA and ECDSA signatures. Many of those machines were routers and embedded devices that generated their keys in the first seconds after booting, when the input_pool had barely accumulated any noise. The practical consequence is brutal: recoverable private keys, forgeable certificates and decryption of other people’s traffic without touching the mathematics of encryption.

The hole is at boot (and in cloned machines)

The two scenarios where entropy runs out are well known. The first is the boot-time entropy hole: a freshly powered device generates its keys before enough events exist. It is mitigated by saving 256 bytes of seed on shutdown (systemd-random-seed) and feeding them back at boot, or by waiting for the hardware to report its first number. The second is more common than it seems: cloning virtual machines. If you duplicate a VM from an already-booted image, both can inherit the same CRNG state and generate the same SSH host key; it is not an attack, it is a direct consequence of copying the state of a deterministic generator.

Check it on your own machine

On Linux you can look inside the system: cat /proc/sys/kernel/random/entropy_avail (today it returns 256 and always will; it is a legacy counter that no longer estimates anything), cat /sys/devices/virtual/misc/hw_random/rng_current to see whether your hardware exposes a TRNG, or rngtest from the rng-tools package to run the FIPS battery over a sample of /dev/urandom. And if you run virtual servers, make sure the machine has an entropy source from the hypervisor: it is the most boring configuration line and the one that most raises the cost of breaking your encryption.

The entire edifice of digital security —the 256 bits of AES, the elliptic curves, the hashes— rests on a single physical premise: that at some point, someone measured something they could not predict. If that measurement is bad, cryptography does not fail at the bottom, it fails at the top.