Fixing Getrandom()
lwn.net
lwn.net
https://www.openbsd.org/papers/hackfest2014-arc4random
Also suggest reading from page 19 on, which covers OpenBSD"s random(4) subsystem, and getentropy(2) syscall which suffers from none of the issue that are plaguing Linux getrandom today.
https://www.openbsd.org/papers/hackfest2014-arc4random/mgp00...
https://man.openbsd.org/man4/random.4 https://man.openbsd.org/arc4random.3
Incidentally, I really wish we could get the arc4random(3) family on GNU/Linux already. It's the only notable *NIX platform that still doesn't provide it; illumos has it, every BSD has it, macOS has it. Given the difficulties with entropy as noted above, however, the whole "non-failing cryptographically secure PRNG" model just won't work with Linux.
https://sourceware.org/ml/libc-alpha/2018-05/msg00891.html
https://sourceware.org/bugzilla/show_bug.cgi?id=4417
https://www.openwall.com/lists/musl/2018/07/03/3
That patch was held over for 2.29 but then disappeared.If glibc had added it then musl libc would have and all would be right with the world, at least from the perspective of userland. The kernel would still need to get its story straight.
I once had the (dis)pleasure of meeting him once at a former company when he came onsite and he came across as every bit the condescending asshole as he does on bigzilla. Didn't really get the chance to get to know him as a person, but as they say, first impressions... I get that he's in a tough spot maintaining glibc, but a bit of tack in correspondence would go a long way.
I get where either were coming from (BSD was open-sourcing an established codebase, Linux was a from-scratch effort), but it does seem like that foundational culture persisted.
Sounds like GLibc is more of the latter.
Theo de Raat doesn't suffer any fools. He calls bullshit as soon as he sees it (ok, Linis does too) and is fairly uncompromising when it comes to code quality and security regardless of whether it's kernel or userspace.
Seems to me, Linus is primarily focused on kernel space being secure and as long as kernel changes dont break userspace, hes cool.
I appreciate both views, but tend to like Theo's better.
Has musl committed to adding it if glibc does? If not, why would musl add it?
> ... glibc has adding [sic] the arc4random interfaces and it seems reasonable that we should too....
How does OpenBSD deal with this issue?
# Push the old seed into the kernel, create a future seed and create a seed
# file for the boot-loader.
random_seed() {
dd if=/var/db/host.random of=/dev/random bs=65536 count=1 status=none
chmod 600 /var/db/host.random
dd if=/dev/random of=/var/db/host.random bs=65536 count=1 status=none
dd if=/dev/random of=/etc/random.seed bs=512 count=1 status=none
chmod 600 /etc/random.seed
}
* https://cvsweb.openbsd.org/src/etc/rc?rev=1.537FreeBSD:
* https://svnweb.freebsd.org/base/head/libexec/save-entropy/
* https://www.freebsd.org/cgi/man.cgi?loader.conf(5) (see "entropy_cache_load")
OpenBSD's boot loader also injects entropy into the kernel.
This business of /var/ not being writable early enough is probably to do with the wonderful complexities of modern Linux, and is just not a problem that OpenBSD has.
They also do it at shutdown, before /var is R/O or unmounted.
One can also have multiple files, and have a regular cron job that replaces one of them occasionally while the system is running. This is what the FreeBSD script does.
* https://svnweb.freebsd.org/base/head/libexec/save-entropy/
* https://svnweb.freebsd.org/base/head/libexec/rc/rc.d/random
Other systems have solved this problem, so I'm not sure why all the high drama with Linux.
FreeBSD runs a regular cron job so that there are multiple files. If /var goes R-O, you still have a bunch of files from when it wasn't and they are not the same as on initial boot (assuming that (a) /var was mounted R-W at some point, and (b) cron managed to run as well).
Also, on shutdown there is an attempt to write 4096B to both /entropy and /boot/entropy:
* https://svnweb.freebsd.org/base/head/libexec/rc/rc.d/random?...
Further, all of these various seed files are not the only sources of entropy (timers, RDRAND, etc).
Not a good assumption if the initial r/w mount is the one that fails...
But for >99% of cases where the system comes up cleanly, and runs cleanly for a period of time, you'll have a bunch of seed files ready to go for the next boot. This configuration optimizes for the common case.
https://svnweb.freebsd.org/base/head/libexec/rc/rc.d/random?...
Similar idea to what OpenBSD does.
Because OpenBSD assumes existence of RDRAND and a previous entropy file. Linus stated that not all systems have RDRAND or r/w media.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...
Still, if you're booting a system that will be doing one thing, and that one thing needs entropy, then you have a problem. And the only practical solution then is to accept using things like RDRAND and a previous shutdown's saved seed to seed the system's SRNG, then add better entropy slowly as you can get it.
EDIT: I agree with tytso: if you trust the CPU enough to run on it, then you should trust its RDRAND or equivalent (if it has it).
Of course, not all applications need that kind of cryptographic entropy but during early boot it's pretty much the best randomness you can get (seeding from datetime isn't available on the RPi, so until you can bring up the network and contact the NTP server, you're stuck with whatever getrandom() returns)
I understand in general why seed reuse is bad. If an attacker can get access to two things that used the same seed, that attacker can often learn things that the randomness was suppose to make unlearnable.
In this particular case, though, I wonder if that is actually a problem. If the seed is used before you have writable storage, and then the system is rebooted without writable storage ever becoming available (and so before the seed could be updated), and then the system reuses that seed on the next boot--the only way an attacker can get access to two things that used the same seed is if something that used it on the first boot has persisted somewhere.
Since there was no local writable storage the first time, this can only happen if the results of using the seed were communicated off the system, via networking or via a terminal, to someplace that did have working writable storage.
Thus, it would seem, that if you block networking with other machines and terminal access until /var becomes writable and the seed is updated, there is no problem with seed reuse.
Am I misreading this or is Ted T'so really suggesting that we should all just stop worrying and love the secret and compeltely unauditable RNG offered by the same company that has literally backdoored every CPU they've sold in the past 12 years?
Intel hid an entire x86 core running minix --- with security holes --- and told no one. Between the firmware code which runs in System Management Mode and in UEFI, which persists after the OS is booted and can take over the system and read and write arbitrary memory locations --- if you fear a backdoor in the CPU, RDRAND is not the only place where an attacker can screw you over. The bottom line is the entire CPU can not be audited. So trust it. Or don't trust it. Use another CPU architecture. Or go back to using pen and paper, and don't use any computers or cell phones at all.
We have to trust the bootloader to verify the digital signature on the kernel, so we might as well trust the bootloader to get a secure random seed. But from where? It could call UEFI or try use the RNG from the TPM (if available). But now you have to trust Intel, and/or the motherboard manufacturer, and/or the TPM. The bootloader could read from a seed file from the HDD/SSD. But we know that nation-state intelligence agencies (like the NSA) have the capability of implanting malware into HDD firmware (which is also unauditable), and we also know that we can't trust most consumer grade manufacturers or IOT devices to correctly insert device-specific secure entropy into the seed file at manufacturing time. Otherwise, all of the seed files will likely have the same value, at which point when the device is generating its long-term private key, immediately after it is first plugged in, the key will very likely be weak (see the "Mining your p's and q's"[1] paper).
The bottom line is that unless you propose to personally wire up your CPU from transistors, and then create your own compiler from assembly language (see the "Reflections on Trusting Trust"[2] paper by Ken Thompson about what can be hidden inside an untrustworthy compiler), and then personally audit all of the open source code you propose to compile using that compiler and use on your system, you have to trust someone.
What makes this political, and difficult to address, is everyone has different opinions on what they are willing to trust and not trust. But some combinations, such as "we can't trust Intel because their firmware can't be audited", and "but we insist on using Intel CPU's", really don't make much sense.
[2] https://www.archive.ece.cmu.edu/~ganger/712.fall02/papers/p7...
It would probably not be possible to get away with an XOR instruction that doesn't behave as advertised. There is simply no way to determine if RDRAND is behaving as advertised or not.
> you have to trust someone
Well, yes. Intel specifically has to my mind demonstrated beyond a shadow of a doubt that they are not be trusted (that "entire x86 core running minix --- with security holes" thing you just mentioned, thought it was ARM though). So if the only difference is moving my root of trust from Intel to a random, unknown party that is not Intel, that is already something of an improvement.
The main difference is that the behavior of the rest of the CPU is deterministic, so it can be verified. When you use the ADD instruction, the output will always be the sum of its inputs; when you use the RDRAND instruction, the output comes from a black box which is supposed to mix internal non-deterministic noise sources in a non-reversible way. How can you distinguish a correct RDRAND from a malicious or broken one which generates its output in a reversible way or based on a fixed key, since the apparent output (an arbitrary number) is the same in both cases?
[1]: https://techreport.com/review/17732/intel-graphics-drivers-e...
The claim is not "can't trust RDRAND [to keep your system secure] because could be backdoored", the claim is "can't trust RDRAND [to generate unique unguessable numbers] because could be backdoored.
RDRAND not only can be backdoored, but its implementation flawed or too weak for some attackers. Or it can be a pinnacle of RNGs(unlikely). In any case, it is reasonable to not trust it to generate unique unguessable numbers. That trust requires control of the generation.
The impact this distrust has on decision of using Intel CPU's is specific to the use case. I trust my Intel CPU to do deterministic computational work for me, because in some cases I can rerun the job and compare the results, or check the results in another way. But I don't trust it to generate unguessable numbers for me. That is better done by separate HW device, ideally one that I would construct and control.
I don't have to trust implicitly in my computer to use it. At the same time, I do not want my kernel to rely on RDRAND to get random numbers, if more trustworthy source is viable. No that perfect randomness is required, but if the authors can do better than rely on RDRAND, they should.
> The bottom line is the entire CPU can not be audited. So trust it. Or don't trust it.
I can trust it to evaluate 1234+1234, or play a video for me, but I don't trust it to generate unique unguessable numbers.
There is trusting them not to be malicious.
Then there is trusting them not to more innocently have some errata effecting quality of randomness.
Do we? I was under the impression that most people would not care if the bootloader did that or not.
I think the sentiment (or at least my sentiment) is that the number of systems where early entropy is used for something important like key generation but that lack strong sources is diminishing. Many, if no most, x86 and ARM embedded platforms over the past ~5 years have had at at least an on-chip RNG, and over the past 5-10 years some at least some on-board RNG (e.g. Intel NIC controllers often contain an RNG, AMDs PSP provides an RNG, plus various other options like SPI RNG chips).
Ideally there would be multiple sources, but ultimately it's the designer's choice. Likewise, any new platform that lacks any source but has software that expects strong entropy is unequivocally broken. Older systems are disappearing and are unlikely to be upgraded, anyhow.
Excessive paranoia about RDRAND is counter productive. It's speculation that it's weak, while we know for a fact that the machinations userland code goes through to work around the poor semantics and unreliability of Linux kernel randomness interfaces has caused and is causing real problems, including real security problems. At some point the risk of a bugged RDRAND is less than the risk of assuming a non-bugged RDRAND. Plus, if the kernel is loud about its expectations for quality hardware sources it creates an environment where people (embedded designers, savvy laptop purchasers) demand quality sources and manufacturers will compete along that axis (more so than they already do--the VIA C3 was the first to add an on-chip RNG on a mass production chip nearly 15 years ago).
Ten years back I had an embedded app that was struggling with this. It's always been my assumption/fear that jitter on an RTOS is not a particularly rich source of entropy. Not to the degree of a Linux kernel sitting on a loud network (maybe switches have worsened this as well?)
Thankfully the system had a few things going for it. First, the flavor of PRNG we were using had a seed function that was cumulative (not all are). Second, useful implementation of system time in nanoseconds (at the time, not a given). And third, the writers had a longish list of bootstrapping tasks to perform prior to making any network calls.
The code that started these tasks was all located in one bootstrapping file. So in addition to whatever crap entropy the libraries could gin up, we pushed another handful of bits of entropy in for each task by taking the nanoseconds and stuffing it into the seed data. doTask1(), seed(nanos()), doTask2(), etc.
This is the same observation made in Linux's RNG, and that is demonstrated in the algorithm for randomness from a biased coin: A high quality mixing algorithm and a large volume biased data can be transformed into a smaller quantity of high quality entropy. Which makes me wonder why Linux doesn't use RDRAND with a low entropy estimate to augment the early sources.
How is that supposed to work? Entropy does not get exhausted.
You can see this when reading /dev/random on a low-entropy machine (such as a VM), and adding whatever you want to the entropy pool manually. The reading process will unblock, read a few bytes, then block again until you add more.
What were you using that uses /dev/random?
I'm not the same guy, so I have no idea what he was reading /dev/random for. Just pointing out that it can in fact be "exhausted."
I'm not a crypto expert either, but wouldn't it still make sense to use /dev/random when generating long-lived keys (e.g. PGP, SSL CA, ssh keys...)?
I understand, I think, that a CSPRNG seeded with just the minimum amount of entropy should be "good enough." More entropy has to be at least theoretically better though, doesn't it?
If the only tradeoff is having to wait a few more seconds or possibly minutes to generate a key I'm going to use for years... why wouldn't I want to do that?
No. https://sockpuppet.org/blog/2014/02/25/safely-generate-rando...
Since then there is get_random(2) which does the right thing for most applications.
The man page also has this to say:
> The /dev/random device is a legacy interface which dates back to a time where the cryptographic primitives used in the implementation of /dev/urandom were not widely trusted.
I must admit though, that I still don't understand why blocking on insufficient entropy is a bad thing for generating long-lived keys. I'm going to use the key for years, why wouldn't I just wait a couple of seconds or minutes?
In the Linux kernel view of the world, /dev/random "loses" 1 bit of entropy for every bit that gets read.
That is not how cryptographic and hashing primitives work, if it were it would be dangerous to use an AES key to encrypt more than a few megabytes for example.
You wouldn't blame them for it 20-25 years ago, but we've known better for at least 15 years so it'd be nice if they'd get with the program. And it can be fixed without breaking their userspace ABI that they're usually fanatical about not breaking. Linus wanting to break getrandom's ABI just shows he still doesn't understand how CSPRNGs work.
Doesn't it all depend on how you are using it? As far as I recall, Linux does not use RDRAND is a direct source for random numbers, but rather mixes it with the entropy pool. Since xor'ing with (potentially) low-entropy data does not reduce the entropy, the argumentation is that it is safe. The potentially backdoored RDRAND is problematic as a source of random numbers or when the entropy has too little entropy (since RDRAND would determine the entropy).
And this is still insecure https://blog.cr.yp.to/20140205-entropy.html
DJB has an axe to grind (and rightly so) here in that he's pushing cryptographic algorithms that need less (or no) entropy. Specifically EdDSA instead of ECDSA. And he's also dismantling some of the bad arguments about how /dev/urandom should operate.
An operating system doesn't know why an application needs entropy, just that it does, and I don't see the problem with having an SRNG for that purpose. DJB doesn't even say that a system SRNG is not good, but, rather, he's quite sensibly saying that _applications_ should stretch one good 256-bit chunk of entropy. And yes, DJB correctly points out that there's no need to have security relative to an attacker that once saw the entire state of the SRNG at an earlier point in time -- but that does not mean that a kernel-land SRNG shouldn't add entropy to its pool, just that it doesn't buy you much.
Of course that's a totally different and more complex attack. Is it still plausible enough to possibly worry about? I have no idea, honestly -- this is way outside my area of expertise.
What I do know is that hardware RNGs made from open-source and verifiable hardware is readily available for about US$50 for qty 1, cheaper in bulk.
Given that, it doesn't seem worth more than a couple of minutes investigating whether or not RDRAND can be trusted. If there is the slightest hint of doubt, I just disable it and move on with life.
> we need to find some way to fix userspace's assumptions that they can always get high quality entropy in early boot, or we need to get over people's distrust of Intel and RDRAND
Though ts'o is also ignoring the third option — and the one used by openbsd — of storing an rng seed after boot (and on shutdown).
The very first boot does remain problematic if the image isn't seeded though.
http://manpages.ubuntu.com/manpages/trusty/man4/random.4.htm...
For example, an installation process using an .iso image could, after verifying the .iso, put a random seed inside the .iso (unpack-modify-pack) as a pre-configuration step. Like an extra preparation step after downloading. New installation = new pre-configuration step, to avoid seed reuse.
The previous would apply to VMs and containers and such.
For traditional embedded/IoT style devices, the step could be done at the factory when flashing the image. Or maybe there could be a small flash area with the seed as part of the initial flashing procedure.
I guess some forms of installation end up being "problematic" to handle (ro root filesystems maybe).
Randomness in VMs isn't a problem. If VM hypervisors aren't providing VirtIO-RNG, it's still just a quick fix and reboot away. The quickest way to make sure all hypervisors and hosting providers enable VirtIO-RNG, or something similar, is for the kernel to being assuming, loudly, that strong entropy is available at boot time.
For embedded stuff SPI RNG chips and similar solutions have been available since forever, not to mention the on-chip sources on most modern ARM and x86 CPUs and SoCs.
If a product designer (e.g. embedded device) or solution provider (cloud hosting) chooses to put their trust in RDRAND alone, then that's their choice--Linux shouldn't be second guessing it, or at least allow such a choice to dictate the semantics of its APIs.
If you have RDRAND hardware, you could (I suppose) pipe it's output from DOM0 into an encrypted root terminal session on DOMU, and feed that into the pool.
I personally don't want to rely on RDRAND. Unlike a tampered ADD instruction, a tampered RDRAND instruction would appear to be undetectable, even in principle. I wish Intel had given me the raw bits from their DRBG, instead of providing only the whitened stream. Or hell, give me both - but not just an opaque stream.
This seems eminently unfeasible for many applications, and it won't work at all for read-only filesystems as you've mentioned.
It's a speaking pattern meant to convey "we've got to do something about <x> and people don't like <y> (so it's gotta be <x>)". In reality there are almost always more <options> than the duality implies but at no point does the person ever actually want <y>.
In your example, the fact that the first option is self-evidently correct even in a vacuum, is something of a cue that the second option isn't meant to be taken as seriously.
In Tso's statement, it's not immediately clear to me which of the two options he prefers. In fact, his use of the phrase "get over it" leads me to think that is actually his preferred variant. To me, that phrasing means if not an outright trivial and unworthy concern, then at least one that only needs the passage of time. There doesn't seem to be any indication that he's using the phrase ironically or anything.
Of course it is always possible that I'm just misreading or misinterpreting it. But that is why the first half didn't, and still doesn't, seem relevant to me.
And above all: you will also probably be able to modify others supposed sources of entropy (if you restrict yourself to sources, I still think it is a terrible idea if you have that kind of capabilities), so short of analyses showing why this would be way more difficult, dropping the dedicated hw gen for a theoretical problem that would also be an end-game for virtually everything else is insane. You get no actual advantages, and tons of drawbacks.
Really, the hypothesis of what the attackers are able to do and what they are not makes no sense IMO; like:
> For example, an attacker can't exert any serious control over the content of my keystrokes while I'm logged in; I don't see how hashing this particular content into my laptop's entropy pool can allow any attacks.
Yeah, so that mythical unicorn can invoke utter craziness in RDRAND, but is somehow unable to modify the key inputs and/or timings just when that data reaches the entropy input algos? I just don't buy it. Like I don't buy that the user is somehow recomputing everything on a second computer and comparing both results (or using other fancy proof of work things, that I'm not aware that even exist on real code we are talking about).
My litmus test is: imagining I'd have to attack, I would never do it by such a convoluted method. Or maybe only ever if Ben Laden Two is the target, AND if it seems to actually make sense in the technical context of the attack: the proba of both occurring is, I guess, quite low...
The kernel knows it's early in the boot process, and it knows that there isn't enough entropy that it will have to block getrandom() calls. We also know that what caused this issue was some FS efficiency improvements that result in fewer disk accesses during early boot, which results in fewer interrupts, which results in less entropy.
So... when we get into this situation, why doesn't the kernel just start issuing some disk accesses (perhaps with weakly-random offsets and sizes) until enough interrupts are generated to fill the entropy pool to a safe level?
(Your point also raises the question: on systems that don't have disks, how are requests for early-boot entropy handled?)
Right. On those kinds of systems, persisting some saved state between boots is your best first option. (As other commenters point out, you really don't need very much! 256 bits or 32 bytes is basically adequate.) Any additional entropy you get from device interrupts or machine-dependent random sources like RDRAND are good to mix in.
(I don't think the adversarial RDRAND thread model is a reasonable one, and that has been adequate addressed elsewhere in this thread by tytso, tptacek, and tedunangst. Any adversarial CPU that can defeat cryptographic digest whitening of entropy sources is so sophisticated/privileged it already fully owns your operating system; game over.)
Linux systems already do this, kind of! But Linux has taken the stance that entropy you can't delete from the boot media at the time it is fed into the CSPRNG as entropy doesn't count ("credit") as far as initial seeding, and that decision is what moots its utility for early CSPRNG availability. It's not an unreasonably paranoid take, but not an especially practical one (IMO). I suspect the net effect on security, holistically, is negative.
> (Your point also raises the question: on systems that don't have disks, how are requests for early-boot entropy handled?)
Depends which subsystem you ask and how you ask it, right? And whether or not a jitter entropy scheme is enabled in the kernel. (I might be misunderstanding your question, sorry if that's the case.) If you ask /dev/random or getrandom(~GRND_NONBLOCK), they'll block until the CSPRNG is satisfied enough entropy is available. If you ask /dev/urandom, it just spews unseeded and likely predictable garbage at you. If you ask getrandom(GRND_NONBLOCK), it returns -1/EAGAIN.
Not entirely, but I think my question was just more narrow. Considering the case that started this off (machines that used to work, now hanging on boot because of lack of entropy, triggered by too few disk interrupts), I don't get how this generalizes. If you take that same system, and remove the disk (replacing it with netboot or whatever), how would it ever boot, at least not without making some changes to how early entropy is seeded? I guess in the netboot case you end up with the timing of network interrupts that you can feed into the entropy pool, but this whole thing just feels off to me.
If a system was relying on a specific, inefficient set of disk access to give it just enough entropy to get through early boot, and that making the FS code more efficient caused it to fail to have enough entropy, I'd suggest that (likely unbeknownst to the system administrators), this system was already pretty broken. I get why Torvalds decided to bucket this under the "we don't break userspace" umbrella, and appreciate the care he takes to that sort of thing, but suggesting that "FS access patterns during early boot" is sorta a part of the kernel's ABI is... a bit too incredible for me to take seriously.
- interrupts
- rdrand
- timer/instruction jitter
Why don't they throw more sources at the problem? LSBs from analog sources such as audio inputs, stray network packets (put the nic in promiscuous mode). Even uninitialized memory might be worth a few bits (not all systems zero it on boot).Hardware devices are initialized before init is started, so you should still be able to gather entropy from the various input devices.
Lack of entropy can't cause the kernel to not boot; it's just userspace (typically services which require encryption) which can have a problem. It would be silly to start a webserver or sshd before the FS is remounted rw.
I've solved this for some systems by changing the java security properties file to instead point to /dev/./urandom .
Something in the chain switched urandom and random. Isolate each component until the culprit is found.
I doubled throughput on two different projects by 'fixing' the /dev/random-/dev/urandom problem.
But writing your own can be worse. Stumbled onto a substantial CSRNG bug on an embedded system than was ignoring most of the seed data due to a premature optimization in the ingestion code. Even after that the people who wrote the glue code wanted to do their own entropy mixing. Lesson not learned, at all.
That's just a special case when you do a reboot. There are many cases where the system starts and there's either no previous state, or the previous state is explicitly killed to prevent sharing.
For example a lot of AWS instances will boot once once in their lifetime, and will do that from a shared AMI. You can't reuse a shared random seed in that case or getting random values from one VM would allow you to predict new values on another.
So persisting the state will help desktop users, but that's addressing only a specific version of this problem, not solving it for everyone.
Why can't AWS seed you with a random number before giving you control? In fact does it not do that already? If it doesn't, either I'm surprised, or I don't understand why it's not possible.
For some hypervisors this is solved in a different way: https://wiki.qemu.org/Features/VirtIORNG but as far as I know AWS does not support it yet.
Drama would come from the same place as "we shouldn't trust rdrand". That's still avoiding the issue of: sometimes can't write that seed in some configurations.
(Or if you meant creating the VM, as explained before they can't do that for encrypted volumes for example)
I agree that the LKML fear-mongering over RDRAND is doing more harm than good.
If your system is too small to be able to persist 32 bytes, it's probably too small to perform any amount of meaningful cryptography anyway.
There are absolutely devices with exclusively RO media with plenty of processing power to perform meaningful crypto (e.g., embedded devices with 802.11 wifi). So:
> If your system is too small to be able to persist 32 bytes, it's probably too small to perform any amount of meaningful cryptography anyway.
This sentence is not based in reality.
Well, those devices are flawed. Unless they have special hardware to generate random numbers? I mean, the ability to generate random number is such a basic feature. If your communication hardware doesn't have it, your communication hardware is crap, and that's the end of it.
I maintain what I said: if a system is big enough to do crypto, it is big enough to persist 32 bytes. When you can process a 64-byte Chacha20 block in RAM, you can spare 32 bytes of EEPROM or flash. I think this is reasonable enough to be "grounded in reality".
That said, of course many devices out there are so badly designed that even though they're powerful enough to process elliptic curves (and I presume the entire Linux kernel), they don't even have enough persistent memory to store 256 bits of entropy, and they don't have a reliable, fast way to generate 256 bits of entropy. Stupidity is a thing, I know.
Acknowledging such stupidly designed devices is of course very important. We do what we can with what we have. But let's not go the C standard route, and use that stupidity as an excuse to never use persistent state or random generation instructions. Let's use the capabilities of our platforms, dammit.
For instance, that stupid WiFi router is not an excuse to not persist state on a freaking desktop. (Or laptop. Or palmtop. Or R-Pi. Or virtualised server. Etc.)
Don't most microcontrollers have some EEPROM that could be used for this? I'm assuming even 4 bytes would help a lot. I am pretty sure STM32's with hardware crypto have EEPROM good for a million write cycles.
Linux has lots and lots of hardware specific drivers. This shouldn't be any different.
The current way of gathering initial entropy should not be the default, it should be a fallback. If a device have neither persistent storage (32 bytes for crying out loud) nor a hardware random generator, they should be treated like second class citizen, with only best effort random numbers.
Right now, everyone is a second class citizen. Kind of insane, don't you think?
> it's not as trivial as you paint it
It is, under one (extremely hard to fulfil) condition: collaboration from hardware vendors. It's just 32 persistent bytes. Just bury them in a chip and memory map the damn thing! The driver can be reduced to an offset.
> I think jitterentropy is a better and more easily tested use of developer hours than implementing 1000s of SoC drivers
That one? https://fuchsia.dev/fuchsia-src/zircon/jitterentropy/config-...
It's one of the first links I found, I hope it is obsolete: they say the internal state of Jitterentropy is puny 64 bits number. What were they thinking, we need four times as much! That kind of thing is why people are tempted to shed the system's RNG, and ask users to wiggle their mouse instead.
> That one? https://fuchsia.dev/fuchsia-src/zircon/jitterentropy/config-....
> It's one of the first links I found, I hope it is obsolete: they say the internal state of Jitterentropy is puny 64 bits number
You skimmed too quickly and came to a judgement based on a misreading or misunderstanding of the concept. Obviously 64 bits is not sufficient.
The idea of the jitter entropy mechanism is that most modern CPUs have super high resolution clock or cycle counters available (even embedded boards), and instruction execution speed has mild variance.
You run a series of trials, each of which produces one or more bits of output (classically: 1). You run as many as you want, producing an infinite stream of weak entropy, until you have collected a satisfactory number of output bits. Trials can be run relatively quickly (many nanoseconds or a handful of milliseconds per trial).
For each trial, you perform some minimal workload intended to exacerbate CPU runtime variance (this might be where you saw "64 bits"), and extract some number of output bits (maybe 1) from one or more of: the low bits of the cyclecounter, nanosecond clock, or something similar of that nature.
Caveat: jitter is an even weaker entropy source than most non-HWRNG sources typically consumed by entropy gatherers. Your motto of "just 256 bits" assumes total independence and 8 bits per byte of entropy. It isn't met by most real-world entropy sources on server systems (expect 4-5 bits/byte) and especially not by jitter entropy. Empirically, jitter seems to come closer to 1 bit per byte minimum in SP800-90B evaluations on the raw output — it's a pretty weak entropy source.
Anyway: feel free to read more about the concept at any of the sources. The Fuschia writeup you linked is a good one if you read it more closely; there's also:
* From the original (2013) proponent, Stephan Mueller: description: http://www.chronox.de/jent.html and sources: https://github.com/smuellerDD/jitterentropy-library
* LWN's 2015 writeup of the concept as a Linux entropy source: https://lwn.net/Articles/642166/
* And this is all suddenly topical due to the latest nonsense from Linus (TFA, 2019), who still does not understand CSPRNGs. Anyway, Linus wrote and merged a version of jitter entropy quite recently: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin... This is a relatively happy outcome in that Linus didn't just break the ABI to be completely insecure by default.
Yes of course. This is easily obtained by hashing a much bigger input. The problem is determining how big the input should be. That is, how much entropy it actually holds. You can also hash piecemeal (H is whatever you think is secure):
H0 = H(I0)
H1 = H(I1 || H0)
H2 = H(I2 || H1)
H3 = H(I3 || H2)
You can stop as soon as you gathered enough input to be happy about its entropy. Then just switch to fast key erasure with Chacha20 and stop wasting cycles on entropy gathering.> Anyway, Linus wrote and merged a version of jitter entropy quite recently. […] This is a relatively happy outcome in that Linus didn't just break the ABI to be completely insecure by default.
I'm genuinely relieved. This would have been the worst way to break userspace. Still, tiny embedded systems might need to persist (properly seeded) 32 bytes instead of relying on jitter entropy.