diff mbox series

[isar-cip-core,RFC] initramfs-crypt-hook: Add clevis for buster and bullseye

Message ID 20230315110338.379064-1-Quirin.Gylstorff@siemens.com (mailing list archive)
State Superseded
Headers show
Series [isar-cip-core,RFC] initramfs-crypt-hook: Add clevis for buster and bullseye | expand

Commit Message

Quirin Gylstorff March 15, 2023, 11:03 a.m. UTC
From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

This will remove the requirement to use bullseye backports.

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 .../preferences.bullseye-backports.tpm.conf   |   8 -
 doc/README.tpm2.encryption.md                 |   7 +-
 kas/opt/encrypt-partitions.yml                |   3 -
 .../files/encrypt_partition.clevis.hook       |  79 ++++++++++
 .../files/encrypt_partition.clevis.script     | 138 ++++++++++++++++++
 ...on.hook => encrypt_partition.systemd.hook} |   0
 ...cript => encrypt_partition.systemd.script} |   0
 .../initramfs-crypt-hook/files/pwquality.conf |   1 +
 .../initramfs-crypt-hook_0.1.bb               |  30 +++-
 9 files changed, 242 insertions(+), 24 deletions(-)
 delete mode 100644 conf/distro/preferences.bullseye-backports.tpm.conf
 create mode 100755 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.hook
 create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.script
 rename recipes-initramfs/initramfs-crypt-hook/files/{encrypt_partition.hook => encrypt_partition.systemd.hook} (100%)
 mode change 100644 => 100755
 rename recipes-initramfs/initramfs-crypt-hook/files/{encrypt_partition.script => encrypt_partition.systemd.script} (100%)
 create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/pwquality.conf

Comments

Jan Kiszka March 16, 2023, 5:51 p.m. UTC | #1
On 15.03.23 12:03, Quirin Gylstorff wrote:
> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> 
> This will remove the requirement to use bullseye backports.
> 
> Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> ---
>  .../preferences.bullseye-backports.tpm.conf   |   8 -
>  doc/README.tpm2.encryption.md                 |   7 +-
>  kas/opt/encrypt-partitions.yml                |   3 -
>  .../files/encrypt_partition.clevis.hook       |  79 ++++++++++
>  .../files/encrypt_partition.clevis.script     | 138 ++++++++++++++++++
>  ...on.hook => encrypt_partition.systemd.hook} |   0
>  ...cript => encrypt_partition.systemd.script} |   0
>  .../initramfs-crypt-hook/files/pwquality.conf |   1 +
>  .../initramfs-crypt-hook_0.1.bb               |  30 +++-
>  9 files changed, 242 insertions(+), 24 deletions(-)
>  delete mode 100644 conf/distro/preferences.bullseye-backports.tpm.conf
>  create mode 100755 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.hook
>  create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.script
>  rename recipes-initramfs/initramfs-crypt-hook/files/{encrypt_partition.hook => encrypt_partition.systemd.hook} (100%)
>  mode change 100644 => 100755
>  rename recipes-initramfs/initramfs-crypt-hook/files/{encrypt_partition.script => encrypt_partition.systemd.script} (100%)
>  create mode 100644 recipes-initramfs/initramfs-crypt-hook/files/pwquality.conf
> 
> diff --git a/conf/distro/preferences.bullseye-backports.tpm.conf b/conf/distro/preferences.bullseye-backports.tpm.conf
> deleted file mode 100644
> index 60c4265..0000000
> --- a/conf/distro/preferences.bullseye-backports.tpm.conf
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -Package: *
> -Pin: release n=bullseye-backports
> -Pin-Priority: -1
> -
> -Explanation: Use systemd and its dependencies from debian-backports to support systemd-cryptenroll
> -Package: libnss-myhostname libnss-mymachines libnss-resolve libnss-systemd libpam-systemd libudev* libsystemd* systemd systemd-* udev
> -Pin: release n=bullseye-backports
> -Pin-Priority: 801
> diff --git a/doc/README.tpm2.encryption.md b/doc/README.tpm2.encryption.md
> index 7914bf3..ef03596 100644
> --- a/doc/README.tpm2.encryption.md
> +++ b/doc/README.tpm2.encryption.md
> @@ -6,10 +6,6 @@ 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
> @@ -18,7 +14,8 @@ apt-get install swtpm
>  
>  ## TPM2 protected LUKS passphrase
>  
> -The recipe `initramfs-crypt-hook` uses `systemd-cryptenroll` to enroll a TPM2 protected LUKS passphrase.
> +The recipe `initramfs-crypt-hook` uses `systemd-cryptenroll`(Debian 12(bookworm) and later) 

The trailing whitespace could be used in "`systemd-cryptenroll`(Debian". ;)

> +or `clevis`(Debian 10 and Debian 11)to enroll a TPM2 protected LUKS passphrase.

But here we need buy two extra whitespaces, before and after the brackets.

>  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
> diff --git a/kas/opt/encrypt-partitions.yml b/kas/opt/encrypt-partitions.yml
> index 418e753..2fe38f8 100644
> --- a/kas/opt/encrypt-partitions.yml
> +++ b/kas/opt/encrypt-partitions.yml
> @@ -13,8 +13,5 @@ header:
>    version: 12
>  
>  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/initramfs-crypt-hook/files/encrypt_partition.clevis.hook b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.hook
> new file mode 100755
> index 0000000..8adcd8b
> --- /dev/null
> +++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.hook
> @@ -0,0 +1,79 @@
> +#!/bin/sh
> +# Copyright (C) Siemens AG, 2020-2022
> +#
> +# SPDX-License-Identifier: MIT
> +
> +PREREQ=""
> +set -x
> +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/clevis || hook_error "/usr/bin/clevis not found"
> +copy_exec /usr/bin/clevis-decrypt || hook_error "/usr/bin/clevis-decrypt not found"
> +copy_exec /usr/bin/clevis-encrypt-tpm2 || hook_error "/usr/bin/clevis-encrypt-tpm2 not found"
> +copy_exec /usr/bin/clevis-decrypt-tpm2 || hook_error "/usr/bin/clevis-decrypt-tpm2 not found"
> +copy_exec /usr/bin/clevis-luks-bind || hook_error "/usr/bin/clevis-luks-bind not found"
> +copy_exec /usr/bin/clevis-luks-unlock || hook_error "/usr/bin/clevis-luks-unlock not found"
> +copy_exec /usr/bin/clevis-luks-list || hook_error "/usr/bin/clevis-luks-list not found"
> +copy_exec /usr/bin/clevis-luks-common-functions || hook_error "/usr/bin/clevis-luks-common-functions not found"
> +copy_exec /usr/bin/tpm2_createprimary || hook_error "Unable to copy /usr/bin/tpm2_createprimary" 
> +copy_exec /usr/bin/tpm2_unseal || hook_error "Unable to copy /usr/bin/tpm2_unseal"
> +copy_exec /usr/bin/tpm2_create || hook_error "Unable to copy /usr/bin/tpm2_create"
> +copy_exec /usr/bin/tpm2_load || hook_error "Unable to copy /usr/bin/tpm2_load"
> +copy_exec /usr/bin/tpm2_pcrread || hook_error "Unable to copy /usr/bin/tpm2_pcrread"
> +copy_exec /usr/bin/tpm2_createpolicy || hook_error "Unable to copy /usr/bin/tpm2_createpolicy"
> +copy_exec /usr/bin/tpm2_flushcontext || hook_error "Unable to copy /usr/bin/tpm2_flushcontext"
> +copy_exec /usr/bin/bash || hook_error "Unable to copy /usr/bin/bash"
> +copy_exec /usr/bin/luksmeta || hook_error "Unable to copy /usr/bin/luksmeta"
> +copy_exec /usr/bin/jose || hook_error "Unable to copy /usr/bin/jose"
> +copy_exec /usr/bin/sed || hook_error "Unable to copy /usr/bin/sed"
> +copy_exec /usr/bin/tail || hook_error "Unable to copy /usr/bin/tail"
> +copy_exec /usr/bin/sort || hook_error "Unable to copy /usr/bin/sort"
> +copy_exec /usr/bin/rm || hook_error "Unable to copy /usr/bin/rm"
> +copy_exec /usr/bin/mktemp || hook_error "Unable to copy /usr/bin/mktemp"
> +copy_exec /usr/bin/basename || hook_error "Unable to copy /usr/bin/basename"
> +copy_exec /usr/bin/seq || hook_error "Unable to copy /usr/bin/seq"
> +copy_exec /usr/bin/pwmake || hook_error "Unable to copy /usr/bin/pwmake"
> +copy_exec /usr/bin/file || hook_error "Unable to copy /usr/bin/file "
> +
> +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
> +copy_file pwmake-config /usr/share/encrypt_partition/pwquality.conf /etc/security/pwquality.conf
> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.script b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.script
> new file mode 100644
> index 0000000..37bb024
> --- /dev/null
> +++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.script
> @@ -0,0 +1,138 @@
> +#!/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/bin/clevis luks unlock -n "$crypt_mount_name" \
> +		 -d "$1"; then
> +		panic "Can't decrypt '$1' !"
> +	fi
> +}
> +
> +enroll_tpm2_token() {
> +	if [ -x /usr/bin/clevis ]; then
> +		 clevis luks bind -d "$1" tpm2 '{"pcr_ids":"7"}' < "$2"
> +	else
> +		panic "clevis not available cannot enroll tpm2 key!"
> +	fi
> +}
> +
> +reencrypt_existing_partition() {
> +	part_size_blocks="$(cat /sys/class/block/"$(awk -v dev="$1" '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
> +
> +# clevis needs /dev/fd create it in the initramfs
> +if [ ! -e /dev/fd ]; then
> +	ln -s /proc/self/fd /dev/fd
> +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"
> +	# clevis does not work with links in /dev/disk*
> +	part_device=$(readlink -f "$partition")
> +
> +	if /usr/sbin/cryptsetup luksDump --batch-mode "$partition" \
> +			| grep -q "clevis"; then
> +		open_tpm2_partition "$part_device"
> +		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 "$part_device" "$tmp_key"
> +			enroll_tpm2_token "$part_device" "$tmp_key"
> +			open_tpm2_partition "$part_device"
> +		;;
> +		"format")
> +			/usr/sbin/cryptsetup luksFormat --batch-mode \
> +				 --type luks2 "$partition" < "$tmp_key"
> +			enroll_tpm2_token "$part_device" "$tmp_key"
> +			open_tpm2_partition_tpm2_partition "$part_device"
> +			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
> +	cryptsetup -v luksKillSlot -q  "$part_device" 0
> +done
> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.hook b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.systemd.hook
> old mode 100644
> new mode 100755
> similarity index 100%
> rename from recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.hook
> rename to recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.systemd.hook
> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.systemd.script
> similarity index 100%
> rename from recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script
> rename to recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.systemd.script
> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/pwquality.conf b/recipes-initramfs/initramfs-crypt-hook/files/pwquality.conf
> new file mode 100644
> index 0000000..0d8afa5
> --- /dev/null
> +++ b/recipes-initramfs/initramfs-crypt-hook/files/pwquality.conf
> @@ -0,0 +1 @@
> +dictcheck = 0
> 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
> index c5b2268..ae6916a 100644
> --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.1.bb
> +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.1.bb
> @@ -9,13 +9,25 @@
>  # SPDX-License-Identifier: MIT
>  
>  inherit dpkg-raw
> -
> -DEBIAN_DEPENDS = "initramfs-tools, cryptsetup, systemd(>= 251), \
> +DEBIAN_DEPENDS = "initramfs-tools, cryptsetup,  \
>      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"
> +CLEVIS_DEPEND = ", clevis-tpm2, clevis-luks, jose, bash, luksmeta, file, libpwquality-tools, libpwquality-common"

clevis-luks depends on luksmeta. libpwquality-common is pulled by
libpwquality1, and that is a dependency of libpwquality-tools.

> +
> +DEBIAN_DEPENDS:append:buster = "${CLEVIS_DEPEND}"
> +DEBIAN_DEPENDS:append:bullseye = "${CLEVIS_DEPEND}"
> +DEBIAN_DEPENDS:append:bookworm = ", systemd (>= 251)" 
> +DEBIAN_DEPENDS:append:sid = ", systemd (>= 251)" 

This can't be modeled with Debian dependency logic ("|"), can it? Or
could we simply do

"systemd (>= 251) | clevis-tpm2" by default and conditionally append the
rest of CLEVIS_DEPEND for buster and bullseye?

> +
> +CRYPT_BACKEND:buster = "clevis"
> +CRYPT_BACKEND:bullseye = "clevis"
> +CRYPT_BACKEND:bookworm = "systemd"
> +CRYPT_BACKEND:sid = "systemd"

As you are not appending:

CRYPT_BACKEND = "systemd"

should be enough as default (sid, bookworm, future).

> +
> +SRC_URI += "file://encrypt_partition.env.tmpl \
> +            file://encrypt_partition.${CRYPT_BACKEND}.script \
> +            file://encrypt_partition.${CRYPT_BACKEND}.hook \
> +            file://pwquality.conf"
>  
>  # CRYPT_PARTITIONS elements are <partition-label>:<mountpoint>:<reencrypt or format>
>  CRYPT_PARTITIONS ??= "home:/home:reencrypt var:/var:reencrypt"
> @@ -29,11 +41,13 @@ 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"
> +    ${D}/usr/share/initramfs-tools/scripts/local-bottom \
> +    ${D}/usr/lib/encrypt_partition"
>  do_install() {
>      install -m 0600 "${WORKDIR}/encrypt_partition.env" "${D}/usr/share/encrypt_partition/encrypt_partition.env"
> -    install -m 0755 "${WORKDIR}/encrypt_partition.script" \
> +    install -m 0755 "${WORKDIR}/encrypt_partition.${CRYPT_BACKEND}.script" \
>          "${D}/usr/share/initramfs-tools/scripts/local-bottom/encrypt_partition"
> -    install -m 0755 "${WORKDIR}/encrypt_partition.hook" \
> +    install -m 0755 "${WORKDIR}/encrypt_partition.${CRYPT_BACKEND}.hook" \
>          "${D}/usr/share/initramfs-tools/hooks/encrypt_partition"
> +    install -m 0644 "${WORKDIR}/pwquality.conf" "${D}/usr/share/encrypt_partition/pwquality.conf"
>  }

Thanks,
Jan
diff mbox series

Patch

diff --git a/conf/distro/preferences.bullseye-backports.tpm.conf b/conf/distro/preferences.bullseye-backports.tpm.conf
deleted file mode 100644
index 60c4265..0000000
--- a/conf/distro/preferences.bullseye-backports.tpm.conf
+++ /dev/null
@@ -1,8 +0,0 @@ 
-Package: *
-Pin: release n=bullseye-backports
-Pin-Priority: -1
-
-Explanation: Use systemd and its dependencies from debian-backports to support systemd-cryptenroll
-Package: libnss-myhostname libnss-mymachines libnss-resolve libnss-systemd libpam-systemd libudev* libsystemd* systemd systemd-* udev
-Pin: release n=bullseye-backports
-Pin-Priority: 801
diff --git a/doc/README.tpm2.encryption.md b/doc/README.tpm2.encryption.md
index 7914bf3..ef03596 100644
--- a/doc/README.tpm2.encryption.md
+++ b/doc/README.tpm2.encryption.md
@@ -6,10 +6,6 @@  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
@@ -18,7 +14,8 @@  apt-get install swtpm
 
 ## TPM2 protected LUKS passphrase
 
-The recipe `initramfs-crypt-hook` uses `systemd-cryptenroll` to enroll a TPM2 protected LUKS passphrase.
+The recipe `initramfs-crypt-hook` uses `systemd-cryptenroll`(Debian 12(bookworm) and later) 
+or `clevis`(Debian 10 and Debian 11)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
diff --git a/kas/opt/encrypt-partitions.yml b/kas/opt/encrypt-partitions.yml
index 418e753..2fe38f8 100644
--- a/kas/opt/encrypt-partitions.yml
+++ b/kas/opt/encrypt-partitions.yml
@@ -13,8 +13,5 @@  header:
   version: 12
 
 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/initramfs-crypt-hook/files/encrypt_partition.clevis.hook b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.hook
new file mode 100755
index 0000000..8adcd8b
--- /dev/null
+++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.hook
@@ -0,0 +1,79 @@ 
+#!/bin/sh
+# Copyright (C) Siemens AG, 2020-2022
+#
+# SPDX-License-Identifier: MIT
+
+PREREQ=""
+set -x
+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/clevis || hook_error "/usr/bin/clevis not found"
+copy_exec /usr/bin/clevis-decrypt || hook_error "/usr/bin/clevis-decrypt not found"
+copy_exec /usr/bin/clevis-encrypt-tpm2 || hook_error "/usr/bin/clevis-encrypt-tpm2 not found"
+copy_exec /usr/bin/clevis-decrypt-tpm2 || hook_error "/usr/bin/clevis-decrypt-tpm2 not found"
+copy_exec /usr/bin/clevis-luks-bind || hook_error "/usr/bin/clevis-luks-bind not found"
+copy_exec /usr/bin/clevis-luks-unlock || hook_error "/usr/bin/clevis-luks-unlock not found"
+copy_exec /usr/bin/clevis-luks-list || hook_error "/usr/bin/clevis-luks-list not found"
+copy_exec /usr/bin/clevis-luks-common-functions || hook_error "/usr/bin/clevis-luks-common-functions not found"
+copy_exec /usr/bin/tpm2_createprimary || hook_error "Unable to copy /usr/bin/tpm2_createprimary" 
+copy_exec /usr/bin/tpm2_unseal || hook_error "Unable to copy /usr/bin/tpm2_unseal"
+copy_exec /usr/bin/tpm2_create || hook_error "Unable to copy /usr/bin/tpm2_create"
+copy_exec /usr/bin/tpm2_load || hook_error "Unable to copy /usr/bin/tpm2_load"
+copy_exec /usr/bin/tpm2_pcrread || hook_error "Unable to copy /usr/bin/tpm2_pcrread"
+copy_exec /usr/bin/tpm2_createpolicy || hook_error "Unable to copy /usr/bin/tpm2_createpolicy"
+copy_exec /usr/bin/tpm2_flushcontext || hook_error "Unable to copy /usr/bin/tpm2_flushcontext"
+copy_exec /usr/bin/bash || hook_error "Unable to copy /usr/bin/bash"
+copy_exec /usr/bin/luksmeta || hook_error "Unable to copy /usr/bin/luksmeta"
+copy_exec /usr/bin/jose || hook_error "Unable to copy /usr/bin/jose"
+copy_exec /usr/bin/sed || hook_error "Unable to copy /usr/bin/sed"
+copy_exec /usr/bin/tail || hook_error "Unable to copy /usr/bin/tail"
+copy_exec /usr/bin/sort || hook_error "Unable to copy /usr/bin/sort"
+copy_exec /usr/bin/rm || hook_error "Unable to copy /usr/bin/rm"
+copy_exec /usr/bin/mktemp || hook_error "Unable to copy /usr/bin/mktemp"
+copy_exec /usr/bin/basename || hook_error "Unable to copy /usr/bin/basename"
+copy_exec /usr/bin/seq || hook_error "Unable to copy /usr/bin/seq"
+copy_exec /usr/bin/pwmake || hook_error "Unable to copy /usr/bin/pwmake"
+copy_exec /usr/bin/file || hook_error "Unable to copy /usr/bin/file "
+
+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
+copy_file pwmake-config /usr/share/encrypt_partition/pwquality.conf /etc/security/pwquality.conf
diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.script b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.script
new file mode 100644
index 0000000..37bb024
--- /dev/null
+++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.clevis.script
@@ -0,0 +1,138 @@ 
+#!/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/bin/clevis luks unlock -n "$crypt_mount_name" \
+		 -d "$1"; then
+		panic "Can't decrypt '$1' !"
+	fi
+}
+
+enroll_tpm2_token() {
+	if [ -x /usr/bin/clevis ]; then
+		 clevis luks bind -d "$1" tpm2 '{"pcr_ids":"7"}' < "$2"
+	else
+		panic "clevis not available cannot enroll tpm2 key!"
+	fi
+}
+
+reencrypt_existing_partition() {
+	part_size_blocks="$(cat /sys/class/block/"$(awk -v dev="$1" '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
+
+# clevis needs /dev/fd create it in the initramfs
+if [ ! -e /dev/fd ]; then
+	ln -s /proc/self/fd /dev/fd
+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"
+	# clevis does not work with links in /dev/disk*
+	part_device=$(readlink -f "$partition")
+
+	if /usr/sbin/cryptsetup luksDump --batch-mode "$partition" \
+			| grep -q "clevis"; then
+		open_tpm2_partition "$part_device"
+		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 "$part_device" "$tmp_key"
+			enroll_tpm2_token "$part_device" "$tmp_key"
+			open_tpm2_partition "$part_device"
+		;;
+		"format")
+			/usr/sbin/cryptsetup luksFormat --batch-mode \
+				 --type luks2 "$partition" < "$tmp_key"
+			enroll_tpm2_token "$part_device" "$tmp_key"
+			open_tpm2_partition_tpm2_partition "$part_device"
+			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
+	cryptsetup -v luksKillSlot -q  "$part_device" 0
+done
diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.hook b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.systemd.hook
old mode 100644
new mode 100755
similarity index 100%
rename from recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.hook
rename to recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.systemd.hook
diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.systemd.script
similarity index 100%
rename from recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script
rename to recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.systemd.script
diff --git a/recipes-initramfs/initramfs-crypt-hook/files/pwquality.conf b/recipes-initramfs/initramfs-crypt-hook/files/pwquality.conf
new file mode 100644
index 0000000..0d8afa5
--- /dev/null
+++ b/recipes-initramfs/initramfs-crypt-hook/files/pwquality.conf
@@ -0,0 +1 @@ 
+dictcheck = 0
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
index c5b2268..ae6916a 100644
--- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.1.bb
+++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.1.bb
@@ -9,13 +9,25 @@ 
 # SPDX-License-Identifier: MIT
 
 inherit dpkg-raw
-
-DEBIAN_DEPENDS = "initramfs-tools, cryptsetup, systemd(>= 251), \
+DEBIAN_DEPENDS = "initramfs-tools, cryptsetup,  \
     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"
+CLEVIS_DEPEND = ", clevis-tpm2, clevis-luks, jose, bash, luksmeta, file, libpwquality-tools, libpwquality-common"
+
+DEBIAN_DEPENDS:append:buster = "${CLEVIS_DEPEND}"
+DEBIAN_DEPENDS:append:bullseye = "${CLEVIS_DEPEND}"
+DEBIAN_DEPENDS:append:bookworm = ", systemd (>= 251)" 
+DEBIAN_DEPENDS:append:sid = ", systemd (>= 251)" 
+
+CRYPT_BACKEND:buster = "clevis"
+CRYPT_BACKEND:bullseye = "clevis"
+CRYPT_BACKEND:bookworm = "systemd"
+CRYPT_BACKEND:sid = "systemd"
+
+SRC_URI += "file://encrypt_partition.env.tmpl \
+            file://encrypt_partition.${CRYPT_BACKEND}.script \
+            file://encrypt_partition.${CRYPT_BACKEND}.hook \
+            file://pwquality.conf"
 
 # CRYPT_PARTITIONS elements are <partition-label>:<mountpoint>:<reencrypt or format>
 CRYPT_PARTITIONS ??= "home:/home:reencrypt var:/var:reencrypt"
@@ -29,11 +41,13 @@  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"
+    ${D}/usr/share/initramfs-tools/scripts/local-bottom \
+    ${D}/usr/lib/encrypt_partition"
 do_install() {
     install -m 0600 "${WORKDIR}/encrypt_partition.env" "${D}/usr/share/encrypt_partition/encrypt_partition.env"
-    install -m 0755 "${WORKDIR}/encrypt_partition.script" \
+    install -m 0755 "${WORKDIR}/encrypt_partition.${CRYPT_BACKEND}.script" \
         "${D}/usr/share/initramfs-tools/scripts/local-bottom/encrypt_partition"
-    install -m 0755 "${WORKDIR}/encrypt_partition.hook" \
+    install -m 0755 "${WORKDIR}/encrypt_partition.${CRYPT_BACKEND}.hook" \
         "${D}/usr/share/initramfs-tools/hooks/encrypt_partition"
+    install -m 0644 "${WORKDIR}/pwquality.conf" "${D}/usr/share/encrypt_partition/pwquality.conf"
 }