public inbox for cip-dev@lists.cip-project.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] initramfs-crypt-hook patch
@ 2025-03-04 13:07 Claudius Heine
  2025-03-04 13:07 ` [PATCH v3 1/4] initramfs-crypt-hook: make sure that mount path exists Claudius Heine
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Claudius Heine @ 2025-03-04 13:07 UTC (permalink / raw)
  To: cip-dev, Jan Kiszka, Quirin Gylstorff; +Cc: Claudius Heine

Hi,

here is v3 of my patchset, I rebased this on the current next branch and
fixed the review issues.

regards,
Claudius

Changes from v2:
 - Rebase on current next
 - Extended `noencrypt` documentation
 - support clevis tokens for re-encryption recovery

Changes from v1:
 - Added more descriptive commit message
 - Added more descriptive documentation about noencrypt option
 - Fixed typos in documentation
 - removed unecessary setting of /conf/param.conf in initramfs-crypt-hook
 - added re-encryption recovery patch

Claudius Heine (4):
  initramfs-crypt-hook: make sure that mount path exists
  initramfs-crypt-hook: implement 'noencrypt' option
  initramfs-crypt-hook: add 'format-if-empty' feature
  initramfs-crypt-hook: add re-encryption recovery

 doc/README.tpm2.encryption.md                 | 23 +++++-
 .../files/local-bottom-complete               |  1 +
 .../files/local-top-complete                  | 73 ++++++++++++++++---
 .../initramfs-crypt-hook_0.6.bb               |  5 +-
 4 files changed, 87 insertions(+), 15 deletions(-)

-- 
2.47.2



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

* [PATCH v3 1/4] initramfs-crypt-hook: make sure that mount path exists
  2025-03-04 13:07 [PATCH v3 0/4] initramfs-crypt-hook patch Claudius Heine
@ 2025-03-04 13:07 ` Claudius Heine
  2025-03-04 13:07 ` [PATCH v3 2/4] initramfs-crypt-hook: implement 'noencrypt' option Claudius Heine
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Claudius Heine @ 2025-03-04 13:07 UTC (permalink / raw)
  To: cip-dev, Jan Kiszka, Quirin Gylstorff; +Cc: Claudius Heine

Wherever or not the mount directory (and their parents) gets created
seem to be inconsistent; mentioning a missing mount point in the
`/etc/fstab` might cause the boot to fail, while using systemd `.mount`
units will just create the mount point.

Wic creates missing mount points that where mentioned in the `.wks`
file; so moving from such a setup to letting `initramfs-crypt-hook`
mount the file system at boot inside the ramdisk, the mount would
suddenly fail.

Therefore creating the mount point for your, if it doesn't exists seem to
provide a smoother transition.

Signed-off-by: Claudius Heine <ch@denx.de>
---
 .../initramfs-crypt-hook/files/local-bottom-complete             | 1 +
 1 file changed, 1 insertion(+)

diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-bottom-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-bottom-complete
index b991cb4..80553d1 100644
--- a/recipes-initramfs/initramfs-crypt-hook/files/local-bottom-complete
+++ b/recipes-initramfs/initramfs-crypt-hook/files/local-bottom-complete
@@ -41,6 +41,7 @@ mount_partition() {
 	partition_mountpoint=$2
 	[ "$debug" = "y" ] && echo "mount device: '$partition_dev_path' to '$partition_mountpoint'"
 	if ! mountpoint -q "${partition_mountpoint}"; then
+		mkdir -p "${partition_mountpoint}"
 		if ! mount -t "$(get_fstype "${partition_dev_path}")" "${partition_dev_path}" \
 			 "${partition_mountpoint}"; then
 			panic "Can't mount partition '${partition_dev_path}'!"
-- 
2.47.2



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

* [PATCH v3 2/4] initramfs-crypt-hook: implement 'noencrypt' option
  2025-03-04 13:07 [PATCH v3 0/4] initramfs-crypt-hook patch Claudius Heine
  2025-03-04 13:07 ` [PATCH v3 1/4] initramfs-crypt-hook: make sure that mount path exists Claudius Heine
@ 2025-03-04 13:07 ` Claudius Heine
  2025-03-04 15:11   ` Jan Kiszka
  2025-03-04 13:07 ` [PATCH v3 3/4] initramfs-crypt-hook: add 'format-if-empty' feature Claudius Heine
  2025-03-04 13:07 ` [PATCH v3 4/4] initramfs-crypt-hook: add re-encryption recovery Claudius Heine
  3 siblings, 1 reply; 14+ messages in thread
From: Claudius Heine @ 2025-03-04 13:07 UTC (permalink / raw)
  To: cip-dev, Jan Kiszka, Quirin Gylstorff; +Cc: Claudius Heine

In case encryption needs to be enabled via an update, while still
allowing the update fall back to work. One update step where encryption
is supported, but no reencryption is taking place if the device is not
encrypted.

For this the `noencrypt` hook is implemented, which requires some
restructure/reordering of the `local-top-complete` script.

Signed-off-by: Claudius Heine <ch@denx.de>
---
 doc/README.tpm2.encryption.md                 | 22 ++++++++++++++++-
 .../files/local-top-complete                  | 24 +++++++++++++++----
 2 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/doc/README.tpm2.encryption.md b/doc/README.tpm2.encryption.md
index 3f7e89f..a97425c 100644
--- a/doc/README.tpm2.encryption.md
+++ b/doc/README.tpm2.encryption.md
@@ -42,11 +42,12 @@ The initramfs-crypt-hook recipe has the following variables which can be overwri
 ### CRYPT_PARTITIONS
 
 The variable `CRYPT_PARTITIONS` contains the information which partition shall be encrypted where to mount it.
-Each entry uses the schema `<partition-identifier>:<mountpoint>:<reencrypt or format>`.
+Each entry uses the schema `<partition-identifier>:<mountpoint>:<reencrypt | format | noencrypt>`.
 - The `partition-idenitifer` is used to identify the partition on the disk, it can contain a partition label, partition UUID or absolute path to the partition device, e.g. `/dev/sda`.
 - 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`
+- `noencrypt` will not try to encrypt the partition, if it isn't encrypted already, but will open it if it is. See the section [Encrypting the shared partition via an update](#### Encrypting the shared partition via an update) for more information
 
 #### Encrypted root file system
 
@@ -58,6 +59,25 @@ The mountpoint is empty as the root partition is mounted  by a seperate initramf
 Both partitions are encrypted during first boot. The initramfs hook opens `${ABROOTFS_PART_UUID_A}` and `${ABROOTFS_PART_UUID_B}`
 during boot.
 
+#### Encrypting the shared partition via an update
+
+With the following requirements, special handling is necessary:
+
+- A/B update scheme is used
+- Both slots have a shared volume, that needs to be encrypted as well
+- The system in field is currently unencrypted and encryption should be added via an update
+- When the update failed, the fallback system needs to deal with an encrypted data partition
+
+If this case the fallback system needs to support an encrypted shared data partition, but would not encrypt it themselves. For this the `noencrypt` flag can be used.
+
+The data partition in the fallback system will have the `noencrypt` flag set, while the update system will set the flag to `reencrypt`, this will handle the following case, for example
+
+- Un-encrypted system on slot A is running, shared data partition has set `noencrypt` flag and is not encrypted
+- Update for enabling encryption is applied to slot B, where the shared data partition has the `reencrypt` flag
+- System reboots to slot B, encrypting the shared data partition
+- Update fails at a later point and is not blessed, system reboots into the fallback system on slot A
+- Fallback system now needs to be able to use the shared data partition
+
 ### CRYPT_CREATE_FILE_SYSTEM_CMD
 
 The variable `CRYPT_CREATE_FILE_SYSTEM_CMD` contains the command to create a new file system on a newly
diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
index cf49e63..1ef784d 100644
--- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
+++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
@@ -240,18 +240,32 @@ for partition_set in $partition_sets; do
 	if [ ! -e  "$part_device" ]; then
 		panic "Could not find device  mapped to '$partition' cannot be encrypted!"
 	fi
-	decrypted_part=/dev/mapper/"$crypt_mount_name"
-	# check if we are trying to mount root
-	if [ "$partition_mountpoint" = "/" ]; then
-		echo "ROOT=$decrypted_part" >/conf/param.conf
-	fi
 
+	# If partition is already encrypted, decrypt and continue with next partition:
+	decrypted_part=/dev/mapper/"$crypt_mount_name"
 	if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
 			| grep -q "luks2"; then
 		open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
+
+		# check if we are trying to mount root, set ROOT to decrypted partition:
+		if [ "$partition_mountpoint" = "/" ]; then
+			echo "ROOT=$decrypted_part" >/conf/param.conf
+		fi
+
 		continue
 	fi
 
+	# If partition should not be encrypted, continue with next partition:
+	if [ "$partition_format" = "noencrypt" ]
+	then
+		continue
+	fi
+
+	# check if we are trying to mount root, set ROOT to decrypted partition:
+	if [ "$partition_mountpoint" = "/" ]; then
+		echo "ROOT=$decrypted_part" >/conf/param.conf
+	fi
+
 	# service watchdog in the background during lengthy re-encryption
 	if [ -z "$watchdog_pid" ]; then
 		service_watchdog &
-- 
2.47.2



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

* [PATCH v3 3/4] initramfs-crypt-hook: add 'format-if-empty' feature
  2025-03-04 13:07 [PATCH v3 0/4] initramfs-crypt-hook patch Claudius Heine
  2025-03-04 13:07 ` [PATCH v3 1/4] initramfs-crypt-hook: make sure that mount path exists Claudius Heine
  2025-03-04 13:07 ` [PATCH v3 2/4] initramfs-crypt-hook: implement 'noencrypt' option Claudius Heine
@ 2025-03-04 13:07 ` Claudius Heine
  2025-03-04 15:03   ` Jan Kiszka
  2025-03-04 13:07 ` [PATCH v3 4/4] initramfs-crypt-hook: add re-encryption recovery Claudius Heine
  3 siblings, 1 reply; 14+ messages in thread
From: Claudius Heine @ 2025-03-04 13:07 UTC (permalink / raw)
  To: cip-dev, Jan Kiszka, Quirin Gylstorff; +Cc: Claudius Heine

When encryption is enabled from one update to the next there is a
difference between flashing a fresh factory image to a empty storage
device, which contains an empty fallback partition set and updating it,
where the fallback partition contains the actual fallback partitions.

In the update case, the update case, the fallback system should be left
alone and unencrypted.

When doing a factory flash, the fallback partitions can be encrypted.

The best marker on in which case the system is booted is, if the
partition is empty or not. The 'format-if-empty' option will format the
partition with a luks format in case the first 10MiB are empty.

Signed-off-by: Claudius Heine <ch@denx.de>
---
 doc/README.tpm2.encryption.md                    |  3 ++-
 .../files/local-top-complete                     | 16 ++++++++++++++++
 .../initramfs-crypt-hook_0.6.bb                  |  2 +-
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/doc/README.tpm2.encryption.md b/doc/README.tpm2.encryption.md
index a97425c..84e6cfe 100644
--- a/doc/README.tpm2.encryption.md
+++ b/doc/README.tpm2.encryption.md
@@ -42,12 +42,13 @@ The initramfs-crypt-hook recipe has the following variables which can be overwri
 ### CRYPT_PARTITIONS
 
 The variable `CRYPT_PARTITIONS` contains the information which partition shall be encrypted where to mount it.
-Each entry uses the schema `<partition-identifier>:<mountpoint>:<reencrypt | format | noencrypt>`.
+Each entry uses the schema `<partition-identifier>:<mountpoint>:<reencrypt | format | noencrypt | format-if-empty>`.
 - The `partition-idenitifer` is used to identify the partition on the disk, it can contain a partition label, partition UUID or absolute path to the partition device, e.g. `/dev/sda`.
 - 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`
 - `noencrypt` will not try to encrypt the partition, if it isn't encrypted already, but will open it if it is. See the section [Encrypting the shared partition via an update](#### Encrypting the shared partition via an update) for more information
+- `format-if-empty` will create a empty LUKS partition and formats it, like the `format` option, but only if the first 10MiB are empty (contain only 0x00). This makes it possible to differentiate if a partition is empty and can be encrypted, because it was freshly flashed via a factory image, or if it might contain an unencrypted fallback system and should be left alone.
 
 #### Encrypted root file system
 
diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
index 1ef784d..47533b5 100644
--- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
+++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
@@ -294,6 +294,22 @@ for partition_set in $partition_sets; do
 			eval "${create_file_system_cmd} ${decrypted_part}"
 			log_end_msg
 		;;
+		"format-if-empty")
+			# Check if first 10MiB contain only zeros
+			if cmp -s -n "$(( 10 * 1024 * 1024 ))" "${part_device}" /dev/zero
+			then
+				log_begin_msg "Encryption of ${part_device}"
+				/usr/sbin/cryptsetup luksFormat --batch-mode \
+					 --type luks2 "$part_device" < "$tmp_key"
+				enroll_tpm2_token "$part_device" "$tmp_key" "$tpm_device" "$tpm_key_algorithm" "$pcr_bank_hash_type"
+				open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
+				eval "${create_file_system_cmd} ${decrypted_part}"
+				log_end_msg
+			else
+				# If not empty, leave it alone.
+				continue
+			fi
+		;;
 		*)
 			panic "Unknown value ${partition_format}. Cannot create a encrypted partition !"
 		;;
diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
index df335c9..c9a7f89 100644
--- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
+++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
@@ -41,7 +41,7 @@ HOOK_ADD_MODULES = " \
 
 HOOK_COPY_EXECS = " \
     openssl mke2fs grep awk expr seq sleep basename uuidparse mountpoint \
-    e2fsck resize2fs cryptsetup \
+    e2fsck resize2fs cryptsetup cmp \
     tpm2_pcrread tpm2_testparms tpm2_flushcontext \
     /usr/lib/*/libgcc_s.so.1"
 
-- 
2.47.2



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

* [PATCH v3 4/4] initramfs-crypt-hook: add re-encryption recovery
  2025-03-04 13:07 [PATCH v3 0/4] initramfs-crypt-hook patch Claudius Heine
                   ` (2 preceding siblings ...)
  2025-03-04 13:07 ` [PATCH v3 3/4] initramfs-crypt-hook: add 'format-if-empty' feature Claudius Heine
@ 2025-03-04 13:07 ` Claudius Heine
  2025-03-04 14:52   ` Jan Kiszka
  3 siblings, 1 reply; 14+ messages in thread
From: Claudius Heine @ 2025-03-04 13:07 UTC (permalink / raw)
  To: cip-dev, Jan Kiszka, Quirin Gylstorff; +Cc: Claudius Heine

Integrate detection and recovery of power failures while a partition is
being encrypted.

There are possible scenarios:
1. Power-fail happens while the partition is reencrypted:
  - The LUKS header contains `online-reencrypt-v2` and needs to be
    repaired with `cryptsetup repair` before it can continue.
  - Also no resizing of the file system is necessary
2. Power-fail happens before the systemd-tpm2/clevis token can be installed
  - The LUKS header does not contain 'systemd-tpm2'/'clevis', thus it
    needs to be registered and the temporary encryption key needs to be
    removed

In both scenarios the system after the reboot needs to have access to
the temporary encryption key that was initially used. So using a random
one, generated via `openssl rand` is not possible. Since it is only a
temporary key and gets removed after the systemd-tpm2/clevis token was
installed, a known password can be used.

The list of these scenarios is not complete, there might be other
instances where a sudden power-fail could be fatal to the system, but
these where the most obvious and risky ones.

Signed-off-by: Claudius Heine <ch@denx.de>
---
 .../files/local-top-complete                  | 33 +++++++++++++++----
 .../initramfs-crypt-hook_0.6.bb               |  5 ++-
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
index 47533b5..e67f26f 100644
--- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
+++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
@@ -72,6 +72,9 @@ reencrypt_existing_partition() {
 	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"
+
+	CRYPTSETUP_PARAMS="--reduce-device-size ${reduce_device_size}k"
+
 	case $partition_fstype in
 	ext*)
 		# reduce the filesystem and partition by 32M to fit the LUKS header
@@ -90,14 +93,25 @@ reencrypt_existing_partition() {
 	squashfs|swap|erofs|"")
 		[ "$debug" = "y" ] && echo "skip disk resize as it is not supported or unnecessary for fstype: '$partition_fstype'"
 		;;
+	luks)
+		# Check if reencrypt was aborted
+		if /usr/sbin/cryptsetup luksDump --batch-mode "$1" \
+				| grep -q "online-reencrypt-v2"; then
+			/usr/sbin/cryptsetup repair --batch-mode "$1" < "$2" || \
+				panic "cryptsetup repair was not successful"
+		fi
+
+		# already luks partition, don't resize
+		CRYPTSETUP_PARAMS=""
+		;;
 	*)
 		panic "cannot resize partition, unsupported fstype: '$partition_fstype'"
 		;;
 	esac
 	if [ -x /usr/sbin/cryptsetup-reencrypt ]; then
-		/usr/sbin/cryptsetup-reencrypt --new --reduce-device-size "$reduce_device_size"k "$1" < "$2"
+		/usr/sbin/cryptsetup-reencrypt --new ${CRYPTSETUP_PARAMS} "$1" < "$2"
 	else
-		/usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-size "$reduce_device_size"k "$1" < "$2"
+		/usr/sbin/cryptsetup reencrypt --encrypt ${CRYPTSETUP_PARAMS} "$1" < "$2"
 	fi
 }
 
@@ -244,7 +258,7 @@ for partition_set in $partition_sets; do
 	# If partition is already encrypted, decrypt and continue with next partition:
 	decrypted_part=/dev/mapper/"$crypt_mount_name"
 	if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
-			| grep -q "luks2"; then
+			| grep -q "systemd-tpm2\|clevis"; then
 		open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
 
 		# check if we are trying to mount root, set ROOT to decrypted partition:
@@ -255,6 +269,12 @@ for partition_set in $partition_sets; do
 		continue
 	fi
 
+	# If partition contains an aborted reencrypt luks header, switch to reencrypt mode:
+	if /usr/sbin/cryptsetup luksDump --batch-mode "${part_device}" \
+			| grep -q "online-reencrypt-v2"; then
+		partition_format="reencrypt"
+	fi
+
 	# If partition should not be encrypted, continue with next partition:
 	if [ "$partition_format" = "noencrypt" ]
 	then
@@ -272,10 +292,11 @@ for partition_set in $partition_sets; do
 		watchdog_pid=$!
 	fi
 
-	# create random password for initial encryption
-	# this will be dropped after reboot
+	# use partuuid of the partition for initial encryption password, this key
+	# will be removed after the reencryption has finished and the TPM2 token is
+	# registered:
 	tmp_key=/tmp/"$(basename "$part_device")-lukskey"
-	openssl rand -base64 32 > "$tmp_key"
+	lsblk -no partuuid "$part_device" > "$tmp_key"
 
 	case "${partition_format}" in
 		"reencrypt")
diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
index c9a7f89..5e82521 100644
--- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
+++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
@@ -14,7 +14,6 @@ require recipes-initramfs/initramfs-hook/hook.inc
 DEBIAN_DEPENDS .= ", \
     cryptsetup, \
     awk, \
-    openssl, \
     e2fsprogs, \
     tpm2-tools, \
     coreutils, \
@@ -40,8 +39,8 @@ HOOK_ADD_MODULES = " \
     ecb aes_generic xts"
 
 HOOK_COPY_EXECS = " \
-    openssl mke2fs grep awk expr seq sleep basename uuidparse mountpoint \
-    e2fsck resize2fs cryptsetup cmp \
+    mke2fs grep awk expr seq sleep basename uuidparse mountpoint \
+    e2fsck resize2fs cryptsetup cmp lsblk \
     tpm2_pcrread tpm2_testparms tpm2_flushcontext \
     /usr/lib/*/libgcc_s.so.1"
 
-- 
2.47.2



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

* Re: [PATCH v3 4/4] initramfs-crypt-hook: add re-encryption recovery
  2025-03-04 13:07 ` [PATCH v3 4/4] initramfs-crypt-hook: add re-encryption recovery Claudius Heine
@ 2025-03-04 14:52   ` Jan Kiszka
  2025-03-04 15:10     ` Quirin Gylstorff
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Kiszka @ 2025-03-04 14:52 UTC (permalink / raw)
  To: Claudius Heine, cip-dev, Quirin Gylstorff

On 04.03.25 14:07, Claudius Heine wrote:
> Integrate detection and recovery of power failures while a partition is
> being encrypted.
> 

Why is this at the end of the series? It can already help the existing
implementation during encrypt-on-first-boot.

> There are possible scenarios:
> 1. Power-fail happens while the partition is reencrypted:
>   - The LUKS header contains `online-reencrypt-v2` and needs to be
>     repaired with `cryptsetup repair` before it can continue.
>   - Also no resizing of the file system is necessary
> 2. Power-fail happens before the systemd-tpm2/clevis token can be installed
>   - The LUKS header does not contain 'systemd-tpm2'/'clevis', thus it
>     needs to be registered and the temporary encryption key needs to be
>     removed
> 
> In both scenarios the system after the reboot needs to have access to
> the temporary encryption key that was initially used. So using a random
> one, generated via `openssl rand` is not possible. Since it is only a
> temporary key and gets removed after the systemd-tpm2/clevis token was
> installed, a known password can be used.
> 
> The list of these scenarios is not complete, there might be other
> instances where a sudden power-fail could be fatal to the system, but
> these where the most obvious and risky ones.

For recovery of the first boot, this might be enough. But when proposing
this for in-field recovery, we should be stricter with thinking the
details through. If we fix them, immediately or later (or never if
unfixable) is on a different page.

> 
> Signed-off-by: Claudius Heine <ch@denx.de>
> ---
>  .../files/local-top-complete                  | 33 +++++++++++++++----
>  .../initramfs-crypt-hook_0.6.bb               |  5 ++-
>  2 files changed, 29 insertions(+), 9 deletions(-)
> 
> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> index 47533b5..e67f26f 100644
> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> @@ -72,6 +72,9 @@ reencrypt_existing_partition() {
>  	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"
> +
> +	CRYPTSETUP_PARAMS="--reduce-device-size ${reduce_device_size}k"
> +
>  	case $partition_fstype in
>  	ext*)
>  		# reduce the filesystem and partition by 32M to fit the LUKS header
> @@ -90,14 +93,25 @@ reencrypt_existing_partition() {
>  	squashfs|swap|erofs|"")
>  		[ "$debug" = "y" ] && echo "skip disk resize as it is not supported or unnecessary for fstype: '$partition_fstype'"
>  		;;
> +	luks)
> +		# Check if reencrypt was aborted
> +		if /usr/sbin/cryptsetup luksDump --batch-mode "$1" \
> +				| grep -q "online-reencrypt-v2"; then
> +			/usr/sbin/cryptsetup repair --batch-mode "$1" < "$2" || \
> +				panic "cryptsetup repair was not successful"
> +		fi
> +
> +		# already luks partition, don't resize
> +		CRYPTSETUP_PARAMS=""
> +		;;
>  	*)
>  		panic "cannot resize partition, unsupported fstype: '$partition_fstype'"
>  		;;
>  	esac
>  	if [ -x /usr/sbin/cryptsetup-reencrypt ]; then
> -		/usr/sbin/cryptsetup-reencrypt --new --reduce-device-size "$reduce_device_size"k "$1" < "$2"
> +		/usr/sbin/cryptsetup-reencrypt --new ${CRYPTSETUP_PARAMS} "$1" < "$2"
>  	else
> -		/usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-size "$reduce_device_size"k "$1" < "$2"
> +		/usr/sbin/cryptsetup reencrypt --encrypt ${CRYPTSETUP_PARAMS} "$1" < "$2"
>  	fi
>  }
>  
> @@ -244,7 +258,7 @@ for partition_set in $partition_sets; do
>  	# If partition is already encrypted, decrypt and continue with next partition:
>  	decrypted_part=/dev/mapper/"$crypt_mount_name"
>  	if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
> -			| grep -q "luks2"; then
> +			| grep -q "systemd-tpm2\|clevis"; then
>  		open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
>  
>  		# check if we are trying to mount root, set ROOT to decrypted partition:
> @@ -255,6 +269,12 @@ for partition_set in $partition_sets; do
>  		continue
>  	fi
>  
> +	# If partition contains an aborted reencrypt luks header, switch to reencrypt mode:
> +	if /usr/sbin/cryptsetup luksDump --batch-mode "${part_device}" \
> +			| grep -q "online-reencrypt-v2"; then
> +		partition_format="reencrypt"
> +	fi
> +
>  	# If partition should not be encrypted, continue with next partition:
>  	if [ "$partition_format" = "noencrypt" ]
>  	then
> @@ -272,10 +292,11 @@ for partition_set in $partition_sets; do
>  		watchdog_pid=$!
>  	fi
>  
> -	# create random password for initial encryption
> -	# this will be dropped after reboot
> +	# use partuuid of the partition for initial encryption password, this key
> +	# will be removed after the reencryption has finished and the TPM2 token is
> +	# registered:
>  	tmp_key=/tmp/"$(basename "$part_device")-lukskey"
> -	openssl rand -base64 32 > "$tmp_key"
> +	lsblk -no partuuid "$part_device" > "$tmp_key"

This should be factored out into a separate commit. I don't disagree
about it, it just deserves an own, clear reasoning. Without recovery, it
looks to me like a nice size optimization for the initramfs by dropping
the openssl dependency.

>  
>  	case "${partition_format}" in
>  		"reencrypt")
> diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
> index c9a7f89..5e82521 100644
> --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
> +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
> @@ -14,7 +14,6 @@ require recipes-initramfs/initramfs-hook/hook.inc
>  DEBIAN_DEPENDS .= ", \
>      cryptsetup, \
>      awk, \
> -    openssl, \
>      e2fsprogs, \
>      tpm2-tools, \
>      coreutils, \
> @@ -40,8 +39,8 @@ HOOK_ADD_MODULES = " \
>      ecb aes_generic xts"
>  
>  HOOK_COPY_EXECS = " \
> -    openssl mke2fs grep awk expr seq sleep basename uuidparse mountpoint \
> -    e2fsck resize2fs cryptsetup cmp \
> +    mke2fs grep awk expr seq sleep basename uuidparse mountpoint \
> +    e2fsck resize2fs cryptsetup cmp lsblk \
>      tpm2_pcrread tpm2_testparms tpm2_flushcontext \
>      /usr/lib/*/libgcc_s.so.1"
>  

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center


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

* Re: [PATCH v3 3/4] initramfs-crypt-hook: add 'format-if-empty' feature
  2025-03-04 13:07 ` [PATCH v3 3/4] initramfs-crypt-hook: add 'format-if-empty' feature Claudius Heine
@ 2025-03-04 15:03   ` Jan Kiszka
  0 siblings, 0 replies; 14+ messages in thread
From: Jan Kiszka @ 2025-03-04 15:03 UTC (permalink / raw)
  To: Claudius Heine, cip-dev, Quirin Gylstorff

On 04.03.25 14:07, Claudius Heine wrote:
> When encryption is enabled from one update to the next there is a
> difference between flashing a fresh factory image to a empty storage
> device, which contains an empty fallback partition set and updating it,
> where the fallback partition contains the actual fallback partitions.
> 
> In the update case, the update case, the fallback system should be left
> alone and unencrypted.

Please re-read the sentence and fix it.

So, we are talking about encrypting the a/b rootfs partitions here,
right? Then please also explain WHY we should not start encrypting both
partitions. What is the difference to having to continue with encrypting
the single data partition after a rollback?

I guess encrypting both would be against our principle to not touch the
working partition set on an a/b update. Please make that clear. If there
is more, please write it up.

> 
> When doing a factory flash, the fallback partitions can be encrypted.
> 
> The best marker on in which case the system is booted is, if the

Please re-read the sentence and fix it.

> partition is empty or not. The 'format-if-empty' option will format the
> partition with a luks format in case the first 10MiB are empty.
> 
> Signed-off-by: Claudius Heine <ch@denx.de>
> ---
>  doc/README.tpm2.encryption.md                    |  3 ++-
>  .../files/local-top-complete                     | 16 ++++++++++++++++
>  .../initramfs-crypt-hook_0.6.bb                  |  2 +-
>  3 files changed, 19 insertions(+), 2 deletions(-)
> 
> diff --git a/doc/README.tpm2.encryption.md b/doc/README.tpm2.encryption.md
> index a97425c..84e6cfe 100644
> --- a/doc/README.tpm2.encryption.md
> +++ b/doc/README.tpm2.encryption.md
> @@ -42,12 +42,13 @@ The initramfs-crypt-hook recipe has the following variables which can be overwri
>  ### CRYPT_PARTITIONS
>  
>  The variable `CRYPT_PARTITIONS` contains the information which partition shall be encrypted where to mount it.
> -Each entry uses the schema `<partition-identifier>:<mountpoint>:<reencrypt | format | noencrypt>`.
> +Each entry uses the schema `<partition-identifier>:<mountpoint>:<reencrypt | format | noencrypt | format-if-empty>`.
>  - The `partition-idenitifer` is used to identify the partition on the disk, it can contain a partition label, partition UUID or absolute path to the partition device, e.g. `/dev/sda`.
>  - 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`
>  - `noencrypt` will not try to encrypt the partition, if it isn't encrypted already, but will open it if it is. See the section [Encrypting the shared partition via an update](#### Encrypting the shared partition via an update) for more information
> +- `format-if-empty` will create a empty LUKS partition and formats it, like the `format` option, but only if the first 10MiB are empty (contain only 0x00). This makes it possible to differentiate if a partition is empty and can be encrypted, because it was freshly flashed via a factory image, or if it might contain an unencrypted fallback system and should be left alone.
>  
>  #### Encrypted root file system
>  
> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> index 1ef784d..47533b5 100644
> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> @@ -294,6 +294,22 @@ for partition_set in $partition_sets; do
>  			eval "${create_file_system_cmd} ${decrypted_part}"
>  			log_end_msg
>  		;;
> +		"format-if-empty")
> +			# Check if first 10MiB contain only zeros
> +			if cmp -s -n "$(( 10 * 1024 * 1024 ))" "${part_device}" /dev/zero
> +			then

if ...; then

> +				log_begin_msg "Encryption of ${part_device}"
> +				/usr/sbin/cryptsetup luksFormat --batch-mode \
> +					 --type luks2 "$part_device" < "$tmp_key"
> +				enroll_tpm2_token "$part_device" "$tmp_key" "$tpm_device" "$tpm_key_algorithm" "$pcr_bank_hash_type"

Please re-wrap that line into two, it's getting too long.

> +				open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
> +				eval "${create_file_system_cmd} ${decrypted_part}"
> +				log_end_msg
> +			else
> +				# If not empty, leave it alone.
> +				continue
> +			fi
> +		;;
>  		*)
>  			panic "Unknown value ${partition_format}. Cannot create a encrypted partition !"
>  		;;
> diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
> index df335c9..c9a7f89 100644
> --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
> +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
> @@ -41,7 +41,7 @@ HOOK_ADD_MODULES = " \
>  
>  HOOK_COPY_EXECS = " \
>      openssl mke2fs grep awk expr seq sleep basename uuidparse mountpoint \
> -    e2fsck resize2fs cryptsetup \
> +    e2fsck resize2fs cryptsetup cmp \
>      tpm2_pcrread tpm2_testparms tpm2_flushcontext \
>      /usr/lib/*/libgcc_s.so.1"
>  

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center


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

* Re: [PATCH v3 4/4] initramfs-crypt-hook: add re-encryption recovery
  2025-03-04 14:52   ` Jan Kiszka
@ 2025-03-04 15:10     ` Quirin Gylstorff
  2025-03-04 15:12       ` Jan Kiszka
  0 siblings, 1 reply; 14+ messages in thread
From: Quirin Gylstorff @ 2025-03-04 15:10 UTC (permalink / raw)
  To: Jan Kiszka, Claudius Heine, cip-dev



On 3/4/25 15:52, Jan Kiszka wrote:
> On 04.03.25 14:07, Claudius Heine wrote:
>> Integrate detection and recovery of power failures while a partition is
>> being encrypted.
>>
> 
> Why is this at the end of the series? It can already help the existing
> implementation during encrypt-on-first-boot.
> 
>> There are possible scenarios:
>> 1. Power-fail happens while the partition is reencrypted:
>>    - The LUKS header contains `online-reencrypt-v2` and needs to be
>>      repaired with `cryptsetup repair` before it can continue.
>>    - Also no resizing of the file system is necessary
>> 2. Power-fail happens before the systemd-tpm2/clevis token can be installed
>>    - The LUKS header does not contain 'systemd-tpm2'/'clevis', thus it
>>      needs to be registered and the temporary encryption key needs to be
>>      removed
>>
>> In both scenarios the system after the reboot needs to have access to
>> the temporary encryption key that was initially used. So using a random
>> one, generated via `openssl rand` is not possible. Since it is only a
>> temporary key and gets removed after the systemd-tpm2/clevis token was
>> installed, a known password can be used.
>>
>> The list of these scenarios is not complete, there might be other
>> instances where a sudden power-fail could be fatal to the system, but
>> these where the most obvious and risky ones.
> 
> For recovery of the first boot, this might be enough. But when proposing
> this for in-field recovery, we should be stricter with thinking the
> details through. If we fix them, immediately or later (or never if
> unfixable) is on a different page.
> 
>>
>> Signed-off-by: Claudius Heine <ch@denx.de>
>> ---
>>   .../files/local-top-complete                  | 33 +++++++++++++++----
>>   .../initramfs-crypt-hook_0.6.bb               |  5 ++-
>>   2 files changed, 29 insertions(+), 9 deletions(-)
>>
>> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>> index 47533b5..e67f26f 100644
>> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>> @@ -72,6 +72,9 @@ reencrypt_existing_partition() {
>>   	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"
>> +
>> +	CRYPTSETUP_PARAMS="--reduce-device-size ${reduce_device_size}k"
>> +
>>   	case $partition_fstype in
>>   	ext*)
>>   		# reduce the filesystem and partition by 32M to fit the LUKS header
>> @@ -90,14 +93,25 @@ reencrypt_existing_partition() {
>>   	squashfs|swap|erofs|"")
>>   		[ "$debug" = "y" ] && echo "skip disk resize as it is not supported or unnecessary for fstype: '$partition_fstype'"
>>   		;;
>> +	luks)
>> +		# Check if reencrypt was aborted
>> +		if /usr/sbin/cryptsetup luksDump --batch-mode "$1" \
>> +				| grep -q "online-reencrypt-v2"; then
>> +			/usr/sbin/cryptsetup repair --batch-mode "$1" < "$2" || \
>> +				panic "cryptsetup repair was not successful"
>> +		fi
>> +
>> +		# already luks partition, don't resize
>> +		CRYPTSETUP_PARAMS=""
>> +		;;
>>   	*)
>>   		panic "cannot resize partition, unsupported fstype: '$partition_fstype'"
>>   		;;
>>   	esac
>>   	if [ -x /usr/sbin/cryptsetup-reencrypt ]; then
>> -		/usr/sbin/cryptsetup-reencrypt --new --reduce-device-size "$reduce_device_size"k "$1" < "$2"
>> +		/usr/sbin/cryptsetup-reencrypt --new ${CRYPTSETUP_PARAMS} "$1" < "$2"
>>   	else
>> -		/usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-size "$reduce_device_size"k "$1" < "$2"
>> +		/usr/sbin/cryptsetup reencrypt --encrypt ${CRYPTSETUP_PARAMS} "$1" < "$2"
>>   	fi
>>   }
>>   
>> @@ -244,7 +258,7 @@ for partition_set in $partition_sets; do
>>   	# If partition is already encrypted, decrypt and continue with next partition:
>>   	decrypted_part=/dev/mapper/"$crypt_mount_name"
>>   	if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
>> -			| grep -q "luks2"; then
>> +			| grep -q "systemd-tpm2\|clevis"; then
>>   		open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
>>   
>>   		# check if we are trying to mount root, set ROOT to decrypted partition:
>> @@ -255,6 +269,12 @@ for partition_set in $partition_sets; do
>>   		continue
>>   	fi
>>   
>> +	# If partition contains an aborted reencrypt luks header, switch to reencrypt mode:
>> +	if /usr/sbin/cryptsetup luksDump --batch-mode "${part_device}" \
>> +			| grep -q "online-reencrypt-v2"; then
>> +		partition_format="reencrypt"
>> +	fi
>> +
>>   	# If partition should not be encrypted, continue with next partition:
>>   	if [ "$partition_format" = "noencrypt" ]
>>   	then
>> @@ -272,10 +292,11 @@ for partition_set in $partition_sets; do
>>   		watchdog_pid=$!
>>   	fi
>>   
>> -	# create random password for initial encryption
>> -	# this will be dropped after reboot
>> +	# use partuuid of the partition for initial encryption password, this key
>> +	# will be removed after the reencryption has finished and the TPM2 token is
>> +	# registered:
>>   	tmp_key=/tmp/"$(basename "$part_device")-lukskey"
>> -	openssl rand -base64 32 > "$tmp_key"
>> +	lsblk -no partuuid "$part_device" > "$tmp_key"
> 
> This should be factored out into a separate commit. I don't disagree
> about it, it just deserves an own, clear reasoning. Without recovery, it
> looks to me like a nice size optimization for the initramfs by dropping
> the openssl dependency.

Why `lsblk` instead of `blkid -s PARTUUID -o value`, as blkid is already 
used in initramfs-verity-hook and initramfs-abrootfs-hook this would 
save more space.

Quirin
> 
>>   
>>   	case "${partition_format}" in
>>   		"reencrypt")
>> diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
>> index c9a7f89..5e82521 100644
>> --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
>> +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb
>> @@ -14,7 +14,6 @@ require recipes-initramfs/initramfs-hook/hook.inc
>>   DEBIAN_DEPENDS .= ", \
>>       cryptsetup, \
>>       awk, \
>> -    openssl, \
>>       e2fsprogs, \
>>       tpm2-tools, \
>>       coreutils, \
>> @@ -40,8 +39,8 @@ HOOK_ADD_MODULES = " \
>>       ecb aes_generic xts"
>>   
>>   HOOK_COPY_EXECS = " \
>> -    openssl mke2fs grep awk expr seq sleep basename uuidparse mountpoint \
>> -    e2fsck resize2fs cryptsetup cmp \
>> +    mke2fs grep awk expr seq sleep basename uuidparse mountpoint \
>> +    e2fsck resize2fs cryptsetup cmp lsblk \
>>       tpm2_pcrread tpm2_testparms tpm2_flushcontext \
>>       /usr/lib/*/libgcc_s.so.1"
>>   
> 
> Jan
> 



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

* Re: [PATCH v3 2/4] initramfs-crypt-hook: implement 'noencrypt' option
  2025-03-04 13:07 ` [PATCH v3 2/4] initramfs-crypt-hook: implement 'noencrypt' option Claudius Heine
@ 2025-03-04 15:11   ` Jan Kiszka
  2025-03-05  8:21     ` Claudius Heine
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Kiszka @ 2025-03-04 15:11 UTC (permalink / raw)
  To: Claudius Heine, cip-dev, Quirin Gylstorff

On 04.03.25 14:07, Claudius Heine wrote:
> In case encryption needs to be enabled via an update, while still
> allowing the update fall back to work. One update step where encryption
> is supported, but no reencryption is taking place if the device is not
> encrypted.
> 
> For this the `noencrypt` hook is implemented, which requires some
> restructure/reordering of the `local-top-complete` script.
> 
> Signed-off-by: Claudius Heine <ch@denx.de>
> ---
>  doc/README.tpm2.encryption.md                 | 22 ++++++++++++++++-
>  .../files/local-top-complete                  | 24 +++++++++++++++----
>  2 files changed, 40 insertions(+), 6 deletions(-)
> 
> diff --git a/doc/README.tpm2.encryption.md b/doc/README.tpm2.encryption.md
> index 3f7e89f..a97425c 100644
> --- a/doc/README.tpm2.encryption.md
> +++ b/doc/README.tpm2.encryption.md
> @@ -42,11 +42,12 @@ The initramfs-crypt-hook recipe has the following variables which can be overwri
>  ### CRYPT_PARTITIONS
>  
>  The variable `CRYPT_PARTITIONS` contains the information which partition shall be encrypted where to mount it.
> -Each entry uses the schema `<partition-identifier>:<mountpoint>:<reencrypt or format>`.
> +Each entry uses the schema `<partition-identifier>:<mountpoint>:<reencrypt | format | noencrypt>`.
>  - The `partition-idenitifer` is used to identify the partition on the disk, it can contain a partition label, partition UUID or absolute path to the partition device, e.g. `/dev/sda`.
>  - 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`
> +- `noencrypt` will not try to encrypt the partition, if it isn't encrypted already, but will open it if it is. See the section [Encrypting the shared partition via an update](#### Encrypting the shared partition via an update) for more information

"...encrypt the partition if it isn't..." (not sure about the second
comma as non-native speaker, though)

>  
>  #### Encrypted root file system
>  
> @@ -58,6 +59,25 @@ The mountpoint is empty as the root partition is mounted  by a seperate initramf
>  Both partitions are encrypted during first boot. The initramfs hook opens `${ABROOTFS_PART_UUID_A}` and `${ABROOTFS_PART_UUID_B}`
>  during boot.
>  
> +#### Encrypting the shared partition via an update
> +
> +With the following requirements, special handling is necessary:
> +
> +- A/B update scheme is used
> +- Both slots have a shared volume, that needs to be encrypted as well
> +- The system in field is currently unencrypted and encryption should be added via an update
> +- When the update failed, the fallback system needs to deal with an encrypted data partition
> +
> +If this case the fallback system needs to support an encrypted shared data partition, but would not encrypt it themselves. For this the `noencrypt` flag can be used.

"In this case"? Sounds strange.

"themselves" - where is the plural coming from?

> +
> +The data partition in the fallback system will have the `noencrypt` flag set, while the update system will set the flag to `reencrypt`, this will handle the following case, for example
> +
> +- Un-encrypted system on slot A is running, shared data partition has set `noencrypt` flag and is not encrypted
> +- Update for enabling encryption is applied to slot B, where the shared data partition has the `reencrypt` flag
> +- System reboots to slot B, encrypting the shared data partition
> +- Update fails at a later point and is not blessed, system reboots into the fallback system on slot A
> +- Fallback system now needs to be able to use the shared data partition

Where do you describe the "format-if-empty" usage of patch 3? Seems that
is an important element as well.

> +
>  ### CRYPT_CREATE_FILE_SYSTEM_CMD
>  
>  The variable `CRYPT_CREATE_FILE_SYSTEM_CMD` contains the command to create a new file system on a newly
> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> index cf49e63..1ef784d 100644
> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> @@ -240,18 +240,32 @@ for partition_set in $partition_sets; do
>  	if [ ! -e  "$part_device" ]; then
>  		panic "Could not find device  mapped to '$partition' cannot be encrypted!"
>  	fi
> -	decrypted_part=/dev/mapper/"$crypt_mount_name"
> -	# check if we are trying to mount root
> -	if [ "$partition_mountpoint" = "/" ]; then
> -		echo "ROOT=$decrypted_part" >/conf/param.conf
> -	fi
>  
> +	# If partition is already encrypted, decrypt and continue with next partition:
> +	decrypted_part=/dev/mapper/"$crypt_mount_name"
>  	if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
>  			| grep -q "luks2"; then
>  		open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
> +
> +		# check if we are trying to mount root, set ROOT to decrypted partition:
> +		if [ "$partition_mountpoint" = "/" ]; then
> +			echo "ROOT=$decrypted_part" >/conf/param.conf
> +		fi
> +
>  		continue
>  	fi
>  
> +	# If partition should not be encrypted, continue with next partition:
> +	if [ "$partition_format" = "noencrypt" ]
> +	then
> +		continue
> +	fi
> +
> +	# check if we are trying to mount root, set ROOT to decrypted partition:
> +	if [ "$partition_mountpoint" = "/" ]; then
> +		echo "ROOT=$decrypted_part" >/conf/param.conf
> +	fi
> +
>  	# service watchdog in the background during lengthy re-encryption
>  	if [ -z "$watchdog_pid" ]; then
>  		service_watchdog &

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center


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

* Re: [PATCH v3 4/4] initramfs-crypt-hook: add re-encryption recovery
  2025-03-04 15:10     ` Quirin Gylstorff
@ 2025-03-04 15:12       ` Jan Kiszka
  2025-03-05  7:25         ` Claudius Heine
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Kiszka @ 2025-03-04 15:12 UTC (permalink / raw)
  To: Quirin Gylstorff, Claudius Heine, cip-dev

On 04.03.25 16:10, Quirin Gylstorff wrote:
> 
> 
> On 3/4/25 15:52, Jan Kiszka wrote:
>> On 04.03.25 14:07, Claudius Heine wrote:
>>> Integrate detection and recovery of power failures while a partition is
>>> being encrypted.
>>>
>>
>> Why is this at the end of the series? It can already help the existing
>> implementation during encrypt-on-first-boot.
>>
>>> There are possible scenarios:
>>> 1. Power-fail happens while the partition is reencrypted:
>>>    - The LUKS header contains `online-reencrypt-v2` and needs to be
>>>      repaired with `cryptsetup repair` before it can continue.
>>>    - Also no resizing of the file system is necessary
>>> 2. Power-fail happens before the systemd-tpm2/clevis token can be
>>> installed
>>>    - The LUKS header does not contain 'systemd-tpm2'/'clevis', thus it
>>>      needs to be registered and the temporary encryption key needs to be
>>>      removed
>>>
>>> In both scenarios the system after the reboot needs to have access to
>>> the temporary encryption key that was initially used. So using a random
>>> one, generated via `openssl rand` is not possible. Since it is only a
>>> temporary key and gets removed after the systemd-tpm2/clevis token was
>>> installed, a known password can be used.
>>>
>>> The list of these scenarios is not complete, there might be other
>>> instances where a sudden power-fail could be fatal to the system, but
>>> these where the most obvious and risky ones.
>>
>> For recovery of the first boot, this might be enough. But when proposing
>> this for in-field recovery, we should be stricter with thinking the
>> details through. If we fix them, immediately or later (or never if
>> unfixable) is on a different page.
>>
>>>
>>> Signed-off-by: Claudius Heine <ch@denx.de>
>>> ---
>>>   .../files/local-top-complete                  | 33 +++++++++++++++----
>>>   .../initramfs-crypt-hook_0.6.bb               |  5 ++-
>>>   2 files changed, 29 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-
>>> complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-
>>> complete
>>> index 47533b5..e67f26f 100644
>>> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>>> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>>> @@ -72,6 +72,9 @@ reencrypt_existing_partition() {
>>>       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"
>>> +
>>> +    CRYPTSETUP_PARAMS="--reduce-device-size ${reduce_device_size}k"
>>> +
>>>       case $partition_fstype in
>>>       ext*)
>>>           # reduce the filesystem and partition by 32M to fit the
>>> LUKS header
>>> @@ -90,14 +93,25 @@ reencrypt_existing_partition() {
>>>       squashfs|swap|erofs|"")
>>>           [ "$debug" = "y" ] && echo "skip disk resize as it is not
>>> supported or unnecessary for fstype: '$partition_fstype'"
>>>           ;;
>>> +    luks)
>>> +        # Check if reencrypt was aborted
>>> +        if /usr/sbin/cryptsetup luksDump --batch-mode "$1" \
>>> +                | grep -q "online-reencrypt-v2"; then
>>> +            /usr/sbin/cryptsetup repair --batch-mode "$1" < "$2" || \
>>> +                panic "cryptsetup repair was not successful"
>>> +        fi
>>> +
>>> +        # already luks partition, don't resize
>>> +        CRYPTSETUP_PARAMS=""
>>> +        ;;
>>>       *)
>>>           panic "cannot resize partition, unsupported fstype:
>>> '$partition_fstype'"
>>>           ;;
>>>       esac
>>>       if [ -x /usr/sbin/cryptsetup-reencrypt ]; then
>>> -        /usr/sbin/cryptsetup-reencrypt --new --reduce-device-size
>>> "$reduce_device_size"k "$1" < "$2"
>>> +        /usr/sbin/cryptsetup-reencrypt --new ${CRYPTSETUP_PARAMS}
>>> "$1" < "$2"
>>>       else
>>> -        /usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-
>>> size "$reduce_device_size"k "$1" < "$2"
>>> +        /usr/sbin/cryptsetup reencrypt --encrypt
>>> ${CRYPTSETUP_PARAMS} "$1" < "$2"
>>>       fi
>>>   }
>>>   @@ -244,7 +258,7 @@ for partition_set in $partition_sets; do
>>>       # If partition is already encrypted, decrypt and continue with
>>> next partition:
>>>       decrypted_part=/dev/mapper/"$crypt_mount_name"
>>>       if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
>>> -            | grep -q "luks2"; then
>>> +            | grep -q "systemd-tpm2\|clevis"; then
>>>           open_tpm2_partition "$part_device" "$crypt_mount_name"
>>> "$tpm_device"
>>>             # check if we are trying to mount root, set ROOT to
>>> decrypted partition:
>>> @@ -255,6 +269,12 @@ for partition_set in $partition_sets; do
>>>           continue
>>>       fi
>>>   +    # If partition contains an aborted reencrypt luks header,
>>> switch to reencrypt mode:
>>> +    if /usr/sbin/cryptsetup luksDump --batch-mode "${part_device}" \
>>> +            | grep -q "online-reencrypt-v2"; then
>>> +        partition_format="reencrypt"
>>> +    fi
>>> +
>>>       # If partition should not be encrypted, continue with next
>>> partition:
>>>       if [ "$partition_format" = "noencrypt" ]
>>>       then
>>> @@ -272,10 +292,11 @@ for partition_set in $partition_sets; do
>>>           watchdog_pid=$!
>>>       fi
>>>   -    # create random password for initial encryption
>>> -    # this will be dropped after reboot
>>> +    # use partuuid of the partition for initial encryption password,
>>> this key
>>> +    # will be removed after the reencryption has finished and the
>>> TPM2 token is
>>> +    # registered:
>>>       tmp_key=/tmp/"$(basename "$part_device")-lukskey"
>>> -    openssl rand -base64 32 > "$tmp_key"
>>> +    lsblk -no partuuid "$part_device" > "$tmp_key"
>>
>> This should be factored out into a separate commit. I don't disagree
>> about it, it just deserves an own, clear reasoning. Without recovery, it
>> looks to me like a nice size optimization for the initramfs by dropping
>> the openssl dependency.
> 
> Why `lsblk` instead of `blkid -s PARTUUID -o value`, as blkid is already
> used in initramfs-verity-hook and initramfs-abrootfs-hook this would
> save more space.

Or just use "some-long-hardcoded-temporary-password". From a security
perspective, there should be no difference.

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center


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

* Re: [PATCH v3 4/4] initramfs-crypt-hook: add re-encryption recovery
  2025-03-04 15:12       ` Jan Kiszka
@ 2025-03-05  7:25         ` Claudius Heine
  0 siblings, 0 replies; 14+ messages in thread
From: Claudius Heine @ 2025-03-05  7:25 UTC (permalink / raw)
  To: Jan Kiszka, Quirin Gylstorff, cip-dev

Hi Jan,

On 2025-03-04 4:12 pm, Jan Kiszka wrote:
> On 04.03.25 16:10, Quirin Gylstorff wrote:
>>
>>
>> On 3/4/25 15:52, Jan Kiszka wrote:
>>> On 04.03.25 14:07, Claudius Heine wrote:
>>>> Integrate detection and recovery of power failures while a partition is
>>>> being encrypted.
>>>>
>>>
>>> Why is this at the end of the series? It can already help the existing
>>> implementation during encrypt-on-first-boot.

Because that was the order this feature was implemented, to us the 
support for 'noencrypt' was more important than the re-encryption recovery.

I can look into reordering it.

>>>
>>>> There are possible scenarios:
>>>> 1. Power-fail happens while the partition is reencrypted:
>>>>     - The LUKS header contains `online-reencrypt-v2` and needs to be
>>>>       repaired with `cryptsetup repair` before it can continue.
>>>>     - Also no resizing of the file system is necessary
>>>> 2. Power-fail happens before the systemd-tpm2/clevis token can be
>>>> installed
>>>>     - The LUKS header does not contain 'systemd-tpm2'/'clevis', thus it
>>>>       needs to be registered and the temporary encryption key needs to be
>>>>       removed
>>>>
>>>> In both scenarios the system after the reboot needs to have access to
>>>> the temporary encryption key that was initially used. So using a random
>>>> one, generated via `openssl rand` is not possible. Since it is only a
>>>> temporary key and gets removed after the systemd-tpm2/clevis token was
>>>> installed, a known password can be used.
>>>>
>>>> The list of these scenarios is not complete, there might be other
>>>> instances where a sudden power-fail could be fatal to the system, but
>>>> these where the most obvious and risky ones.
>>>
>>> For recovery of the first boot, this might be enough. But when proposing
>>> this for in-field recovery, we should be stricter with thinking the
>>> details through. If we fix them, immediately or later (or never if
>>> unfixable) is on a different page.
>>>
>>>>
>>>> Signed-off-by: Claudius Heine <ch@denx.de>
>>>> ---
>>>>    .../files/local-top-complete                  | 33 +++++++++++++++----
>>>>    .../initramfs-crypt-hook_0.6.bb               |  5 ++-
>>>>    2 files changed, 29 insertions(+), 9 deletions(-)
>>>>
>>>> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-
>>>> complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-
>>>> complete
>>>> index 47533b5..e67f26f 100644
>>>> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>>>> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>>>> @@ -72,6 +72,9 @@ reencrypt_existing_partition() {
>>>>        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"
>>>> +
>>>> +    CRYPTSETUP_PARAMS="--reduce-device-size ${reduce_device_size}k"
>>>> +
>>>>        case $partition_fstype in
>>>>        ext*)
>>>>            # reduce the filesystem and partition by 32M to fit the
>>>> LUKS header
>>>> @@ -90,14 +93,25 @@ reencrypt_existing_partition() {
>>>>        squashfs|swap|erofs|"")
>>>>            [ "$debug" = "y" ] && echo "skip disk resize as it is not
>>>> supported or unnecessary for fstype: '$partition_fstype'"
>>>>            ;;
>>>> +    luks)
>>>> +        # Check if reencrypt was aborted
>>>> +        if /usr/sbin/cryptsetup luksDump --batch-mode "$1" \
>>>> +                | grep -q "online-reencrypt-v2"; then
>>>> +            /usr/sbin/cryptsetup repair --batch-mode "$1" < "$2" || \
>>>> +                panic "cryptsetup repair was not successful"
>>>> +        fi
>>>> +
>>>> +        # already luks partition, don't resize
>>>> +        CRYPTSETUP_PARAMS=""
>>>> +        ;;
>>>>        *)
>>>>            panic "cannot resize partition, unsupported fstype:
>>>> '$partition_fstype'"
>>>>            ;;
>>>>        esac
>>>>        if [ -x /usr/sbin/cryptsetup-reencrypt ]; then
>>>> -        /usr/sbin/cryptsetup-reencrypt --new --reduce-device-size
>>>> "$reduce_device_size"k "$1" < "$2"
>>>> +        /usr/sbin/cryptsetup-reencrypt --new ${CRYPTSETUP_PARAMS}
>>>> "$1" < "$2"
>>>>        else
>>>> -        /usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-
>>>> size "$reduce_device_size"k "$1" < "$2"
>>>> +        /usr/sbin/cryptsetup reencrypt --encrypt
>>>> ${CRYPTSETUP_PARAMS} "$1" < "$2"
>>>>        fi
>>>>    }
>>>>    @@ -244,7 +258,7 @@ for partition_set in $partition_sets; do
>>>>        # If partition is already encrypted, decrypt and continue with
>>>> next partition:
>>>>        decrypted_part=/dev/mapper/"$crypt_mount_name"
>>>>        if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
>>>> -            | grep -q "luks2"; then
>>>> +            | grep -q "systemd-tpm2\|clevis"; then
>>>>            open_tpm2_partition "$part_device" "$crypt_mount_name"
>>>> "$tpm_device"
>>>>              # check if we are trying to mount root, set ROOT to
>>>> decrypted partition:
>>>> @@ -255,6 +269,12 @@ for partition_set in $partition_sets; do
>>>>            continue
>>>>        fi
>>>>    +    # If partition contains an aborted reencrypt luks header,
>>>> switch to reencrypt mode:
>>>> +    if /usr/sbin/cryptsetup luksDump --batch-mode "${part_device}" \
>>>> +            | grep -q "online-reencrypt-v2"; then
>>>> +        partition_format="reencrypt"
>>>> +    fi
>>>> +
>>>>        # If partition should not be encrypted, continue with next
>>>> partition:
>>>>        if [ "$partition_format" = "noencrypt" ]
>>>>        then
>>>> @@ -272,10 +292,11 @@ for partition_set in $partition_sets; do
>>>>            watchdog_pid=$!
>>>>        fi
>>>>    -    # create random password for initial encryption
>>>> -    # this will be dropped after reboot
>>>> +    # use partuuid of the partition for initial encryption password,
>>>> this key
>>>> +    # will be removed after the reencryption has finished and the
>>>> TPM2 token is
>>>> +    # registered:
>>>>        tmp_key=/tmp/"$(basename "$part_device")-lukskey"
>>>> -    openssl rand -base64 32 > "$tmp_key"
>>>> +    lsblk -no partuuid "$part_device" > "$tmp_key"
>>>
>>> This should be factored out into a separate commit. I don't disagree
>>> about it, it just deserves an own, clear reasoning. Without recovery, it
>>> looks to me like a nice size optimization for the initramfs by dropping
>>> the openssl dependency.
>>
>> Why `lsblk` instead of `blkid -s PARTUUID -o value`, as blkid is already
>> used in initramfs-verity-hook and initramfs-abrootfs-hook this would
>> save more space.

Good idea.

> 
> Or just use "some-long-hardcoded-temporary-password". From a security
> perspective, there should be no difference.

That is was we did initially downstream, but I thought that just 
inserting some fixed hard-coded password string might have even more 
issues being accepted here upstream than using some device parameter.

We could also use `dmidecode -s system-uuid`, that at least would 
require to readout the uuid of the system. Having the storage medium 
alone would not be enough.

regards,
Claudius

> 
> Jan
> 

-- 
DENX Software Engineering GmbH,        Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-54 Fax: (+49)-8142-66989-80 Email: ch@denx.de



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

* Re: [PATCH v3 2/4] initramfs-crypt-hook: implement 'noencrypt' option
  2025-03-04 15:11   ` Jan Kiszka
@ 2025-03-05  8:21     ` Claudius Heine
  2025-03-05  8:27       ` Jan Kiszka
  0 siblings, 1 reply; 14+ messages in thread
From: Claudius Heine @ 2025-03-05  8:21 UTC (permalink / raw)
  To: Jan Kiszka, cip-dev, Quirin Gylstorff

Hi Jan,

On 2025-03-04 4:11 pm, Jan Kiszka wrote:
> On 04.03.25 14:07, Claudius Heine wrote:
>> In case encryption needs to be enabled via an update, while still
>> allowing the update fall back to work. One update step where encryption
>> is supported, but no reencryption is taking place if the device is not
>> encrypted.
>>
>> For this the `noencrypt` hook is implemented, which requires some
>> restructure/reordering of the `local-top-complete` script.
>>
>> Signed-off-by: Claudius Heine <ch@denx.de>
>> ---
>>   doc/README.tpm2.encryption.md                 | 22 ++++++++++++++++-
>>   .../files/local-top-complete                  | 24 +++++++++++++++----
>>   2 files changed, 40 insertions(+), 6 deletions(-)
>>
>> diff --git a/doc/README.tpm2.encryption.md b/doc/README.tpm2.encryption.md
>> index 3f7e89f..a97425c 100644
>> --- a/doc/README.tpm2.encryption.md
>> +++ b/doc/README.tpm2.encryption.md
>> @@ -42,11 +42,12 @@ The initramfs-crypt-hook recipe has the following variables which can be overwri
>>   ### CRYPT_PARTITIONS
>>   
>>   The variable `CRYPT_PARTITIONS` contains the information which partition shall be encrypted where to mount it.
>> -Each entry uses the schema `<partition-identifier>:<mountpoint>:<reencrypt or format>`.
>> +Each entry uses the schema `<partition-identifier>:<mountpoint>:<reencrypt | format | noencrypt>`.
>>   - The `partition-idenitifer` is used to identify the partition on the disk, it can contain a partition label, partition UUID or absolute path to the partition device, e.g. `/dev/sda`.
>>   - 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`
>> +- `noencrypt` will not try to encrypt the partition, if it isn't encrypted already, but will open it if it is. See the section [Encrypting the shared partition via an update](#### Encrypting the shared partition via an update) for more information
> 
> "...encrypt the partition if it isn't..." (not sure about the second
> comma as non-native speaker, though)

fixed, thx.

> 
>>   
>>   #### Encrypted root file system
>>   
>> @@ -58,6 +59,25 @@ The mountpoint is empty as the root partition is mounted  by a seperate initramf
>>   Both partitions are encrypted during first boot. The initramfs hook opens `${ABROOTFS_PART_UUID_A}` and `${ABROOTFS_PART_UUID_B}`
>>   during boot.
>>   
>> +#### Encrypting the shared partition via an update
>> +
>> +With the following requirements, special handling is necessary:
>> +
>> +- A/B update scheme is used
>> +- Both slots have a shared volume, that needs to be encrypted as well
>> +- The system in field is currently unencrypted and encryption should be added via an update
>> +- When the update failed, the fallback system needs to deal with an encrypted data partition
>> +
>> +If this case the fallback system needs to support an encrypted shared data partition, but would not encrypt it themselves. For this the `noencrypt` flag can be used.
> 
> "In this case"? Sounds strange.

fixed, thx.

> 
> "themselves" - where is the plural coming from?

There is the rule: "He, she, it; das S muss mit"

I went ahead and let languagetool decide, and it also wants there to be 
"themselves" instead of "themself", but just to be sure, I rewrote 
'themselves' to 'on its own' there. (notice the s there as well :)

> 
>> +
>> +The data partition in the fallback system will have the `noencrypt` flag set, while the update system will set the flag to `reencrypt`, this will handle the following case, for example
>> +
>> +- Un-encrypted system on slot A is running, shared data partition has set `noencrypt` flag and is not encrypted
>> +- Update for enabling encryption is applied to slot B, where the shared data partition has the `reencrypt` flag
>> +- System reboots to slot B, encrypting the shared data partition
>> +- Update fails at a later point and is not blessed, system reboots into the fallback system on slot A
>> +- Fallback system now needs to be able to use the shared data partition
> 
> Where do you describe the "format-if-empty" usage of patch 3? Seems that
> is an important element as well.

I will add a note there in the format-if-empty patch.

regards,
Claudius

> 
>> +
>>   ### CRYPT_CREATE_FILE_SYSTEM_CMD
>>   
>>   The variable `CRYPT_CREATE_FILE_SYSTEM_CMD` contains the command to create a new file system on a newly
>> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>> index cf49e63..1ef784d 100644
>> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>> @@ -240,18 +240,32 @@ for partition_set in $partition_sets; do
>>   	if [ ! -e  "$part_device" ]; then
>>   		panic "Could not find device  mapped to '$partition' cannot be encrypted!"
>>   	fi
>> -	decrypted_part=/dev/mapper/"$crypt_mount_name"
>> -	# check if we are trying to mount root
>> -	if [ "$partition_mountpoint" = "/" ]; then
>> -		echo "ROOT=$decrypted_part" >/conf/param.conf
>> -	fi
>>   
>> +	# If partition is already encrypted, decrypt and continue with next partition:
>> +	decrypted_part=/dev/mapper/"$crypt_mount_name"
>>   	if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
>>   			| grep -q "luks2"; then
>>   		open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
>> +
>> +		# check if we are trying to mount root, set ROOT to decrypted partition:
>> +		if [ "$partition_mountpoint" = "/" ]; then
>> +			echo "ROOT=$decrypted_part" >/conf/param.conf
>> +		fi
>> +
>>   		continue
>>   	fi
>>   
>> +	# If partition should not be encrypted, continue with next partition:
>> +	if [ "$partition_format" = "noencrypt" ]
>> +	then
>> +		continue
>> +	fi
>> +
>> +	# check if we are trying to mount root, set ROOT to decrypted partition:
>> +	if [ "$partition_mountpoint" = "/" ]; then
>> +		echo "ROOT=$decrypted_part" >/conf/param.conf
>> +	fi
>> +
>>   	# service watchdog in the background during lengthy re-encryption
>>   	if [ -z "$watchdog_pid" ]; then
>>   		service_watchdog &
> 
> Jan
> 

-- 
DENX Software Engineering GmbH,        Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-54 Fax: (+49)-8142-66989-80 Email: ch@denx.de



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

* Re: [PATCH v3 2/4] initramfs-crypt-hook: implement 'noencrypt' option
  2025-03-05  8:21     ` Claudius Heine
@ 2025-03-05  8:27       ` Jan Kiszka
  2025-03-05  8:39         ` Claudius Heine
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Kiszka @ 2025-03-05  8:27 UTC (permalink / raw)
  To: Claudius Heine, cip-dev, Quirin Gylstorff

On 05.03.25 09:21, Claudius Heine wrote:
> Hi Jan,
> 
> On 2025-03-04 4:11 pm, Jan Kiszka wrote:
>> On 04.03.25 14:07, Claudius Heine wrote:
>>> In case encryption needs to be enabled via an update, while still
>>> allowing the update fall back to work. One update step where encryption
>>> is supported, but no reencryption is taking place if the device is not
>>> encrypted.
>>>
>>> For this the `noencrypt` hook is implemented, which requires some
>>> restructure/reordering of the `local-top-complete` script.
>>>
>>> Signed-off-by: Claudius Heine <ch@denx.de>
>>> ---
>>>   doc/README.tpm2.encryption.md                 | 22 ++++++++++++++++-
>>>   .../files/local-top-complete                  | 24 +++++++++++++++----
>>>   2 files changed, 40 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/doc/README.tpm2.encryption.md b/doc/
>>> README.tpm2.encryption.md
>>> index 3f7e89f..a97425c 100644
>>> --- a/doc/README.tpm2.encryption.md
>>> +++ b/doc/README.tpm2.encryption.md
>>> @@ -42,11 +42,12 @@ The initramfs-crypt-hook recipe has the following
>>> variables which can be overwri
>>>   ### CRYPT_PARTITIONS
>>>     The variable `CRYPT_PARTITIONS` contains the information which
>>> partition shall be encrypted where to mount it.
>>> -Each entry uses the schema `<partition-
>>> identifier>:<mountpoint>:<reencrypt or format>`.
>>> +Each entry uses the schema `<partition-
>>> identifier>:<mountpoint>:<reencrypt | format | noencrypt>`.
>>>   - The `partition-idenitifer` is used to identify the partition on
>>> the disk, it can contain a partition label, partition UUID or
>>> absolute path to the partition device, e.g. `/dev/sda`.
>>>   - 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`
>>> +- `noencrypt` will not try to encrypt the partition, if it isn't
>>> encrypted already, but will open it if it is. See the section
>>> [Encrypting the shared partition via an update](#### Encrypting the
>>> shared partition via an update) for more information
>>
>> "...encrypt the partition if it isn't..." (not sure about the second
>> comma as non-native speaker, though)
> 
> fixed, thx.
> 
>>
>>>     #### Encrypted root file system
>>>   @@ -58,6 +59,25 @@ The mountpoint is empty as the root partition is
>>> mounted  by a seperate initramf
>>>   Both partitions are encrypted during first boot. The initramfs hook
>>> opens `${ABROOTFS_PART_UUID_A}` and `${ABROOTFS_PART_UUID_B}`
>>>   during boot.
>>>   +#### Encrypting the shared partition via an update
>>> +
>>> +With the following requirements, special handling is necessary:
>>> +
>>> +- A/B update scheme is used
>>> +- Both slots have a shared volume, that needs to be encrypted as well
>>> +- The system in field is currently unencrypted and encryption should
>>> be added via an update
>>> +- When the update failed, the fallback system needs to deal with an
>>> encrypted data partition
>>> +
>>> +If this case the fallback system needs to support an encrypted
>>> shared data partition, but would not encrypt it themselves. For this
>>> the `noencrypt` flag can be used.
>>
>> "In this case"? Sounds strange.
> 
> fixed, thx.
> 
>>
>> "themselves" - where is the plural coming from?
> 
> There is the rule: "He, she, it; das S muss mit"
> 

"the fallback system... would not encrypt it itself" - it's only one
fallback system from my reading of the sentence.

Jan

> I went ahead and let languagetool decide, and it also wants there to be
> "themselves" instead of "themself", but just to be sure, I rewrote
> 'themselves' to 'on its own' there. (notice the s there as well :)
> 
>>
>>> +
>>> +The data partition in the fallback system will have the `noencrypt`
>>> flag set, while the update system will set the flag to `reencrypt`,
>>> this will handle the following case, for example
>>> +
>>> +- Un-encrypted system on slot A is running, shared data partition
>>> has set `noencrypt` flag and is not encrypted
>>> +- Update for enabling encryption is applied to slot B, where the
>>> shared data partition has the `reencrypt` flag
>>> +- System reboots to slot B, encrypting the shared data partition
>>> +- Update fails at a later point and is not blessed, system reboots
>>> into the fallback system on slot A
>>> +- Fallback system now needs to be able to use the shared data partition
>>
>> Where do you describe the "format-if-empty" usage of patch 3? Seems that
>> is an important element as well.
> 
> I will add a note there in the format-if-empty patch.
> 
> regards,
> Claudius
> 
>>
>>> +
>>>   ### CRYPT_CREATE_FILE_SYSTEM_CMD
>>>     The variable `CRYPT_CREATE_FILE_SYSTEM_CMD` contains the command
>>> to create a new file system on a newly
>>> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-
>>> complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-
>>> complete
>>> index cf49e63..1ef784d 100644
>>> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>>> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>>> @@ -240,18 +240,32 @@ for partition_set in $partition_sets; do
>>>       if [ ! -e  "$part_device" ]; then
>>>           panic "Could not find device  mapped to '$partition' cannot
>>> be encrypted!"
>>>       fi
>>> -    decrypted_part=/dev/mapper/"$crypt_mount_name"
>>> -    # check if we are trying to mount root
>>> -    if [ "$partition_mountpoint" = "/" ]; then
>>> -        echo "ROOT=$decrypted_part" >/conf/param.conf
>>> -    fi
>>>   +    # If partition is already encrypted, decrypt and continue with
>>> next partition:
>>> +    decrypted_part=/dev/mapper/"$crypt_mount_name"
>>>       if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
>>>               | grep -q "luks2"; then
>>>           open_tpm2_partition "$part_device" "$crypt_mount_name"
>>> "$tpm_device"
>>> +
>>> +        # check if we are trying to mount root, set ROOT to
>>> decrypted partition:
>>> +        if [ "$partition_mountpoint" = "/" ]; then
>>> +            echo "ROOT=$decrypted_part" >/conf/param.conf
>>> +        fi
>>> +
>>>           continue
>>>       fi
>>>   +    # If partition should not be encrypted, continue with next
>>> partition:
>>> +    if [ "$partition_format" = "noencrypt" ]
>>> +    then
>>> +        continue
>>> +    fi
>>> +
>>> +    # check if we are trying to mount root, set ROOT to decrypted
>>> partition:
>>> +    if [ "$partition_mountpoint" = "/" ]; then
>>> +        echo "ROOT=$decrypted_part" >/conf/param.conf
>>> +    fi
>>> +
>>>       # service watchdog in the background during lengthy re-encryption
>>>       if [ -z "$watchdog_pid" ]; then
>>>           service_watchdog &
>>
>> Jan
>>
> 

-- 
Siemens AG, Foundational Technologies
Linux Expert Center


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

* Re: [PATCH v3 2/4] initramfs-crypt-hook: implement 'noencrypt' option
  2025-03-05  8:27       ` Jan Kiszka
@ 2025-03-05  8:39         ` Claudius Heine
  0 siblings, 0 replies; 14+ messages in thread
From: Claudius Heine @ 2025-03-05  8:39 UTC (permalink / raw)
  To: Jan Kiszka, cip-dev, Quirin Gylstorff

On 2025-03-05 9:27 am, Jan Kiszka wrote:
>>> "themselves" - where is the plural coming from?
>> There is the rule: "He, she, it; das S muss mit"
>>
> "the fallback system... would not encrypt it itself" - it's only one
> fallback system from my reading of the sentence.

They/them is not necessarily plural, but as I said, I changed it to `on 
its own`, for the next version.

https://en.wikipedia.org/wiki/Singular_they

-- 
DENX Software Engineering GmbH,        Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-54 Fax: (+49)-8142-66989-80 Email: ch@denx.de



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

end of thread, other threads:[~2025-03-05  8:39 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-04 13:07 [PATCH v3 0/4] initramfs-crypt-hook patch Claudius Heine
2025-03-04 13:07 ` [PATCH v3 1/4] initramfs-crypt-hook: make sure that mount path exists Claudius Heine
2025-03-04 13:07 ` [PATCH v3 2/4] initramfs-crypt-hook: implement 'noencrypt' option Claudius Heine
2025-03-04 15:11   ` Jan Kiszka
2025-03-05  8:21     ` Claudius Heine
2025-03-05  8:27       ` Jan Kiszka
2025-03-05  8:39         ` Claudius Heine
2025-03-04 13:07 ` [PATCH v3 3/4] initramfs-crypt-hook: add 'format-if-empty' feature Claudius Heine
2025-03-04 15:03   ` Jan Kiszka
2025-03-04 13:07 ` [PATCH v3 4/4] initramfs-crypt-hook: add re-encryption recovery Claudius Heine
2025-03-04 14:52   ` Jan Kiszka
2025-03-04 15:10     ` Quirin Gylstorff
2025-03-04 15:12       ` Jan Kiszka
2025-03-05  7:25         ` Claudius Heine

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox