Linux has two random number generators available to userspace, /dev/random
and /dev/urandom
.
/dev/random
is a source of "true" randomness - i.e. it is not generated by a pseudo-random number generator. Entropy is fed into this by the input driver and the interrupt handler, through the functions add_input_randomness
and add_interrupt_randomness
. Processes reading this device will block if the entropy runs out.
/dev/urandom
is a pseudo-random number generator. It is fed by the same entropy pool as /dev/random
, but when that runs out, it switches to a cryptographically strong generator.
Userspace applications can feed into the entropy pool by writing to /dev/{,u}random
.
Have a read of the random(4) manual page, and the file drivers/char/random.c
in the kernel source tree. It is well commented and most of what you ask is explained there.
FreeBSD's /dev/random
by default is a pseudo-random number generator using the Yarrow algorithm (but can point to a hardware RNG if one is connected). The software generator takes entropy from Ethernet and serial connections and hardware interrupts (changeable through sysctl kern.random
). The Yarrow algorithm is believed to be secure as long as the internal state is unknown, therefore /dev/random
should always output high-quality data without blocking.
See random(4).
On NetBSD, /dev/random
provides random data based only on entropy collected (from disks, network, input devices, and/or tape drives; adjustable using rndctl), while /dev/urandom
falls back to a PRNG when the entropy pool is empty, similar to Linux.
See random(4), rndctl(8), rnd(9).
OpenBSD has four generators: /dev/random
is a hardware generator, /dev/srandom
is a secure random data generator (using MD5 on the entropy pool: "disk and network device interrupts and such"), /dev/urandom
is similar but falls back to a PRNG when the entropy pool is empty. The fourth, /dev/arandom
, is also a PRNG but using RC4.
See random(4), arc4random(3).
Mac OS X also uses the Yarrow algorithm for /dev/random
, but has an identically working /dev/urandom
for compatibility. "Additional entropy is fed to the generator regularly by the SecurityServer daemon from random jitter measurements of the kernel." See random(4).
GnuPG consumes several bytes from /dev/random
for each random byte it actually uses. You can easily check that with this command:
start cmd:> strace -e trace=open,read gpg --armor --gen-random 2 16 2>&1 | tail
open("/etc/gcrypt/rngseed", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/dev/urandom", O_RDONLY) = 3
read(3, "\\\224F\33p\314j\235\7\200F9\306V\3108", 16) = 16
open("/dev/random", O_RDONLY) = 4
read(4, "/\311\342\377...265\213I"..., 300) = 128
read(4, "\325\3\2161+1...302@\202"..., 172) = 128
read(4, "\5[\372l\16?\...6iY\363z"..., 44) = 44
open("/home/hl/.gnupg/random_seed", O_WRONLY|O_CREAT, 0600) = 5
cCVg2XuvdjzYiV0RE1uzGQ==
+++ exited with 0 +++
In order to output 16 bytes of high-quality entropy GnuPG reads 300 bytes from /dev/random
.
This is explained here: Random-Number Subsystem Architecture
Linux stores a maximum of 4096 bytes (see cat /proc/sys/kernel/random/poolsize
) of entropy. If a process needs more than available (see cat /proc/sys/kernel/random/entropy_avail
) then the CPU usage becomes more or less irrelevant as the feeding speed of the kernel's entropy pool becomes the relevant factor.
Best Answer
As explained in other answers and comments the reason for what you observe is the way
Bash
handles pipes. In order to filter what you really want in similar situations you can try to enclose the first letter of thegrep
argument in[]
like this:EDIT:
As correctly noted by R. in the comment below in fact
strace
does not see the other side of the pipe. Similarly tops aux | grep grep
which also showsgrep grep
in its outputw
is is walking through/proc
directory and findsgrep
process there.