public inbox for cip-dev@lists.cip-project.org
 help / color / mirror / Atom feed
From: "Claudius Heine" <ch@denx.de>
To: "Jan Kiszka" <jan.kiszka@siemens.com>, <cip-dev@lists.cip-project.org>
Cc: "Quirin Gylstorff" <quirin.gylstorff@siemens.com>,
	"Heinisch Alexander" <alexander.heinisch@siemens.com>,
	"Cetin Gokhan" <gokhan.cetin@siemens.com>
Subject: Re: [PATCH v7 1/4] initramfs-crypt-hook: store initial encryption key in TPM2
Date: Thu, 26 Jun 2025 11:09:12 +0200	[thread overview]
Message-ID: <DAWCIGASLNSS.7IYFZ3C6183I@denx.de> (raw)
In-Reply-To: <ad98c6ad-d8e4-4e04-8e15-8281b087c88f@siemens.com>

On Mon Jun 16, 2025 at 12:06 PM CEST, Jan Kiszka wrote:
> On 16.06.25 11:30, Claudius Heine wrote:
>> cryptsetup and systemd-cryptenroll do not currently support encrypting
>> partitions directly with keys stored in the TPM. For that reason a
>> temporary random password is used for the initial encryption, which will
>> get removed once the TPM2 token is added to the partition.
>
> BTW, did you already try to discuss this use case with systemd at least?
> Not to see as pushback for these changes, but maybe we can once simplify
> things again if upstream address this as well.

I talked with systemd-devel about this:
https://lists.freedesktop.org/archives/systemd-devel/2025-June/051456.html

And from what I gather is that reencryption isn't supported by systemd
and likely will stay that way.

I was pointed to systemd-repart, but that doesn't have reencryption
support:
https://github.com/systemd/systemd/pull/29731

From what I gather, they have a very different approach to encrypting
file systems, that isn't compatible to the custom scripting that was
done here in cip-core.

IIUC: They already assume that some key was programmed into the TPM2
(SRK-key), and then use systemd-repart to create new encrypted
partitions using that key and use `CopyFiles` directive to copy plain
text files to the encrypted file system from somewhere.

regards,
Claudius

>
> Jan
>
>> 
>> However this process does not allow continuing with the encryption
>> process in case of power failure.
>> 
>> For that reason store the initial encryption password in the TPM,
>> protected via measured boot based on the TPM2-PCR:7 register, which is
>> the default for `systemd-cryptenroll` and load it if it exists.
>> 
>> Signed-off-by: Claudius Heine <ch@denx.de>
>> ---
>>  .../initramfs-crypt-hook/files/local-top-complete  | 56 ++++++++++++++++++++--
>>  .../initramfs-crypt-hook_0.7.bb                    | 13 ++---
>>  2 files changed, 60 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 ae0dcef4cb62a135beb6d4229237144b6d4edf8b..e511e8ef2d0bd4f4c8fd2fca248312dee173d224 100644
>> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
>> @@ -216,6 +216,54 @@ if [ ! -e "$tpm_device" ]; then
>>  	panic "No tpm device exists or supports pcr_hash '$pcr_bank_hash_type' or '$tpm_key_algorithm' - cannot create a encrypted device!"
>>  fi
>>  
>> +export TPM2TOOLS_TCTI="device:${tpm_device}"
>> +TPM2_HANDLE="0x81080001"
>> +tpm2_key_get() {
>> +	key_file="$1"
>> +	TPM2_WORKDIR="/tmp/tpm2"
>> +
>> +	if ! tpm2_getcap handles-persistent | grep -q "$TPM2_HANDLE"; then
>> +		mkdir -p "${TPM2_WORKDIR}"
>> +		# Open session:
>> +		tpm2_startauthsession -S "${TPM2_WORKDIR}/session.ctx"
>> +		tpm2_policypcr -Q -S "${TPM2_WORKDIR}/session.ctx" \
>> +			-l "${HASH_TYPE}:7" \
>> +			-L "${TPM2_WORKDIR}/pcr7.${HASH_TYPE}.policy"
>> +		tpm2_flushcontext "${TPM2_WORKDIR}/session.ctx"
>> +
>> +		# Add new key to tpm:
>> +		tpm2_createprimary -Q -C o -c "${TPM2_WORKDIR}/prim.ctx"
>> +		echo "$(tr -dc 'A-Za-z0-9_' </dev/urandom | head -c 32)" | \
>> +			tpm2_create -Q -g "sha256" \
>> +				-u "${TPM2_WORKDIR}/pcr_seal_key.pub" \
>> +				-r "${TPM2_WORKDIR}/pcr_seal_key.priv" \
>> +				-i- \
>> +				-C "${TPM2_WORKDIR}/prim.ctx" \
>> +				-L "${TPM2_WORKDIR}/pcr7.${HASH_TYPE}.policy"
>> +		tpm2_load -Q \
>> +			-C "${TPM2_WORKDIR}/prim.ctx" \
>> +			-u "${TPM2_WORKDIR}/pcr_seal_key.pub" \
>> +			-r "${TPM2_WORKDIR}/pcr_seal_key.priv" \
>> +			-n "${TPM2_WORKDIR}/pcr_seal_key.name" \
>> +			-c "${TPM2_WORKDIR}/pcr_seal_key.ctx"
>> +		tpm2_evictcontrol -c "${TPM2_WORKDIR}/pcr_seal_key.ctx" \
>> +			"$TPM2_HANDLE" -C o
>> +
>> +		rm -rf "${TPM2_WORKDIR}"
>> +	fi
>> +
>> +	mkdir -p "${TPM2_WORKDIR}"
>> +	tpm2_startauthsession --policy-session -S "${TPM2_WORKDIR}/session.ctx"
>> +	tpm2_policypcr -Q -S "${TPM2_WORKDIR}/session.ctx" -l "${HASH_TYPE}:7"
>> +	tpm2_unseal -p "session:${TPM2_WORKDIR}/session.ctx" -c "$TPM2_HANDLE" >"$key_file"
>> +	tpm2_flushcontext "${TPM2_WORKDIR}/session.ctx"
>> +	rm -rf "${TPM2_WORKDIR}"
>> +}
>> +
>> +tpm2_key_del() {
>> +	tpm2_evictcontrol -C o -c "$TPM2_HANDLE"
>> +}
>> +
>>  prepare_for_encryption
>>  
>>  for partition_set in $partition_sets; do
>> @@ -259,16 +307,17 @@ for partition_set in $partition_sets; do
>>  		watchdog_pid=$!
>>  	fi
>>  
>> -	# create random password for initial encryption
>> -	# this will be dropped after reboot
>> +	# create random password, store it in the tpm2 encrypted and protected with
>> +	# PCR:7 registers to allow continuing reencryption in case of power-failure.
>>  	tmp_key=/tmp/"$(basename "$part_device")-lukskey"
>> -	openssl rand -base64 32 > "$tmp_key"
>> +	tpm2_key_get "${tmp_key}"
>>  
>>  	case "${partition_format}" in
>>  		"reencrypt")
>>  			log_begin_msg "Encryption of ${part_device}"
>>  			reencrypt_existing_partition "$part_device" "$tmp_key"
>>  			enroll_tpm2_token "$part_device" "$tmp_key" "$tpm_device" "$tpm_key_algorithm" "$pcr_bank_hash_type"
>> +			tpm2_key_del
>>  			open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
>>  			log_end_msg
>>  		;;
>> @@ -277,6 +326,7 @@ for partition_set in $partition_sets; do
>>  			/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"
>> +			tpm2_key_del
>>  			open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
>>  			eval "${create_file_system_cmd} ${decrypted_part}"
>>  			log_end_msg
>> diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.7.bb b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.7.bb
>> index 80a4755e4e0acfc96bb2d0f8e175e2787473e384..b48c6e89384f7f43737fdbb3438d5be15bb5945e 100644
>> --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.7.bb
>> +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.7.bb
>> @@ -14,7 +14,6 @@ require recipes-initramfs/initramfs-hook/hook.inc
>>  DEBIAN_DEPENDS .= ", \
>>      cryptsetup, \
>>      awk, \
>> -    openssl, \
>>      e2fsprogs, \
>>      tpm2-tools, \
>>      coreutils, \
>> @@ -40,19 +39,21 @@ HOOK_ADD_MODULES = " \
>>      ecb aes_generic xts"
>>  
>>  HOOK_COPY_EXECS = " \
>> -    openssl mke2fs grep awk expr seq sleep basename uuidparse mountpoint \
>> -    e2fsck resize2fs cryptsetup \
>> -    tpm2_pcrread tpm2_testparms tpm2_flushcontext \
>> +    mke2fs grep awk expr seq sleep basename uuidparse mountpoint \
>> +    e2fsck resize2fs cryptsetup head tr rm \
>> +    tpm2_pcrread tpm2_testparms tpm2_flushcontext tpm2_startauthsession \
>> +    tpm2_policypcr tpm2_createprimary tpm2_create tpm2_load tpm2_evictcontrol \
>> +    tpm2_unseal tpm2_getcap \
>>      /usr/lib/*/libgcc_s.so.1"
>>  
>>  HOOK_COPY_EXECS:append:clevis = " \
>>      clevis clevis-decrypt clevis-encrypt-tpm2 clevis-decrypt-tpm2 \
>>      clevis-luks-bind clevis-luks-unlock \
>>      clevis-luks-list clevis-luks-common-functions \
>> -    tpm2_createprimary tpm2_unseal tpm2_create tpm2_load tpm2_createpolicy \
>> +    tpm2_createpolicy \
>>      bash luksmeta jose sed tail sort rm mktemp pwmake file"
>>  HOOK_COPY_EXECS:append:systemd = " \
>> -    systemd-cryptenroll tpm2_pcrread tpm2_testparms \
>> +    systemd-cryptenroll \
>>      /usr/lib/systemd/systemd-cryptsetup \
>>      /usr/lib/*/cryptsetup/libcryptsetup-token-systemd-tpm2.so"
>>  
>> 




-- 
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



  reply	other threads:[~2025-06-26  9:09 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-16  9:30 [PATCH v7 0/4] initramfs-crypt-hook patch Claudius Heine
2025-06-16  9:30 ` [PATCH v7 1/4] initramfs-crypt-hook: store initial encryption key in TPM2 Claudius Heine
2025-06-16 10:06   ` Jan Kiszka
2025-06-26  9:09     ` Claudius Heine [this message]
2025-06-16  9:30 ` [PATCH v7 2/4] initramfs-crypt-hook: add re-encryption recovery Claudius Heine
2025-06-16  9:30 ` [PATCH v7 3/4] initramfs-crypt-hook: implement 'noencrypt' option Claudius Heine
2025-06-16  9:30 ` [PATCH v7 4/4] initramfs-crypt-hook: add 'format-if-empty' feature 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=DAWCIGASLNSS.7IYFZ3C6183I@denx.de \
    --to=ch@denx.de \
    --cc=alexander.heinisch@siemens.com \
    --cc=cip-dev@lists.cip-project.org \
    --cc=gokhan.cetin@siemens.com \
    --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