Howto: Completly encrypted harddisk including the suspend to disk partition with Ubuntu 6.10 Edgy Eft

I'm now using Ubuntu 8.10 with built in encryption. It works like a charme - no patching necessary. Good job Ubuntu!

Prerequisitions

I've a notebook capable of suspend to disk (and to ram) with Linux. Both, suspend to disk and suspend to ram are working out of the box with my Hewlett Packard HP nx6110.

During installation I wrote some notes to a text file. This was the base for this howto. It's possible that something is missing. Feel free to write me (eMail on contact information).

I use the following partition layout:

partitionmount point
/dev/hda5/
/dev/hda2/boot
/dev/hda4swap
/dev/hda6/home
Table 1: partition layout

Aim

I wanted to encrypt the whole hard disk. Even the suspend to disk image should be written to an encrypted partition.

Encryption of the root filesystem

Just install Ubuntu, the server profile, into /dev/hda4, the later swap. Don't specify swap during installation process, we will introduce it later. Use /dev/hda5 as /boot. /boot will not be encrypted, because the kernel must be read from somewhere ;-)

Boot into your freshly installed Ubuntu.

Prepare /dev/hda5, the later root, for encryption:

cryptsetup -h sha256 -c aes-cbc-essiv:sha256 -s 256 luksFormat /dev/hda5

Map /dev/hda5 to cryptroot:

cryptsetup luksOpen /dev/hda5 cryptroot

Make a filesystem on the encrypted device:

mkfs.ext3 /dev/mapper/cryptroot

Mount it:

mount /dev/mapper/cryptroot /mnt

Copy Ubuntu to the new filesystem:

cp -ax / /mnt

Mount (special) filesystems for later use in chroot environment:

mount --bind /dev /mnt/dev

mount --bind /proc /mnt/proc

mount --bind /sys /mnt/sys

mount --bind /boot /mnt/boot

Chroot into /mnt the later root:

chroot /mnt /bin/bash

Add line in /etc/crypttab for encrypted root:

cryptroot /dev/hda5 none luks

Change root entry in /etc/fstab into:

/dev/mapper/cryptroot / ext3 defaults,errors=remount-ro 0 1

I had problems reading cryptsetup password from <&1. Cryptsetup just jumped over without waiting for keyboard input.
So I patched /lib/cryptsetup/cryptdisks.functions:

--- tt/lib/cryptsetup/cryptdisks.functions	2006-09-21 12:12:50.000000000 +0200
+++ cryptdisks.functions.doku	2007-01-18 23:48:39.000000000 +0100
@@ -291,7 +291,7 @@
 		if test "x$INTERACTIVE" != "xyes" ; then
 			PARAMS="$PARAMS --key-file=$key"
 		fi
-		$CRYPTCMD $PARAMS luksOpen $src $dst <&1
+		$CRYPTCMD $PARAMS luksOpen $src $dst </dev/console
 		RESULT=$?
 		if [ $RESULT = 0 ] ; then
 			if [ "$CHECK" != ""  ] && ! $CHECK $MAPPER/$dst $CHECKARGS; then

I'm note sure when this file was introduced. But now the /etc/initramfs-tools/conf.d/cryptroot contains:

CRYPTOPTS="target=cryptroot,source=/dev/hda5"

Update initramfs for changes in cryptdisks.functions, fstab and crypttab:

update-initramfs -u -k 2.6.17-10-generic

Remove the splash option from /boot/grub/menu.lst:

# defoptions=quiet splash

Update grub:

update-grub

Reboot:

reboot

After asking for the LUKS passphrase my system came up with the login prompt. Fine.

Encryption of home

/ (root) and /home were on the same partition. And a fresh installation of Ubuntu was a pain, copying /home to USB disk and back... So I decided to use a separate filesystem for /home.
Prepare /dev/hda6, the later /home, for encryption:

cryptsetup -h sha256 -c aes-cbc-essiv:sha256 -s 256 luksFormat /dev/hda6

Map /dev/hda6 to cryptroot:

cryptsetup luksOpen /dev/hda6 crypthome

Make a filesystem on the encrypted device:

mkfs.ext3 /dev/mapper/crypthome

Mount it:

mount /dev/mapper/crypthome /mnt

Move the content from the old, mainly skeleton files from the freshly by the Ubuntu installation added user, to the new /home:

mv /home/* /mnt/

Because we have an encrypted filesystem now, we can save the key of the /home partition to a plain text file.
Create an additional LUKS key:

dd if=/dev/random of=/etc/keys/home.key bs=32 count=1

Add the newly created key to the LUKS partition:

cryptsetup luksAddKey /dev/hda6 /etc/keys/home.key

Add line in /etc/crypttab for encrypted /home:

crypthome /dev/hda6 /etc/keys/home.key luks

Add home entry to /etc/fstab into:

/dev/mapper/crypthome /home ext3 defaults 0 2

Update initramfs for changes in fstab and crypttab:

update-initramfs -u -k 2.6.17-10-generic

Reboot:

reboot

Now you have an encrypted root and home filesystem, the key for /home beeing read from the encrypted root filesystem.

Encryption of swap

Enrypting swap is easy, but all howtos I've seen work with a random key for swap - a little difficult for the kernel to guess ;-)
Prepare /dev/hda4, the later swap and suspend to disk device, for encryption:

cryptsetup -h sha256 -c aes-cbc-essiv:sha256 -s 256 luksFormat /dev/hda4

Map /dev/hda4 to cryptswap:

cryptsetup luksOpen /dev/hda4 cryptswap

Make a cryptswap a swap device:

mkswap /dev/mapper/cryptswap

Add line in /etc/crypttab for encrypted swap:

cryptswap /dev/hda4 none luks

Add swap entry to /etc/fstab:

/dev/mapper/cryptswap none swap sw 0 0

We need to aks for the passphrase of the swap device during boot. I was lazy, so I hardcoded the command and the partition.
Patch /usr/share/initramfs-tools/scripts/local-top/cryptroot:

--- tt/usr/share/initramfs-tools/scripts/local-top/cryptroot	2006-09-21 12:12:50.000000000 +0200
+++ cryptroot.doc	2007-01-20 19:00:09.000000000 +0100
@@ -164,6 +164,7 @@
 		/sbin/cryptgetpw < /dev/console | $cryptcreate
 	else
 		$cryptcreate < /dev/console
+		/sbin/cryptsetup luksOpen /dev/hda4 cryptswap
 	fi
 
 	FSTYPE=''

Ubuntu needs to know what's its new device for suspend to disk.
Patch /etc/acpi/hibernate.sh:

--- hibernate.sh	2006-10-15 21:30:57.000000000 +0200
+++ /etc/acpi/hibernate.sh	2007-01-07 00:03:08.000000000 +0100
@@ -29,6 +29,7 @@
 
 if [ -x /sbin/s2disk ]; then
     DEVICE="/dev/disk/by-uuid/`awk -F= '{print $3}' </etc/initramfs-tools/conf.d/resume`"
+    DEVICE="/dev/mapper/cryptswap"
     if [ -f /etc/usplash.conf ]; then
 	. /etc/usplash.conf
 	/sbin/s2disk -x "$xres" -y "$yres" $DEVICE

Ubuntu also needs to know what's its new device for resume.
Change RESUME variable in /etc/initramfs-tools/conf.d/resume:

set RESUME=/dev/mapper/cryptswap

Update initramfs:

update-initramfs -u -k 2.6.17-10-generic

Reboot:

reboot

Finished. During boot the system will ask two times for a LUKS passphrase, first for the root devcie and second for the swap device. During resuming from suspend to disk the system will also ask for the two LUKS passphrases.