plenty of hacks - home

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:

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!