Subject: [PATCH v3] Support encrypted root in setup-disk

From: Drew DeVault <[email-masked]>
Date: Wed, 8 Jan 2020 12:49:32 -0500

---
 setup-disk.in | 44 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/setup-disk.in b/setup-disk.in
index 5eb8638..955d771 100644
--- a/setup-disk.in
+++ b/setup-disk.in
@@ -402,6 +402,9 @@ install_mounted_root() {
 		esac
 	done
 
+	if [ "$USE_CRYPT" ]; then
+		initfs_features="${initfs_features% cryptsetup} cryptsetup"
+	fi
 
 	if [ -n "$VERBOSE" ]; then
 		echo "Root device:     $rootdev"
@@ -442,6 +445,11 @@ install_mounted_root() {
 	if [ -n "$(get_bootopt nomodeset)" ]; then
 		kernel_opts="nomodeset $kernel_opts"
 	fi
+	if [ "$USE_CRYPT" ]; then
+		root=$(cryptsetup status "$rootdev" | awk '/device:/ { print $2 }')
+		kernel_opts="cryptroot=$root cryptdm=root"
+		root=/dev/mapper/root
+	fi
 	modules="sd-mod,usb-storage,${root_fs}${raidmod}"
 
 	# generate the fstab
@@ -503,6 +511,10 @@ unmount_partitions() {
 
 	# unmount the partitions
 	umount $(awk '{print $2}' /proc/mounts | egrep "^$mnt(/|\$)" | sort -r)
+
+	if [ "$USE_CRYPT" ]; then
+		cryptsetup close /dev/mapper/root
+	fi
 }
 
 # figure out decent default swap size in mega bytes
@@ -994,6 +1006,18 @@ native_disk_install_lvm() {
 	setup_root $root_dev $BOOT_DEV
 }
 
+setup_crypt() {
+	mkdir -p /run/cryptsetup
+	echo "Preparing root partition for encryption." >&2
+	echo "You will be prompted for your password at boot." >&2
+	echo "If you forget your password, your data will be lost." >&2
+	cryptsetup luksFormat --type luks2 "$1" >&2
+	echo "Enter password again to unlock disk for installation." >&2
+	cryptsetup open "$1" root >&2
+	cryptroot="$1"
+	echo "/dev/mapper/root"
+}
+
 native_disk_install() {
 	local prep_part_type=$(partition_id prep)
 	local root_part_type=$(partition_id linux)
@@ -1065,6 +1089,10 @@ native_disk_install() {
 		root_dev=$(find_nth_non_boot_parts $index "$root_part_type" $@)
 	fi
 
+	if [ "$USE_CRYPT" ]; then
+		root_dev=$(setup_crypt $root_dev)
+	fi
+
 	[ $SWAP_SIZE -gt 0 ] && setup_swap_dev $swap_dev
 	setup_root $root_dev $BOOT_DEV $@
 }
@@ -1143,7 +1171,7 @@ ask_disk() {
 
 usage() {
 	cat <<-__EOF__
-		usage: setup-disk [-hLqrv] [-k kernelflavor] [-m MODE] [-o apkovl] [-s SWAPSIZE]
+		usage: setup-disk [-hLqrve] [-k kernelflavor] [-m MODE] [-o apkovl] [-s SWAPSIZE]
 		                  [MOUNTPOINT | DISKDEV...]
 
 		Install alpine on harddisk.
@@ -1157,6 +1185,7 @@ usage() {
 
 		options:
 		 -h  Show this help
+		 -e  Encrypt disk
 		 -m  Use disk for MODE without asking, where MODE is either 'data' or 'sys'
 		 -o  Restore system from given apkovl file
 		 -k  Use kernelflavor instead of $KERNEL_FLAVOR
@@ -1193,11 +1222,13 @@ case $kver in
 	*) KERNEL_FLAVOR=vanilla;;
 esac
 
+USE_CRYPT=
 DISK_MODE=
 USE_LVM=
 # Parse args
-while getopts "hk:Lm:o:qrs:v" opt; do
+while getopts "hek:Lm:o:qrs:v" opt; do
 	case $opt in
+		e) USE_CRYPT=1;;
 		m) DISK_MODE="$OPTARG";;
 		k) KERNEL_FLAVOR="$OPTARG";;
 		L) USE_LVM="_lvm";;
@@ -1290,6 +1321,15 @@ if [ -n "$diskdevs" ] && [ -z "$DISK_MODE" ]; then
 		esac
 	done
 	DISK_MODE="$answer"
+	# TODO: support encryption for more installation types
+	if [ -z "$USE_CRYPT" ] && [ "$DISK_MODE" = "sys" ] && [ -z "$USE_LVM" ]; then
+		echon "Would you like to encrypt $it_them? [y/N] "
+		default_read answer '?'
+		if yesno "$answer"
+		then
+			USE_CRYPT=1
+		fi
+	fi
 fi
 
 if [ -z "$SWAP_SIZE" ]; then
-- 
2.24.1