From: Claudius Heine <ch@denx.de>
To: cip-dev@lists.cip-project.org,
Jan Kiszka <jan.kiszka@siemens.com>,
Quirin Gylstorff <quirin.gylstorff@siemens.com>
Cc: Claudius Heine <ch@denx.de>
Subject: [PATCH v2 4/4] initramfs-crypt-hook: add re-encryption recovery
Date: Thu, 27 Feb 2025 15:30:22 +0100 [thread overview]
Message-ID: <20250227143022.323950-5-ch@denx.de> (raw)
In-Reply-To: <20250227143022.323950-1-ch@denx.de>
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 token can be installed
- The LUKS header does not contain 'systemd-tpm2', 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 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 4b6451a..6034175 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
}
@@ -219,7 +233,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"; then
open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
# check if we are trying to mount root, set ROOT to decrypted partition:
@@ -230,6 +244,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
@@ -247,10 +267,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
next prev parent reply other threads:[~2025-02-27 14:30 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-27 14:30 [PATCH v2 0/4] initramfs-crypt-hook patch Claudius Heine
2025-02-27 14:30 ` [PATCH v2 1/4] initramfs-crypt-hook: make sure that mount path exists Claudius Heine
2025-02-27 14:30 ` [PATCH v2 2/4] initramfs-crypt-hook: implement 'noencrypt' option Claudius Heine
2025-02-27 14:42 ` Quirin Gylstorff
2025-02-27 14:49 ` Claudius Heine
2025-02-27 16:07 ` Quirin Gylstorff
2025-02-27 16:46 ` Jan Kiszka
2025-02-27 16:51 ` Claudius Heine
2025-02-27 14:30 ` [PATCH v2 3/4] initramfs-crypt-hook: add 'format-if-empty' feature Claudius Heine
2025-02-27 14:30 ` Claudius Heine [this message]
2025-02-27 14:37 ` [PATCH v2 4/4] initramfs-crypt-hook: add re-encryption recovery Quirin Gylstorff
2025-02-27 14:46 ` Claudius Heine
2025-02-27 14:56 ` Quirin Gylstorff
2025-02-27 15:03 ` Claudius Heine
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250227143022.323950-5-ch@denx.de \
--to=ch@denx.de \
--cc=cip-dev@lists.cip-project.org \
--cc=jan.kiszka@siemens.com \
--cc=quirin.gylstorff@siemens.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox