Why does the installer add a paswordless key to LUKS-encrypted partition?

I’ve recently installed Manjaro Gnome and used “encrypt this partition” option during installation.

I then switched to systemd-boot in order to speed up boot time (the grub one is slow at decrypting the partition).

When I switched to systemd-boot, I’ve discovered that the computer boots properly without prompting for a decryption password. Using sudo cryptsetup luksDump /dev/sda2 I’ve realized that there are two keys attached to my main partition - apparently one was passwordless.

This means that the encryption is entirely pointless, because one could just take out the HDD of my PC and see all the files…

Why is that so?

1 Like

I noticed the same thing as well during my tests of the 21.1 RC.

However, in my case, the key is useless, since it lives within the encrypted system partition itself. :rofl: (How can the bootloader retrieve the key to unlock the container when the container needs to be unlocked to retrieve the key?!) :chicken::egg:


Curious, what is your partition layout? How is it retrieving the key?

Are you using the traditional method of,

  • Separate / shared EFI system partition <— plain
  • Separate boot (/boot) partition <— plain
  • System (/) partition <— encrypted

Or the leaner method of,

  • Separate / shared EFI system partition <— plain
  • System (/) partition <— encrypted

You can easily destroy one of the keyslots, which will only leave the passphrase-slot. However, if you accidentally destroy the wrong slot, and then delete the keyfile, you lose your data forever.

I did remove one of the slots and now it can only be unlocked with the passphrase. I was just curious why this default setup was botched. I have no idea where the key for that second slot was located (how do I check that?)

Here’s my partition setup, hope it answers your question:

NAME                   MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
sda                      8:0    0 931,5G  0 disk  
├─sda1                   8:1    0   300M  0 part  /boot/efi
├─sda2                   8:2    0 907,6G  0 part  
│ └─luks-58f5***       254:0    0 907,6G  0 crypt /
└─sda3                   8:3    0  23,6G  0 part  
  └─luks-094***        254:1    0  23,6G  0 crypt [SWAP]

Two files can guide you to where that key exists:

  • /etc/default/grub (delineated by colon-separated options)
  • /etc/crypttab (requires root user to read the contents)

The crypttab is actually unnecessary for the system partition, since that is handled by the initramfs and bootloader. Where the crypttab is actually used is for any other encrypted device/container aside from the system partition.

Yet, distros still automatically make an entry for the system partition in the crypttab (perhaps for the end-user’s own reference?)

I always comment out the entry for the system partition in my crypttab after a successful installation.


Don’t believe me? Just look at the big bold warning in every crypttab. They wrote it for a reason. Yet distros still add the system partition entry after installation. Not sure why. :man_shrugging: I always comment it out.

# NOTE: Do not list your root (/) partition here, it must be set up
#       beforehand by the initramfs (/etc/mkinitcpio.conf).

My /etc/crypttab is empty. Grub config does not have any mention of any decryption keys. Besides, Grub required a passphrase to decrypt the disk, so likely it doesn’t even know about the other key…

Not a single entry for crypttab, and you read it with root privleges?


Does this file exist on your system:

ls -lh /crypto_keyfile.bin


Grub always prompted for a passphrase? Even before you destroyed LUKS key slot 1?

I thought you switched to systemd-boot, because of how slow Grub is at decrypting the key? What happens if you try with systemd-boot now, after having destroyed the extra key slot?


Systemd-boot was retrieving the key file from somewhere if you could decrypt without your passphrase.

Last place I would look is under /etc/mkinitcpio.conf

Look for a line that reads

FILES="/crypto_keyfile.bin"

If such a line exists, comment it out or remove it.

What this does is load the key file into the initramfs (like a “mini” filesystem that lives and runs in RAM), and so the boot-loader has a filesystem it can work with and retrieve files, if needed, before you get access to the real root filesystem.


Commenting out the above line and removing the file /crypto_keyfile.bin should remove any traces of this behavior.

Don’t forget to rebuild and update.

sudo mkinitcpio -P
sudo grub-install
sudo update-grub

Also check out systemd-boot config:

sudo bootctl list

Alternatively, check the config file(s) under the folder “[esp]/loader/entries/” in your EFI system partition.


UPDATE: I’m not sure if you decided to switch back to Grub or still continue to use systemd-boot?

I was sure i read it with sudo. Checked again and indeed there are entries in there. They point to /crypto_keyfile.bin

That’s correct

That was indeed my reason to do so

After deleting the extra key slot systemd-boot now asks me for the passphrase. Before that it just booted to login screen without asking for a password :man_shrugging:

I continue to use systemd-boot, because it’s much faster at decrypting than GRUB. It just struck me as very weird that right after switching to systemd-boot the passphrase had no longer been necessary.


I’m worried this will make my system unbootable. Isn’t the key file needed to decrypt the partition? After all, the passphrase is for decrypting some key, not the entire partition, right?

I’m assuming you destroyed Key Slot 1 (as I believe Key Slot 0 is the passphrase you created at install). Prior to that, systemd-boot was reading the contents of your initrd (small initramfs located on your ESP) in order to find a file named crypto_keyfile.bin, which it used to unlock Key Slot 1, which is then used to decrypted the Master Key, which is what actually decrypts your system partition.

I highly recommend you investigate the following to better gauge what’s going on:

  • Contents of /etc/mkinitcpio.conf
    – Look for an entry named FILES=()
    – It lists what files to copy into the initrd.img when generating a new image
    – I’m pretty sure you’ll see FILES=(/crypto_keyfile.bin)
    – This means it copies that file into the initrd, so that systemd-boot has access to it (in order to automatically decrypt your system partition)

  • The existence of the actual keyfile located at /crypto_keyfile.bin
    – Without this keyfile laying around in the open, mkinitcpio’s FILES=(/crypto_keyfile.bin) would have nothing to copy to the initrd in the first place! :open_mouth:

  • The number of key slots in your LUKS header
    – You originally had two (which I assume are automatically created during installation with Calamares)
    – The first of these two (Key Slot 0) is based on your passphrase
    – The second of these two (Key Slot 1) is based on crypto_keyfile.bin (which the installer automatically generated behind the scenes)
    – You destroyed Key Slot 1, which means crypto_keyfile.bin is useless from now on
    – You can leave crypto_keyfile.bin alone, but it serves no point if you destroyed Key Slot 1

  • Additional crypttab references to key slots or keyfiles
    – One thing that can clue you is /etc/crypttab (must read as “root”)
    – The crypttab is used for everything but the system partition, since the bootloader is responsible for passing the options
    – This entry (for the system partition) is automatically generated and can be commented out (remember, it’s not even accessible to systemd-boot or Grub, since it lives on an encrypted partition, yet you can still boot your system with no problems, read below)
    – If you want to specify and pass options to other LUKS partitions, crypttab is where you add entries, in similar fashion to fstab (name, device, options, etc)
    – If you want to specify and pass options to your encrypted system partition, you do this in the bootloader entries (Grub or systemd-boot), for example to allow SSD trims to pass through LUKS: rd.luks.options=allow-discards can be appended to the “linux” line in Grub or systemd-boot entry.

  • The bootloader options
    – Grub and systemd-boot use their own options to identify, unlock, and apply options to the encrypted system parittion
    – Run the command as root: bootctl list or read the file (esp)/loader/entries/manjaro.conf
    – Look for any lines that mention the keyfile or other LUKS options
    – Look for options named something like “rd.luks”, which stands for ramdisk LUKS options
    – An example might be rd.luks.key=/crypto_keyfile.bin
    – The above example is moot if you destroyed the corresponding key slot, or deleted the file crypto_keyfile.bin, or removed the entry for FILES=(/crypto_keyfile.bin) from mkinitcpio.conf


Perhaps there’s a confusion of terms? crypto_keyfile.bin is equivalent to a passphrase: it’s used to unlock a key slot, which is used to decrypt the master key, which is then used to actually decrypt the partition.

  • Master Key
    – The 256-bit randomly generated key that is used in the AES cipher process which is the unique thing (to your LUKS partition) that encrypts/decrypts data.
    – You don’t choose it. It’s randomly generated for you the first time you initialize a LUKS device.
    – It’s not stored anywhere in the open
    – An encrypted form of it is stored in the LUKS header
    – This encryped (and useless) form of the Master Key needs to be decrypted back to its original form and loaded into RAM (useful!) to be used for encrypting/decrypting data on the LUKS device

  • Keyfiles and Passphrases
    – These are used to actually encrypt (and decrypt) the Master Key itself
    – They can be in the form of a passphrase or an actual file (such as crypto_file.bin)
    – You can even use a photo from Google Image search as a keyfile! (No joke, I’ve done it!)
    – While the LUKS device is currently unlocked, the actual Master Key lives in RAM
    – The Master Key is combined with a new passphrase or keyfile, runs through a complex and straining derivation process, which generates a key slot
    – In order to reverse this process against the key slot (to access the Master Key), you must provide a valid passphrase or keyfile
    – Upon doing so, if correct, the key slot is reversed, and thus it is used to decrypt the Master Key, and thus decrypt the data on the partition

  • Key Slots
    – LUKS supports multiple key slots
    – They start from 0 and incrementally count up to 7 (maybe more with LUKS2?)
    – At initial creation of the LUKS device, at least one key slot must be used (or else no access, whoops!)
    – These key slots can be generated from a passphrase or keyfile
    – Any of them can be destroyed at any time, which will void the passphrase or keyfile associated with that key slot
    – If you destroy the wrong one by mistake, you could potentially lock yourself out forever
    – You cannot destroy the last one, or else your data is gone forever. At least one key slot must exist

At no time when using LUKS are you ever directly dealing with the Master Key. You don’t create it, you don’t provide it, you don’t save it.

You only interact with your own passphrases and keyfiles, which are saved as key slots (encrypted forms of your passphrases and keyfiles). By providing a valid passphrase or keyfile, the rest is handled by dmcrypt/LUKS.

Your passphrase or keyfile is processed through a complex function through many iterations, against each key slot to find a match. If a match is found, the key slot is decrypted, and this new decrypted string is fed into an algorithm to decrypt the Master Key, which is then loaded into RAM to be used for the cipher (decrypt / encrypt data being read / written to the LUKS device.)


Addendum:

  • Passphrases can never be “lost” or “deleted”, as they live in your mind’s memory. This is why they are less volatile and easier to deal with. (While they can’t be “lost” they can be “forgotten”.)
  • Keyfiles can be lost (or deleted). If you don’t make a backup of your keyfile(s) then there’s no way to decrypt the key slot(s) associated with the former keyfile(s).

This illustrates why I believe passphrases are superior. You must use extra care and caution if solely relying on keyfiles.

You should always delegate at least one of your LUKS key slots to a passphrase, in case you lose access to (or delete) any associated keyfiles.

5 Likes

Thanks for the detailed response. I understand my current status better. I guess that without installing systemd-boot the keyfile wouldn’t land in initramfs in the first place.

Still, I think it’s alarming that the default installer creates this Key Slot 1 that uses a keyfile… Why not just one slot with a passphrase? It almost looks like a backdor :smiley:

Did you have the FILES=(/crypto_keyfile.bin) in the /etc/mkinitcpio.conf or not?

If yes, then this is a backdoor, meaning the key do decrypt your disk is added to the unencrypted initramfs in /boot.
If not, then there’s no harm because this key file is on the encrypted partition of the disk.

I have just encountered problems with probably a similar thing, though I didn’t move from GRUB to systemd-boot but I deleted the /crypto_keyfile.bin from FILES= in mkinitcpio.conf (I had a different problem, my home partition was not unlocking from key file), but after that I am being asked twice for unlocking the root partition, once straight after powerup “before” grub menu and second at the start of init.

I did use manjaro architect to create encrypted root setup with password.
Though, if I do cryptsetup luksDump on the root partition it shows two key slots but I never added another slot ( I know Slot 0 is the password, so the Slot 1 is possibly keyfile?)

My theory:

  • The (plain, unencrypted) boot partition is mounted at /boot/efi (which contains grub).
  • Init (initramfs?) is in /boot, which lives in root partition, so it’s obviously encrypted with the whole root disk and that’s why grub has to decrypt it before doing anything else
  • Now (I don’t really understand the init process, but I am guessing) grub loads the selected init image into memory and executes it, giving control over, though the unlocked state of root is not carried over to init
  • With that in mind, init has to decrypt the disk again so it can bring alive the rest of the system. Without the /crypto_keyfile.bin in FILES it has to ask for password.

If the above is right, I am guessing the systemd-boot of yours @kuba-orlik somehow loaded the crypto_keyfile.bin and used it to decrypt it once and maybe systemd-boot is somehow able to carry the unlocked state (the decrypted LUKS header) through out the whole boot & init process OR it packed the keyfile with itself into the boot stage, thus not asking for password at start.

EDIT:
To summarize the whole boot up & decryption process:

  1. Your bootloader starts, possibly asks you for password and begins decrypting the root partition so it can see your initramfs and kernel
  2. Bootloader loads initramfs into memory and passes control over to it, the decrypted state (decrypted LUKS header) of root is lost
  3. Init sees encrypted root and
    • has a keyfile to decrypt the root
    • asks for password (which would be the same one as given to your bootloader)
  4. System is alive

Yes, I had. Still have, in fact

Ok, this is serious. I’ve been able to extract the crypto_keyfile.bin from the initramfs file stored on unencrypted /boot… Meaning, the default disk encryption is useless, because the decryption key is just sitting there in /boot!

I’ve tried it on a colleague’s machine, where no tinkering was done with the bootloader, and the result is the same.

This… needs to be escalated.

4 Likes

Here I am - with @kuba-orlik we just checked it on my machine. I have a default LUKS manjaro install and i was able to extract the crypto_keyfile.bin from initramfs-5.10-x86_64 on /boot

2 Likes

Could you please read my post above.

Your /boot is located on the encrypted root partition right?
Which means that the whole file is encrypted with the rest of the system, it’s not accessible unless the partition is already decrypted, the point of having it in initramfs is so that it the init process can decrypt the root filesystem to bring the system online, because the root does not stay decrypted between boot and initramfs load.

See the warning on top of dm-crypt/Device encryption - ArchWiki, especially the point beginning with /boot

1 Like

So did you created a bug report with the calamares project? It needs to be fixed there.

But, on a default install, /boot is part of /. Which means the initdamfs is encrypted anyway. Also a Keyfile is necessary to encrypt a separate /home without typing in a password again.

Ah :man_facepalming: Indeed it is. Sorry, I had this assumption that /boot is unencrypted, while in fact it’s only /boot/efi that’s unencrypted. Now everything checks out.

Not sure why GRUB needs to have the keyfile in order to not ask for the passphrase twice, as systemd-boot does away without keyfile and asks for the passphrase only once, but that’s besides this topic.

Thank you for your explanation! :pray:

3 Likes

And now I know that, as well. While setting up systemd-boot i made a snafu of copying the initramfs to /boot/efi, so systemd-boot doesn’t have decrypt /boot in order to get the initial root filesystem

Indeed that is interesting. I am guessing sytemd-boot might be able to carry the decrypted state over to initramfs (which is basically systemd)?
Though now I am pretty sure that is not the case, it’s more of that the crypto_keyfile.bin is simply embedded in the initramfs so it does not ask again.