On the proper use of /dev/random

Colin Plumb (colin@nyx.net)
Fri, 25 Dec 1998 16:33:24 -0700 (MST)


The "yes" utility alrady exists, because it has served a useful purpose,
and if someone wants a version that does not append a trailing
newline, I'm sure they can cobble a -n option onto it.

To really emulate this proposed (silly) /dev/repeat, also add a "-" option,
which buffers stdin until EOF and the repeats it endlessly. I.e.
"yes foo" would be equivalent to "echo foo | yes -".

In any case, it can easily and usefully be done in user space.
In truth, /dev/null could be, too, but historically it has been
available, the kernel implementation is trivial, and it's somewhat
more efficient than a pipe to a data-sink application.

Now, as for /dev/random...
/dev/random tries to deliver one-time-pad quality random numbers.
These are generated from hardware entropy sources, and are unpredictable
to an attacker with infinite computational power. This is extremely
difficult to do from user level, and thus is a valuable service.

/dev/urandom gives numbers that are, in paractice, almost as good.
The amount of output /dev/random can generate is limited by the
hardware sources. This leads to blocking reads which is, at times,
highly inconvenient. The service /dev/urandom provides to userland is
that the numbers are as good as they can be without waiting.

But even though it won't block indefinitely, it's still slow. Fine for
generating small cryptographic keys directly, but the emphasis is very
much on security over speed. The intensive speed optimization you see
is all in the interrpt-handler path, where the original entropy is
gathered. The code goes to great lengths to avoid delaying that any more
than absolutely necessary. The algorithm trades off time gathering
entropy (into an in-kernel buffer) for time reading the output.

If you want *lots* of random data, that can be done easily in user
space. Choose a cyptographic RNG which suits your speed and
security needs, seed it from /dev/urandom, and go to town.

A kernel-level implementation could not possibly be faster that this,
and wouldn't offer any security advantages. It's just not necessary.

See my sterilize.c code for an example of how to do it right.
(The fallback to /dev/random is because Solaris offers /dev/random
but not /dev/urandom, at least as far as I know.) That code uses
a particularly high-speed but somewhat experimental RNG,
because it needs megabytes of output. Other applications might
prefer to be a little bit more conservative.

Maybe I should just write up a random-noise-generating utility for
user space?

-- 
	-Colin

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/