From patchwork Wed Mar 5 12:00:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudius Heine X-Patchwork-Id: 14002513 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id EE7CEC19F32 for ; Wed, 5 Mar 2025 12:00:32 +0000 (UTC) Received: from mx.denx.de (mx.denx.de [89.58.32.78]) by mx.groups.io with SMTP id smtpd.web10.11600.1741176027158394964 for ; Wed, 05 Mar 2025 04:00:27 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@denx.de header.s=mx-20241105 header.b=eoOqhr0L; spf=pass (domain: denx.de, ip: 89.58.32.78, mailfrom: ch@denx.de) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5A9C610381917; Wed, 5 Mar 2025 13:00:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=mx-20241105; t=1741176025; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=0GlwVKv11gA9qDnee0LQP54AxnuVIYBEB4M4WRqYeQI=; b=eoOqhr0LCcWgrd94qNVTc0T93LvP6Qk7rvLwMlIkmlZPB3XHwKBzUa/lDwwh3E4JJFjl+G R9DIXrKB9WWtXjC4pqr5u9MlUL1GBgYlw4M9JsIAe5bKyLB8U3NU4/6gVxrV5Oy1kBq22b /5dpV47WGGqrDw75J9gdjMHJ7Pjv8/RSNkqcLhLbjcpm12v71cYhEuxPhtOdEyt/r1bwh/ wPnv1ONKtlvzZu35PePYIlp9UkgGIvvCU/LJ4t46sNrrSXz+Kcx4Op3P6MQCdWq0C88tdN VfAVBJImOQVc2idVnUfQ0iqLbO5Y0dhWvu7YoUGWsDv3OpJ00ELhoBUZKjoeUw== From: Claudius Heine Date: Wed, 05 Mar 2025 13:00:19 +0100 Subject: [PATCH v4 1/5] initramfs-crypt-hook: make sure that mount path exists MIME-Version: 1.0 Message-Id: <20250305-initramfs-crypt-hook-patches-2-v4-1-4170912e5261@denx.de> References: <20250305-initramfs-crypt-hook-patches-2-v4-0-4170912e5261@denx.de> In-Reply-To: <20250305-initramfs-crypt-hook-patches-2-v4-0-4170912e5261@denx.de> To: cip-dev@lists.cip-project.org Cc: Jan Kiszka , Quirin Gylstorff , Claudius Heine X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 05 Mar 2025 12:00:32 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/18042 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 --- recipes-initramfs/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 b991cb49fbdfdc4b2ffc81c1424fb3c695a973cd..80553d1cd8ccde7a6cc9b324c6e5faba8d8f3579 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}'!" From patchwork Wed Mar 5 12:00:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudius Heine X-Patchwork-Id: 14002517 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 12D50C28B23 for ; Wed, 5 Mar 2025 12:00:33 +0000 (UTC) Received: from mx.denx.de (mx.denx.de [89.58.32.78]) by mx.groups.io with SMTP id smtpd.web10.11601.1741176028346165463 for ; Wed, 05 Mar 2025 04:00:28 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@denx.de header.s=mx-20241105 header.b=U+B3cn/W; spf=pass (domain: denx.de, ip: 89.58.32.78, mailfrom: ch@denx.de) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 8809E10381919; Wed, 5 Mar 2025 13:00:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=mx-20241105; t=1741176026; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=xcCyhcGu2r0nuRsIHgzPkBE3xajeJLfWmoOAiA62FXE=; b=U+B3cn/W5UnY5Oy1GavjyEMdnMEQb5i+0m/9CMut6657XGud31t4m72KLxvCJj6WZ8ubIR aDPwEK7gbrzE0iAcoejGysZhYpRnJ4pjolHUNviEP5uJJgXpKsIw9jaWt1PY4/MMBF+DBI gv3YZUesKGUS0KQFxL25krM6NOvURxOli7x8GIS19xFQ2WICMQ+8XQV57ctXxq4j3ZLJV+ c9I/thC+/vmHuNa/wTZv8D9jF1Dv3juqPQaQ5WjuSVfWuobROMfGXDwfz0t4VmVpnFW4Zz dQUCRGhBHZKAyezDMEHboDDht7Zva+9uSgZVSis7yf73qFhydM+z7JKohp7iwg== From: Claudius Heine Date: Wed, 05 Mar 2025 13:00:20 +0100 Subject: [PATCH v4 2/5] initramfs-crypt-hook: use static temporary encryption key MIME-Version: 1.0 Message-Id: <20250305-initramfs-crypt-hook-patches-2-v4-2-4170912e5261@denx.de> References: <20250305-initramfs-crypt-hook-patches-2-v4-0-4170912e5261@denx.de> In-Reply-To: <20250305-initramfs-crypt-hook-patches-2-v4-0-4170912e5261@denx.de> To: cip-dev@lists.cip-project.org Cc: Jan Kiszka , Quirin Gylstorff , Claudius Heine X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 05 Mar 2025 12:00:33 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/18043 Using a temporary random value for the temporary encryption key makes it impossible to continue encryption if it was aborted at a later date. Instead a static key can be used, which will allow the continuation of the encryption process. Security wise the partially encrypted volume, with a static temporary encryption key can be considered the same as the un-encrypted partition that was there before the system has booted. So using a known temporary encryption key should not affect the system security in that way. It is just important to let the re-encryption process properly finish until the temporary encryption key is removed. Signed-off-by: Claudius Heine --- recipes-initramfs/initramfs-crypt-hook/files/local-top-complete | 7 ++++--- recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete index ae0dcef4cb62a135beb6d4229237144b6d4edf8b..ea9b6352daadbea625d6168d1dc75ad616028fe0 100644 --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete @@ -259,10 +259,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" + blkid -s PARTUUID -o value "$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 df335c9f75d6e74b3e167689ec9c73dd3781a890..69d204e9539c2e5024db832e5b305fe73396317b 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,7 +39,7 @@ HOOK_ADD_MODULES = " \ ecb aes_generic xts" HOOK_COPY_EXECS = " \ - openssl mke2fs grep awk expr seq sleep basename uuidparse mountpoint \ + mke2fs grep awk expr seq sleep basename uuidparse mountpoint \ e2fsck resize2fs cryptsetup \ tpm2_pcrread tpm2_testparms tpm2_flushcontext \ /usr/lib/*/libgcc_s.so.1" From patchwork Wed Mar 5 12:00:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudius Heine X-Patchwork-Id: 14002515 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10C9EC282EC for ; Wed, 5 Mar 2025 12:00:33 +0000 (UTC) Received: from mx.denx.de (mx.denx.de [89.58.32.78]) by mx.groups.io with SMTP id smtpd.web11.11517.1741176029488306803 for ; Wed, 05 Mar 2025 04:00:29 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@denx.de header.s=mx-20241105 header.b=Tr8nFSLJ; spf=pass (domain: denx.de, ip: 89.58.32.78, mailfrom: ch@denx.de) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B378510382C18; Wed, 5 Mar 2025 13:00:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=mx-20241105; t=1741176027; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=r4vN1sk2JotAfbrSYXyPncgWgHVFX+8drF4NCit29gI=; b=Tr8nFSLJZRmcovSDYELmKj4qBjf1cirpphco1yhLFrnDGbbOqDac5Ahv/Ku0SGsYSvypSS xD+MeY4sCkFIy+0nZWOGLS7/Ffmu8bFo/1abHAWlnOJpsX+6kgiMpELOcNs+orsS5vwTRC wzUrcmbaf2MLWrn+kDXJ2mvOAZamSK/uGkesnSHnFugw4Q/WezrCTiiFQoWbq7OaS9GuwN EMr9aBr1ZHZfxYT1FV8AohlVX8d695rPG9hGxqG8r6DlhkCowY6lo3Ukjx48Cms+tRFvm6 SLPjhR/a4aYC21wKXEBSKbywiv4bCiZm9Qw23fVCP98EhvLZFrwXlYUkNFuTig== From: Claudius Heine Date: Wed, 05 Mar 2025 13:00:21 +0100 Subject: [PATCH v4 3/5] initramfs-crypt-hook: add re-encryption recovery MIME-Version: 1.0 Message-Id: <20250305-initramfs-crypt-hook-patches-2-v4-3-4170912e5261@denx.de> References: <20250305-initramfs-crypt-hook-patches-2-v4-0-4170912e5261@denx.de> In-Reply-To: <20250305-initramfs-crypt-hook-patches-2-v4-0-4170912e5261@denx.de> To: cip-dev@lists.cip-project.org Cc: Jan Kiszka , Quirin Gylstorff , Claudius Heine X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 05 Mar 2025 12:00:33 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/18044 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 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 --- .../initramfs-crypt-hook/files/local-top-complete | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete index ea9b6352daadbea625d6168d1dc75ad616028fe0..2660812b1689703336f1dbf3c07b7bbfb9f9b0f3 100644 --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete @@ -73,6 +73,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 @@ -91,14 +94,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 } @@ -248,11 +262,17 @@ for partition_set in $partition_sets; do fi 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" 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 + # service watchdog in the background during lengthy re-encryption if [ -z "$watchdog_pid" ]; then service_watchdog & From patchwork Wed Mar 5 12:00:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudius Heine X-Patchwork-Id: 14002516 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0EA87C28B21 for ; Wed, 5 Mar 2025 12:00:33 +0000 (UTC) Received: from mx.denx.de (mx.denx.de [89.58.32.78]) by mx.groups.io with SMTP id smtpd.web11.11518.1741176030915002824 for ; Wed, 05 Mar 2025 04:00:31 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@denx.de header.s=mx-20241105 header.b=Gky8XVAb; spf=pass (domain: denx.de, ip: 89.58.32.78, mailfrom: ch@denx.de) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DF65410381917; Wed, 5 Mar 2025 13:00:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=mx-20241105; t=1741176029; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=Ar9i5uoYNTSZOR9/ngQUlwwzjxUUGvbjeGVrXQYBa8A=; b=Gky8XVAbVuWQ6Qf7hF+gvAirtyPfqN22GszPrjPHFeya+bV8pE3YOmo4mgn/83bjCXRlWe XHO1EWCmkxIcUo6mfu1cauttHi5lIK3vHRwp21Fuv6su4OrGonUFvMNF3uJFZLd5y+6ZPo JIIaI9eNRint3gV1g8y/Y3y/bBaNBIxCyPIQh27ZfMSNvtOeOjgzG4k640gHsWMgqHmCBX UYDvNZZNI0Wz7RN5SwWe2JclQmZaA2rwc1OcvSGJUrmpdPgDGuCkt+xmwwYxU8cuGhcQDb XAcp5q7fBe/Ojb+Wdfwi/FrXDhno1t2hoKluju1hqML8dGFk1fgRgcuXB7NYnQ== From: Claudius Heine Date: Wed, 05 Mar 2025 13:00:22 +0100 Subject: [PATCH v4 4/5] initramfs-crypt-hook: implement 'noencrypt' option MIME-Version: 1.0 Message-Id: <20250305-initramfs-crypt-hook-patches-2-v4-4-4170912e5261@denx.de> References: <20250305-initramfs-crypt-hook-patches-2-v4-0-4170912e5261@denx.de> In-Reply-To: <20250305-initramfs-crypt-hook-patches-2-v4-0-4170912e5261@denx.de> To: cip-dev@lists.cip-project.org Cc: Jan Kiszka , Quirin Gylstorff , Claudius Heine X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 05 Mar 2025 12:00:33 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/18045 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 --- doc/README.tpm2.encryption.md | 22 +++++++++++++++++++- .../initramfs-crypt-hook/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 3f7e89f34fa4638a42285989e61370d8970afcde..2256f95a039044313807ab75ce219fa3eb7408b6 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 `::`. +Each entry uses the schema `::`. - 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 the field is currently unencrypted, and encryption should be added via an update. +- When the update fails, the fallback system needs to deal with an encrypted data partition. + +In this case, the fallback system needs to support an encrypted shared data partition but would not encrypt it on its own. 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: + +- Unencrypted system on slot A is running; the shared data partition has set the `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 2660812b1689703336f1dbf3c07b7bbfb9f9b0f3..e0b5372da92148fc8b2df86b7e4b491daf740c30 100644 --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete @@ -255,15 +255,18 @@ 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 "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: + if [ "$partition_mountpoint" = "/" ]; then + echo "ROOT=$decrypted_part" >/conf/param.conf + fi + continue fi @@ -273,6 +276,17 @@ for partition_set in $partition_sets; do partition_format="reencrypt" 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 & From patchwork Wed Mar 5 12:00:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudius Heine X-Patchwork-Id: 14002518 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2660FC28B22 for ; Wed, 5 Mar 2025 12:00:33 +0000 (UTC) Received: from mx.denx.de (mx.denx.de [89.58.32.78]) by mx.groups.io with SMTP id smtpd.web10.11603.1741176032200514431 for ; Wed, 05 Mar 2025 04:00:32 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@denx.de header.s=mx-20241105 header.b=Kelj/AD0; spf=pass (domain: denx.de, ip: 89.58.32.78, mailfrom: ch@denx.de) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 56C1E10382C18; Wed, 5 Mar 2025 13:00:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=mx-20241105; t=1741176030; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=4+9N6Y6c5GPVsH+WnJVAovrng7Vy6YdU2bRy98/2D70=; b=Kelj/AD00O8jRR9AI5SLhHmKCQ5LSBiShGl3If4sglUVTMQOJXJj/TdBWW8B4Cu3bS3fM9 bCXY+egQtVH2RB4qMtqiR3FPqYsmjL353f13HFgvjwUcKaQAWlWVYUk0sT/vxW0nqJfcUo nRXtQMeTvLCfgb3AOQ7Lg0zSL+LczWYS79XKRAEWOs+a2Mxq7Q7xamCsB6OZDtkTNyuhjB z5jbwwMnva2NRL2KE5wEtzOfShdbgAWjR6kT0wC5x4tP2OphBEdF1T405FboAFr8yYmEvz 2K+aEQAMKmFYGak37l/QGR1dOxqKJ9uaIfDzXNQJ/p9HD9fEnHiszRUs3TE+Sw== From: Claudius Heine Date: Wed, 05 Mar 2025 13:00:23 +0100 Subject: [PATCH v4 5/5] initramfs-crypt-hook: add 'format-if-empty' feature MIME-Version: 1.0 Message-Id: <20250305-initramfs-crypt-hook-patches-2-v4-5-4170912e5261@denx.de> References: <20250305-initramfs-crypt-hook-patches-2-v4-0-4170912e5261@denx.de> In-Reply-To: <20250305-initramfs-crypt-hook-patches-2-v4-0-4170912e5261@denx.de> To: cip-dev@lists.cip-project.org Cc: Jan Kiszka , Quirin Gylstorff , Claudius Heine X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 05 Mar 2025 12:00:33 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/18046 With the A/B update scheme, the goal is to have two (mostly) independent system slots, one that is active and one that is inactive. The active system slot writes updates to the inactive system slot and switches the active and inactive slot via a reboot. Late when booting the new system, it will decide if the current system is stable and then 'bless' it in the bootloader, or it will consider the update failed and the system reboots, without the updated system slot being blessed. In the last case, the system in the old slot will work as a fallback system, that reports the failed update back to the backend, and continue the service, as it has before the update was applied. It is important here that the update does not modify the fallback system in any avoidable way, because doing so might break the fallback and make the system not remotely recoverable. If encryption is added via an update, there are two cases to consider: 1. Update is applied to the inactive update slot via the normal update procedure. In this case the fallback system should not be modified. 2. A system that uses encryption is flashed via a factory flash. In this case there is no fallback system and all partitions of both update slots need to be encrypted. To differentiate between these cases, the content of each fallback partition can be looked at, if they contain data, we are in case (1) and these partitions should be left alone, if they contain only 0x00, they can be formatted, because we are in case (2). The `format-if-empty` option is implemented here, will look if the first 10 MiB of each partition marked with this option contains 0x00 or not and will either format it or leave it alone. Signed-off-by: Claudius Heine --- doc/README.tpm2.encryption.md | 5 ++++- .../initramfs-crypt-hook/files/local-top-complete | 16 ++++++++++++++++ .../initramfs-crypt-hook/initramfs-crypt-hook_0.6.bb | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/doc/README.tpm2.encryption.md b/doc/README.tpm2.encryption.md index 2256f95a039044313807ab75ce219fa3eb7408b6..3c29381209c5bec8aa0b031d941d23b7bf0cfd95 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 `::`. +Each entry uses the schema `::`. - 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 an empty LUKS partition and format it, like the `format` option, but only if the first 10 MiB 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 @@ -78,6 +79,8 @@ The data partition in the fallback system will have the `noencrypt` flag set, wh - 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. +In this case, where encryption is added via an update, the `format-if-empty` option is also useful. The system with encryption enabled has the `format-if-empty` option set for the partition(s) in the inactive update slot. This will cause both sets of partitions in both slots to be encrypted after the first boot on a fresh factory flashed system, but will not disturb existing data of any fallback system if booted after an update. + ### 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 e0b5372da92148fc8b2df86b7e4b491daf740c30..aa1910f0b75b98edae49ef3fad1573db758ca8bc 100644 --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete @@ -316,6 +316,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 69d204e9539c2e5024db832e5b305fe73396317b..ce139082de8da0eeffb4970df40afce7c5568e01 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 @@ -40,7 +40,7 @@ HOOK_ADD_MODULES = " \ HOOK_COPY_EXECS = " \ 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"