Encrypted Raspberry Pi with FIDO2

Urban Pleša | Apr 25, 2025 min read

This is a tutorial how to encrypt root partition on a Raspberry Pi and also how to unlock it using hardware security key supporting FIDO2.

Formatting SD Card

To begin, you need to format the SD card for your Raspberry Pi with a suitable MBR partition table. The recommended layout is as follows:

PartitionSizeType codeType description
Boot512M0cW95 FAT32 (LBA)
Rootmax83Linux

You can achieve this using tools like fdisk.

Writing Image to SD Card

First, download the desired Raspberry Pi image from the official website. Any image should work. Decompress the image using:

xz -d 2023-12-11-raspios-bookworm-arm64-lite.img.xz

Note: From this point onwards, all commands should be executed as the root user.

Writing boot partition:

# Set up a loop device for the image
losetup -fP 2023-12-11-raspios-bookworm-arm64-lite.img

# Write the boot partition to the SD card
dd if=/dev/loop0p1 of=/dev/mmcblk0p1 bs=1M

Encrypting root partition:

# Format the root partition with LUKS2 and ChaCha20 encryption
cryptsetup luksFormat --type=luks2 --cipher=xchacha20,aes-adiantum-plain64 /dev/mmcblk0p2

# Enroll the FIDO2 device for unlocking
systemd-cryptenroll --fido2-device=auto /dev/mmcblk0p2

# Open the encrypted root partition
cryptsetup open /dev/mmcblk0p2 root

Writing root partition

# Write the root partition to the SD card
dd if=/dev/loop0p2 of=/dev/mapper/root bs=1M

# Check and resize the file system
e2fsck -f /dev/mapper/root
resize2fs -f /dev/mapper/root

Preparing the OS

Chroot into OS:

# Mount the root and boot partitions
mount /dev/mapper/root /mnt
mount /dev/mmcblk0p1 /mnt/boot/firmware

# Chroot into the OS
arch-chroot /mnt

Installing FIDO2 unlocking package:

# Update and upgrade the package list
apt update && apt full-upgrade -y && apt autoremove -y

# Install required packages
apt install cryptsetup-initramfs fido2-tools jq debhelper git vim -y

# Clone and build the FIDO2 LUKS package
git clone https://github.com/bertogg/fido2luks && cd fido2luks
fakeroot debian/rules binary && sudo apt install ../fido2luks*.deb
cd .. && rm -rf fido2luks*

Configuring crypttab and fstab:

Edit /etc/crypttab:

root            /dev/mmcblk0p2          none            luks,keyscript=/lib/fido2luks/keyscript.sh

Edit /etc/fstab:

/dev/mmcblk0p1    /boot/firmware  vfat    defaults          0       2
/dev/mapper/root  /               ext4    defaults,noatime  0       1

In /boot/firmware/cmdline.txt, update the root parameter to /dev/mapper/root and add cryptdevice=/dev/mmcblk0p2:root to the end.

In /etc/initramfs-tools/initramfs.conf, change dep to most.

Updating initramfs:

# Update the PATH to include /sbin
PATH="$PATH:/sbin"

# Update the initramfs
update-initramfs -u

Final steps:

# Exit the chroot environment
exit

# Unmount the partitions
umount -R /mnt

# Close the encrypted root partition
cryptsetup close root