Librem 5 PGP verification through cryptsetup

Can we use our PGP cards as a separate auth token to force LUKS to be unlocked only if the password and card are provided properly?

4 Likes

Or could another form of 2FA work for a secondary token to add this layer (think Yubikey or Nitrokey).

2 Likes

I recall @Kyle_Rankin discussing about this concept years ago, although I believe it was only successfully implemented for PureOS on the desktop.

@jonathon.hall

3 Likes

There are probably two questions in there.

  1. Can LUKS use the OpenPGP card to unlock a slot i.e. instead of entering a passphrase?
  2. Does LUKS even support requiring two factors i.e. passphrase and OpenPGP?
4 Likes

I asked ChatGPT and got this response::

"If you want to use the presence of a YubiKey as a condition to allow the LUKS password to be used for decryption, you can modify the approach slightly. Here’s how you can achieve this:

1. Prepare Your System

Make sure your system has cryptsetup installed and your LUKS-encrypted device is set up correctly.

2. Configure a udev Rule for YubiKey Detection

Create a udev rule that triggers a script when the YubiKey is plugged in. This script will enable or disable the LUKS password entry based on the YubiKey’s presence.

Create a file in /etc/udev/rules.d/, for example, 99-yubikey.rules:

sudo nano /etc/udev/rules.d/99-yubikey.rules

Add the following rule:

KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="*", TAG+="uaccess", SYMLINK+="yubikey%n", ENV{ID_YUBIKEY}="1"

Replace 1050 with the actual idVendor of your YubiKey if it’s different.

3. Create a Script to Handle LUKS Password Entry

Create a script that will check if the YubiKey is present and conditionally allow LUKS password entry. For example, create /usr/local/sbin/yubikey_luks_allow_password:

sudo nano /usr/local/sbin/yubikey_luks_allow_password

Add the following script:

#!/bin/bash

# Path to ykinfo
YKINFO="/usr/bin/ykinfo"

# LUKS UUID of your encrypted device
LUKS_UUID="your_luks_uuid_here"

# Check if YubiKey is connected
if [ -e /dev/yubikey0 ]; then
    echo "YubiKey detected. Allowing LUKS password entry."
    exit 0
fi

# If YubiKey not present, prompt for LUKS password
echo "YubiKey not detected. Enter LUKS password: "
cryptsetup luksOpen /dev/disk/by-uuid/$LUKS_UUID luks_device_name_here

Replace your_luks_uuid_here with the UUID of your LUKS device and luks_device_name_here with a name you want for the unlocked device.

4. Set Permissions

Make the script executable:

sudo chmod +x /usr/local/sbin/yubikey_luks_allow_password

5. Test and Restart udev

Reload udev rules:

sudo udevadm control --reload-rules && sudo udevadm trigger

6. Configure LUKS

Ensure your LUKS device is set up with a password:

sudo cryptsetup luksAddKey /dev/disk/by-uuid/$LUKS_UUID

7. Test the Setup

Now, when you plug in your YubiKey, the script should detect it and allow direct decryption using the LUKS password. If the YubiKey is not present, it will prompt for the LUKS password.

Notes:

  • Modify the script paths (/usr/bin/ykinfo) and UUIDs (LUKS_UUID) as necessary based on your system setup.
  • Ensure that your YubiKey is properly detected by the udev rule (ATTRS{idVendor} and ATTRS{idProduct} values).
  • Test the entire setup in a controlled environment before relying on it for production use.

This setup allows you to conditionally use the LUKS password based on the presence of a YubiKey, providing an additional layer of security to your encrypted Linux system."

1 Like

Since LLMs can produce random garbage, did you do as Step 7 suggests and actually test the whole procedure? Did it work?

Regardless of that … out of the questions offered in my first post, or a question not offered in that post, which scenario is your question asking for?

Based on my understanding of the answer produced by ChatGPT, it is closer to the first question than the second; but based on my understanding of your original question, the original question is closer to the second question.

I could be wrong but I don’t think LUKS can do 2FA.

2 Likes

Was planning on spinning up a VM of PureOS and trying on a dedicated machine first. My thought was using the Yubikey as a conditional, not MFA… if the Yubikey is not inserted, LUKS does not decrypt even with the proper password

2 Likes

But that is 2FA.

My understanding (disclaimers apply) is that LUKS offers N key slots. As long as you can unlock any one key slot, then you can unlock the encrypted disk. Each key slot can be unlocked by a passphrase or by something else (like using an OpenPGP card).

So you can do:

  • require an OpenPGP card and there is no alternative (no way of unlocking with a passphrase - no passphrase set - but this is considered to be risky), OR
  • use an OpenPGP card but fail over to using a passphrase if the card is absent (so this is a convenient choice between a short PIN to unlock the card or a much stronger, longer passphrase as ‘emergency’ backup)

but you can’t do:

  • require an OpenPGP card and a passphrase (which is 2FA, in the classic sense)

However, there’s a lot of subtlety in LUKS, so maybe I missed something.

It should also be pointed out that an OpenPGP card itself requires to be unlocked. Therefore you get the effect of 2FA. So by asserting that LUKS can’t do it, I am only talking about LUKS itself.

Also, with customised code you can surely achieve anything you want. (So, maybe, two LUKS containers, one inside the other, and the outer LUKS container is unlocked by one factor and the inner LUKS container is then unlocked by the other factor??)

2 Likes

It takes some finagling. I managed to install Gentoo to my Librem 14 with smartcard+LUKS support in the initramfs. I encrypted it using the Librem Key’s GPG key, and password protected the Key itself. I added a separate sort of “backup” keyphrase in case the Librem Key gets stolen, but that part can be excluded to get what I understand to be 2FA. I need both the Librem Key plugged in, and its passphrase, to open the encrypted volume.

I have not yet finished documenting this process, though… Still working out some kinks.

3 Likes

When you get it documented, it’d be a great help, I’m wanting to make a more locked down method on my L5

2 Likes

A long password/passphrase with high entropy is recommended then.

1 Like

Nice going. However the OP is asking about the Librem 5. So that would be extra work!

I believe that TrueCrypt had / Veracrypt has true 2FA (i.e. the choice to use two factors within the disk encryption framework itself) - rather than that users have to cobble something together.

2 Likes

Fair point, it was extra work for me to do it on the laptop, as well. It’s not a setup that’s ezpz out of the box right now. Maybe with some advanced tooling in the future!

3 Likes

This is similar to the Librem Key disk unlock that @FranklyFlawless mentioned, which is here: About the Librem Key - Purism - Librem products documentation (check the linked repo as well)

While this is documented for the Librem Key, it only uses the Librem Key’s embedded GPG smart card and should also work with a smart card in the Librem 5.

As written, to unlock the disk, the smart card must be present, and you must enter the smart card’s user PIN.

The fundamental procedure should be the same but it might need some adaptations for the Librem 5. Off the top of my head:

  • The changes to the kernel command line via GRUB config won’t work as-is on the Librem 5, you’d need to make equivalent changes to the kernel command line
  • There might not be an on-screen keyboard during the disk unlock prompt (I haven’t checked it), as written it might need you to plug in a USB keyboard
  • There might not be a way to boot the recovery option if you lose the smart card or forget the PIN, etc., you might be locked out until you can edit the kernel command line (say by booting with Jumpdrive)
2 Likes