FS#5374 - cryptsetup: External key file for encrypted root

Attached to Project: Arch Linux
Opened by Alex Merry (pippin) - Saturday, 09 September 2006, 00:43 GMT
Last edited by Tobias Powalowski (tpowa) - Saturday, 09 September 2006, 13:44 GMT
Task Type Feature Request
Category Packages: Current
Status Closed
Assigned To Thomas Bächler (brain0)
Architecture not specified
Severity Low
Priority Normal
Reported Version 0.7.2 Gimmick
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

Wasn't sure where this should go, so it's here:

I wanted the initcpio encrypted root hook to allow for a key to be stored on an external device. This, for example, means you can have the key on an external usb drive and the computer will boot (without prompting for a password) providing the drive is in the machine. So I hacked the hook included with cryptsetup to allow this (using two command line options: cryptokeydev and cryptokeyfile).

If you want to add this (or something similar), that would be great.
This task depends upon

Closed by  Thomas Bächler (brain0)
Sunday, 17 December 2006, 13:29 GMT
Reason for closing:  Implemented
Comment by Alex Merry (pippin) - Saturday, 09 September 2006, 00:45 GMT
And here's the install hook. Apparently I can't attach more than one file in a non-javascript browser.
Comment by Aaron Griffin (phrakture) - Monday, 11 September 2006, 06:38 GMT
Wow, thanks alot - I haven't had the time to look at this 100% but I will definately integrate this or something like it. brain0 is "my man" when it comes to the encryption stuff, so I will defer to him on some of this...
Comment by Alex Merry (pippin) - Monday, 11 September 2006, 15:00 GMT
OK, I was very naughty and didn't test the scripts in a real situation last time. As a result, some bashisms crept in that aren't available in the klibc sh. Attached is a much improved version, complete with (hopefully) helpful error messages.

Some documentation would still need updating: I had to include vfat and nls_cp473 in the MODULES parameter of mkinitcpio.conf and USB in HOOKS to get my pen drive to work. But I'm using the script without any problems at the moment.

It now uses crypto, rather than cryptokeydev and cryptokeyfile, because of the issues with cleaning the kernel command line (replacing . and - with _ - see /lib/initcpio/init). The format is crypto=keydev:keydevfstype:keyfile, where keyfile is relative to the root of the keydev filesystem.

So for me, this is: crypto=/dev/sda1:vfat:keys/root.key
Comment by Thomas Bächler (brain0) - Thursday, 21 September 2006, 11:19 GMT
I didn't really have a very close look at this, but I already have some comments:

Don't use crypto=, we need that for legacy cryptsetup, it would be better to introduce another option, like cryptkey=dev:fstye:file. I see another problem here: if you are using scsi or sata disks, there is a risk that the usb stick ends up being sda, while the disk will be sdb, which you really don't want (I don't know how to work around that yet, but we'll see).
Otherwise the idea is good and I will look into it, so that we can integrate it without breaking existing systems. Another idea would be saving the key in the area between the partition table and the first partition on the stick (which is unused), specifying an offset. Or storing the key on a floppy or a CD.
Comment by Aaron Griffin (phrakture) - Thursday, 21 September 2006, 14:48 GMT
With regards to the sda/sdb thing, it's possible to use the udev funky naming, I think - last I checked it symlinks disks to some devfs-ish path too... dunno details at this time.
Comment by Thomas Bächler (brain0) - Thursday, 21 September 2006, 15:56 GMT
But that doesn't change the kernel's internal naming scheme (aka /sys/block) and thus, even if you rename the USB stick with NAME= to another name, the first scsi disk will still be sdb instead of sda. so unless you use persistant names in fstab and in early-userspace (by-UUID for example), which most people don't, this is an issue.
Comment by Aaron Griffin (phrakture) - Thursday, 21 September 2006, 16:16 GMT
Right, but if we add a early-userspace udev rule to make /dev/usb0 /dev/usb1 etc etc symlinks, the rest of the info (major:minor numbers, fstype, etc) should be easy to glean from there, and it should be possible to do e.q. cryptokey=/dev/usb0:/mykey or something
Comment by Thomas Bächler (brain0) - Thursday, 21 September 2006, 16:38 GMT
IMO, the only proper solution is to make sure that the usb stick is initialized AFTER all scsi and sata drives. Otherwise most fstab, crypttab, root= command line settings that don't use permanent namings may be invalidated (as sda MAY become sdb, regardless of what name we give udev for the usb stick).

Finding the usb stick is the smallest problem here, it can be uniquely identified and symlinked easily. Making sure that sda is what the user assumes to be sda will prove more difficult.
Comment by Alex Merry (pippin) - Monday, 25 September 2006, 11:30 GMT
With future kernel versions, this will be a problem even with more than one sata or scsi drive - even now, the kernel no longer guarantees ordering of device names. This, after all, is the point of the persistent naming schemes and of placing udev in early userspace.
Comment by Thomas Bächler (brain0) - Monday, 25 September 2006, 15:46 GMT
Yes, we should add some howtos about properly handling persistant naming in fstab and boot manager. That would eliminate the problem completely.
Anyway, I am definitely going to add this feature when I have time again to work on early-userspace (which will be 2 days from now). I will look at your input of course. I'll report back here once I have done some testing and the feature is ready for inclusion.
Comment by Thomas Bächler (brain0) - Sunday, 17 December 2006, 00:57 GMT
Alex, please test this:

Update to newest cryptsetup package from testing (if you don't want to add testing to the repo list, just use this link: ftp://ftp.archlinux.org/testing/os/i686/cryptsetup-1.0.4-1.pkg.tar.gz). Keep a copy of your old initramfs image (e.g. kernel26.img). Generate a new one with the new cryptsetup package.

It works like this (for both LUKS and non-LUKS): you add a cryptkey kernel command line parameter, here are some examples:

cryptkey=/dev/cruzer1:vfat:/keyfile
You also need the vfat and nls_437 modules in MODULES and the usb (or the right host controller and usb-storage module) hook, as well as a FILES="/etc/udev/rules.d/01-usbstick.rules". The latter has a rule to create a /dev/cruzer and /dev/cruzer1 symlink for my usb drive. You may as well use the sda/sdb name, but I like this better, as it identifies the usb drive by its serial number (KERNEL=="sd*", ATTRS{serial}=="someserial", SYMLINK+="cruzer%n"). The generic format is cryptkey=BLOCKDEVICE:FILESYSTEM:FILENAME, which mounts BLOCKDEVICE as FILESYSTEM and looks for FILENAME.
You could also try this: add "floppy" to the modules and write a line like cryptkey=/dev/fd0:vfat:/keyfile

cryptkey=/dev/cruzer:7680:512
cryptkey=/dev/fd0:0:1024
This is more tricky, but I think it's awesome. Again, you need usb respectively floppy drivers, but no filesystem modules. The format cryptkey=BLOCKDEVICE:OFFSET:SIZE uses dd to get the keyfile from BLOCKDEVICE, reading SIZE bytes starting from OFFSET bytes. In the first example, I wrote a keyfile in the space between the partition table and the first partition on my usb drive (again, the name is generated by a udev rule). In the second example, I wrote my keyfile on a floppy disk in the first 1024 bytes.

Please test what you like and tell me with which parameter you successfully used it.

Loading...