@@ -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"
@@ -14,3 +14,5 @@ inherit initramfs
INITRAMFS_INSTALL += " \
initramfs-overlay-hook \
"
+
+INITRAMFS_INSTALL:append:encrypt-partitions = " initramfs-crypt-hook"
new file mode 100644
@@ -0,0 +1,2 @@
+PARTITIONS="${CRYPT_PARTITIONS}"
+CREATE_FILE_SYSTEM_CMD="${CRYPT_CREATE_FILE_SYSTEM_CMD}"
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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"
+}
@@ -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"