TL;DR
Use /dev/urandom
for most practical purposes.
The longer answer depends on the flavour of Unix that you're running.
Linux
Historically, /dev/random
and /dev/urandom
were introduced at the same time.
As @DavidSchwartz pointed out in a comment, using /dev/urandom
is preferred in the vast majority of cases. He and others also provided a link to the excellent Myths about /dev/urandom
article which I recommend for further reading.
In summary:
- The manpage is misleading.
- Both are fed by the same CSPRNG to generate randomness (diagrams 2 and 3)
/dev/random
blocks when it runs out of entropy,
so reading from /dev/random
can halt process execution.
- The amount of entropy is conservatively estimated, but not counted
/dev/urandom
will never block.
- In rare cases very shortly after boot, the CSPRNG may not have had enough entropy to be properly seeded and
/dev/urandom
may not produce high-quality randomness.
- Entropy running low is not a problem if the CSPRNG was initially seeded properly.
- The CSPRNG is being constantly re-seeded.
- In Linux 4.8 and onward,
/dev/urandom
does not deplete the entropy pool (used by /dev/random
) but uses the CSPRNG output from upstream.
- Use
/dev/urandom
.
Exceptions to the rule
In the Cryptography Stack Exchange's When to use /dev/random
over /dev/urandom
in Linux
@otus gives two use cases:
Shortly after boot on a low entropy device, if enough entropy has not yet been generated to properly seed /dev/urandom
.
Generating a one-time pad with information theoretic security
If you're worried about (1), you can check the entropy available in /dev/random
.
If you're doing (2) you'll know it already :)
Note: You can check if reading from /dev/random will block, but beware of possible race conditions.
Alternative: use neither!
@otus also pointed out that the getrandom()
system will read from /dev/urandom
and only block if the initial seed entropy is unavailable.
There are issues with changing /dev/urandom
to use getrandom()
, but it is conceivable that a new /dev/xrandom
device is created based upon getrandom()
.
macOS
It doesn't matter, as
Wikipedia says:
macOS uses 160-bit Yarrow based on SHA1. There is no difference between /dev/random and /dev/urandom; both behave identically. Apple's iOS also uses Yarrow.
FreeBSD
It doesn't matter, as Wikipedia says:
/dev/urandom
is just a link to /dev/random
and only blocks until properly seeded.
This means that after boot, FreeBSD is smart enough to wait until enough seed entropy has been gathered before delivering a never-ending stream of random goodness.
NetBSD
Use /dev/urandom
, assuming your system has read at least once from /dev/random
to ensure proper initial seeding.
The rnd(4) manpage says:
/dev/urandom
never blocks.
/dev/random
sometimes blocks. Will block early at boot if the
system's state is known to be predictable.
Applications should read from /dev/urandom
when they need randomly
generated data, e.g. cryptographic keys or seeds for simulations.
Systems should be engineered to judiciously read at least once from
/dev/random
at boot before running any services that talk to the
internet or otherwise require cryptography, in order to avoid
generating keys predictably.
Consider reading the information you need directly from the /proc
filesystem rather than through a tool such as ps
. You will find the information you're looking for ("args") inside file /proc/$pid/cmdline
, only separated by NUL bytes instead of spaces.
You can use this sed
one-liner to get the args of process $pid
:
sed -e 's/\x00\?$/\n/' -e 's/\x00/ /g' "/proc/$pid/cmdline"
This command is equivalent to:
ps -o args= -p "$pid"
(Using args=
in ps
will omit the header.)
The sed
command will first look for the last trailing NUL byte and replace it with a newline, and after that replace all other NUL bytes (separating individual arguments) with spaces, finally producing the same format you're seeing from ps
.
Regarding listing processes in the system, ps
does it by listing directories in /proc
, but there are inherent race conditions to that procedure, since processes are starting and exiting while ps
is running, so what you get is not really a snapshot but an approximation. In particular, it's possible that ps
will show processes that have already terminated by the time it shows its results, or omits processes that have started while it was running (but weren't returned by the kernel while listing the contents of /proc
.)
I always assumed that if a process is there before ps
starts and is still there after it's done, then it would not be missed by it, I assumed the kernel would guarantee those would be always included, even if there's a lot of churn of other processes being created and destroyed. What you're describing implies that's not the case. I'm still skeptical on that, but given there are known race conditions in how ps
works, I guess it's at least plausible that listing PIDs from /proc
might miss an existing one due to those race conditions.
It would be possible to verify that by checking the source of the Linux kernel, but I haven't done that (yet) so can't really tell for sure whether such a race condition exists that would miss a long-running process, as you describe.
The other part is the way ps
works. Even if you're passing it a single PID with the -p
argument, it's still listing all the existing PIDs, even though you're only interested in that single one. It could definitely take a shortcut in that case and skip listing the entries in /proc
and going directly to /proc/$pid
.
I can't say why it was implemented this way. Perhaps because most ps
options are "filters" on the processes, so implementing -p
the same way was easier, taking a shortcut to go straight to /proc/$pid
might involve a separate code path or code duplication... Another hypothesis is that some cases including -p
plus additional options would end up requiring listing, so it's perhaps complex to determine which exact cases would allow taking the shortcut and which ones wouldn't.
Which takes us to the workaround, going straight to /proc/$pid
, without listing the full set of PIDs of the system, avoiding all the known races and simply getting the information you need straight from the source.
It's a bit ugly, but the issue you describe indeed exists, it should be a reliable way to fetch that information.
Best Answer
This RNG comes as part of a Trusted Platform Module. Unless your computer was part of an order for a large organization, the TPM is disabled by default, because it can make your computer unbootable if misconfigured, and because it can make your computer more traceable¹.
If you want to use the RNG, you'll have to enable it in the BIOS. The Thinkpad wiki has detailed instructions for a Thinkpad, which may still help with adaptations if you have another model. I'm not sure if it's enough to enable the TPM in the BIOS or if you also need to initialize it from Linux at boot time. If you need Linux support, install TrouSerS (most distributions should have a package for it).
You can use other things from the TPM, mainly secure boot (so that even someone with root access to your machine can't infect the bootloader to plant a rootkit²). You need Trusted Grub for secure boot.
Note that Linux has a good built-in cryptographic-quality pseudo-random number generator, and is good at collecting entropy to seed that PRNG. So the benefit from a hardware RNG is very limited.
¹ More precisely, a TPM gives your computer a hard-to-spoof identity that you can't easily deny. This would be a major privacy concern, but it is in fact a lot less of a problem than popularly perceived. Software using the TPM correctly does not send your computer's identity to remote parties, but use an application-specific key that isn't traceable to the TPM — so it's like having an account with the third party, no more. Software using the TPM incorrectly can expose your privacy, but so can any software — browsers are famous for revealing a lot of things about you. Everyday web browsing exposes far more than what you risk from a TPM.
² But note that there are other places to plant a rootkit. A TPM can only really provide protection if you lock the system down so much that it's hard to install any extra software.