cip-dev.lists.cip-project.org archive mirror
 help / color / mirror / Atom feed
* [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs
@ 2023-03-09  8:53 Quirin Gylstorff
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 1/6] KConfig: add option to encrypt data partitions Quirin Gylstorff
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Quirin Gylstorff @ 2023-03-09  8:53 UTC (permalink / raw)
  To: cip-dev, christian.storm, jan.kiszka

From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

This encrypts a partition with LUKS and uses the TPM2 to unlock the partition during
boot. 

Adapt start-qemu to support tpm2.

The implementation uses systemd-cryptenroll to add the TPM protected
passphrase to the LUKS header. systemd-cryptenroll was added with systemd version > 248.

The following table shows the support of systemd-cryptenroll in Debian
release.

| Debian version | systemd-cryptenroll suppported |
| Buster(10)     | No                             |
| Bullseye(11)   | with backports                 |
| Bookworm(12)   | yes                            |

I am currently testing a adaptation for Debian 11 (Bullseye) with 
clevis instead of systemd-cryptenroll. If clevis works I will sent a
additional patch.

Changes v2:
 - rewrite for multiple partition
 - add rencrypt for populated partitions
 - encrypt /var and /home

Changes v3:
 - remove additional partition crypt_data
 - add Readme
 - fix KConfig
 - only systemd is from backports
 - start-qemu now checks .config.yaml for TPM2 support
 - correct whitespaces

Changes v4:
 - whitespaces
 - README add requirements for systemd 248
 - Kconfig add help information
 - adapt commit message of patch 4 (add information about extra-space)

Changes v5:
 - rebase on origin/next
 - rename kas/opt/tpm.yml to kas/opt/encrypt-partitions.yml
 - Kconfig change help text and option name from IMAGE_TPM_ENCRYPTION
to IMAGE_DATA_ENCRYPTION
 

Quirin Gylstorff (6):
  KConfig: add option to encrypt data partitions
  start-qemu.sh: Create a tpm2 device
  Add initramfs hook to encrypt a partition
  overlay: add prerequisite 'encrypt_partition'
  .gitlabci: Add ci build
  Add README for encrypted partitions

 .gitlab-ci.yml                                |  13 ++
 Kconfig                                       |  10 ++
 doc/README.tpm2.encryption.md                 |  55 +++++++
 kas/opt/encrypt-partitions.yml                |   3 +-
 .../cip-core-initramfs/cip-core-initramfs.bb  |   2 +
 .../files/encrypt_partition.env.tmpl          |   2 +
 .../files/encrypt_partition.hook              |  53 +++++++
 .../files/encrypt_partition.script            | 145 ++++++++++++++++++
 .../initramfs-crypt-hook_0.1.bb               |  40 +++++
 .../initramfs-overlay-hook/files/overlay.hook |   1 +
 .../files/overlay.script.tmpl                 |  12 +-
 .../initramfs-overlay-hook_0.1.bb             |   2 +-
 start-qemu.sh                                 |  27 +++-
 wic/x86-efibootguard.wks.in                   |   5 +-
 14 files changed, 356 insertions(+), 14 deletions(-)
 create mode 100644 doc/README.tpm2.encryption.md
 create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl
 create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.hook
 create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script
 create mode 100644 recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.1.bb

-- 
2.39.2



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [cip-dev][isar-cip-core][PATCH v5 1/6] KConfig: add option to encrypt data partitions
  2023-03-09  8:53 [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Quirin Gylstorff
@ 2023-03-09  8:53 ` Quirin Gylstorff
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 2/6] start-qemu.sh: Create a tpm2 device Quirin Gylstorff
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Quirin Gylstorff @ 2023-03-09  8:53 UTC (permalink / raw)
  To: cip-dev, christian.storm, jan.kiszka

From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 Kconfig | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Kconfig b/Kconfig
index 7d72094..cafb04c 100644
--- a/Kconfig
+++ b/Kconfig
@@ -193,4 +193,14 @@ config KAS_INCLUDE_SWUPDATE_SECBOOT
 	default "kas/opt/ebg-swu.yml" if IMAGE_SWUPDATE && !IMAGE_SECURE_BOOT
 	default "kas/opt/ebg-secure-boot-snakeoil.yml" if IMAGE_SECURE_BOOT
 
+config IMAGE_DATA_ENCRYPTION
+	bool "Encrypt data partitions on first boot"
+	depends on TARGET_QEMU_AMD64
+	help
+	  This enables LUKS encryption for the partitions /var and /home.
+
+config KAS_INCLUDE_DATA_ENCRYPTION
+	string
+	default "kas/opt/encrypt-partitions.yml" if IMAGE_DATA_ENCRYPTION
+
 endif
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [cip-dev][isar-cip-core][PATCH v5 2/6] start-qemu.sh: Create a tpm2 device
  2023-03-09  8:53 [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Quirin Gylstorff
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 1/6] KConfig: add option to encrypt data partitions Quirin Gylstorff
@ 2023-03-09  8:53 ` Quirin Gylstorff
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 3/6] Add initramfs hook to encrypt a partition Quirin Gylstorff
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Quirin Gylstorff @ 2023-03-09  8:53 UTC (permalink / raw)
  To: cip-dev, christian.storm, jan.kiszka

From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

This allows testing the partition encryption with qemu.

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 start-qemu.sh | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/start-qemu.sh b/start-qemu.sh
index fcfbc5b..7436636 100755
--- a/start-qemu.sh
+++ b/start-qemu.sh
@@ -28,6 +28,9 @@ if grep -s -q "IMAGE_SECURE_BOOT: true" .config.yaml; then
 elif grep -s -q "IMAGE_SWUPDATE: true" .config.yaml; then
 	SWUPDATE_BOOT="true"
 fi
+if grep -s -q "IMAGE_TPM2_ENCRYPTION: true" .config.yaml; then
+	TPM2_ENCRYPTION="true"
+fi
 
 if [ -n "${QEMU_PATH}" ]; then
 	QEMU_PATH="${QEMU_PATH}/"
@@ -143,7 +146,21 @@ QEMU_COMMON_OPTIONS=" \
 	-m 1G \
 	-serial mon:stdio \
 	-netdev user,id=net,hostfwd=tcp:127.0.0.1:22222-:22 \
-	${QEMU_EXTRA_ARGS}"
+	"
+
+if [ "$TPM2_ENCRYPTION" = "true" ] && [ -x /usr/bin/swtpm ]; then
+	swtpm_dir="/tmp/qemu-swtpm"
+	mkdir -p "${swtpm_dir}"
+	rm "${swtpm_dir}"/*
+	if swtpm socket -d --tpmstate dir="${swtpm_dir}" \
+			 --ctrl type=unixio,path="${swtpm_dir}"/sock \
+			 --tpm2; then
+		QEMU_EXTRA_ARGS="${QEMU_EXTRA_ARGS} \
+			 -chardev socket,id=chrtpm,path=${swtpm_dir}/sock \
+			 -tpmdev emulator,id=tpm0,chardev=chrtpm \
+			 -device tpm-tis,tpmdev=tpm0"
+	fi
+fi
 
 if [ -n "${SECURE_BOOT}${SWUPDATE_BOOT}" ]; then
 	case "${arch}" in
@@ -158,14 +175,14 @@ if [ -n "${SECURE_BOOT}${SWUPDATE_BOOT}" ]; then
 					-drive if=pflash,format=raw,unit=0,readonly=on,file=${ovmf_code} \
 					-drive if=pflash,format=raw,file=${ovmf_vars} \
 					-drive file=${IMAGE_PREFIX}.wic,discard=unmap,if=none,id=disk,format=raw \
-					${QEMU_COMMON_OPTIONS} "$@"
+					${QEMU_COMMON_OPTIONS} ${QEMU_EXTRA_ARGS} "$@"
 			else
 				ovmf_code=${OVMF_CODE:-./build/tmp/deploy/images/qemu-amd64/OVMF/OVMF_CODE_4M.fd}
 
 				${QEMU_PATH}${QEMU} \
 					-drive file=${IMAGE_PREFIX}.wic,discard=unmap,if=none,id=disk,format=raw \
 					-drive if=pflash,format=raw,unit=0,readonly=on,file=${ovmf_code} \
-					${QEMU_COMMON_OPTIONS} "$@"
+					${QEMU_COMMON_OPTIONS} ${QEMU_EXTRA_ARGS} "$@"
 			fi
 			;;
 		arm64|aarch64|arm|armhf)
@@ -174,7 +191,7 @@ if [ -n "${SECURE_BOOT}${SWUPDATE_BOOT}" ]; then
 			${QEMU_PATH}${QEMU} \
 				-drive file=${IMAGE_PREFIX}.wic,discard=unmap,if=none,id=disk,format=raw \
 				-bios ${u_boot_bin} \
-				${QEMU_COMMON_OPTIONS} "$@"
+				${QEMU_COMMON_OPTIONS} ${QEMU_EXTRA_ARGS} "$@"
 			;;
 		rv64|riscv64)
 			opensbi_bin=${FIRMWARE_BIN:-./build/tmp/deploy/images/qemu-${QEMU_ARCH}/fw_payload.bin}
@@ -199,5 +216,5 @@ else
 			-drive file=${IMAGE_FILE},discard=unmap,if=none,id=disk,format=raw \
 			-kernel ${KERNEL_FILE} -append "${KERNEL_CMDLINE}" \
 			-initrd ${INITRD_FILE} \
-			${QEMU_COMMON_OPTIONS} "$@"
+			${QEMU_COMMON_OPTIONS} ${QEMU_EXTRA_ARGS} "$@"
 fi
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [cip-dev][isar-cip-core][PATCH v5 3/6] Add initramfs hook to encrypt a partition
  2023-03-09  8:53 [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Quirin Gylstorff
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 1/6] KConfig: add option to encrypt data partitions Quirin Gylstorff
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 2/6] start-qemu.sh: Create a tpm2 device Quirin Gylstorff
@ 2023-03-09  8:53 ` Quirin Gylstorff
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 4/6] overlay: add prerequisite 'encrypt_partition' Quirin Gylstorff
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Quirin Gylstorff @ 2023-03-09  8:53 UTC (permalink / raw)
  To: cip-dev, christian.storm, jan.kiszka

From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

This creates a new luks encrypted ext4 partition with a the
key stored in the tpm2.

The initial key is randomly generated and removed from the
LUKS partition. Therefore a new key cannot be added by the user
and if the LUKS header is corrupted the data is no longer readable.

Add extra-space to /var and /home as the partition size are reduced if
they are encrypted.

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 kas/opt/encrypt-partitions.yml                |   3 +-
 .../cip-core-initramfs/cip-core-initramfs.bb  |   2 +
 .../files/encrypt_partition.env.tmpl          |   2 +
 .../files/encrypt_partition.hook              |  53 +++++++
 .../files/encrypt_partition.script            | 145 ++++++++++++++++++
 .../initramfs-crypt-hook_0.1.bb               |  40 +++++
 wic/x86-efibootguard.wks.in                   |   5 +-
 7 files changed, 247 insertions(+), 3 deletions(-)
 create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl
 create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.hook
 create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script
 create mode 100644 recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.1.bb

diff --git a/kas/opt/encrypt-partitions.yml b/kas/opt/encrypt-partitions.yml
index 1f91c0c..f6baf9f 100644
--- a/kas/opt/encrypt-partitions.yml
+++ b/kas/opt/encrypt-partitions.yml
@@ -16,5 +16,6 @@ local_conf_header:
   systemd-cryptenroll: |
     DISTRO_APT_SOURCES:append:bullseye = " conf/distro/debian-bullseye-backports.list"
     DISTRO_APT_PREFERENCES:append:bullseye = " conf/distro/preferences.bullseye-backports.tpm.conf"
-
+  initramfs-option-encrypt-partitions: |
+    OVERRIDES .= ":encrypt-partitions"
 
diff --git a/recipes-initramfs/cip-core-initramfs/cip-core-initramfs.bb b/recipes-initramfs/cip-core-initramfs/cip-core-initramfs.bb
index 2935ed8..0e4cf74 100644
--- a/recipes-initramfs/cip-core-initramfs/cip-core-initramfs.bb
+++ b/recipes-initramfs/cip-core-initramfs/cip-core-initramfs.bb
@@ -14,3 +14,5 @@ inherit initramfs
 INITRAMFS_INSTALL += " \
     initramfs-overlay-hook \
     "
+
+INITRAMFS_INSTALL:append:encrypt-partitions = " initramfs-crypt-hook"
diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl
new file mode 100644
index 0000000..d04be56
--- /dev/null
+++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl
@@ -0,0 +1,2 @@
+PARTITIONS="${CRYPT_PARTITIONS}"
+CREATE_FILE_SYSTEM_CMD="${CRYPT_CREATE_FILE_SYSTEM_CMD}"
diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.hook b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.hook
new file mode 100644
index 0000000..2deee80
--- /dev/null
+++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.hook
@@ -0,0 +1,53 @@
+#!/bin/sh
+# Copyright (C) Siemens AG, 2020-2022
+#
+# SPDX-License-Identifier: MIT
+
+PREREQ=""
+
+prereqs()
+{
+     echo "$PREREQ"
+}
+
+case $1 in
+prereqs)
+     prereqs
+     exit 0
+     ;;
+esac
+
+. /usr/share/initramfs-tools/hook-functions
+
+hook_error() {
+    echo "(ERROR): $2" >&2
+    exit 1
+}
+
+manual_add_modules tpm
+manual_add_modules tpm_tis_core
+manual_add_modules tpm_tis
+manual_add_modules tpm_crb
+manual_add_modules dm_mod
+manual_add_modules dm_crypt
+
+copy_exec /usr/bin/openssl || hook_error "/usr/bin/openssl not found"
+copy_exec /usr/sbin/mke2fs || hook_error "/usr/sbin/mke2fs not found"
+copy_exec /usr/bin/grep || hook_error "/usr/bin/grep not found"
+copy_exec /usr/bin/awk || hook_error "/usr/bin/awk not found"
+copy_exec /usr/bin/expr || hook_error "/usr/bin/expr not found"
+copy_exec /usr/sbin/e2fsck || hook_error "/usr/sbin/e2fsck not found"
+copy_exec /usr/sbin/resize2fs || hook_error "/usr/sbin/resize2fs not found"
+copy_exec /usr/sbin/cryptsetup || hook_error "/usr/sbin/cryptsetup not found"
+copy_exec /usr/bin/systemd-cryptenroll || hook_error "/usr/bin/systemd-cryptenroll not found"
+copy_exec /usr/lib/systemd/systemd-cryptsetup || hook_error "/usr/lib/systemd/systemd-cryptsetup not found"
+
+if [ -x cryptsetup-reencrypt ]; then
+    copy_exec /usr/sbin/cryptsetup-reencrypt
+fi
+
+for _LIBRARY in /usr/lib/*/libtss2*; do
+    copy_exec "$_LIBRARY"
+done
+
+copy_file library /usr/share/encrypt_partition/encrypt_partition.env /usr/share/encrypt_partition/encrypt_partition.env
diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script
new file mode 100644
index 0000000..468b308
--- /dev/null
+++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script
@@ -0,0 +1,145 @@
+#!/bin/sh
+#
+# CIP Core, generic profile
+#
+# Copyright (c) Siemens AG, 2023
+#
+# Authors:
+#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+prereqs()
+{
+	# Make sure that this script is run last in local-top
+	local req
+	for req in "${0%/*}"/*; do
+		script="${req##*/}"
+		if [ "$script" != "${0##*/}" ]; then
+			printf '%s\n' "$script"
+		fi
+	done
+}
+case $1 in
+prereqs)
+	prereqs
+	exit 0
+	;;
+esac
+
+. /scripts/functions
+
+# get configuration variables
+. /usr/share/encrypt_partition/encrypt_partition.env
+
+# load necessary kernel modules:
+modprobe tpm_tis
+modprobe tpm_crb
+
+# fixed tpm device or do we need to find it
+tpm_device=/dev/tpmrm0
+partition_sets="$PARTITIONS"
+create_file_system_cmd="$CREATE_FILE_SYSTEM_CMD"
+
+if [ -z "${create_file_system_cmd}" ]; then
+	create_file_system_cmd = "mke2fs -t ext4"
+fi
+
+open_tpm2_partition() {
+	if ! /usr/lib/systemd/systemd-cryptsetup attach "$crypt_mount_name" \
+		 "$1" - tpm2-device="$tpm_device"; then
+		panic "Can't decrypt '$1' !"
+	fi
+}
+
+enroll_tpm2_token() {
+	#check systemd version and export password if necessary
+	if [ -x /usr/bin/systemd-cryptenroll ]; then
+		systemd_version=$(systemd-cryptenroll --version | \
+			  awk -F " " 'NR==1{print $2 }')
+		#check systemd version and export password if necessary
+		if [ "$systemd_version" -ge "251" ]; then
+			PASSWORD=$(cat "$2" )
+			export PASSWORD
+			/usr/bin/systemd-cryptenroll --tpm2-device="$tpm_device" \
+				 --tpm2-pcrs=7 "$1"
+			PASSWORD=
+		else
+			panic "Unknown systemd version: '$systemd_version'!"
+		fi
+	else
+		panic "systemd-cryptenroll not available cannot enroll tpm2 key!"
+	fi
+}
+
+reencrypt_existing_partition() {
+	part_device=$(readlink -f "$partition")
+	part_size_blocks=$(cat /sys/class/block/"$(awk -v dev=$part_device 'BEGIN{split(dev,a,"/"); print a[3]}' )"/size)
+	# reduce the filesystem and partition by 32M to fit the LUKS header
+	reduce_device_size=32768
+	reduced_size=$(expr $part_size_blocks - 65536 )
+	reduced_size_in_byte=$(expr $reduced_size \* 512)
+	reduced_size_in_kb=$(expr $reduced_size_in_byte / 1024)K
+	resize2fs "$1" "${reduced_size_in_kb}"
+	if [ -x cryptsetup-reencrypt ]; then
+		/usr/sbin/cryptsetup-reencrypt --new --reduce-device-size "$reduce_device_size"k $1 < $2
+	else
+		/usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-size "$reduce_device_size"k $1 < $2
+	fi
+
+}
+
+if [ ! -e "$tpm_device" ]; then
+	panic "tpm device '$tpm_device' does not exists - cannot create a encrypted device!"
+fi
+
+for partition_set in $partition_sets; do
+	partition_label=$(awk -v var=$partition_set 'BEGIN{split(var,a,":"); print a[1]}')
+	partition_mountpoint=$(awk -v var=$partition_set 'BEGIN{split(var,a,":"); print a[2]}')
+	partition_format=$(awk -v var=$partition_set 'BEGIN{split(var,a,":"); print a[3]}')
+	partition=/dev/disk/by-partlabel/$partition_label
+	crypt_mount_name="encrypted_$partition_label"
+	decrypted_part=/dev/mapper/"$crypt_mount_name"
+
+	# check if partition is already encrypted with systemd-tpm2
+	if /usr/sbin/cryptsetup luksDump --batch-mode "$partition" \
+			| grep -q "systemd-tpm2"; then
+		open_tpm2_partition "$partition"
+		if ! mount -t $(get_fstype "${decrypted_part}") "${decrypted_part}" \
+			 "${rootmnt}${partition_mountpoint}"; then
+			panic "Can't mount encrypted partition '${decrypted_part}'!"
+		fi
+		continue
+	fi
+
+	# create random password for initial encryption
+	# this will be dropped after reboot
+	tmp_key=/tmp/"$partition_label-lukskey"
+	openssl rand -base64 32 > "$tmp_key"
+
+	case "${partition_format}" in
+		"reencrypt")
+			reencrypt_existing_partition "$partition" "$tmp_key"
+			enroll_tpm2_token "$partition" "$tmp_key"
+			open_tpm2_partition "$partition"
+		;;
+		"format")
+			/usr/sbin/cryptsetup luksFormat --batch-mode \
+				 --type luks2 "$partition" < "$tmp_key"
+			enroll_tpm2_token "$partition" "$tmp_key"
+			open_tpm2_partition_tpm2_partition "$partition"
+			eval "${create_file_system_cmd} ${decrypted_part}"
+		;;
+		*)
+			panic "Unknown value ${partition_format}. Cannot create a encrypted partition !"
+		 ;;
+	esac
+
+	if ! mount -t $(get_fstype "${decrypted_part}") "${decrypted_part}" \
+		 "${rootmnt}${partition_mountpoint}"; then
+		panic "Can't mount encrypted partition '${decrypted_part}'!"
+	fi
+
+	# delete initial key
+	# afterwards no new keys can be enrolled
+	/usr/bin/systemd-cryptenroll "$partition" --wipe-slot=0
+done
diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.1.bb b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.1.bb
new file mode 100644
index 0000000..30c89a2
--- /dev/null
+++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.1.bb
@@ -0,0 +1,40 @@
+#
+# CIP Core, generic profile
+#
+# Copyright (c) Siemens AG, 2020-2022
+#
+# Authors:
+#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+
+
+inherit dpkg-raw
+
+DEBIAN_DEPENDS = "initramfs-tools, cryptsetup, systemd(>= 251), \
+    awk, openssl, libtss2-esys-3.0.2-0, libtss2-rc0, libtss2-mu0, e2fsprogs"
+
+SRC_URI += "file://encrypt_partition.hook \
+            file://encrypt_partition.script \
+            file://encrypt_partition.env.tmpl"
+
+# CRYPT_PARTITIONS elements are <partition-label>:<mountpoint>:<reencrypt or format>
+CRYPT_PARTITIONS ??= "home:/home:reencrypt var:/var:reencrypt"
+# CRYPT_CREATE_FILE_SYSTEM_CMD contains the shell command to create the filesystem
+# in a newly formatted LUKS Partition
+CRYPT_CREATE_FILE_SYSTEM_CMD ??= "mke2fs -t ext4"
+
+TEMPLATE_VARS = "CRYPT_PARTITIONS CRYPT_CREATE_FILE_SYSTEM_CMD"
+TEMPLATE_FILES = "encrypt_partition.env.tmpl"
+
+do_install[cleandirs] += " \
+    ${D}/usr/share/initramfs-tools/hooks \
+    ${D}/usr/share/encrypt_partition \
+    ${D}/usr/share/initramfs-tools/scripts/local-bottom"
+do_install() {
+    install -m 0600 "${WORKDIR}/encrypt_partition.env" "${D}/usr/share/encrypt_partition/encrypt_partition.env"
+    install -m 0755 "${WORKDIR}/encrypt_partition.script" \
+        "${D}/usr/share/initramfs-tools/scripts/local-bottom/encrypt_partition"
+    install -m 0755 "${WORKDIR}/encrypt_partition.hook" \
+        "${D}/usr/share/initramfs-tools/hooks/encrypt_partition"
+}
diff --git a/wic/x86-efibootguard.wks.in b/wic/x86-efibootguard.wks.in
index b635a8b..24b4387 100644
--- a/wic/x86-efibootguard.wks.in
+++ b/wic/x86-efibootguard.wks.in
@@ -7,7 +7,8 @@ part --source rawcopy --sourceparams "file=${IMAGE_FULLNAME}.squashfs" --align 1
 part --source empty --align 1024 --fixed-size 1G --uuid "${ABROOTFS_PART_UUID_B}"
 
 # home and var are extra partitions
-part /home --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/home --fstype=ext4 --label home --align 1024  --size 1G
-part /var --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/var --fstype=ext4 --label var --align 1024  --size 2G
+
+part /home --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/home --fstype=ext4 --label home --align 1024  --size 1G --extra-space=100M 
+part /var --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/var --fstype=ext4 --label var --align 1024  --size 2G --extra-space=100M
 
 bootloader --ptable gpt --append="console=tty0 console=ttyS0,115200 rootwait earlyprintk"
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [cip-dev][isar-cip-core][PATCH v5 4/6] overlay: add prerequisite 'encrypt_partition'
  2023-03-09  8:53 [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Quirin Gylstorff
                   ` (2 preceding siblings ...)
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 3/6] Add initramfs hook to encrypt a partition Quirin Gylstorff
@ 2023-03-09  8:53 ` Quirin Gylstorff
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 5/6] .gitlabci: Add ci build Quirin Gylstorff
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Quirin Gylstorff @ 2023-03-09  8:53 UTC (permalink / raw)
  To: cip-dev, christian.storm, jan.kiszka

From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

If /var shall be encrypted encrypt_partition needs to be executed
before the overlay script.

If the prerequisite is not available the overlay script will be executed.

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 .../initramfs-overlay-hook/files/overlay.hook        |  1 +
 .../initramfs-overlay-hook/files/overlay.script.tmpl | 12 +++++++-----
 .../initramfs-overlay-hook_0.1.bb                    |  2 +-
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/recipes-initramfs/initramfs-overlay-hook/files/overlay.hook b/recipes-initramfs/initramfs-overlay-hook/files/overlay.hook
index 5bec258..8b00ecf 100644
--- a/recipes-initramfs/initramfs-overlay-hook/files/overlay.hook
+++ b/recipes-initramfs/initramfs-overlay-hook/files/overlay.hook
@@ -23,4 +23,5 @@ esac
 . /usr/share/initramfs-tools/hook-functions
 
 manual_add_modules overlay
+copy_exec /usr/bin/mountpoint
 copy_exec /usr/bin/awk
diff --git a/recipes-initramfs/initramfs-overlay-hook/files/overlay.script.tmpl b/recipes-initramfs/initramfs-overlay-hook/files/overlay.script.tmpl
index 87ec72f..71d2599 100644
--- a/recipes-initramfs/initramfs-overlay-hook/files/overlay.script.tmpl
+++ b/recipes-initramfs/initramfs-overlay-hook/files/overlay.script.tmpl
@@ -9,7 +9,7 @@
 #  Quirin Gylstorff <quirin.gylstorff@siemens.com>
 #
 
-PREREQ=""
+PREREQ="encrypt_partition"
 
 prereqs()
 {
@@ -33,10 +33,12 @@ ovl_lower_dirs="${INITRAMFS_OVERLAY_PATHS}"
 
 root_mount_storage=${rootmnt}${ovl_storage_path}
 
-if ! mount -t $(get_fstype /dev/disk/by-label/${ovl_partition_label}) \
-	   /dev/disk/by-label/${ovl_partition_label} \
-	   ${rootmnt}/${ovl_partition_label}; then
-	panic "Can't mount /${ovl_partition_label} partition - overlay will not work!"
+if ! mountpoint -q "${rootmnt}/${ovl_partition_label}"; then
+	if ! mount -t $(get_fstype /dev/disk/by-label/${ovl_partition_label}) \
+		 /dev/disk/by-label/${ovl_partition_label} \
+		 ${rootmnt}/${ovl_partition_label}; then
+		panic "Can't mount /${ovl_partition_label} partition - overlay will not work!"
+	fi
 fi
 
 for ovl_lower_dir in ${ovl_lower_dirs}; do
diff --git a/recipes-initramfs/initramfs-overlay-hook/initramfs-overlay-hook_0.1.bb b/recipes-initramfs/initramfs-overlay-hook/initramfs-overlay-hook_0.1.bb
index 78831ba..566bd15 100644
--- a/recipes-initramfs/initramfs-overlay-hook/initramfs-overlay-hook_0.1.bb
+++ b/recipes-initramfs/initramfs-overlay-hook/initramfs-overlay-hook_0.1.bb
@@ -26,7 +26,7 @@ TEMPLATE_VARS += " INITRAMFS_OVERLAY_STORAGE_PATH \
     INITRAMFS_OVERLAY_PATHS \
     INITRAMFS_OVERLAY_STORAGE_PARTITION_LABEL"
 
-DEBIAN_DEPENDS = "initramfs-tools, awk, coreutils"
+DEBIAN_DEPENDS = "initramfs-tools, awk, coreutils, util-linux"
 
 do_install[cleandirs] += " \
     ${D}/usr/share/initramfs-tools/hooks \
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [cip-dev][isar-cip-core][PATCH v5 5/6] .gitlabci: Add ci build
  2023-03-09  8:53 [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Quirin Gylstorff
                   ` (3 preceding siblings ...)
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 4/6] overlay: add prerequisite 'encrypt_partition' Quirin Gylstorff
@ 2023-03-09  8:53 ` Quirin Gylstorff
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 6/6] Add README for encrypted partitions Quirin Gylstorff
  2023-03-13  9:37 ` [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Jan Kiszka
  6 siblings, 0 replies; 8+ messages in thread
From: Quirin Gylstorff @ 2023-03-09  8:53 UTC (permalink / raw)
  To: cip-dev, christian.storm, jan.kiszka

From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 .gitlab-ci.yml | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f51b64b..1ef13ea 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,6 +19,7 @@ variables:
   release: bullseye
   extension: none
   use_rt: enable
+  tpm: disable
   wic_targz: enable
   targz: disable
   dtb: none
@@ -55,6 +56,7 @@ default:
     - if [ "${release}" = "buster" ]; then base_yaml="${base_yaml}:kas/opt/buster.yml"; fi
     - if [ "${release}" = "bullseye" ]; then base_yaml="${base_yaml}:kas/opt/bullseye.yml"; fi
     - if [ "${release}" = "sid-ports" ]; then base_yaml="${base_yaml}:kas/opt/sid-ports.yml"; fi
+    - if [ "${tpm}" = "enable" ]; then base_yaml="${base_yaml}:kas/opt/tpm.yml"; fi
     - echo "Building ${base_yaml}"
     - kas build ${base_yaml}
     - if [ "${deploy}" = "enable" ]; then scripts/deploy-cip-core.sh ${release} ${target} ${extension} ${dtb} ${CI_COMMIT_REF_SLUG}; fi
@@ -224,6 +226,17 @@ build:qemu-amd64-secure-boot:
     wic_targz: disable
     deploy: disable
 
+build:qemu-amd64-secure-boot-tpm:
+  extends:
+    - .build_base
+  variables:
+    target: qemu-amd64
+    extension: ebg-secure-boot-snakeoil
+    use_rt: disable
+    wic_targz: disable
+    deploy: disable
+    tpm: enable
+
 build:qemu-amd64-swupdate:
   extends:
     - .build_base
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [cip-dev][isar-cip-core][PATCH v5 6/6] Add README for encrypted partitions
  2023-03-09  8:53 [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Quirin Gylstorff
                   ` (4 preceding siblings ...)
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 5/6] .gitlabci: Add ci build Quirin Gylstorff
@ 2023-03-09  8:53 ` Quirin Gylstorff
  2023-03-13  9:37 ` [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Jan Kiszka
  6 siblings, 0 replies; 8+ messages in thread
From: Quirin Gylstorff @ 2023-03-09  8:53 UTC (permalink / raw)
  To: cip-dev, christian.storm, jan.kiszka

From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 doc/README.tpm2.encryption.md | 55 +++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 doc/README.tpm2.encryption.md

diff --git a/doc/README.tpm2.encryption.md b/doc/README.tpm2.encryption.md
new file mode 100644
index 0000000..58ebb8a
--- /dev/null
+++ b/doc/README.tpm2.encryption.md
@@ -0,0 +1,55 @@
+# Encrypted Partitions
+
+By adding the recipe `initramfs-crypt-hook` to the initramfs build user defined partitions will be
+encrypted during first boot. The encrypted partition is a LUKS partition and uses a TPM to secure the
+passphrase on the device.
+
+## Requirements
+
+To enroll the keys Debian 12(bookworm) or Debian 11(bullseye) with backports is required. 
+The implementation in Debian 11 is for *demonstration purpose only* as we need backports for
+systemd >= 248. [systemd version 248](https://github.com/systemd/systemd/blob/a41ac8ac407a1a58612059a45229f0d440f58e28/NEWS#L3391) adds the necessary systemd-cryptenroll functionality.
+
+Testing with qemu-amd64 requires the package `swtpm`. Under Debian/Ubuntu this can be installed
+
+``` shell
+apt-get install swtpm
+```
+
+## TPM2 protected LUKS passphrase
+
+The recipe `initramfs-crypt-hook` uses `systemd-cryptenroll` to enroll a TPM2 protected LUKS passphrase.
+The procedure for storing a key is described in [systemd/src/shared/tpm2-util.c](https://github.com/systemd/systemd/blob/0254e4d66af7aa893b31b2326335ded5dde48b51/src/shared/tpm2-util.c#L1395).
+
+## How to build an QEMU image with TPM encryption
+An example for qemu-amd64 can be build with by selecting the option after calling:
+
+```
+./kas-container menu
+```
+or by adding using the following command line build:
+
+```
+./kas-container build kas-cip.yml:kas/board/qemu-amd64.yml:kas/opt/ebg-swu.yml:kas/opt/encrypt-partitions.yml
+```
+## initramfs-crypt-hook configuration
+
+The initramfs-crypt-hook recipe has the following variables which can be overwritten during image build:
+- CRYPT_PARTITIONS
+- CRYPT_CREATE_FILE_SYSTEM_CMD
+
+### CRYPT_PARTITIONS
+
+The variable `CRYPT_PARTITIONS` contains the information which partition shall be encrypted where to mount it.
+Each entry uses the schema `<partition-label>:<mountpoint>:<reencrypt or format>`.
+- The `partition-label` is used to identify the partition on the disk
+- The `mountpoint` is used mount the decrypted partition in the root file system
+- `reencrypt` uses `cryptsetup reencrypt` to encrypt the exiting content of the partition. This reduces the partition by 32MB and the file system by a similar amount
+- `format` creates a empty LUKS partition and creates a file system defined with the shell command given in `CRYPT_CREATE_FILE_SYSTEM_CMD`
+
+### CRYPT_CREATE_FILE_SYSTEM_CMD
+
+The variable `CRYPT_CREATE_FILE_SYSTEM_CMD` contains the command to create a new file system on a newly
+encrypted partition. The Default (`mke2fs -t ext4`) creates an ext4 partition.
+
+
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs
  2023-03-09  8:53 [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Quirin Gylstorff
                   ` (5 preceding siblings ...)
  2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 6/6] Add README for encrypted partitions Quirin Gylstorff
@ 2023-03-13  9:37 ` Jan Kiszka
  6 siblings, 0 replies; 8+ messages in thread
From: Jan Kiszka @ 2023-03-13  9:37 UTC (permalink / raw)
  To: Quirin Gylstorff, cip-dev, christian.storm

On 09.03.23 09:53, Quirin Gylstorff wrote:
> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> 
> This encrypts a partition with LUKS and uses the TPM2 to unlock the partition during
> boot. 
> 
> Adapt start-qemu to support tpm2.
> 
> The implementation uses systemd-cryptenroll to add the TPM protected
> passphrase to the LUKS header. systemd-cryptenroll was added with systemd version > 248.
> 
> The following table shows the support of systemd-cryptenroll in Debian
> release.
> 
> | Debian version | systemd-cryptenroll suppported |
> | Buster(10)     | No                             |
> | Bullseye(11)   | with backports                 |
> | Bookworm(12)   | yes                            |
> 
> I am currently testing a adaptation for Debian 11 (Bullseye) with 
> clevis instead of systemd-cryptenroll. If clevis works I will sent a
> additional patch.
> 
> Changes v2:
>  - rewrite for multiple partition
>  - add rencrypt for populated partitions
>  - encrypt /var and /home
> 
> Changes v3:
>  - remove additional partition crypt_data
>  - add Readme
>  - fix KConfig
>  - only systemd is from backports
>  - start-qemu now checks .config.yaml for TPM2 support
>  - correct whitespaces
> 
> Changes v4:
>  - whitespaces
>  - README add requirements for systemd 248
>  - Kconfig add help information
>  - adapt commit message of patch 4 (add information about extra-space)
> 
> Changes v5:
>  - rebase on origin/next
>  - rename kas/opt/tpm.yml to kas/opt/encrypt-partitions.yml
>  - Kconfig change help text and option name from IMAGE_TPM_ENCRYPTION
> to IMAGE_DATA_ENCRYPTION
>  
> 
> Quirin Gylstorff (6):
>   KConfig: add option to encrypt data partitions
>   start-qemu.sh: Create a tpm2 device
>   Add initramfs hook to encrypt a partition
>   overlay: add prerequisite 'encrypt_partition'
>   .gitlabci: Add ci build
>   Add README for encrypted partitions
> 
>  .gitlab-ci.yml                                |  13 ++
>  Kconfig                                       |  10 ++
>  doc/README.tpm2.encryption.md                 |  55 +++++++
>  kas/opt/encrypt-partitions.yml                |   3 +-
>  .../cip-core-initramfs/cip-core-initramfs.bb  |   2 +
>  .../files/encrypt_partition.env.tmpl          |   2 +
>  .../files/encrypt_partition.hook              |  53 +++++++
>  .../files/encrypt_partition.script            | 145 ++++++++++++++++++
>  .../initramfs-crypt-hook_0.1.bb               |  40 +++++
>  .../initramfs-overlay-hook/files/overlay.hook |   1 +
>  .../files/overlay.script.tmpl                 |  12 +-
>  .../initramfs-overlay-hook_0.1.bb             |   2 +-
>  start-qemu.sh                                 |  27 +++-
>  wic/x86-efibootguard.wks.in                   |   5 +-
>  14 files changed, 356 insertions(+), 14 deletions(-)
>  create mode 100644 doc/README.tpm2.encryption.md
>  create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl
>  create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.hook
>  create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script
>  create mode 100644 recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.1.bb
> 

Thanks, merged to next with some massaging.

I'm still open to resolve the backports issue with an alternative before
the release if there is a working solution.

Jan

-- 
Siemens AG, Technology
Competence Center Embedded Linux



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-03-13  9:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-09  8:53 [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Quirin Gylstorff
2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 1/6] KConfig: add option to encrypt data partitions Quirin Gylstorff
2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 2/6] start-qemu.sh: Create a tpm2 device Quirin Gylstorff
2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 3/6] Add initramfs hook to encrypt a partition Quirin Gylstorff
2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 4/6] overlay: add prerequisite 'encrypt_partition' Quirin Gylstorff
2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 5/6] .gitlabci: Add ci build Quirin Gylstorff
2023-03-09  8:53 ` [cip-dev][isar-cip-core][PATCH v5 6/6] Add README for encrypted partitions Quirin Gylstorff
2023-03-13  9:37 ` [cip-dev][isar-cip-core][PATCH v5 0/6] Encrypt Partition in initramfs Jan Kiszka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).