Skip to content

Commit

Permalink
Random number generator updates
Browse files Browse the repository at this point in the history
This includes the POSIX interface getentropy, that is simpler to use
than getrandom, and in practice it is available for as long as getrandom
is available in glibc, in addition to being part of OpenBSD before that.
https://pubs.opengroup.org/onlinepubs/9799919799/

This patch set also removes the long discussion about /dev/random and
/dev/urandom which I loved, but today these interfaces function similarly.
torvalds/linux@30c08ef

Further discussion at:
ossf#158

Signed-off-by: Nikos Mavrogiannopoulos <[email protected]>
  • Loading branch information
Nikos Mavrogiannopoulos committed Dec 17, 2024
1 parent de4e51f commit 8bd6c98
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions secure_software_development_fundamentals.md
Original file line number Diff line number Diff line change
Expand Up @@ -4808,6 +4808,11 @@ Here are some examples of how to call the predictable PRNG versus a cryptographi
<td><tt>Random()</tt></td>
<td><tt>SecureRandom()</tt></td>
</tr>
<tr>
<td>C (POSIX)</td>
<td><tt>rand(), *rand48()</tt></td>
<td><tt>getentropy()</tt></td>
</tr>
<tr>
<td>C#</td>
<td><tt>System.Random</tt></td>
Expand All @@ -4834,9 +4839,7 @@ Another challenge is that software is fundamentally deterministic; given exactly

There is a simple solution: use a CSPRNG and use hardware to correctly provide data to it. Most operating system kernels today provide cryptographically secure random numbers by gathering environmental noise from multiple hardware devices and implementing a CSPRNG. If you’re running on bare metal (instead of an operating system kernel) there are usually reusable libraries you can use for this purpose. These cryptographically secure random numbers can be used directly, or can be used as a secure seed for a cryptographically secure PRNG.

For example, the Linux kernel provides cryptographically secure random number values via its `getrandom` system call, as well as the special files `/dev/urandom` and `/dev/random`. In most cases you would want to use the `getrandom` system call where practical, or the `/dev/urandom` special file if `getrandom` is hard to access (e.g., from a shell script). These generate cryptographically secure random values using a CSPRNG and entropy gathered by the kernel. In special circumstances, such as creating a long-lived cryptographic key, you might instead want to use `/dev/random` or the equivalent option in `getrandom`; this forces the kernel to wait (block) until it has a high estimated amount of internal entropy. The purpose of `/dev/random` is to ensure there is a large amount of internal entropy, but the blocking may be indefinite in some circumstances and it’s usually not necessary. What's important is that an attacker can't practically guess the random value, not the value of this internal entropy estimate. (see [“Myths about /dev/urandom”](https://www.2uo.de/myths-about-urandom/) by Thomas). In the future there may be no difference between `/dev/random` and `/dev/urandom`.

For example, the Linux kernel provides cryptographically secure random number values via its **/dev/urandom** special file, its **/dev/random** special file, and its **getrandom** system call. In most cases you would want to use the **/dev/urandom** special file or the **getrandom** system call. These generate cryptographically secure random values using a CSPRNG and entropy gathered by the kernel. In special circumstances, such as creating a long-lived cryptographic key, you might instead want to use **/dev/random** or the equivalent option in **getrandom**; this forces the kernel to wait (block) until it has a high estimated amount of internal entropy. The purpose of **/dev/random** is to ensure there is internal entropy, but the blocking may be indefinite in some circumstances and it’s usually not necessary
For example, the POSIX specification defines the `getentropy` interface to access a cryptographically secure pseudo-random number generator. On Linux systems `getentropy` is a wrapper around the Linux-specific and more flexible `getrandom` system call. The Linux kernel additionally provides the special readable files `/dev/urandom` and `/dev/random`. The Linux kernel, and many other systems, gather entropy from hardware and mix that into random values using a CSPRNG to provide these cryptographically secure random values. Typical Linux systems record old seeds on shutdown so they will continue to produce highly random values when they reboot. Unfortunately, some of these requests will block - possibly forever - until the underlying system's estimate of internal entropy is high enough (`getentropy`, `/dev/random`, and some uses of `getrandom` will all block). In most cases on Linux kernel based systems you should use avoid blocking indefinitely, and instead use a non-blocking form for `getrandom` or the non-blocking `/dev/urandom`. However, for creating long-lived secrets (like GPG/TLS/SSH keys) where the quality of randomness is especially critical, consider using the blocking versions. This is a potential trade-off between availability and other aspects of security. See the Linux man page [urandom(4)](https://linux.die.net/man/4/urandom).

A particularly nasty security problem in computer systems is *insecure random number generators*. An insecure random number generator produces values that look fine, but destroys the security of the entire system. Many failures of cryptographic systems have been traced back to bad random number generation, in part because it can be hard to detect the problem.

Expand Down

0 comments on commit 8bd6c98

Please sign in to comment.