random: rewrite header introductory comment
Now that we've re-documented the various sections, we can remove the outdated text here and replace it with a high-level overview. Cc: Theodore Ts'o <tytso@mit.edu> Reviewed-by: Eric Biggers <ebiggers@google.com> Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
0deff3c432
commit
5f75d9f3ba
|
@ -2,168 +2,27 @@
|
|||
/*
|
||||
* Copyright (C) 2017-2022 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
* Copyright Matt Mackall <mpm@selenic.com>, 2003, 2004, 2005
|
||||
* Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All
|
||||
* rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Exported interfaces ---- output
|
||||
* ===============================
|
||||
* Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All rights reserved.
|
||||
*
|
||||
* There are four exported interfaces; two for use within the kernel,
|
||||
* and two for use from userspace.
|
||||
* This driver produces cryptographically secure pseudorandom data. It is divided
|
||||
* into roughly six sections, each with a section header:
|
||||
*
|
||||
* Exported interfaces ---- userspace output
|
||||
* -----------------------------------------
|
||||
* - Initialization and readiness waiting.
|
||||
* - Fast key erasure RNG, the "crng".
|
||||
* - Entropy accumulation and extraction routines.
|
||||
* - Entropy collection routines.
|
||||
* - Userspace reader/writer interfaces.
|
||||
* - Sysctl interface.
|
||||
*
|
||||
* The userspace interfaces are two character devices /dev/random and
|
||||
* /dev/urandom. /dev/random is suitable for use when very high
|
||||
* quality randomness is desired (for example, for key generation or
|
||||
* one-time pads), as it will only return a maximum of the number of
|
||||
* bits of randomness (as estimated by the random number generator)
|
||||
* contained in the entropy pool.
|
||||
*
|
||||
* The /dev/urandom device does not have this limit, and will return
|
||||
* as many bytes as are requested. As more and more random bytes are
|
||||
* requested without giving time for the entropy pool to recharge,
|
||||
* this will result in random numbers that are merely cryptographically
|
||||
* strong. For many applications, however, this is acceptable.
|
||||
*
|
||||
* Exported interfaces ---- kernel output
|
||||
* --------------------------------------
|
||||
*
|
||||
* The primary kernel interfaces are:
|
||||
*
|
||||
* void get_random_bytes(void *buf, size_t nbytes);
|
||||
* u32 get_random_u32()
|
||||
* u64 get_random_u64()
|
||||
* unsigned int get_random_int()
|
||||
* unsigned long get_random_long()
|
||||
*
|
||||
* These interfaces will return the requested number of random bytes
|
||||
* into the given buffer or as a return value. This is equivalent to a
|
||||
* read from /dev/urandom. The get_random_{u32,u64,int,long}() family
|
||||
* of functions may be higher performance for one-off random integers,
|
||||
* because they do a bit of buffering.
|
||||
*
|
||||
* prandom_u32()
|
||||
* -------------
|
||||
*
|
||||
* For even weaker applications, see the pseudorandom generator
|
||||
* prandom_u32(), prandom_max(), and prandom_bytes(). If the random
|
||||
* numbers aren't security-critical at all, these are *far* cheaper.
|
||||
* Useful for self-tests, random error simulation, randomized backoffs,
|
||||
* and any other application where you trust that nobody is trying to
|
||||
* maliciously mess with you by guessing the "random" numbers.
|
||||
*
|
||||
* Exported interfaces ---- input
|
||||
* ==============================
|
||||
*
|
||||
* The current exported interfaces for gathering environmental noise
|
||||
* from the devices are:
|
||||
*
|
||||
* void add_device_randomness(const void *buf, size_t size);
|
||||
* void add_input_randomness(unsigned int type, unsigned int code,
|
||||
* unsigned int value);
|
||||
* void add_interrupt_randomness(int irq);
|
||||
* void add_disk_randomness(struct gendisk *disk);
|
||||
* void add_hwgenerator_randomness(const void *buffer, size_t count,
|
||||
* size_t entropy);
|
||||
* void add_bootloader_randomness(const void *buf, size_t size);
|
||||
*
|
||||
* add_device_randomness() is for adding data to the random pool that
|
||||
* is likely to differ between two devices (or possibly even per boot).
|
||||
* This would be things like MAC addresses or serial numbers, or the
|
||||
* read-out of the RTC. This does *not* add any actual entropy to the
|
||||
* pool, but it initializes the pool to different values for devices
|
||||
* that might otherwise be identical and have very little entropy
|
||||
* available to them (particularly common in the embedded world).
|
||||
*
|
||||
* add_input_randomness() uses the input layer interrupt timing, as well as
|
||||
* the event type information from the hardware.
|
||||
*
|
||||
* add_interrupt_randomness() uses the interrupt timing as random
|
||||
* inputs to the entropy pool. Using the cycle counters and the irq source
|
||||
* as inputs, it feeds the randomness roughly once a second.
|
||||
*
|
||||
* add_disk_randomness() uses what amounts to the seek time of block
|
||||
* layer request events, on a per-disk_devt basis, as input to the
|
||||
* entropy pool. Note that high-speed solid state drives with very low
|
||||
* seek times do not make for good sources of entropy, as their seek
|
||||
* times are usually fairly consistent.
|
||||
*
|
||||
* All of these routines try to estimate how many bits of randomness a
|
||||
* particular randomness source. They do this by keeping track of the
|
||||
* first and second order deltas of the event timings.
|
||||
*
|
||||
* add_hwgenerator_randomness() is for true hardware RNGs, and will credit
|
||||
* entropy as specified by the caller. If the entropy pool is full it will
|
||||
* block until more entropy is needed.
|
||||
*
|
||||
* add_bootloader_randomness() is the same as add_hwgenerator_randomness() or
|
||||
* add_device_randomness(), depending on whether or not the configuration
|
||||
* option CONFIG_RANDOM_TRUST_BOOTLOADER is set.
|
||||
*
|
||||
* Ensuring unpredictability at system startup
|
||||
* ============================================
|
||||
*
|
||||
* When any operating system starts up, it will go through a sequence
|
||||
* of actions that are fairly predictable by an adversary, especially
|
||||
* if the start-up does not involve interaction with a human operator.
|
||||
* This reduces the actual number of bits of unpredictability in the
|
||||
* entropy pool below the value in entropy_count. In order to
|
||||
* counteract this effect, it helps to carry information in the
|
||||
* entropy pool across shut-downs and start-ups. To do this, put the
|
||||
* following lines an appropriate script which is run during the boot
|
||||
* sequence:
|
||||
*
|
||||
* echo "Initializing random number generator..."
|
||||
* random_seed=/var/run/random-seed
|
||||
* # Carry a random seed from start-up to start-up
|
||||
* # Load and then save the whole entropy pool
|
||||
* if [ -f $random_seed ]; then
|
||||
* cat $random_seed >/dev/urandom
|
||||
* else
|
||||
* touch $random_seed
|
||||
* fi
|
||||
* chmod 600 $random_seed
|
||||
* dd if=/dev/urandom of=$random_seed count=1 bs=512
|
||||
*
|
||||
* and the following lines in an appropriate script which is run as
|
||||
* the system is shutdown:
|
||||
*
|
||||
* # Carry a random seed from shut-down to start-up
|
||||
* # Save the whole entropy pool
|
||||
* echo "Saving random seed..."
|
||||
* random_seed=/var/run/random-seed
|
||||
* touch $random_seed
|
||||
* chmod 600 $random_seed
|
||||
* dd if=/dev/urandom of=$random_seed count=1 bs=512
|
||||
*
|
||||
* For example, on most modern systems using the System V init
|
||||
* scripts, such code fragments would be found in
|
||||
* /etc/rc.d/init.d/random. On older Linux systems, the correct script
|
||||
* location might be in /etc/rcb.d/rc.local or /etc/rc.d/rc.0.
|
||||
*
|
||||
* Effectively, these commands cause the contents of the entropy pool
|
||||
* to be saved at shut-down time and reloaded into the entropy pool at
|
||||
* start-up. (The 'dd' in the addition to the bootup script is to
|
||||
* make sure that /etc/random-seed is different for every start-up,
|
||||
* even if the system crashes without executing rc.0.) Even with
|
||||
* complete knowledge of the start-up activities, predicting the state
|
||||
* of the entropy pool requires knowledge of the previous history of
|
||||
* the system.
|
||||
*
|
||||
* Configuring the /dev/random driver under Linux
|
||||
* ==============================================
|
||||
*
|
||||
* The /dev/random driver under Linux uses minor numbers 8 and 9 of
|
||||
* the /dev/mem major number (#1). So if your system does not have
|
||||
* /dev/random and /dev/urandom created already, they can be created
|
||||
* by using the commands:
|
||||
*
|
||||
* mknod /dev/random c 1 8
|
||||
* mknod /dev/urandom c 1 9
|
||||
* The high level overview is that there is one input pool, into which
|
||||
* various pieces of data are hashed. Some of that data is then "credited" as
|
||||
* having a certain number of bits of entropy. When enough bits of entropy are
|
||||
* available, the hash is finalized and handed as a key to a stream cipher that
|
||||
* expands it indefinitely for various consumers. This key is periodically
|
||||
* refreshed as the various entropy collectors, described below, add data to the
|
||||
* input pool and credit it. There is currently no Fortuna-like scheduler
|
||||
* involved, which can lead to malicious entropy sources causing a premature
|
||||
* reseed, and the entropy estimates are, at best, conservative guesses.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
|
Loading…
Reference in New Issue