diff --git a/secure_software_development_fundamentals.md b/secure_software_development_fundamentals.md index a310e14..aaa0b1e 100644 --- a/secure_software_development_fundamentals.md +++ b/secure_software_development_fundamentals.md @@ -4781,6 +4781,11 @@ Here are some examples of how to call the predictable PRNG versus a cryptographi Random() SecureRandom() + + C (POSIX) + rand(), *rand48() + getentropy() + C# System.Random @@ -4807,9 +4812,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, POSIX defines the `getentropy` interface to access a cryptographically secure pseudo-random number generator. On Linux systems `getentropy` is wrapper over the `getrandom` system call. The Linux kernel additionally provides the special files `/dev/urandom` and `/dev/random` that have been similar since Linux kernel version 5.6. In most cases you would want to use the `getentropy` interface where practical, or the `/dev/random` special file if `getentropy` is hard to access (e.g., from a shell script). Both generate cryptographically secure random values using a CSPRNG and entropy gathered by the kernel. The key difference between `/dev/urandom` and `/dev/random`, is that `/dev/urandom` may provide output during early boot even before the random generator is fully seeded, while `getentropy` and `/dev/random` block until the generator is fully initialized. 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.