installation/guides: add EFI Boot Stub guide
This guide covers installing Void to boot the kernel directly from the firmware. It was tested in a qemu virtual machine using OVMF.
Parts of this guide overlap with Full Disk Encryption. Should we wait for #177 to provide a general guide for manual installation and reduce this to the specifics of dracut and efibootmgr?
Thanks for the prompt review.
I would like to see it repeat as few steps from the chroot guide as possible, instead focusing on what needs to be done differently.
I think we'll need to see things settle on #85 to know how exactly this is going to look like. Given that multiple people are working on it, I don't think I can meaningfully contribute there.
I would also like to add the possibility of using gummiboot to create a kernel bundle, and document it here (it usually mounts ESP in /boot/efi, but there's very little stuff that needs to be changed).
A kernel bundle? I don't know anything about that, but feel free to elaborate.
Here are some more needed improvements:
- Dracut reads from
/dev/urandombefore it is initialized. Normally, the systemd module takes care of that, but it is rightfully disabled by the runit-void package. This could be resolved by writing a dracut module for haveged. - The efibootmgr kernel hook configuration should support UUIDs and labels. I'm working on a patch for that.
If you want to give your thoughts on any of the issues surrounding this, you are welcome to! We appreciate the help c:
A kernel bundle is created using dracut --uefi (there will be a kernel hook for it when my PR is accepted). It's useful for signing a single image for Secure Boot, because it packages ther kernel, initramfs and the cmdline.
- Have you seen cases of the system failing due to
havegednot being installed and configured? - I haven't used the efibootmgr hook, but thanks!
If you want to give your thoughts on any of the issues surrounding this, you are welcome to! We appreciate the help c:
Thanks, that's nice of you. :relaxed:
Have you seen cases of the system failing due to haveged not being installed and configured?
No… Those warnings come from randomness being required to open the LUKS partition, but the kernel not having gathered enough entropy yet to provide secure random numbers. I fear it might have security implications that I don't understand.
A kernel bundle is created using dracut --uefi (there will be a kernel hook for it when my PR is accepted). It's useful for signing a single image for Secure Boot, because it packages ther kernel, initramfs and the cmdline.
I'll look into it, thank you.
Yeah security is complicated. I don't know about that either. I can try to search for it a bit.
Regarding the EFI bundle, don't sweat it. When we get back to working on this page I can try to add it myself if you don't find the time / way to familiarize yourself with it.
Regarding haveged, https://research.nccgroup.com/2019/12/19/on-linuxs-random-number-generation/ seems to be against it.
Wow, that's a great article! It demolishes the concept of entropy depletion (which haveged promotes), but maintains that some initial amount of entropy is of course necessary:
To work around the blocking issues of
/dev/random, an alternate API was added, called/dev/urandom. It’s the same as/dev/random, except that it does not block. Never. This is better, but not actually good: there are times when the entropy pool is really empty, namely during the early stages of the boot. At that point, the kernel did not obtain many physical events to work on, and it is conceivable that/dev/urandomoutput could be predicted.
A simple solution, then, would be to make dracut pass --use-random to cryptsetup. The article also suggests another option that may prevent any blocks at boot:
Since at least the early 2000s, Linux distributions have applied workarounds to ensure proper entropy at boot time, namely that a boot script injects the contents of a saved file upon boot, and immediately proceeds to regenerate the said file with
/dev/urandom. In effect, this transports the entropy across reboots, so that even if the boot sequence was not enough, by itself, to generate enough entropy, the file contents would ensure that everything is all right.
A simple solution, then, would be to make dracut pass --use-random to cryptsetup
This will make cryptsetup hang until there's enough entropy available in the pool, which might be a while this early in the boot process.
The article also suggests another option that may prevent any blocks at boot:
void stores this in /var/lib/random-seed. You can see it being saved in /etc/runit/3 and loaded in /etc/runit/core-services/05-misc.sh. Does luks need random data to open a volume read only? Maybe we can mount everything read only, use /var/lib/random-seed to initialize the prng, then reopen the volume read/write. The same random seed will be read again after the initramfs exits, which might be a security issue, but random(4) suggests that inserting arbitrary data into the entropy pool is always safe and will never make the entropy pool more predictable to an attacker.
How about removing /var/lib/random-seed after using it? This will produce the expected behavior in /etc/runit/core-services/05-misc.sh. The only problem is that when the system is improperly shutdown, there is no seed file available at boot. However, we should account for missing seed files anyway, for example by blocking in that case and waiting for the kernel to initialize the entropy pool. Would slower boot times after improper shutdowns be acceptable?
https://github.com/void-linux/void-runit/pull/30 removed a line generating a new random seed file in /etc/runit/core-services/05-misc.sh, claiming that newer kernels do not credit entropy added from userspace. Is this the correct way to understand random(4)?
Writing to
/dev/randomor/dev/urandomwill update the entropy pool with the data written, but this will not result in a higher entropy count.
How about removing /var/lib/random-seed after using it?
Might be a good idea but outside the scope of documentation, I think. I can see the argument for removing it, but (it seems to me and I could be completely wrong) that it's less of an issue than using exactly the same seed data twice, so it probably should be deleted if it's not going to be regenerated.
void-linux/void-runit#30 removed a line generating a new random seed file in /etc/runit/core-services/05-misc.sh, claiming that newer kernels do not credit entropy added from userspace. Is this the correct way to understand random(4)?
Yes, that's my best understanding of it. Because you can shove any non-random data into it, the kernel won't count it toward its entropy estimate. But because it gets mixed into the existing entropy pool, the pool definitely won't lose entropy. I think I saw something about an ioctl that can manually change this value in the kernel, but I don't think that's a solution. Changing the number doesn't change the amount of entropy, it just changes what the kernel thinks about it.
Dracut reads from /dev/urandom before it is initialized
I went through your instructions and got a similar setup but I'm not seeing any warnings about this. Are you getting warnings, or is this information you've found elsewhere? Do you know what in dracut is doing it, is it indeed cryptsetup?
Changing the number doesn't change the amount of entropy, it just changes what the kernel thinks about it.
That is how I read it, too. But how does that justify the change in that PR? With the same reasoning, wouldn't it also be futile to "mount everything read only, use /var/lib/random-seed to initialize the prng, then reopen the volume read/write"?
Are you getting warnings, or is this information you've found elsewhere? Do you know what in dracut is doing it, is it indeed cryptsetup?
I get the following in dmesg:
[ 1.39 ] dracut: luksOpen /dev/sda2 root none
[ 7.29 ] urandom_read: 5 callbacks suppressed
[ 7.29 ] random: cryptsetup: uninitialized random read (2 bytes read)
A little bit further down the log after dracut has checked and mounted filesystems:
[ 7.73 ] random: fast init done
So maybe blocking might not be so costly after all?
I went through your instructions and got a similar setup but I'm not seeing any warnings about this.
Is that in a VM?
But how does that justify the change in that PR?
The problem was that right after you put n bits of etnropy into the prng, you use n bits to generate a new random seed in case the computer is not shut down gracefully. If you take the idea of a number of entropy bits in the kernel at face value, this leaves the prng in a state of zero entropy, even if the kernel did recognize the first step as increasing entropy.
I get the following in dmesg:
Okay, cool, I'll keep an eye out for it
Is that in a VM?
No, bare metal. I also cheated a little and installed grub because my efi firmware sucks. Maybe there's a race condition between entropy gathering and cryptsetup?
Maybe there's a race condition between entropy gathering and cryptsetup?
Yes, probably. I'll try with cryptsetup reading /dev/random to see if that incurs any significant performance cost.
The problem was that right after you put n bits of etnropy into the prng, you use n bits to generate a new random seed in case the computer is not shut down gracefully. If you take the idea of a number of entropy bits in the kernel at face value, this leaves the prng in a state of zero entropy, even if the kernel did recognize the first step as increasing entropy.
Okay, but the article linked above says that entropy depletion is irrelevant because the random number generator is cryptographically secure:
The RNG will not give away its raw pool bits just like that; instead, it will use the pool as a seed in a cryptographically strong RNG, whose output is what is sent back to applications. The whole idea of a RNG being cryptographically strong is that it is computationally infeasible to actually obtain information about the seed by just observing the output. The RNG, effectively, plugs the leak, and no depletion occurs in any practical sense.
Rereading my last few posts I realize I seem to be having a different conversation in each one. Sorry about that. Hopefully another post won't make it more confusing..
I agree with the article on all of the issues it brings up in the Linux PRNG. Mostly it's something I hadn't thought too much about, but the points raised seem to be valid.
The whole idea of a RNG being cryptographically strong is that it is computationally infeasible to actually obtain information about the seed by just observing the output. The RNG, effectively, plugs the leak, and no depletion occurs in any practical sense.
This is the part that I'm not sure about. It doesn't matter how cryptographically secure the hashing function is, if you start with low entropy (and an attacker knows it) then then do any known deterministic process, the system is potentially vulnerable to brute force attacks that reveal the internal state. You don't unveil the random pool by reversing the hashing function, you do it by finding a seed value that produces the random output you got, and use that to reconstruct the pool. I don't think the author of the article is unaware of this, I think they see it as once the system is up and running it will get sufficient entropy coming in that it won't be an issue.
I agree with the author that reading n bits does not remove n bits of entropy from the pool, but they haven't made a convincing argument that the amount of entropy it removes is negligible. My intuition is that this number is closer to n than to 0. Their argument seems to be that accounting the entropy is a difficult task that is handled poorly so it just shouldn't be done. In terms of how you do that accounting better.. I have absolutely no idea. But simply saying it doesn't pose any problems in "a practical sense" is a bit too hand-wavey.
We should probably give as little cryptographic advice as possible, instead leaving warnings to do more research and not assume things are working the way you've been told.
if you start with low entropy (and an attacker knows it) then do any known deterministic process, the system is potentially vulnerable to brute force attacks that reveal the internal state. You don't unveil the random pool by reversing the hashing function, you do it by finding a seed value that produces the random output you got, and use that to reconstruct the pool.
I agree that you need enough initial entropy. But this does nothing to argue that entropy is depleted. It seems to me that the very concept of a Cryptographically Secure Pseudo Random Number Generator is to not (significantly/practically) reduce the entropy of the pool when emitting random numbers. From Wikipedia:
From an information-theoretic point of view, the amount of randomness, the entropy that can be generated, is equal to the entropy provided by the system. But sometimes, in practical situations, more random numbers are needed than there is entropy available. Also, the processes to extract randomness from a running system are slow in actual practice. In such instances, a CSPRNG can sometimes be used. A CSPRNG can "stretch" the available entropy over more bits.
I believe this property stems from the formal requirement for a CSPRNG to satisfy the next-bit test.
Every CSPRNG should satisfy the next-bit test. That is, given the first k bits of a random sequence, there is no polynomial-time algorithm that can predict the (k+1)th bit with probability of success non-negligibly better than 50%. Andrew Yao proved in 1982 that a generator passing the next-bit test will pass all other polynomial-time statistical tests for randomness.
The following is from Daniel Bernstein, quoted in Myths about /dev/urandom:
Cryptographers are certainly not responsible for this superstitious nonsense. Think about this for a moment: whoever wrote the /dev/random manual page seems to simultaneously believe that
- we can't figure out how to deterministically expand one 256-bit /dev/random output into an endless stream of unpredictable keys (this is what we need from urandom), but
- we can figure out how to use a single key to safely encrypt many messages (this is what we need from SSL, PGP, etc.).
For a cryptographer this doesn't even pass the laugh test.
We should probably give as little cryptographic advice as possible, instead leaving warnings to do more research and not assume things are working the way you've been told.
Yep. The Handbook is for Void-specific information; providing general security advice, particularly around crypto, is definitely out-of-scope.
Closing because this PR is stale, probably outdated and I'm not using Void anymore.