11

What I have: A large file containing lots of secret, true-random bytes (yes, I'm sure they're not merely pseudo-random). I'll call it F.

What I want to do: Tell Linux that it can use this file as an entropy source for /dev/random (each byte should be estimated at a full 8 bits of entropy)

What I already know about and don't want to be lectured about:

  • /dev/urandom
  • Existing tools for collecting entropy from other devices in the system

What I'm looking for: A shell command or the name of a tool (and the relevant function) that will either:

  • Append F to /dev/random
  • Cause accesses to /dev/random to consume bytes from F as if it were a device, without reusing any

Is this possible? What are the security implications?

  • 5
    Can I just ask... why? What is the problem that you are solving by doing this? I mean, "for funsies" is completely fine, I just want to be sure you're not doing it because you expect some kind of tangible security improvement. – Polynomial Oct 10 '14 at 22:26
  • 2
    You can't really "consume" entropy. Besides, /dev/urandom is designed to provide an essentially unlimited CSRPNG through the use of AES-CTR keyed from /dev/random, which means you're guaranteed to have strong random numbers as long as you've got even a bare minimum of collected entropy. You'd have to run some kind of tiny cut-down kernel on a low-entropy embedded device and pull gigabytes of random data from /dev/urandom to impact security in a negative way. – Polynomial Oct 10 '14 at 22:36
  • 2
    I'm really not interested in getting into a "when to use /dev/urandom versus /dev/random" debate... I just need the above question answered, irrespective of the many wonderful uses for /dev/urandom. The application we are creating requires lots of true-random entropy, not CSPRNG output. – Clayton Oct 10 '14 at 23:28
  • 2
    Care to explain what specific requirement you have that /dev/urandom doesn't solve? The term "true-random entropy" doesn't make any sense in this context. – Polynomial Oct 10 '14 at 23:30
  • 6
    @Clayton you seem to be under the impression that /dev/random does not use a CSPRNG. – tylerl Oct 11 '14 at 7:20
19

First of all, to answer your question directly: This cannot be done. It is purposefully not allowed.

You can, in fact write to /dev/random and it will mix your input into the random pool, potentially improving the quality of the output. But it won't update the entropy_count and unlock /dev/random for reading, because that would be cheating. Otherwise you'd be able to do something like this:

cat /dev/urandom > /dev/random  # Sup dawg, I heard you like random pools...

Except that you can. Sort of.

There's an ioctl called RNDADDENTROPY available on /dev/random that updates the entropy pool and then increments the entropy_count accordingly. The idea is to allow you to read from a hardware RNG in userspace and dump it into the kernel pool without writing your own driver. Nifty. And while anyone is allowed to dump their entropy into /dev/random (it can't hurt), only root is allowed to use RNDADDENTROPY.

And yes, there is a tool out there that allows you to do this relatively easily; it's called rngd. Its primary purpose is to read from an RNG like /dev/hwrandom or your processor's RDRAND instruction, and constantly re-seed your entropy pool as it gets low. But it takes an arbitrary filename for input, so yes, you can even do this:

rngd -r /dev/urandom

Which, in all honesty, is not entirely unlike doing this:

ln -sf /dev/urandom /dev/random

But as I stated originally, that doesn't mean that you can use this tool to make the kernel use your file as its source of entropy. That bit, at least, is not allowed. You can use it as an additional source of entropy mixed in with all the others, but not the only source of entropy.

If you're convinced your file is of prime-grade randomness, then just use that. You don't have to inject it through the kernel's entropy estimation system. If instead you have a mechanism for generating TRNGs, then by all means dump it in there with all the rest of the entropy sources; rngd makes that pretty simple.

I won't bother telling you about the utter absurdity of religiously avoiding /dev/urandom on real servers, as clearly you've heard that lecture several times and choose not to listen.

But for everyone else, the difference between /dev/random and /dev/urandom only matters immediately at startup on devices without reasonable sources of randomness (like some embedded devices), where the startup conditions are precisely repeatable, and where the random pool is not saved between boots. In all other cases, any theoretical attack against /dev/urandom would require techniques and technology that literally do not exist, and are not expected to ever exist, ever.

From the wording of your question, you seem to be under the impression that /dev/random outputs the result of a TRNG, while /dev/urandom uses a PRNG. This is not accurate. The only difference in output is that random will "lock up" if it's generating bytes faster than it's observing random events, while urandom will not. Otherwise they both run the exact same code on their respective pools. Neither directly outputs the raw bits from a TRNG. Both use random events to constantly re-seed a PRNG.

  • This answered my question, thank you. I really do understand the difference between /dev/random and /dev/urandom, and your explanation for why the system is not set up to do what I was thinking to do also makes sense. – Clayton Oct 12 '14 at 1:34
  • My file is of "prime grade randomness" (basically, white noise that has been post-processed through an off-the-shelf CSPRNG but compressed not expanded). The difference between our application and others is the need to generate "bulk true randomness", rather than sip a little true randomness from /dev/random and stretch it out through a CSPRNG. As for server security, the application is a distributed peer-to-peer system, so the security of individual servers in the network is mostly irrelevant to the overall security of the distributed system. – Clayton Oct 12 '14 at 1:38
  • Apropos cheating: have a look at this scary Google search. – CL. Oct 12 '14 at 9:06
  • 1
    Linux could do everyone a favor and take the bsd approach here. Maybe create a new char device called /dev/pedanticrandom that keeps the current entropy rules. – tylerl Oct 12 '14 at 16:41
  • Small nitpick, but it's CAP_SYS_ADMIN, not root, which is allowed to use that ioctl. – forest Jun 9 '18 at 4:43
3

Given everything you said, you should probably read directly from your file instead of from /dev/random. As you apparently don't trust how /dev/random works (perhaps you read this paper) then be declarative, and don't place your trust in it.

You should realize by now that there should be no way anyone can be allowed to inject data directly into the entropy pool. Otherwise it would be an attack vector that could compromise SSL/TLS key generation, and all the bad guys would be doing it already.

If you insist on pressing forward, check out how rng-tools inserts data into the entropy pool. It's designed to integrate the output from a hardware RNG, and you could modify it to read from your file instead of from a hardware device. My concern is that even if you provide enough data from your file, /dev/random may block if it doesn't get enough entropy from its other sources. It's not supposed to get all its entropy bits from a single source, so no matter how fast you supply them, I think it might block.

If you are using an actual hardware random number generator to create your files, I'd consider using rng-tools to tie it directly into the entropy pool without the intermediate step of committing it to the file system.

The nice thing about this approach is that it reduces the risk of your file being a corrupting influence on random numbers (the data is mixed with other sources of entropy) and it reduces the risk of an attacker copying your file and learning your random numbers (due to the other sources of entropy).

  • It's not that we don't trust /dev/random - it works for its ordinary applications... it's that our application is a little different than your usual "I want a key to encrypt something, can you give me some high-quality secret bits, please?" We need to generate massive quantities of true random tokens that cannot have any conceivable relationship between the bits, whether cryptographic or otherwise. We do use a CSPRNG to process the bits, but we do it in a way that we end up with fewer output bits than input bits to the CSPRNG, that is, we are compressing, not stretching. – Clayton Oct 12 '14 at 1:46
0

On most Linux systems, the entropy pool used by /dev/random is initialized at boot using /var/run/random-seed. If this process were omitted, then two identical servers using the same distribution of Linux may have an identical boot sequence and would therefore have an identical /dev/random state.

To prevent this from happening, upon shutdown the current value of the /dev/random entropy pool is saved off into /var/run/random-seed, and then restored upon boot. Making everyone's entropy pool a little different, which is a great design.

  • Welcome back, @Rook. You've been largely absent for a while. – tylerl Oct 11 '14 at 7:03
  • 1
    You have that path wrong -- /var/run is a tmpfs and therefore deleted on shutdown. I didn't Google it, but my Ubuntu system appears to use /var/lib/urandom/random-seed. – Matt Nordhoff Oct 12 '14 at 15:47
  • 1
    @Matt Nordhoff I pulled the path from the init script. The path is distro dependent. – rook Oct 12 '14 at 16:45
0

Increasing the kernel's entropy counter requires the RNDADDENTROPY ioctl.

The easiest way to call it is to use the rngd daemon from the rng-tools package:

rngd -r /path/to/F

(Note: rngd expected this to be a hardware device, so when it reaches the end of the file, it will complain that the entropy source is no longer working.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.