anatol / booster

Fast and secure initramfs generator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Specify a particular LUKS keyslot or token to use for unlocking

AidanGG opened this issue · comments

With a LUKS volume with multiple keyslots and/or tokens specified, such as for example (abbreviated output of cryptsetup luksDump):

Keyslots:
  0: luks2
	PBKDF:      pbkdf2
  1: luks2
	PBKDF:      pbkdf2
Tokens:
  0: systemd-recovery
	Keyslot:    0
  1: systemd-fido2
	Keyslot:    1

it would be beneficial to be able to target one of these keyslots or tokens when unlocking the volume without falling back to any other keyslot/token. If specifying a keyslot, password input would be run through that keyslot's PBKDF algorithm as usual. If specifying a token such as token 1 in the example, the key would be retrieved from the relevant token (a FIDO2 key in this case), then used as input to the corresponding keyslot (keyslot 1 in this case) with its specified PBKDF.

I suggest using kernel parameters such as rd.luks.keyslot=i and rd.luks.token=i for this purpose. This would allow for specifying multiple entries in the bootloader, e.g. the default bootloader entry could keep retrying the systemd-fido2 token until successful unlock, and the backup bootloader entry could be used to target the recovery password-based keyslot.

Thank you @AidanGG. It sounds like a reasonable feature to have.

A few questions here:

  • does any other initramfs implement this? To make sure that the booster implementation is interoperable as much as possible.
  • it might make sense to accept a list of slots/tokens e.g. rd.luks.keyslot=0,3,5,6
  • what happens when both parameters (keyslot and token) are used? I assume and matching condition should be used, i.e. process only given tokens and unlock only given slots.

I think you are right to make Booster as interoperable as possible. I have just read the crypttab manpage (https://www.freedesktop.org/software/systemd/man/crypttab.html#) which I assume the systemd and sd-encrypt hooks of mkinitcpio follow. For example,

rd.luks.options=tpm2-device=auto,tpm2-pcrs=7

targets an automatically chosen TPM2 device, with PCR 7. I speculate that this will try all systemd-tpm token slots specified in the LUKS2 header and similarly rd.luks.options=fido2-device=auto will loop through all systemd-fido2 token slots with an automatically chosen present Yubikey. Not specifying one of these options will then target password unlock with PBKDF on all of the keyslots.

So perhaps this might be more suitable for Booster, instead of specifying exact keyslots/token slots? Like just being able to specify a specific token type and looping through all token slots that match that type without falling back to password input.

EDIT: crypttab supports key-slot, so rd.luks.options=key-slot=i to specify a particular keyslot when using password input with a PBKDF. I'm not sure how that interacts with one of the tokens, but I assume that some sort of error would be raised if there was not a token slot of the correct type whose correspond keyslot was that keyslot i.

Just to add to this, dracut also supports rd.luks.options=fido2-device=auto -- I had to remove it from my cmdline when moving to Booster otherwise the computer wouldn't boot (unrecognised option error -- perhaps this could be ignored?)