You are not logged in.

#1 2020-11-26 10:52:15

sham235
Member
Registered: 2014-12-29
Posts: 9

Achieving two-factor authentication with a LUKS-encrypted key file.

I wanted to open root LUKS partition with a LUKS-encrypted keyfile on an external storage.
GRUB asks for LUKS password for /boot. After /boot is unlocked, initramfs uses its own key-for-root-key to unlock root-key from external storage with LUKS.
root-key unlocks root LUKS partition. My setup achieves two-factor authentication.

Note that you can change key sizes in this guide.

Create /root/key-for-root-key

dd bs=512 count=1 if=/dev/random of=/root/key-for-root-key
chmod 600 /root/key-for-root-key

Mount external storage on /mnt/keyfile.

mount -o ... UUID=uuid-id-of-external-partition /mnt/keyfile

Create a LUKS image file in /mnt/keyfile/root-key

cd /mnt/keyfile
dd if=/dev/zero of=root-key bs=1M count=16 status=progress
# for 512-bytes keyfile on top of 16MB LUKS2 header.
truncate --size=+512 root-key

cryptsetup --pbkdf pbkdf2 [--pbkdf-force-iterations N] luksFormat \
root-key /root/key-for-root-key

cryptsetup -d /root/key-for-root-key open root-key root-key

cryptsetup status root-key

dd if=/dev/random of=/dev/mapper/root-key bs=512 count=1 status=progress

cryptsetup --pbkdf pbkdf2 luksAddKey [--pbkdf-force-iterations N] \
/dev/root-dev /dev/mapper/root-key

cryptsetup close root-key

/etc/initcpio/install/lukskeyfile

#!/bin/bash

build() {
  add_dir "/mnt"
  add_module loop
  add_module dm-crypt
  add_runscript
}

help() {
  cat <<EOF
Open root partition with LUKS-encrypted root-key
To use this hook, specify lukskeyfile in kernel parameters.
This hook is designed to produce cryptkey for encrypt hook by
unlocking a LUKS-encrypted key on external storage with a keyfile on initramfs
and copying the key onto a path designated as cryptkey by encrypt hook.

lukskeyfile=keyForRootKey:rootKeyDev:rootKey[:decryptedRootKey]

keyForRootKey = /path/to/keyForRootKey in initramfs
rootKeyDev = /path/to/rootKeyDev, UUID=uuid-of-rootKeyDev, ...
rootKey = /path/to/rootKey in rootKeyDev
decryptedRootKey = /path/to/cryptkey in initramfs.

Default values
decryptedRootKey=/crypto_keyfile.bin
EOF
}

/etc/initcpio/hooks/lukskeyfile

#!/bin/ash

run_hook() {
  if [ -n "$lukskeyfile" ]; then
    # This is needed to open a file with cryptsetup.
    modprobe -a -q loop dm-crypt >/dev/null 2>&1
    # Refer to help from `mkinitcpio -H lukskeyfile`.
    IFS=: read keyForRootKey rootKeyDev rootKey decryptedRootKey <<EOF
$lukskeyfile
EOF

    if [ -z "${decryptedRootKey}" ]; then
      decryptedRootKey=/crypto_keyfile.bin
    fi

    if resolved=$(resolve_device "${rootKeyDev}" $rootdelay); then
      if mount -o noatime "${rootKeyDev}" /mnt>/dev/null 2>&1; then
        if cryptsetup -d "${keyForRootKey}" open "/mnt${rootKey}" root-key \
        >/dev/null 2>&1; then
          cat /dev/mapper/root-key > "$decryptedRootKey"
          cryptsetup close root-key >/dev/null 2>&1
        else
          echo "Failed to open ${rootKey} with ${keyForRootKey}"
          /bin/sh
        fi
        umount /mnt >/dev/null 2>&1
      else
        echo "Failed to mount ${rootKeyDev} on /mnt"
        /bin/sh
      fi
    else
      echo "Failed to find ${rootKeyDev} containing LUKS root key."
    fi
  fi
}

/etc/mkinitcpio.conf

HOOKS=(... lukskeyfile ... encrypt ...)

/etc/default/grub

GRUB_CMDLINE_LINUX="cryptdevice=UUID=uuid-for-root-LUKS-partition:\
cryptroot:allow-discards lukskeyfile=/root/key-for-root-key:\
UUID=uuid-for-partition-containing-root-key:/root-key"

Regenrate initramfs

mkinitcpio -p linux

Update grub config.

grub-mkconfig -o /boot/grub/grub.cfg

Last edited by sham235 (2020-11-27 04:20:21)

Offline

#2 2020-11-26 11:02:47

GaKu999
Member
From: US/Eastern
Registered: 2020-06-21
Posts: 696

Re: Achieving two-factor authentication with a LUKS-encrypted key file.

The forums are not the place for this...will probably get buried pretty soon...
Better write the concept somewhere more...viewable, or as a wiki addition if considered.

...

Now, since we are here, are you aware that the standard encrypt is capable of this?
Cut the middle man and store the key directly in an external device, and access it through the /dev/disk/by-$kind?

Or even better, try some GPG key like the librem/nitro/yubi keys. tongue

Suggestions powered only because I see a double encryption as...weird.
In any case, pick your poison. tongue


My reposSome snippets

Heisenberg might have been here.

Offline

#3 2020-11-26 16:17:03

frostschutz
Member
Registered: 2013-11-15
Posts: 1,652

Re: Achieving two-factor authentication with a LUKS-encrypted key file.

I use a similar setup, except /boot itself is on USB and the keyfile is embedded into the initramfs, so no additional mounting necessary.

As for the 16MB header, it's possible to reduce its size (down to ~128KB per used keyslot) as otherwise (in case of embedding keyfile) each copy of the initramfs would grow by +16MB just for 512 byte of key material...

Regarding pbkdf, this is only necessary for encrypted /boot to be handled by Grub which does not fully support LUKS2 yet. The encrypted keyfile to be handled by initramfs has no such restriction, so you can use argon2 here.

Regarding modules, you should make sure that aesni module is loaded as well. It should probably be the case since the encrypt hook is handling it, but then there should be no need to manually load dm-crypt either, not sure what's going on there.

Last edited by frostschutz (2020-11-26 16:17:46)

Offline

#4 2020-11-26 16:54:44

GaKu999
Member
From: US/Eastern
Registered: 2020-06-21
Posts: 696

Re: Achieving two-factor authentication with a LUKS-encrypted key file.

frostschutz wrote:

Regarding pbkdf, this is only necessary for encrypted /boot to be handled by Grub which does not fully support LUKS2 yet.

But eagerly wait for the next release, they finally are going to bring support to LUKS2. smile

...

An external ESP or just /boot loaded by GRUB in the ESP?
That would be interesting, yet, scary, better allow for a fallback in case the key dies, since they usually tend to give nasty surprises. hmm

In any case, OP, due to the non-issue nature of this thread, you could/should request a mod to move it to one of the non-issue subforums, that way at least, if you want, it would not be buried under support threads in 3 days.


My reposSome snippets

Heisenberg might have been here.

Offline

#5 2020-11-27 02:22:35

sham235
Member
Registered: 2014-12-29
Posts: 9

Re: Achieving two-factor authentication with a LUKS-encrypted key file.

GaKu999 wrote:
frostschutz wrote:

Regarding pbkdf, this is only necessary for encrypted /boot to be handled by Grub which does not fully support LUKS2 yet.

But eagerly wait for the next release, they finally are going to bring support to LUKS2. smile

...

An external ESP or just /boot loaded by GRUB in the ESP?
That would be interesting, yet, scary, better allow for a fallback in case the key dies, since they usually tend to give nasty surprises. hmm

In any case, OP, due to the non-issue nature of this thread, you could/should request a mod to move it to one of the non-issue subforums, that way at least, if you want, it would not be buried under support threads in 3 days.

I could not post in any other subforum.

Last edited by sham235 (2020-11-27 04:19:10)

Offline

#6 2020-11-27 02:34:03

sham235
Member
Registered: 2014-12-29
Posts: 9

Re: Achieving two-factor authentication with a LUKS-encrypted key file.

frostschutz wrote:

I use a similar setup, except /boot itself is on USB and the keyfile is embedded into the initramfs, so no additional mounting necessary.

As for the 16MB header, it's possible to reduce its size (down to ~128KB per used keyslot) as otherwise (in case of embedding keyfile) each copy of the initramfs would grow by +16MB just for 512 byte of key material...

Regarding pbkdf, this is only necessary for encrypted /boot to be handled by Grub which does not fully support LUKS2 yet. The encrypted keyfile to be handled by initramfs has no such restriction, so you can use argon2 here.

Regarding modules, you should make sure that aesni module is loaded as well. It should probably be the case since the encrypt hook is handling it, but then there should be no need to manually load dm-crypt either, not sure what's going on there.

I used to do that before adopting my current setup. Since my USB microSD reader didn't support TRIM, I wanted /boot on a device that supported TRIM. That was SSD.
My setup also allows the external storage to unlock many computers instead of just one. I can just copy key-for-root-key to many computers.

There is a misconception. A luks image file doesn't go into initramfs. Only pure keyfiles go into initramfs in my setup.

Last edited by sham235 (2020-11-27 04:16:52)

Offline

#7 2020-11-27 05:10:12

fukawi2
Ex-Administratorino
From: .vic.au
Registered: 2007-09-28
Posts: 6,237
Website

Re: Achieving two-factor authentication with a LUKS-encrypted key file.

This belongs on your blog, or better yet, contribute it to the wiki which is where people look for guides - the forums are for help when/if the guides fail.

Closing.

Offline

Board footer

Powered by FluxBB