Message ID | 20240715134630.1640160-3-stefan-koch@siemens.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v3,1/4] initramfs-crypt-hook: Do not attempt to repair a partially encrypted filesystem | expand |
On 7/15/24 3:46 PM, Stefan Koch wrote: > As the reencrypt mechanism doesn't work at file system level > so it wouldn't detect used and free blocks. > This means that the block-wise reencryption process could > take a very long time depending on the partition size. > > Using the format mechanism instead of the reencrypt one > would delete all existing data (without wiping). This would be very fast, > because it doesn't matter whether a block is used or free. > > Set CRYPT_FAST_REENCRYPTION to "1" to speed-up the reencrypt process. > So, this would be done: > - Obtain used space of the unencrypted userdata partition > - Shrink the partition and resize it to the size of used space (minimum size) > - reencrypt the userdata partition now with smaller size > - Expand the encrypted userdata partition back to the maximum possible size Why not simple use expand-on-first-boot. It has support for encrypted disks and does this without adding something to the initramfs? Quirin > > Some disk encryption implementations like within the Debian installer > will overwrite the entire partition with random data for security reasons > (e.g. wiping old already deleted data, hiding metadata, etc.). > > However, this speed-up lacks the described security benefit of implicit data overwrite. > So for security reasons, it behaves identical to the format option > (there is no support for explicit random overwrite within initramfs-crypt-hook). > > Keep in mind that a power loss while reencryption will cause data loss > (with or without fast reencryption). > The key is only enrolled after fully succeeded reencryption, yet. > So, no recovery from already encrypted data would be possible. > > Signed-off-by: Stefan Koch <stefan-koch@siemens.com> > --- > .../files/encrypt_partition.env.tmpl | 1 + > .../files/encrypt_partition.script | 53 ++++++++++++++++--- > .../initramfs-crypt-hook_0.2.bb | 8 +++ > 3 files changed, 55 insertions(+), 7 deletions(-) > > diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl > index bb93361..2b02f55 100644 > --- a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl > +++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl > @@ -5,3 +5,4 @@ WATCHDOG_DEV="${INITRAMFS_WATCHDOG_DEVICE}" > HASH_TYPE="${CRYPT_HASH_TYPE}" > KEY_ALGORITHM="${CRYPT_KEY_ALGORITHM}" > ENCRYPTION_IS_OPTIONAL="${CRYPT_ENCRYPTION_OPTIONAL}" > +FAST_REENCRYPTION="${CRYPT_FAST_REENCRYPTION}" > diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script > index f943aea..7bb40c9 100644 > --- a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script > +++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script > @@ -54,6 +54,9 @@ if [ -z "${create_file_system_cmd}" ]; then > create_file_system_cmd="mke2fs -t ext4" > fi > > +# Path to full (non-busybox) losetup binary > +losetup_path="/usr/local/sbin/losetup" > + > service_watchdog() { > for n in $(seq $(($SETUP_TIMEOUT / 10)) ); do > printf '\0' > @@ -62,13 +65,16 @@ service_watchdog() { > } > > reencrypt_existing_partition() { > + reencrypt_device="$1" > part_size_blocks="$(cat /sys/class/block/"$(awk -v dev="$1" 'BEGIN{split(dev,a,"/"); print a[3]}' )"/size)" > - # reduce the filesystem and partition by 32M to fit the LUKS header > + part_size_in_kb="$(expr "$part_size_blocks" / 2)" # blocksize 512 byte > + > partition_fstype=$(get_fstype "${1}") > + # reduce the filesystem and partition by 32M to fit the LUKS header > reduce_device_size=32768 > - reduced_size="$(expr "$part_size_blocks" - 65536 )" > - reduced_size_in_byte="$(expr "$reduced_size" \* 512)" > - reduced_size_in_kb="$(expr "$reduced_size_in_byte" / 1024)K" > + reduce_device_size_blocks="$(expr "$reduce_device_size" \* 2)" # 512 byte blocks > + reduced_size="$(expr "$part_size_blocks" - "$reduce_device_size_blocks" )" > + reduced_size_in_kb="$(expr "$reduced_size" / 2)" # blocksize 512 byte > case $partition_fstype in > ext*) > # reduce the filesystem and partition by 32M to fit the LUKS header > @@ -84,9 +90,31 @@ EOF > if ! cryptsetup luksUUID "$1" &> /dev/null; then > e2fsck -p -f "$1" > fi > - if ! resize2fs "$1" "${reduced_size_in_kb}"; then > + # shrink partition temporarily to minimum > + min_size_fsblocks="$(resize2fs "$1" -P | awk -F ": " '{ print $2 }')" > + if [ "$FAST_REENCRYPTION" = "1" ] && loop_device="$("$losetup_path" -f)" && [ -n "$min_size_fsblocks" ]; then > + # set encrypted size for expanding step > + encrypted_size_in_kb="$reduced_size_in_kb" > + # minimum partition size > + min_size_in_kb="$(expr "$min_size_fsblocks" \* 4)" # blocksize 4096 byte > + # shrinked partition size (reduce_size + minimum partition size) > + reduced_size_in_kb="$(expr "$reduce_device_size" + "$min_size_in_kb")" > + # set loop device as reencrypt device > + reencrypt_device="$loop_device" > + else > + # continue with default reencryption in failure case > + FAST_REENCRYPTION="0" > + fi > + > + if ! resize2fs "$1" "${reduced_size_in_kb}K"; then > panic "reencryption of filesystem $1 cannot continue!" > fi > + > + if [ "$FAST_REENCRYPTION" = "1" ]; then > + # use temporarily loop device to simulate shrinked device > + # because cryptsetup uses device size at reducing > + "$losetup_path" --sizelimit "${reduced_size_in_kb}K" "$loop_device" "$1" > + fi > ;; > squashfs|swap|"") > [ "$debug" = "y" ] && echo "skip disk resize as it is not supported or unnecessary for fstype: '$partition_fstype'" > @@ -96,9 +124,14 @@ EOF > ;; > 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 --reduce-device-size "$reduce_device_size"k "$reencrypt_device" < "$2" > else > - /usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-size "$reduce_device_size"k "$1" < "$2" > + /usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-size "$reduce_device_size"k "$reencrypt_device" < "$2" > + fi > + > + if [ "$FAST_REENCRYPTION" = "1" ]; then > + # remove temporarily loop device > + "$losetup_path" -d "$loop_device" > fi > } > for candidate in /dev/tpm*; do > @@ -182,6 +215,12 @@ for partition_set in $partition_sets; do > reencrypt_existing_partition "$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" > + if [ "$FAST_REENCRYPTION" = "1" ]; then > + # expand encrypted partition to maximum > + /usr/sbin/cryptsetup resize "$decrypted_part" > + # expand filesystem within encrypted layer to maximum > + resize2fs "$decrypted_part" "${encrypted_size_in_kb}K" > + fi > log_end_msg > ;; > "format") > diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb > index 3497d95..e3dd515 100644 > --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb > +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb > @@ -57,6 +57,13 @@ CRYPT_PARTITIONS ??= "home:/home:reencrypt var:/var:reencrypt" > # CRYPT_CREATE_FILE_SYSTEM_CMD contains the shell command to create the filesystem > # in a newly formatted LUKS Partition > CRYPT_CREATE_FILE_SYSTEM_CMD ??= "/usr/sbin/mke2fs -t ext4" > +# Fast reencryption state > +# It uses temporary partition resize, > +# consider security and data reliablity aspects when enabling > +# (e.g. wiping old already deleted data, hiding metadata, etc.) > +# Keep in mind that a power loss while reencryption will cause data loss > +# (with or without fast reencryption). > +CRYPT_FAST_REENCRYPTION ??= "0" > # Timeout for creating / re-encrypting partitions on first boot > CRYPT_SETUP_TIMEOUT ??= "600" > # Watchdog to service during the initial setup of the crypto partitions > @@ -68,6 +75,7 @@ CRYPT_ENCRYPTION_OPTIONAL ??= "false" > > TEMPLATE_VARS = "CRYPT_PARTITIONS CRYPT_CREATE_FILE_SYSTEM_CMD \ > CRYPT_SETUP_TIMEOUT INITRAMFS_WATCHDOG_DEVICE CRYPT_HASH_TYPE \ > + CRYPT_FAST_REENCRYPTION \ > CRYPT_KEY_ALGORITHM CRYPT_ENCRYPTION_OPTIONAL" > TEMPLATE_FILES = "encrypt_partition.env.tmpl" >
On Tue, 2024-07-16 at 10:08 +0200, Gylstorff Quirin wrote: > > > On 7/15/24 3:46 PM, Stefan Koch wrote: > > As the reencrypt mechanism doesn't work at file system level > > so it wouldn't detect used and free blocks. > > This means that the block-wise reencryption process could > > take a very long time depending on the partition size. > > > > Using the format mechanism instead of the reencrypt one > > would delete all existing data (without wiping). This would be very > > fast, > > because it doesn't matter whether a block is used or free. > > > > Set CRYPT_FAST_REENCRYPTION to "1" to speed-up the reencrypt > > process. > > So, this would be done: > > - Obtain used space of the unencrypted userdata partition > > - Shrink the partition and resize it to the size of used space > > (minimum size) > > - reencrypt the userdata partition now with smaller size > > - Expand the encrypted userdata partition back to the maximum > > possible size > > Why not simple use expand-on-first-boot. It has support for encrypted > disks and does this without adding something to the initramfs? > Quirin When using it on devices that are still at customer side, shrinking is needed, too ("reencrypt" of existing data). But keep in mind, that a power loss at reencryption will destroy all data. Because the key is stored within the TPM *after* reencryption has succeed. > > > > Some disk encryption implementations like within the Debian > > installer > > will overwrite the entire partition with random data for security > > reasons > > (e.g. wiping old already deleted data, hiding metadata, etc.). > > > > However, this speed-up lacks the described security benefit of > > implicit data overwrite. > > So for security reasons, it behaves identical to the format option > > (there is no support for explicit random overwrite within > > initramfs-crypt-hook). > > > > Keep in mind that a power loss while reencryption will cause data > > loss > > (with or without fast reencryption). > > The key is only enrolled after fully succeeded reencryption, yet. > > So, no recovery from already encrypted data would be possible. > > > > Signed-off-by: Stefan Koch <stefan-koch@siemens.com> > > --- > > .../files/encrypt_partition.env.tmpl | 1 + > > .../files/encrypt_partition.script | 53 > > ++++++++++++++++--- > > .../initramfs-crypt-hook_0.2.bb | 8 +++ > > 3 files changed, 55 insertions(+), 7 deletions(-) > > > > diff --git a/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.env.tmpl b/recipes- > > initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl > > index bb93361..2b02f55 100644 > > --- a/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.env.tmpl > > +++ b/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.env.tmpl > > @@ -5,3 +5,4 @@ WATCHDOG_DEV="${INITRAMFS_WATCHDOG_DEVICE}" > > HASH_TYPE="${CRYPT_HASH_TYPE}" > > KEY_ALGORITHM="${CRYPT_KEY_ALGORITHM}" > > ENCRYPTION_IS_OPTIONAL="${CRYPT_ENCRYPTION_OPTIONAL}" > > +FAST_REENCRYPTION="${CRYPT_FAST_REENCRYPTION}" > > diff --git a/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.script b/recipes-initramfs/initramfs- > > crypt-hook/files/encrypt_partition.script > > index f943aea..7bb40c9 100644 > > --- a/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.script > > +++ b/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.script > > @@ -54,6 +54,9 @@ if [ -z "${create_file_system_cmd}" ]; then > > create_file_system_cmd="mke2fs -t ext4" > > fi > > > > +# Path to full (non-busybox) losetup binary > > +losetup_path="/usr/local/sbin/losetup" > > + > > service_watchdog() { > > for n in $(seq $(($SETUP_TIMEOUT / 10)) ); do > > printf '\0' > > @@ -62,13 +65,16 @@ service_watchdog() { > > } > > > > reencrypt_existing_partition() { > > + reencrypt_device="$1" > > part_size_blocks="$(cat /sys/class/block/"$(awk -v dev="$1" > > 'BEGIN{split(dev,a,"/"); print a[3]}' )"/size)" > > - # reduce the filesystem and partition by 32M to fit the > > LUKS header > > + part_size_in_kb="$(expr "$part_size_blocks" / 2)" # > > blocksize 512 byte > > + > > partition_fstype=$(get_fstype "${1}") > > + # reduce the filesystem and partition by 32M to fit the > > LUKS header > > reduce_device_size=32768 > > - reduced_size="$(expr "$part_size_blocks" - 65536 )" > > - reduced_size_in_byte="$(expr "$reduced_size" \* 512)" > > - reduced_size_in_kb="$(expr "$reduced_size_in_byte" / > > 1024)K" > > + reduce_device_size_blocks="$(expr "$reduce_device_size" \* > > 2)" # 512 byte blocks > > + reduced_size="$(expr "$part_size_blocks" - > > "$reduce_device_size_blocks" )" > > + reduced_size_in_kb="$(expr "$reduced_size" / 2)" # > > blocksize 512 byte > > case $partition_fstype in > > ext*) > > # reduce the filesystem and partition by 32M to fit > > the LUKS header > > @@ -84,9 +90,31 @@ EOF > > if ! cryptsetup luksUUID "$1" &> /dev/null; then > > e2fsck -p -f "$1" > > fi > > - if ! resize2fs "$1" "${reduced_size_in_kb}"; then > > + # shrink partition temporarily to minimum > > + min_size_fsblocks="$(resize2fs "$1" -P | awk -F ": > > " '{ print $2 }')" > > + if [ "$FAST_REENCRYPTION" = "1" ] && > > loop_device="$("$losetup_path" -f)" && [ -n "$min_size_fsblocks" ]; > > then > > + # set encrypted size for expanding step > > + encrypted_size_in_kb="$reduced_size_in_kb" > > + # minimum partition size > > + min_size_in_kb="$(expr "$min_size_fsblocks" > > \* 4)" # blocksize 4096 byte > > + # shrinked partition size (reduce_size + > > minimum partition size) > > + reduced_size_in_kb="$(expr > > "$reduce_device_size" + "$min_size_in_kb")" > > + # set loop device as reencrypt device > > + reencrypt_device="$loop_device" > > + else > > + # continue with default reencryption in > > failure case > > + FAST_REENCRYPTION="0" > > + fi > > + > > + if ! resize2fs "$1" "${reduced_size_in_kb}K"; then > > panic "reencryption of filesystem $1 cannot > > continue!" > > fi > > + > > + if [ "$FAST_REENCRYPTION" = "1" ]; then > > + # use temporarily loop device to simulate > > shrinked device > > + # because cryptsetup uses device size at > > reducing > > + "$losetup_path" --sizelimit > > "${reduced_size_in_kb}K" "$loop_device" "$1" > > + fi > > ;; > > squashfs|swap|"") > > [ "$debug" = "y" ] && echo "skip disk resize as it > > is not supported or unnecessary for fstype: '$partition_fstype'" > > @@ -96,9 +124,14 @@ EOF > > ;; > > 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 --reduce- > > device-size "$reduce_device_size"k "$reencrypt_device" < "$2" > > else > > - /usr/sbin/cryptsetup reencrypt --encrypt --reduce- > > device-size "$reduce_device_size"k "$1" < "$2" > > + /usr/sbin/cryptsetup reencrypt --encrypt --reduce- > > device-size "$reduce_device_size"k "$reencrypt_device" < "$2" > > + fi > > + > > + if [ "$FAST_REENCRYPTION" = "1" ]; then > > + # remove temporarily loop device > > + "$losetup_path" -d "$loop_device" > > fi > > } > > for candidate in /dev/tpm*; do > > @@ -182,6 +215,12 @@ for partition_set in $partition_sets; do > > reencrypt_existing_partition "$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" > > + if [ "$FAST_REENCRYPTION" = "1" ]; then > > + # expand encrypted partition to > > maximum > > + /usr/sbin/cryptsetup resize > > "$decrypted_part" > > + # expand filesystem within > > encrypted layer to maximum > > + resize2fs "$decrypted_part" > > "${encrypted_size_in_kb}K" > > + fi > > log_end_msg > > ;; > > "format") > > diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs- > > crypt-hook_0.2.bb b/recipes-initramfs/initramfs-crypt- > > hook/initramfs-crypt-hook_0.2.bb > > index 3497d95..e3dd515 100644 > > --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt- > > hook_0.2.bb > > +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt- > > hook_0.2.bb > > @@ -57,6 +57,13 @@ CRYPT_PARTITIONS ??= "home:/home:reencrypt > > var:/var:reencrypt" > > # CRYPT_CREATE_FILE_SYSTEM_CMD contains the shell command to > > create the filesystem > > # in a newly formatted LUKS Partition > > CRYPT_CREATE_FILE_SYSTEM_CMD ??= "/usr/sbin/mke2fs -t ext4" > > +# Fast reencryption state > > +# It uses temporary partition resize, > > +# consider security and data reliablity aspects when enabling > > +# (e.g. wiping old already deleted data, hiding metadata, etc.) > > +# Keep in mind that a power loss while reencryption will cause > > data loss > > +# (with or without fast reencryption). > > +CRYPT_FAST_REENCRYPTION ??= "0" > > # Timeout for creating / re-encrypting partitions on first boot > > CRYPT_SETUP_TIMEOUT ??= "600" > > # Watchdog to service during the initial setup of the crypto > > partitions > > @@ -68,6 +75,7 @@ CRYPT_ENCRYPTION_OPTIONAL ??= "false" > > > > TEMPLATE_VARS = "CRYPT_PARTITIONS CRYPT_CREATE_FILE_SYSTEM_CMD \ > > CRYPT_SETUP_TIMEOUT INITRAMFS_WATCHDOG_DEVICE CRYPT_HASH_TYPE > > \ > > + CRYPT_FAST_REENCRYPTION \ > > CRYPT_KEY_ALGORITHM CRYPT_ENCRYPTION_OPTIONAL" > > TEMPLATE_FILES = "encrypt_partition.env.tmpl" > >
On 7/16/24 10:13 AM, Koch, Stefan (DI PA DCP R&D 3) wrote: > On Tue, 2024-07-16 at 10:08 +0200, Gylstorff Quirin wrote: >> >> >> On 7/15/24 3:46 PM, Stefan Koch wrote: >>> As the reencrypt mechanism doesn't work at file system level >>> so it wouldn't detect used and free blocks. >>> This means that the block-wise reencryption process could >>> take a very long time depending on the partition size. >>> >>> Using the format mechanism instead of the reencrypt one >>> would delete all existing data (without wiping). This would be very >>> fast, >>> because it doesn't matter whether a block is used or free. >>> >>> Set CRYPT_FAST_REENCRYPTION to "1" to speed-up the reencrypt >>> process. >>> So, this would be done: >>> - Obtain used space of the unencrypted userdata partition >>> - Shrink the partition and resize it to the size of used space >>> (minimum size) >>> - reencrypt the userdata partition now with smaller size >>> - Expand the encrypted userdata partition back to the maximum >>> possible size >> >> Why not simple use expand-on-first-boot. It has support for encrypted >> disks and does this without adding something to the initramfs? >> Quirin > When using it on devices that are still at customer side, shrinking is > needed, too ("reencrypt" of existing data). So we are talking about the case of updating an existing device with a expanded partition. > But keep in mind, that a power loss at reencryption will destroy all > data. Because the key is stored within the TPM *after* reencryption has > succeed. Then let us solve this by trying to store the initial encryption key in the TPM. Instead of resizing which will have no impact in the worst case. >>> >>> Some disk encryption implementations like within the Debian >>> installer >>> will overwrite the entire partition with random data for security >>> reasons >>> (e.g. wiping old already deleted data, hiding metadata, etc.). >>> >>> However, this speed-up lacks the described security benefit of >>> implicit data overwrite. >>> So for security reasons, it behaves identical to the format option >>> (there is no support for explicit random overwrite within >>> initramfs-crypt-hook). The initramfs must not do that. If this is required it should be done in an installer. Quirin >>> >>> Keep in mind that a power loss while reencryption will cause data >>> loss >>> (with or without fast reencryption). >>> The key is only enrolled after fully succeeded reencryption, yet. >>> So, no recovery from already encrypted data would be possible. >>> >>> Signed-off-by: Stefan Koch <stefan-koch@siemens.com> >>> --- >>> .../files/encrypt_partition.env.tmpl | 1 + >>> .../files/encrypt_partition.script | 53 >>> ++++++++++++++++--- >>> .../initramfs-crypt-hook_0.2.bb | 8 +++ >>> 3 files changed, 55 insertions(+), 7 deletions(-) >>> >>> diff --git a/recipes-initramfs/initramfs-crypt- >>> hook/files/encrypt_partition.env.tmpl b/recipes- >>> initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl >>> index bb93361..2b02f55 100644 >>> --- a/recipes-initramfs/initramfs-crypt- >>> hook/files/encrypt_partition.env.tmpl >>> +++ b/recipes-initramfs/initramfs-crypt- >>> hook/files/encrypt_partition.env.tmpl >>> @@ -5,3 +5,4 @@ WATCHDOG_DEV="${INITRAMFS_WATCHDOG_DEVICE}" >>> HASH_TYPE="${CRYPT_HASH_TYPE}" >>> KEY_ALGORITHM="${CRYPT_KEY_ALGORITHM}" >>> ENCRYPTION_IS_OPTIONAL="${CRYPT_ENCRYPTION_OPTIONAL}" >>> +FAST_REENCRYPTION="${CRYPT_FAST_REENCRYPTION}" >>> diff --git a/recipes-initramfs/initramfs-crypt- >>> hook/files/encrypt_partition.script b/recipes-initramfs/initramfs- >>> crypt-hook/files/encrypt_partition.script >>> index f943aea..7bb40c9 100644 >>> --- a/recipes-initramfs/initramfs-crypt- >>> hook/files/encrypt_partition.script >>> +++ b/recipes-initramfs/initramfs-crypt- >>> hook/files/encrypt_partition.script >>> @@ -54,6 +54,9 @@ if [ -z "${create_file_system_cmd}" ]; then >>> create_file_system_cmd="mke2fs -t ext4" >>> fi >>> >>> +# Path to full (non-busybox) losetup binary >>> +losetup_path="/usr/local/sbin/losetup" >>> + >>> service_watchdog() { >>> for n in $(seq $(($SETUP_TIMEOUT / 10)) ); do >>> printf '\0' >>> @@ -62,13 +65,16 @@ service_watchdog() { >>> } >>> >>> reencrypt_existing_partition() { >>> + reencrypt_device="$1" >>> part_size_blocks="$(cat /sys/class/block/"$(awk -v dev="$1" >>> 'BEGIN{split(dev,a,"/"); print a[3]}' )"/size)" >>> - # reduce the filesystem and partition by 32M to fit the >>> LUKS header >>> + part_size_in_kb="$(expr "$part_size_blocks" / 2)" # >>> blocksize 512 byte >>> + >>> partition_fstype=$(get_fstype "${1}") >>> + # reduce the filesystem and partition by 32M to fit the >>> LUKS header >>> reduce_device_size=32768 >>> - reduced_size="$(expr "$part_size_blocks" - 65536 )" >>> - reduced_size_in_byte="$(expr "$reduced_size" \* 512)" >>> - reduced_size_in_kb="$(expr "$reduced_size_in_byte" / >>> 1024)K" >>> + reduce_device_size_blocks="$(expr "$reduce_device_size" \* >>> 2)" # 512 byte blocks >>> + reduced_size="$(expr "$part_size_blocks" - >>> "$reduce_device_size_blocks" )" >>> + reduced_size_in_kb="$(expr "$reduced_size" / 2)" # >>> blocksize 512 byte >>> case $partition_fstype in >>> ext*) >>> # reduce the filesystem and partition by 32M to fit >>> the LUKS header >>> @@ -84,9 +90,31 @@ EOF >>> if ! cryptsetup luksUUID "$1" &> /dev/null; then >>> e2fsck -p -f "$1" >>> fi >>> - if ! resize2fs "$1" "${reduced_size_in_kb}"; then >>> + # shrink partition temporarily to minimum >>> + min_size_fsblocks="$(resize2fs "$1" -P | awk -F ": >>> " '{ print $2 }')" >>> + if [ "$FAST_REENCRYPTION" = "1" ] && >>> loop_device="$("$losetup_path" -f)" && [ -n "$min_size_fsblocks" ]; >>> then >>> + # set encrypted size for expanding step >>> + encrypted_size_in_kb="$reduced_size_in_kb" >>> + # minimum partition size >>> + min_size_in_kb="$(expr "$min_size_fsblocks" >>> \* 4)" # blocksize 4096 byte >>> + # shrinked partition size (reduce_size + >>> minimum partition size) >>> + reduced_size_in_kb="$(expr >>> "$reduce_device_size" + "$min_size_in_kb")" >>> + # set loop device as reencrypt device >>> + reencrypt_device="$loop_device" >>> + else >>> + # continue with default reencryption in >>> failure case >>> + FAST_REENCRYPTION="0" >>> + fi >>> + >>> + if ! resize2fs "$1" "${reduced_size_in_kb}K"; then >>> panic "reencryption of filesystem $1 cannot >>> continue!" >>> fi >>> + >>> + if [ "$FAST_REENCRYPTION" = "1" ]; then >>> + # use temporarily loop device to simulate >>> shrinked device >>> + # because cryptsetup uses device size at >>> reducing >>> + "$losetup_path" --sizelimit >>> "${reduced_size_in_kb}K" "$loop_device" "$1" >>> + fi >>> ;; >>> squashfs|swap|"") >>> [ "$debug" = "y" ] && echo "skip disk resize as it >>> is not supported or unnecessary for fstype: '$partition_fstype'" >>> @@ -96,9 +124,14 @@ EOF >>> ;; >>> 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 --reduce- >>> device-size "$reduce_device_size"k "$reencrypt_device" < "$2" >>> else >>> - /usr/sbin/cryptsetup reencrypt --encrypt --reduce- >>> device-size "$reduce_device_size"k "$1" < "$2" >>> + /usr/sbin/cryptsetup reencrypt --encrypt --reduce- >>> device-size "$reduce_device_size"k "$reencrypt_device" < "$2" >>> + fi >>> + >>> + if [ "$FAST_REENCRYPTION" = "1" ]; then >>> + # remove temporarily loop device >>> + "$losetup_path" -d "$loop_device" >>> fi >>> } >>> for candidate in /dev/tpm*; do >>> @@ -182,6 +215,12 @@ for partition_set in $partition_sets; do >>> reencrypt_existing_partition "$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" >>> + if [ "$FAST_REENCRYPTION" = "1" ]; then >>> + # expand encrypted partition to >>> maximum >>> + /usr/sbin/cryptsetup resize >>> "$decrypted_part" >>> + # expand filesystem within >>> encrypted layer to maximum >>> + resize2fs "$decrypted_part" >>> "${encrypted_size_in_kb}K" >>> + fi >>> log_end_msg >>> ;; >>> "format") >>> diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs- >>> crypt-hook_0.2.bb b/recipes-initramfs/initramfs-crypt- >>> hook/initramfs-crypt-hook_0.2.bb >>> index 3497d95..e3dd515 100644 >>> --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt- >>> hook_0.2.bb >>> +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt- >>> hook_0.2.bb >>> @@ -57,6 +57,13 @@ CRYPT_PARTITIONS ??= "home:/home:reencrypt >>> var:/var:reencrypt" >>> # CRYPT_CREATE_FILE_SYSTEM_CMD contains the shell command to >>> create the filesystem >>> # in a newly formatted LUKS Partition >>> CRYPT_CREATE_FILE_SYSTEM_CMD ??= "/usr/sbin/mke2fs -t ext4" >>> +# Fast reencryption state >>> +# It uses temporary partition resize, >>> +# consider security and data reliablity aspects when enabling >>> +# (e.g. wiping old already deleted data, hiding metadata, etc.) >>> +# Keep in mind that a power loss while reencryption will cause >>> data loss >>> +# (with or without fast reencryption). >>> +CRYPT_FAST_REENCRYPTION ??= "0" >>> # Timeout for creating / re-encrypting partitions on first boot >>> CRYPT_SETUP_TIMEOUT ??= "600" >>> # Watchdog to service during the initial setup of the crypto >>> partitions >>> @@ -68,6 +75,7 @@ CRYPT_ENCRYPTION_OPTIONAL ??= "false" >>> >>> TEMPLATE_VARS = "CRYPT_PARTITIONS CRYPT_CREATE_FILE_SYSTEM_CMD \ >>> CRYPT_SETUP_TIMEOUT INITRAMFS_WATCHDOG_DEVICE CRYPT_HASH_TYPE >>> \ >>> + CRYPT_FAST_REENCRYPTION \ >>> CRYPT_KEY_ALGORITHM CRYPT_ENCRYPTION_OPTIONAL" >>> TEMPLATE_FILES = "encrypt_partition.env.tmpl" >>> >
On Tue, 2024-07-16 at 13:43 +0200, Gylstorff Quirin wrote: > > > On 7/16/24 10:13 AM, Koch, Stefan (DI PA DCP R&D 3) wrote: > > On Tue, 2024-07-16 at 10:08 +0200, Gylstorff Quirin wrote: > > > > > > > > > On 7/15/24 3:46 PM, Stefan Koch wrote: > > > > As the reencrypt mechanism doesn't work at file system level > > > > so it wouldn't detect used and free blocks. > > > > This means that the block-wise reencryption process could > > > > take a very long time depending on the partition size. > > > > > > > > Using the format mechanism instead of the reencrypt one > > > > would delete all existing data (without wiping). This would be > > > > very > > > > fast, > > > > because it doesn't matter whether a block is used or free. > > > > > > > > Set CRYPT_FAST_REENCRYPTION to "1" to speed-up the reencrypt > > > > process. > > > > So, this would be done: > > > > - Obtain used space of the unencrypted userdata partition > > > > - Shrink the partition and resize it to the size of used space > > > > (minimum size) > > > > - reencrypt the userdata partition now with smaller size > > > > - Expand the encrypted userdata partition back to the maximum > > > > possible size > > > > > > Why not simple use expand-on-first-boot. It has support for > > > encrypted > > > disks and does this without adding something to the initramfs? > > > Quirin > > When using it on devices that are still at customer side, shrinking > > is > > needed, too ("reencrypt" of existing data). > > So we are talking about the case of updating an existing device with > a > expanded partition. > And that device needs ~45 minutes to reencrypt. Event with working resume of disk-encryption's cryptsetup reencrypt too much. > > > But keep in mind, that a power loss at reencryption will destroy > > all > > data. Because the key is stored within the TPM *after* reencryption > > has > > succeed. > Then let us solve this by trying to store the initial encryption key > in > the TPM. Instead of resizing which will have no impact in the worst > case. > Played a bit around in an early initramfs stage before the disk- encryption-hook was active: Debian bookworm's cryptsetup can automatically use the TPM2 systemd-cryptenroll binding. Just use "cryptsetup open" without defining any key type. > > > > > > > > > Some disk encryption implementations like within the Debian > > > > installer > > > > will overwrite the entire partition with random data for > > > > security > > > > reasons > > > > (e.g. wiping old already deleted data, hiding metadata, etc.). > > > > > > > > However, this speed-up lacks the described security benefit of > > > > implicit data overwrite. > > > > So for security reasons, it behaves identical to the format > > > > option > > > > (there is no support for explicit random overwrite within > > > > initramfs-crypt-hook). > > The initramfs must not do that. If this is required it should be done > in > an installer. > > Quirin Without "speed-up" it was implicit due to block wise operation on free and used blocks (only filesystem knows about this not cryptsetup reencrypt). > > > > > > > > Keep in mind that a power loss while reencryption will cause > > > > data > > > > loss > > > > (with or without fast reencryption). > > > > The key is only enrolled after fully succeeded reencryption, > > > > yet. > > > > So, no recovery from already encrypted data would be possible. > > > > > > > > Signed-off-by: Stefan Koch <stefan-koch@siemens.com> > > > > --- > > > > .../files/encrypt_partition.env.tmpl | 1 + > > > > .../files/encrypt_partition.script | 53 > > > > ++++++++++++++++--- > > > > .../initramfs-crypt-hook_0.2.bb | 8 +++ > > > > 3 files changed, 55 insertions(+), 7 deletions(-) > > > > > > > > diff --git a/recipes-initramfs/initramfs-crypt- > > > > hook/files/encrypt_partition.env.tmpl b/recipes- > > > > initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl > > > > index bb93361..2b02f55 100644 > > > > --- a/recipes-initramfs/initramfs-crypt- > > > > hook/files/encrypt_partition.env.tmpl > > > > +++ b/recipes-initramfs/initramfs-crypt- > > > > hook/files/encrypt_partition.env.tmpl > > > > @@ -5,3 +5,4 @@ WATCHDOG_DEV="${INITRAMFS_WATCHDOG_DEVICE}" > > > > HASH_TYPE="${CRYPT_HASH_TYPE}" > > > > KEY_ALGORITHM="${CRYPT_KEY_ALGORITHM}" > > > > ENCRYPTION_IS_OPTIONAL="${CRYPT_ENCRYPTION_OPTIONAL}" > > > > +FAST_REENCRYPTION="${CRYPT_FAST_REENCRYPTION}" > > > > diff --git a/recipes-initramfs/initramfs-crypt- > > > > hook/files/encrypt_partition.script b/recipes- > > > > initramfs/initramfs- > > > > crypt-hook/files/encrypt_partition.script > > > > index f943aea..7bb40c9 100644 > > > > --- a/recipes-initramfs/initramfs-crypt- > > > > hook/files/encrypt_partition.script > > > > +++ b/recipes-initramfs/initramfs-crypt- > > > > hook/files/encrypt_partition.script > > > > @@ -54,6 +54,9 @@ if [ -z "${create_file_system_cmd}" ]; then > > > > create_file_system_cmd="mke2fs -t ext4" > > > > fi > > > > > > > > +# Path to full (non-busybox) losetup binary > > > > +losetup_path="/usr/local/sbin/losetup" > > > > + > > > > service_watchdog() { > > > > for n in $(seq $(($SETUP_TIMEOUT / 10)) ); do > > > > printf '\0' > > > > @@ -62,13 +65,16 @@ service_watchdog() { > > > > } > > > > > > > > reencrypt_existing_partition() { > > > > + reencrypt_device="$1" > > > > part_size_blocks="$(cat /sys/class/block/"$(awk -v > > > > dev="$1" > > > > 'BEGIN{split(dev,a,"/"); print a[3]}' )"/size)" > > > > - # reduce the filesystem and partition by 32M to fit the > > > > LUKS header > > > > + part_size_in_kb="$(expr "$part_size_blocks" / 2)" # > > > > blocksize 512 byte > > > > + > > > > partition_fstype=$(get_fstype "${1}") > > > > + # reduce the filesystem and partition by 32M to fit the > > > > LUKS header > > > > reduce_device_size=32768 > > > > - reduced_size="$(expr "$part_size_blocks" - 65536 )" > > > > - reduced_size_in_byte="$(expr "$reduced_size" \* 512)" > > > > - reduced_size_in_kb="$(expr "$reduced_size_in_byte" / > > > > 1024)K" > > > > + reduce_device_size_blocks="$(expr "$reduce_device_size" > > > > \* > > > > 2)" # 512 byte blocks > > > > + reduced_size="$(expr "$part_size_blocks" - > > > > "$reduce_device_size_blocks" )" > > > > + reduced_size_in_kb="$(expr "$reduced_size" / 2)" # > > > > blocksize 512 byte > > > > case $partition_fstype in > > > > ext*) > > > > # reduce the filesystem and partition by 32M > > > > to fit > > > > the LUKS header > > > > @@ -84,9 +90,31 @@ EOF > > > > if ! cryptsetup luksUUID "$1" &> /dev/null; > > > > then > > > > e2fsck -p -f "$1" > > > > fi > > > > - if ! resize2fs "$1" "${reduced_size_in_kb}"; > > > > then > > > > + # shrink partition temporarily to minimum > > > > + min_size_fsblocks="$(resize2fs "$1" -P | awk -F > > > > ": > > > > " '{ print $2 }')" > > > > + if [ "$FAST_REENCRYPTION" = "1" ] && > > > > loop_device="$("$losetup_path" -f)" && [ -n > > > > "$min_size_fsblocks" ]; > > > > then > > > > + # set encrypted size for expanding step > > > > + encrypted_size_in_kb="$reduced_size_in_ > > > > kb" > > > > + # minimum partition size > > > > + min_size_in_kb="$(expr > > > > "$min_size_fsblocks" > > > > \* 4)" # blocksize 4096 byte > > > > + # shrinked partition size (reduce_size > > > > + > > > > minimum partition size) > > > > + reduced_size_in_kb="$(expr > > > > "$reduce_device_size" + "$min_size_in_kb")" > > > > + # set loop device as reencrypt device > > > > + reencrypt_device="$loop_device" > > > > + else > > > > + # continue with default reencryption in > > > > failure case > > > > + FAST_REENCRYPTION="0" > > > > + fi > > > > + > > > > + if ! resize2fs "$1" "${reduced_size_in_kb}K"; > > > > then > > > > panic "reencryption of filesystem $1 > > > > cannot > > > > continue!" > > > > fi > > > > + > > > > + if [ "$FAST_REENCRYPTION" = "1" ]; then > > > > + # use temporarily loop device to > > > > simulate > > > > shrinked device > > > > + # because cryptsetup uses device size > > > > at > > > > reducing > > > > + "$losetup_path" --sizelimit > > > > "${reduced_size_in_kb}K" "$loop_device" "$1" > > > > + fi > > > > ;; > > > > squashfs|swap|"") > > > > [ "$debug" = "y" ] && echo "skip disk resize > > > > as it > > > > is not supported or unnecessary for fstype: > > > > '$partition_fstype'" > > > > @@ -96,9 +124,14 @@ EOF > > > > ;; > > > > 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 --reduce- > > > > device-size "$reduce_device_size"k "$reencrypt_device" < "$2" > > > > else > > > > - /usr/sbin/cryptsetup reencrypt --encrypt -- > > > > reduce- > > > > device-size "$reduce_device_size"k "$1" < "$2" > > > > + /usr/sbin/cryptsetup reencrypt --encrypt -- > > > > reduce- > > > > device-size "$reduce_device_size"k "$reencrypt_device" < "$2" > > > > + fi > > > > + > > > > + if [ "$FAST_REENCRYPTION" = "1" ]; then > > > > + # remove temporarily loop device > > > > + "$losetup_path" -d "$loop_device" > > > > fi > > > > } > > > > for candidate in /dev/tpm*; do > > > > @@ -182,6 +215,12 @@ for partition_set in $partition_sets; do > > > > reencrypt_existing_partition > > > > "$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" > > > > + if [ "$FAST_REENCRYPTION" = "1" ]; then > > > > + # expand encrypted partition to > > > > maximum > > > > + /usr/sbin/cryptsetup resize > > > > "$decrypted_part" > > > > + # expand filesystem within > > > > encrypted layer to maximum > > > > + resize2fs "$decrypted_part" > > > > "${encrypted_size_in_kb}K" > > > > + fi > > > > log_end_msg > > > > ;; > > > > "format") > > > > diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs- > > > > crypt-hook_0.2.bb b/recipes-initramfs/initramfs-crypt- > > > > hook/initramfs-crypt-hook_0.2.bb > > > > index 3497d95..e3dd515 100644 > > > > --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt- > > > > hook_0.2.bb > > > > +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt- > > > > hook_0.2.bb > > > > @@ -57,6 +57,13 @@ CRYPT_PARTITIONS ??= "home:/home:reencrypt > > > > var:/var:reencrypt" > > > > # CRYPT_CREATE_FILE_SYSTEM_CMD contains the shell command to > > > > create the filesystem > > > > # in a newly formatted LUKS Partition > > > > CRYPT_CREATE_FILE_SYSTEM_CMD ??= "/usr/sbin/mke2fs -t ext4" > > > > +# Fast reencryption state > > > > +# It uses temporary partition resize, > > > > +# consider security and data reliablity aspects when enabling > > > > +# (e.g. wiping old already deleted data, hiding metadata, > > > > etc.) > > > > +# Keep in mind that a power loss while reencryption will cause > > > > data loss > > > > +# (with or without fast reencryption). > > > > +CRYPT_FAST_REENCRYPTION ??= "0" > > > > # Timeout for creating / re-encrypting partitions on first > > > > boot > > > > CRYPT_SETUP_TIMEOUT ??= "600" > > > > # Watchdog to service during the initial setup of the crypto > > > > partitions > > > > @@ -68,6 +75,7 @@ CRYPT_ENCRYPTION_OPTIONAL ??= "false" > > > > > > > > TEMPLATE_VARS = "CRYPT_PARTITIONS > > > > CRYPT_CREATE_FILE_SYSTEM_CMD \ > > > > CRYPT_SETUP_TIMEOUT INITRAMFS_WATCHDOG_DEVICE > > > > CRYPT_HASH_TYPE > > > > \ > > > > + CRYPT_FAST_REENCRYPTION \ > > > > CRYPT_KEY_ALGORITHM CRYPT_ENCRYPTION_OPTIONAL" > > > > TEMPLATE_FILES = "encrypt_partition.env.tmpl" > > > > > >
On 7/15/24 3:46 PM, Stefan Koch wrote: > As the reencrypt mechanism doesn't work at file system level > so it wouldn't detect used and free blocks. > This means that the block-wise reencryption process could > take a very long time depending on the partition size. > > Using the format mechanism instead of the reencrypt one > would delete all existing data (without wiping). This would be very fast, > because it doesn't matter whether a block is used or free. > > Set CRYPT_FAST_REENCRYPTION to "1" to speed-up the reencrypt process. > So, this would be done: > - Obtain used space of the unencrypted userdata partition > - Shrink the partition and resize it to the size of used space (minimum size) > - reencrypt the userdata partition now with smaller size > - Expand the encrypted userdata partition back to the maximum possible size > > Some disk encryption implementations like within the Debian installer > will overwrite the entire partition with random data for security reasons > (e.g. wiping old already deleted data, hiding metadata, etc.). > > However, this speed-up lacks the described security benefit of implicit data overwrite. > So for security reasons, it behaves identical to the format option > (there is no support for explicit random overwrite within initramfs-crypt-hook). > > Keep in mind that a power loss while reencryption will cause data loss > (with or without fast reencryption). > The key is only enrolled after fully succeeded reencryption, yet. > So, no recovery from already encrypted data would be possible. You don't mention why the losetup is necessary additional to the parameter `--reduce-device-size` of cryptsetup. Quirin > > Signed-off-by: Stefan Koch <stefan-koch@siemens.com> > --- > .../files/encrypt_partition.env.tmpl | 1 + > .../files/encrypt_partition.script | 53 ++++++++++++++++--- > .../initramfs-crypt-hook_0.2.bb | 8 +++ > 3 files changed, 55 insertions(+), 7 deletions(-) > > diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl > index bb93361..2b02f55 100644 > --- a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl > +++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl > @@ -5,3 +5,4 @@ WATCHDOG_DEV="${INITRAMFS_WATCHDOG_DEVICE}" > HASH_TYPE="${CRYPT_HASH_TYPE}" > KEY_ALGORITHM="${CRYPT_KEY_ALGORITHM}" > ENCRYPTION_IS_OPTIONAL="${CRYPT_ENCRYPTION_OPTIONAL}" > +FAST_REENCRYPTION="${CRYPT_FAST_REENCRYPTION}" > diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script > index f943aea..7bb40c9 100644 > --- a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script > +++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script > @@ -54,6 +54,9 @@ if [ -z "${create_file_system_cmd}" ]; then > create_file_system_cmd="mke2fs -t ext4" > fi > > +# Path to full (non-busybox) losetup binary > +losetup_path="/usr/local/sbin/losetup" > + > service_watchdog() { > for n in $(seq $(($SETUP_TIMEOUT / 10)) ); do > printf '\0' > @@ -62,13 +65,16 @@ service_watchdog() { > } > > reencrypt_existing_partition() { > + reencrypt_device="$1" > part_size_blocks="$(cat /sys/class/block/"$(awk -v dev="$1" 'BEGIN{split(dev,a,"/"); print a[3]}' )"/size)" > - # reduce the filesystem and partition by 32M to fit the LUKS header > + part_size_in_kb="$(expr "$part_size_blocks" / 2)" # blocksize 512 byte > + > partition_fstype=$(get_fstype "${1}") > + # reduce the filesystem and partition by 32M to fit the LUKS header > reduce_device_size=32768 > - reduced_size="$(expr "$part_size_blocks" - 65536 )" > - reduced_size_in_byte="$(expr "$reduced_size" \* 512)" > - reduced_size_in_kb="$(expr "$reduced_size_in_byte" / 1024)K" > + reduce_device_size_blocks="$(expr "$reduce_device_size" \* 2)" # 512 byte blocks > + reduced_size="$(expr "$part_size_blocks" - "$reduce_device_size_blocks" )" > + reduced_size_in_kb="$(expr "$reduced_size" / 2)" # blocksize 512 byte > case $partition_fstype in > ext*) > # reduce the filesystem and partition by 32M to fit the LUKS header > @@ -84,9 +90,31 @@ EOF > if ! cryptsetup luksUUID "$1" &> /dev/null; then > e2fsck -p -f "$1" > fi > - if ! resize2fs "$1" "${reduced_size_in_kb}"; then > + # shrink partition temporarily to minimum > + min_size_fsblocks="$(resize2fs "$1" -P | awk -F ": " '{ print $2 }')" > + if [ "$FAST_REENCRYPTION" = "1" ] && loop_device="$("$losetup_path" -f)" && [ -n "$min_size_fsblocks" ]; then > + # set encrypted size for expanding step > + encrypted_size_in_kb="$reduced_size_in_kb" > + # minimum partition size > + min_size_in_kb="$(expr "$min_size_fsblocks" \* 4)" # blocksize 4096 byte > + # shrinked partition size (reduce_size + minimum partition size) > + reduced_size_in_kb="$(expr "$reduce_device_size" + "$min_size_in_kb")" > + # set loop device as reencrypt device > + reencrypt_device="$loop_device" > + else > + # continue with default reencryption in failure case > + FAST_REENCRYPTION="0" > + fi > + > + if ! resize2fs "$1" "${reduced_size_in_kb}K"; then > panic "reencryption of filesystem $1 cannot continue!" > fi > + > + if [ "$FAST_REENCRYPTION" = "1" ]; then > + # use temporarily loop device to simulate shrinked device > + # because cryptsetup uses device size at reducing > + "$losetup_path" --sizelimit "${reduced_size_in_kb}K" "$loop_device" "$1" > + fi > ;; > squashfs|swap|"") > [ "$debug" = "y" ] && echo "skip disk resize as it is not supported or unnecessary for fstype: '$partition_fstype'" > @@ -96,9 +124,14 @@ EOF > ;; > 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 --reduce-device-size "$reduce_device_size"k "$reencrypt_device" < "$2" > else > - /usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-size "$reduce_device_size"k "$1" < "$2" > + /usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-size "$reduce_device_size"k "$reencrypt_device" < "$2" > + fi > + > + if [ "$FAST_REENCRYPTION" = "1" ]; then > + # remove temporarily loop device > + "$losetup_path" -d "$loop_device" > fi > } > for candidate in /dev/tpm*; do > @@ -182,6 +215,12 @@ for partition_set in $partition_sets; do > reencrypt_existing_partition "$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" > + if [ "$FAST_REENCRYPTION" = "1" ]; then > + # expand encrypted partition to maximum > + /usr/sbin/cryptsetup resize "$decrypted_part" > + # expand filesystem within encrypted layer to maximum > + resize2fs "$decrypted_part" "${encrypted_size_in_kb}K" > + fi > log_end_msg > ;; > "format") > diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb > index 3497d95..e3dd515 100644 > --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb > +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb > @@ -57,6 +57,13 @@ CRYPT_PARTITIONS ??= "home:/home:reencrypt var:/var:reencrypt" > # CRYPT_CREATE_FILE_SYSTEM_CMD contains the shell command to create the filesystem > # in a newly formatted LUKS Partition > CRYPT_CREATE_FILE_SYSTEM_CMD ??= "/usr/sbin/mke2fs -t ext4" > +# Fast reencryption state > +# It uses temporary partition resize, > +# consider security and data reliablity aspects when enabling > +# (e.g. wiping old already deleted data, hiding metadata, etc.) > +# Keep in mind that a power loss while reencryption will cause data loss > +# (with or without fast reencryption). > +CRYPT_FAST_REENCRYPTION ??= "0" > # Timeout for creating / re-encrypting partitions on first boot > CRYPT_SETUP_TIMEOUT ??= "600" > # Watchdog to service during the initial setup of the crypto partitions > @@ -68,6 +75,7 @@ CRYPT_ENCRYPTION_OPTIONAL ??= "false" > > TEMPLATE_VARS = "CRYPT_PARTITIONS CRYPT_CREATE_FILE_SYSTEM_CMD \ > CRYPT_SETUP_TIMEOUT INITRAMFS_WATCHDOG_DEVICE CRYPT_HASH_TYPE \ > + CRYPT_FAST_REENCRYPTION \ > CRYPT_KEY_ALGORITHM CRYPT_ENCRYPTION_OPTIONAL" > TEMPLATE_FILES = "encrypt_partition.env.tmpl" >
On Wed, 2024-07-17 at 15:06 +0200, Gylstorff Quirin wrote: > > > On 7/15/24 3:46 PM, Stefan Koch wrote: > > As the reencrypt mechanism doesn't work at file system level > > so it wouldn't detect used and free blocks. > > This means that the block-wise reencryption process could > > take a very long time depending on the partition size. > > > > Using the format mechanism instead of the reencrypt one > > would delete all existing data (without wiping). This would be very > > fast, > > because it doesn't matter whether a block is used or free. > > > > Set CRYPT_FAST_REENCRYPTION to "1" to speed-up the reencrypt > > process. > > So, this would be done: > > - Obtain used space of the unencrypted userdata partition > > - Shrink the partition and resize it to the size of used space > > (minimum size) > > - reencrypt the userdata partition now with smaller size > > - Expand the encrypted userdata partition back to the maximum > > possible size > > > > Some disk encryption implementations like within the Debian > > installer > > will overwrite the entire partition with random data for security > > reasons > > (e.g. wiping old already deleted data, hiding metadata, etc.). > > > > However, this speed-up lacks the described security benefit of > > implicit data overwrite. > > So for security reasons, it behaves identical to the format option > > (there is no support for explicit random overwrite within > > initramfs-crypt-hook). > > > > Keep in mind that a power loss while reencryption will cause data > > loss > > (with or without fast reencryption). > > The key is only enrolled after fully succeeded reencryption, yet. > > So, no recovery from already encrypted data would be possible. > > > You don't mention why the losetup is necessary additional to the > parameter `--reduce-device-size` of cryptsetup. > > Quirin I'll send an updated patchset including this and the other remaining review comments. > > > > Signed-off-by: Stefan Koch <stefan-koch@siemens.com> > > --- > > .../files/encrypt_partition.env.tmpl | 1 + > > .../files/encrypt_partition.script | 53 > > ++++++++++++++++--- > > .../initramfs-crypt-hook_0.2.bb | 8 +++ > > 3 files changed, 55 insertions(+), 7 deletions(-) > > > > diff --git a/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.env.tmpl b/recipes- > > initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl > > index bb93361..2b02f55 100644 > > --- a/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.env.tmpl > > +++ b/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.env.tmpl > > @@ -5,3 +5,4 @@ WATCHDOG_DEV="${INITRAMFS_WATCHDOG_DEVICE}" > > HASH_TYPE="${CRYPT_HASH_TYPE}" > > KEY_ALGORITHM="${CRYPT_KEY_ALGORITHM}" > > ENCRYPTION_IS_OPTIONAL="${CRYPT_ENCRYPTION_OPTIONAL}" > > +FAST_REENCRYPTION="${CRYPT_FAST_REENCRYPTION}" > > diff --git a/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.script b/recipes-initramfs/initramfs- > > crypt-hook/files/encrypt_partition.script > > index f943aea..7bb40c9 100644 > > --- a/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.script > > +++ b/recipes-initramfs/initramfs-crypt- > > hook/files/encrypt_partition.script > > @@ -54,6 +54,9 @@ if [ -z "${create_file_system_cmd}" ]; then > > create_file_system_cmd="mke2fs -t ext4" > > fi > > > > +# Path to full (non-busybox) losetup binary > > +losetup_path="/usr/local/sbin/losetup" > > + > > service_watchdog() { > > for n in $(seq $(($SETUP_TIMEOUT / 10)) ); do > > printf '\0' > > @@ -62,13 +65,16 @@ service_watchdog() { > > } > > > > reencrypt_existing_partition() { > > + reencrypt_device="$1" > > part_size_blocks="$(cat /sys/class/block/"$(awk -v dev="$1" > > 'BEGIN{split(dev,a,"/"); print a[3]}' )"/size)" > > - # reduce the filesystem and partition by 32M to fit the > > LUKS header > > + part_size_in_kb="$(expr "$part_size_blocks" / 2)" # > > blocksize 512 byte > > + > > partition_fstype=$(get_fstype "${1}") > > + # reduce the filesystem and partition by 32M to fit the > > LUKS header > > reduce_device_size=32768 > > - reduced_size="$(expr "$part_size_blocks" - 65536 )" > > - reduced_size_in_byte="$(expr "$reduced_size" \* 512)" > > - reduced_size_in_kb="$(expr "$reduced_size_in_byte" / > > 1024)K" > > + reduce_device_size_blocks="$(expr "$reduce_device_size" \* > > 2)" # 512 byte blocks > > + reduced_size="$(expr "$part_size_blocks" - > > "$reduce_device_size_blocks" )" > > + reduced_size_in_kb="$(expr "$reduced_size" / 2)" # > > blocksize 512 byte > > case $partition_fstype in > > ext*) > > # reduce the filesystem and partition by 32M to fit > > the LUKS header > > @@ -84,9 +90,31 @@ EOF > > if ! cryptsetup luksUUID "$1" &> /dev/null; then > > e2fsck -p -f "$1" > > fi > > - if ! resize2fs "$1" "${reduced_size_in_kb}"; then > > + # shrink partition temporarily to minimum > > + min_size_fsblocks="$(resize2fs "$1" -P | awk -F ": > > " '{ print $2 }')" > > + if [ "$FAST_REENCRYPTION" = "1" ] && > > loop_device="$("$losetup_path" -f)" && [ -n "$min_size_fsblocks" ]; > > then > > + # set encrypted size for expanding step > > + encrypted_size_in_kb="$reduced_size_in_kb" > > + # minimum partition size > > + min_size_in_kb="$(expr "$min_size_fsblocks" > > \* 4)" # blocksize 4096 byte > > + # shrinked partition size (reduce_size + > > minimum partition size) > > + reduced_size_in_kb="$(expr > > "$reduce_device_size" + "$min_size_in_kb")" > > + # set loop device as reencrypt device > > + reencrypt_device="$loop_device" > > + else > > + # continue with default reencryption in > > failure case > > + FAST_REENCRYPTION="0" > > + fi > > + > > + if ! resize2fs "$1" "${reduced_size_in_kb}K"; then > > panic "reencryption of filesystem $1 cannot > > continue!" > > fi > > + > > + if [ "$FAST_REENCRYPTION" = "1" ]; then > > + # use temporarily loop device to simulate > > shrinked device > > + # because cryptsetup uses device size at > > reducing > > + "$losetup_path" --sizelimit > > "${reduced_size_in_kb}K" "$loop_device" "$1" > > + fi > > ;; > > squashfs|swap|"") > > [ "$debug" = "y" ] && echo "skip disk resize as it > > is not supported or unnecessary for fstype: '$partition_fstype'" > > @@ -96,9 +124,14 @@ EOF > > ;; > > 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 --reduce- > > device-size "$reduce_device_size"k "$reencrypt_device" < "$2" > > else > > - /usr/sbin/cryptsetup reencrypt --encrypt --reduce- > > device-size "$reduce_device_size"k "$1" < "$2" > > + /usr/sbin/cryptsetup reencrypt --encrypt --reduce- > > device-size "$reduce_device_size"k "$reencrypt_device" < "$2" > > + fi > > + > > + if [ "$FAST_REENCRYPTION" = "1" ]; then > > + # remove temporarily loop device > > + "$losetup_path" -d "$loop_device" > > fi > > } > > for candidate in /dev/tpm*; do > > @@ -182,6 +215,12 @@ for partition_set in $partition_sets; do > > reencrypt_existing_partition "$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" > > + if [ "$FAST_REENCRYPTION" = "1" ]; then > > + # expand encrypted partition to > > maximum > > + /usr/sbin/cryptsetup resize > > "$decrypted_part" > > + # expand filesystem within > > encrypted layer to maximum > > + resize2fs "$decrypted_part" > > "${encrypted_size_in_kb}K" > > + fi > > log_end_msg > > ;; > > "format") > > diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs- > > crypt-hook_0.2.bb b/recipes-initramfs/initramfs-crypt- > > hook/initramfs-crypt-hook_0.2.bb > > index 3497d95..e3dd515 100644 > > --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt- > > hook_0.2.bb > > +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt- > > hook_0.2.bb > > @@ -57,6 +57,13 @@ CRYPT_PARTITIONS ??= "home:/home:reencrypt > > var:/var:reencrypt" > > # CRYPT_CREATE_FILE_SYSTEM_CMD contains the shell command to > > create the filesystem > > # in a newly formatted LUKS Partition > > CRYPT_CREATE_FILE_SYSTEM_CMD ??= "/usr/sbin/mke2fs -t ext4" > > +# Fast reencryption state > > +# It uses temporary partition resize, > > +# consider security and data reliablity aspects when enabling > > +# (e.g. wiping old already deleted data, hiding metadata, etc.) > > +# Keep in mind that a power loss while reencryption will cause > > data loss > > +# (with or without fast reencryption). > > +CRYPT_FAST_REENCRYPTION ??= "0" > > # Timeout for creating / re-encrypting partitions on first boot > > CRYPT_SETUP_TIMEOUT ??= "600" > > # Watchdog to service during the initial setup of the crypto > > partitions > > @@ -68,6 +75,7 @@ CRYPT_ENCRYPTION_OPTIONAL ??= "false" > > > > TEMPLATE_VARS = "CRYPT_PARTITIONS CRYPT_CREATE_FILE_SYSTEM_CMD \ > > CRYPT_SETUP_TIMEOUT INITRAMFS_WATCHDOG_DEVICE CRYPT_HASH_TYPE > > \ > > + CRYPT_FAST_REENCRYPTION \ > > CRYPT_KEY_ALGORITHM CRYPT_ENCRYPTION_OPTIONAL" > > TEMPLATE_FILES = "encrypt_partition.env.tmpl" > >
diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl index bb93361..2b02f55 100644 --- a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl +++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.env.tmpl @@ -5,3 +5,4 @@ WATCHDOG_DEV="${INITRAMFS_WATCHDOG_DEVICE}" HASH_TYPE="${CRYPT_HASH_TYPE}" KEY_ALGORITHM="${CRYPT_KEY_ALGORITHM}" ENCRYPTION_IS_OPTIONAL="${CRYPT_ENCRYPTION_OPTIONAL}" +FAST_REENCRYPTION="${CRYPT_FAST_REENCRYPTION}" diff --git a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script index f943aea..7bb40c9 100644 --- a/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script +++ b/recipes-initramfs/initramfs-crypt-hook/files/encrypt_partition.script @@ -54,6 +54,9 @@ if [ -z "${create_file_system_cmd}" ]; then create_file_system_cmd="mke2fs -t ext4" fi +# Path to full (non-busybox) losetup binary +losetup_path="/usr/local/sbin/losetup" + service_watchdog() { for n in $(seq $(($SETUP_TIMEOUT / 10)) ); do printf '\0' @@ -62,13 +65,16 @@ service_watchdog() { } reencrypt_existing_partition() { + reencrypt_device="$1" part_size_blocks="$(cat /sys/class/block/"$(awk -v dev="$1" 'BEGIN{split(dev,a,"/"); print a[3]}' )"/size)" - # reduce the filesystem and partition by 32M to fit the LUKS header + part_size_in_kb="$(expr "$part_size_blocks" / 2)" # blocksize 512 byte + partition_fstype=$(get_fstype "${1}") + # reduce the filesystem and partition by 32M to fit the LUKS header reduce_device_size=32768 - reduced_size="$(expr "$part_size_blocks" - 65536 )" - reduced_size_in_byte="$(expr "$reduced_size" \* 512)" - reduced_size_in_kb="$(expr "$reduced_size_in_byte" / 1024)K" + reduce_device_size_blocks="$(expr "$reduce_device_size" \* 2)" # 512 byte blocks + reduced_size="$(expr "$part_size_blocks" - "$reduce_device_size_blocks" )" + reduced_size_in_kb="$(expr "$reduced_size" / 2)" # blocksize 512 byte case $partition_fstype in ext*) # reduce the filesystem and partition by 32M to fit the LUKS header @@ -84,9 +90,31 @@ EOF if ! cryptsetup luksUUID "$1" &> /dev/null; then e2fsck -p -f "$1" fi - if ! resize2fs "$1" "${reduced_size_in_kb}"; then + # shrink partition temporarily to minimum + min_size_fsblocks="$(resize2fs "$1" -P | awk -F ": " '{ print $2 }')" + if [ "$FAST_REENCRYPTION" = "1" ] && loop_device="$("$losetup_path" -f)" && [ -n "$min_size_fsblocks" ]; then + # set encrypted size for expanding step + encrypted_size_in_kb="$reduced_size_in_kb" + # minimum partition size + min_size_in_kb="$(expr "$min_size_fsblocks" \* 4)" # blocksize 4096 byte + # shrinked partition size (reduce_size + minimum partition size) + reduced_size_in_kb="$(expr "$reduce_device_size" + "$min_size_in_kb")" + # set loop device as reencrypt device + reencrypt_device="$loop_device" + else + # continue with default reencryption in failure case + FAST_REENCRYPTION="0" + fi + + if ! resize2fs "$1" "${reduced_size_in_kb}K"; then panic "reencryption of filesystem $1 cannot continue!" fi + + if [ "$FAST_REENCRYPTION" = "1" ]; then + # use temporarily loop device to simulate shrinked device + # because cryptsetup uses device size at reducing + "$losetup_path" --sizelimit "${reduced_size_in_kb}K" "$loop_device" "$1" + fi ;; squashfs|swap|"") [ "$debug" = "y" ] && echo "skip disk resize as it is not supported or unnecessary for fstype: '$partition_fstype'" @@ -96,9 +124,14 @@ EOF ;; 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 --reduce-device-size "$reduce_device_size"k "$reencrypt_device" < "$2" else - /usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-size "$reduce_device_size"k "$1" < "$2" + /usr/sbin/cryptsetup reencrypt --encrypt --reduce-device-size "$reduce_device_size"k "$reencrypt_device" < "$2" + fi + + if [ "$FAST_REENCRYPTION" = "1" ]; then + # remove temporarily loop device + "$losetup_path" -d "$loop_device" fi } for candidate in /dev/tpm*; do @@ -182,6 +215,12 @@ for partition_set in $partition_sets; do reencrypt_existing_partition "$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" + if [ "$FAST_REENCRYPTION" = "1" ]; then + # expand encrypted partition to maximum + /usr/sbin/cryptsetup resize "$decrypted_part" + # expand filesystem within encrypted layer to maximum + resize2fs "$decrypted_part" "${encrypted_size_in_kb}K" + fi log_end_msg ;; "format") diff --git a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb index 3497d95..e3dd515 100644 --- a/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb +++ b/recipes-initramfs/initramfs-crypt-hook/initramfs-crypt-hook_0.2.bb @@ -57,6 +57,13 @@ CRYPT_PARTITIONS ??= "home:/home:reencrypt var:/var:reencrypt" # CRYPT_CREATE_FILE_SYSTEM_CMD contains the shell command to create the filesystem # in a newly formatted LUKS Partition CRYPT_CREATE_FILE_SYSTEM_CMD ??= "/usr/sbin/mke2fs -t ext4" +# Fast reencryption state +# It uses temporary partition resize, +# consider security and data reliablity aspects when enabling +# (e.g. wiping old already deleted data, hiding metadata, etc.) +# Keep in mind that a power loss while reencryption will cause data loss +# (with or without fast reencryption). +CRYPT_FAST_REENCRYPTION ??= "0" # Timeout for creating / re-encrypting partitions on first boot CRYPT_SETUP_TIMEOUT ??= "600" # Watchdog to service during the initial setup of the crypto partitions @@ -68,6 +75,7 @@ CRYPT_ENCRYPTION_OPTIONAL ??= "false" TEMPLATE_VARS = "CRYPT_PARTITIONS CRYPT_CREATE_FILE_SYSTEM_CMD \ CRYPT_SETUP_TIMEOUT INITRAMFS_WATCHDOG_DEVICE CRYPT_HASH_TYPE \ + CRYPT_FAST_REENCRYPTION \ CRYPT_KEY_ALGORITHM CRYPT_ENCRYPTION_OPTIONAL" TEMPLATE_FILES = "encrypt_partition.env.tmpl"
As the reencrypt mechanism doesn't work at file system level so it wouldn't detect used and free blocks. This means that the block-wise reencryption process could take a very long time depending on the partition size. Using the format mechanism instead of the reencrypt one would delete all existing data (without wiping). This would be very fast, because it doesn't matter whether a block is used or free. Set CRYPT_FAST_REENCRYPTION to "1" to speed-up the reencrypt process. So, this would be done: - Obtain used space of the unencrypted userdata partition - Shrink the partition and resize it to the size of used space (minimum size) - reencrypt the userdata partition now with smaller size - Expand the encrypted userdata partition back to the maximum possible size Some disk encryption implementations like within the Debian installer will overwrite the entire partition with random data for security reasons (e.g. wiping old already deleted data, hiding metadata, etc.). However, this speed-up lacks the described security benefit of implicit data overwrite. So for security reasons, it behaves identical to the format option (there is no support for explicit random overwrite within initramfs-crypt-hook). Keep in mind that a power loss while reencryption will cause data loss (with or without fast reencryption). The key is only enrolled after fully succeeded reencryption, yet. So, no recovery from already encrypted data would be possible. Signed-off-by: Stefan Koch <stefan-koch@siemens.com> --- .../files/encrypt_partition.env.tmpl | 1 + .../files/encrypt_partition.script | 53 ++++++++++++++++--- .../initramfs-crypt-hook_0.2.bb | 8 +++ 3 files changed, 55 insertions(+), 7 deletions(-)