FS#17131 - [initscripts] crypt: restore random seed before using for decryption
Attached to Project:
Arch Linux
Opened by Stefan Hermansen (scorpyn) - Saturday, 14 November 2009, 00:53 GMT
Last edited by Tom Gundersen (tomegun) - Tuesday, 08 May 2012, 12:43 GMT
Opened by Stefan Hermansen (scorpyn) - Saturday, 14 November 2009, 00:53 GMT
Last edited by Tom Gundersen (tomegun) - Tuesday, 08 May 2012, 12:43 GMT
|
Details
Description:
In /etc/rc.sysinit, any swap space that is configured as encrypted swap is set up (using /dev/urandom) before the random seed is restored. I suppose this means that the random key used for the swap space might be somewhat predictable. |
This task depends upon
Best solution I can think of right now :
1. Set up all encrypted filesystems where the PASSWORD field is NOT /dev/urandom or SWAP
The OPTIONS field should probably also be checked for '--key-file /dev/urandom' or '-d /dev/urandom'
2. Restore the random seed
3. Set up the rest of the encrypted filesystems
Note : Not tested and needs improvement. The output will most likely be ugly if the random seed is restored while setting up encrypted partitions.
Some brainstorming :
At the moment, it appears that the only type of partition that is actually "supporting" a random password is SWAP, right?
So, if we ignore
FS#15257for now, I suppose we could :1. Set up everything except partitions marked SWAP
2. Mount everything
3. Restore the random seed
4. Set up all encrypted swap points
5. Run swapon -a
Another solution might be storing the random seed in /etc, but that won't work if you want / to be mounted read-only.
A more complicated but possibly more long term solution might be to implement ARSE mode (After Random SEed) for partitions that need to be set up after the random seed is restored :
#swap /dev/hdx4 SWAP,RNG=/dev/hwrng -c aes-cbc-essiv:sha256 -s 256
#swap /dev/hdx4 ARSE,SWAP -c aes-cbc-essiv:sha256 -s 256
#tmp /dev/hdx5 ARSE,TMP -c aes-cbc-essiv:sha256 -s 256
(Yup, I'm working on a patch to enable choosing a custom random number generator. That's how I found this bug.)
(I'm using links atm so I'm not sure if I'm attaching the patch correctly. Lets hope so.)
(Please ignore all earlier patches I made here.)
A weakness I saw in the patch was that it only delays crypttab entries that say SWAP, not those that say /dev/urandom (/dev/urandom might be used:
* for encrypted /tmp
* for swap that's created later, manually, perhaps.
* In Ubuntu, the crypttab syntax for crypto-swap involved saying /dev/urandom there, not SWAP (and the options field would say "swap", without the quotes). I don't know if it's possible in Arch or if that used Ubuntu customizations; Arch and Ubuntu use subtly different crypttab format.
)
On the other hand, hiding the seed on a password-encrypted partition means guest logins or anyone who doesn't enter the password can't easily/immediately get (moderately) secure encrypted swap.
I think it's not for us to decide which route the sysadmin wants to take here.
Actually, I want this to work for for SWAP, TMP, /dev/urandom, /dev/random, /dev/frandom, /dev/hwrandom, /dev/hw_random and /dev/hwrng (that's the ones I know of, there may be more).
As for swap created later (such as manually), you only seed /dev/urandom once at boot time. You don't seed it again whenever you need to use it. So I don't really see how this could be a problem for swap that is set up later.
As for moving the random seed to /etc, it shouldn't be done imo since it's non-standard. I've considered this as well, and come to the conclusion that it's somewhat likely that an admin somewhere would want /etc to be write protected, which would cause serious problems if the random seed was moved to /etc.
As for encrypted random seed, I don't think it's necessary. It should be hidden though. You could simply create a new random seed as soon as it is restored, making it impossible to figure out which random seed is currently in use.
in your last paragraph, you identify one possible attacker: unprivileged software in the running system. You are right to be concerned about that and to make sure that the seed on disk is not marked world-readable, and perhaps even to overwrite it once it's read.
you missed the possible attacker who, for example, boots from a LiveCD to read the disk (including random-seed), and then watches as Arch Linux is booted next, the better to attack the system over the network or via reading the swap later or something. On second thought, this attacker could just replace the Arch kernel and bootloader with something malicious*. *an attack that does have a couple disadvantages: it makes it detectable that there's been an attack; also it might be detectable via a "chain of trust"; also perhaps they could read the disk but not write it for some reason (the exploit they're using? a locked-down piece of system hardware? network-boot from ROM?)..multiple layers of paranoia might be useful. The farthest-reaching consequence might be if the just-booted Arch system generates a SSH or GPG key that will be used for years, if not enough other entropy has been added to the system yet, and not even to realize that someone has a good chance to break it. Okay...these attack situations seem like kind of a stretch. Also, increasing the reliability of encrypted swap is clearly pretty useful.
actually, this last point about encrypted swap makes me think it's pretty important to physically overwrite the random-seed after(before!) it's used to generate the swap key, otherwise an attacker could have a very good guess at decrypting the swap?! (physical overwriting is a bit hard on modern filesystems though...)
I'll be extremely busy for about 1-2 weeks, I'll start making git patches after that.
@Isaac : I didn't miss that attack vector, I simply ignored it, because once someone has that kind of access to the system you're pretty much screwed anyway.
I also have an idea about creating a cron job to create a new random seed about once every hour or so, but I have a feeling that it may be overkill for Arch and better suited to an os like OpenBSD.
What would be the purpose of recreating the random seed every hour? In case it is not properly recreated on shutdown? I think this is overkill. I'd be happy to accept a patch that overwrites the random seed once shortly after reading it though (so we don't boot with exactly the same random seed twice in case of an unclean shutdown). If you do this, it would be great if you could quote some source (kernel docs?) that justifies that this is a sensible thing to do. I.e., it would be stupid if we just read back out exactly the random seed we wrote, but I hope that the kernel will guarantee that this never happens. We could also be super paranoid and reset permissions on the seed to 0600 and ownership to root:root shortly before writing it.
The idea is that since it's pseudo-random instead of random, perhaps there is a way to do that.
However, it's most likely overkill, and may (if true) actually be worse than not doing so, since it'd make it possible to determine the random number usage during a 1 hour period.
Something like this would probably be better, in order to create a new unknown random seed after the random seed from /var is used :
dd if=/dev/random of=/dev/urandom bs=4096 count=1 &
(And a similar line for the random seed, which I don't remember the exact location of right now.)
> dd if=/dev/random of=/dev/urandom bs=4096 count=1 &
Is there a typo there? This will not increase the entropy, as it is just feeding the entropy from /dev/random back into /dev/urandom. The point of the random seed is to store some entropy between reboots, and the kernel will then mix this in with its own entropy when you write it to /dev/urandom (as I'm sure you know). There is no point (but no harm either) in writing anything else to /dev/urandom unless what you write is from a random source (which is different from /dev/urandom itself).
The only thing I would change about the random seed behaviour we have now is to refactor the saving of the random seed (in rc.shutdown) into its own function, and call this function both after loading the random seed on boot and just before shutdown.
The first write is to avoid booting the system with the same random seed twice, the second write is to save the entropy that the system has accumulated since boot.
However, I see what you mean about taking data from the random pool and putting it back there. The main reason I did that was that I don't remember the location of the random seed, which is what I was mainly thinking about when I wrote it. The other reason is that I forgot that /dev/random and /dev/urandom use the same random pool.
So, while it may not have been a typo at the time, I do see why it's wrong.
Either way, you're right, I'm just overanalyzing and trying to fix an issue that doesn't really exist :-)
I agree with what you wrote about when to save and restore the seed.