Automatic Unlock Encrypted Disk Using LUKS â
Unlocking LUKS2 volumes with TPM2, FIDO2, PKCS#11 Security Hardware on systemd 248 @ref: https://0pointer.net/blog/unlocking-luks2-volumes-with-tpm2-fido2-pkcs11-security-hardware-on-systemd-248.html > A very good and simple way to encrypt LUKS
WARNING
Only systemd version 248 and above has native support to unlock disks, as per
With the upcoming systemd v248 the systemd-cryptsetup component of systemd (which is responsible for assembling encrypted volumes during boot) gained direct support for unlocking encrypted storage with three types of security hardware:
Unlocking with FIDO2 security tokens (well, at least with those which implement the hmac-secret extension; most do). i.e. your YubiKeys (series 5 and above), Nitrokey FIDO2, AuthenTrend ATKey.Pro and such.
Unlocking with TPM2 security chips (pretty ubiquitous on non-budget PCs/laptops/âĻ)
Unlocking with PKCS#11 security tokens, i.e. your smartcards and older YubiKeys (the ones that implement PIV). (Strictly speaking this was supported on older systemd already, but was a lot more "manual".)
TIP
The command systemd-cryptenroll
is only available on Ubuntu 21.10 onwards.
Resize Existing LVM rootfs â
Use this if there is existing lvm with rootfs
# resize existing rootfs
lvresize -L -50G ubuntu-vg/ubuntu-lv
# create a new lv with the freed space
lvcreate -L 50G -n rootfs ubuntu-vg
# create new ext4 file system. Can check the [LV Path] using lvdisplay
mkfs.ext4 /dev/ubuntu-vg/rootfs
# create mountpoint
mkdir /mnt/rootfs
# mount the newly created lv named rootfs
mount /dev/ubuntu-vg/rootfs /mnt/rootfs
test create â
DISK_DEV="/dev/loop0"
TPM_NVRAM_ADDR=0x81010023
LUKS_KEY_SLOT=1 # from 0 to 7
TPM_SEAL_PCR="sha256:0" # pcrbank:pcrvalue
# Create test file
dd if=/dev/zero of=enc.disk bs=1M count=10
dd if=/dev/urandom of=disk.key bs=1 count=32
# create loopback device
loopdevice=$(losetup -f) && sudo losetup $loopdevice enc.disk
echo -n "Unsealing TPM2 NVRAM with PCR... "
# initialize a TPM session
tpm2_startauthsession --policy-session -S session.ctx
# Generates a PCR policy event with the TPM.
tpm2_policypcr -Q -S session.ctx -l $TPM_SEAL_PCR
tpm2_unseal -p session:session.ctx -c $TPM_NVRAM_ADDR > /tmp/disk.key
sudo cryptsetup luksFormat --key-file=/tmp/disk.key $loopdevice
# open luks, this will mount to /dev/mapper/enc_volume
sudo cryptsetup luksOpen --key-file=/tmp/disk.key $loopdevice enc_volume
# format file system
sudo mkfs.ext4 -j /dev/mapper/enc_volume
# finally mount
sudo mkdir /mnt/enc_volume
sudo mount /dev/mapper/enc_volume /mnt/enc_volume
Method 1: Manual â
@ref: https://tpm2-software.github.io/2020/04/13/Disk-Encryption.html
Create a random key and save it persistent to TPM NVRAM.
TPM_NVRAM_ADDR=0x81010023
# Creating and persisting a sealing object and sealing a random byte sequence as the disk key.
tpm2_createprimary -Q -C o -c prim.ctx
dd if=/dev/urandom bs=1 count=32 status=none | tpm2_create -Q -g sha256 -u seal.pub -r seal.priv -i- -C prim.ctx
tpm2_load -Q -C prim.ctx -u seal.pub -r seal.priv -n seal.name -c seal.ctx
tpm2_evictcontrol -C o -c seal.ctx $TPM_NVRAM_ADDR
Setup loop device for the partition
loopdevice=$(losetup -f)
losetup $loopdevice /dev/mapper/ubuntu--vg-ubuntu--lv
# Pipe the sealed key from TPM and save it as a luks keyslot 0 in the partitionl
tpm2_unseal -Q -c 0x81010023 | cryptsetup luksFormat --key-file=- $loopdevice
Dump the info. Note that we are using LUKS2, and it allow up to 8 slots, allow key rotation.
cryptsetup luksDump $loopdevice
LUKS header information for /dev/loop3
Version: 1
Cipher name: aes
Cipher mode: xts-plain64
Hash spec: sha256
Payload offset: 4096
MK bits: 256
MK digest: 6b b6 6f 0d 98 3f e4 2b 6c 9e e5 58 3f 41 35 ab c7 05 aa e3
MK salt: 06 cf e0 12 51 74 2d b7 23 a7 7c 2b 22 84 78 53
84 7d f5 17 a1 e9 d8 2b 46 b6 1a 54 24 54 5f 72
MK iterations: 159454
UUID: c002ae7c-f65e-48d8-979a-7696974fffb5
Key Slot 0: ENABLED
Iterations: 2551278
Salt: b4 59 b6 99 a9 99 31 6d eb f0 d8 c0 c9 b0 6d 85
6d f7 6d fe f0 9d bc ae ba 6a 98 60 20 4b 8c 47
Key material offset: 8
AF stripes: 4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED
Scenario 2: Existing LUKS crypt â
Before adding luks key
cryptsetup luksDump /dev/sda3
LUKS header information for /dev/sda3
Version: 1
Cipher name: aes
Cipher mode: xts-plain64
Hash spec: sha256
Payload offset: 4096
MK bits: 256
MK digest: 01 9b 6f b7 18 9e ad 3c 28 f4 12 16 a3 f1 5a b0 a5 7d ab ae
MK salt: 20 d6 38 03 dd e1 10 40 1b 55 cc a2 a7 42 50 a9
62 22 08 88 da a5 30 18 d8 70 dc b0 a3 55 b8 84
MK iterations: 159649
UUID: d00093b4-305c-45f1-946e-cd9b2e8203ab
Key Slot 0: ENABLED
Iterations: 2554386
Salt: cd a2 aa 2d b1 d4 a8 b8 6d 56 9f 22 23 ad f7 72
5c 2a bc 31 11 5a 86 3a f5 26 d3 db 52 b7 41 be
Key material offset: 8
AF stripes: 4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED
After adding luks Key
TPM_NVRAM_ADDR=0x81010023
DISK_DEV=/dev/sda3
tpm2_unseal -Q -c $TPM_NVRAM_ADDR | sudo cryptsetup luksAddKey $DISK_DEV -
Appendix â
Dump LUKS info
cryptsetup luksDump /dev/sda3
It will return nothing if not setup yet