Raspberry Pi 4 with boot disk encryption
There's a ton of references for encrypting the boot disk of a Raspberry Pi. Some are more convoluted than others. I found a simple guide and followed it, but there was a key word missing in one of the instructions, and I had to do my own research to make an informed guess. I was successful on my second attempt!
Here is my guide on how to encrypt your boot disk for the Raspberry Pi. Credit to https://europa.lickwid.net/~tlp/toes.html for the original article. I am going to largely copy the process from there, with the only correction being the key word which is missing (I will point it out below).
My setup is as follows:
- Raspberry Pi 4.
- Debian 10 (the current Raspian image).
- Whole-disk encryption with LUKS.
- My disk is
/dev/sdc
- please update your commands accordingly. - A separate linux machine for performing some required tasks.
All commands are to be ran as root. My suggestion is to make a backup of your SD
card before attempting any of these steps, that way you can easily restore
your system if you make any mistakes or it doesn't work. I used dd
to make
a backup, e.g. dd if=/dev/sdc of=~/backups/sdc.img bs=1M
before proceeding.
Steps to complete on Raspberry Pi
apt update
apt install busybox
apt install cryptsetup
Edit /boot/cmdline.txt
by changing its existing root
parameter and adding
this additional cryptdevice
parameter:
root=/dev/mapper/crypt cryptdevice=/dev/mmcblk0p2:crypt
Edit /etc/fstab
to use a new mount point for our root partition.
First delete the existing entry for /
, and add the following entry:
/dev/mapper/crypt / ext4 defaults,noatime 0 1
Add the following line to /etc/crypttab
to allow the system to know
what to unlock. Important: use tabs, not spaces!
PS: This is where the previous guide was missing information.
The initial guide is missing the ,initramfs
on this line
which was causing a future step to not recognize the need to load
the crypto stuff for initial boot. It makes me wonder if we
need the 'fake encrypted image' step at all. Hmm.
crypt /dev/mmcblk0p2 none luks,initramfs
Here we do a trick to get all the required modules loaded at initial boot. A.k.a. we are going to simply mount a dummy encrypted image in order to trick our system. Create a small encrypted image, the password you choose is not important and does not need to be secure.
dd if=/dev/zero of=/tmp/fakecrypt.img bs=1M count=30
cryptsetup luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 /tmp/fakecrypt.img
cryptsetup luksOpen /tmp/fakecrypt.img crypt
mkfs.ext4 /dev/mapper/crypt
I don't understand the need for this exactly, but we are going to add a script to copy any latest initrd image to a fixed filename.
First, create directory:
mkdir -p /etc/initramfs/post-update.d/
Then create a new file /etc/initramfs/post-update.d/copy_initrd
with the following contents:
#!/bin/sh
cp -v $2 /boot/initrd.img-current
Make sure the new file is executable:
chmod a+x /etc/initramfs/post-update.d/copy_initrd
Generate a new initramfs:
update-initramfs -c -t -k `uname -r` -v
Add the following lines to your /boot/config.txt
to load the correct image:
initramfs initrd.img-current
boot_delay=5
Now it's time to shut off the Raspberry Pi and move the SD card to another linux machine where we can perform the steps to actually encrypt the contents.
Steps to complete on your "other" linux machine
Mount the volume and copy its contents into a tar file:
mkdir pi_mnt
mount /dev/sdc2 ./pi_mnt
tar cf part2_contents.tar -C pi_mnt .
umount pi_mnt
Setup a new encrypted partition:
cryptsetup luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 /dev/sdc2
cryptsetup luksOpen /dev/sdc2 pi_crypt
mkfs.ext4 /dev/mapper/pi_crypt
Copy the data back to the new encrypted filesystem:
mount /dev/mapper/pi_crypt ./pi_mnt
tar xf part2_contents.tar -C pi_mnt
umount pi_mnt
cryptsetup luksClose pi_crypt
That's it! You should now be able to boot up the Raspberry Pi and in a few moments you'll see it boot and prompt for the password. I hope you were successful. Cheers!