Skip to content

Commit c670e6a

Browse files
committed
initrd/bin/kexec-seal-key initrd/etc/luks-functions: last fixups
- fi misplaced - rework reencryption loop - added verbose output on TPM DUK key addition when LUKS container can be unlocked with DRK Current state, left todo for future work: TPM DUK: - TPM DUK setup on defautl boot reuses /boot/kexec_key_devices.txt if present - If not, list all LUKS partitions, asks user for selection and makes sure LUKS passphrase can unlock all - Works on both LUKSv1 and LUKSv2 containers, reusing OS installer settings (Heads doesn't enforce better then OS installer LUKS parameters) LUKS passphrase change/LUKS reencryption: - Reuses /boot/kexec_key_devices.txt if existing - If not, prompts for LUKS passphase, list all LUKS containers not being USB based and attempt to unlock all those, listing only the ones successfully unlocked - Prompts user to reuse found unlockable LUKS partitions with LUKS passphrase, caches and reuse in other LUKS operations (passphrase change as well from oem factory reset/re-ownership) - Deals properly with LUKSv1/LUKSv2/multiple LUKS containers and reencrypt/passphrase changes them all if accepted, otherwise asks user to select individual LUKS container Tested on luksv1,luksv2, btrfs under luks (2x containers) and TPM DUK setup up to booting OS. All good TODO: - LUKS passphrase check is done multiple times across TPM DUK, reencryption and luks passphrase. Could refactor to change this, but since this op is done only one reencrypt+passphrase change) upon hardare reception from OEM, I stopped caring here. Signed-off-by: Thierry Laurion <[email protected]>
1 parent 4daf592 commit c670e6a

File tree

2 files changed

+64
-74
lines changed

2 files changed

+64
-74
lines changed

initrd/bin/kexec-seal-key

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ for dev in $key_devices ; do
7878

7979
DEBUG "Testing $DISK_RECOVERY_KEY_FILE keyfile created from provided passphrase against $dev individual key slots"
8080
if cryptsetup open $dev --test-passphrase --key-file "$DISK_RECOVERY_KEY_FILE" >/dev/null 2>&1; then
81-
DEBUG "LUKS device $dev unlocked successfully with the DRK passphrase"
81+
echo "++++++ $dev: LUKS device unlocked successfully with the DRK passphrase"
8282
luks_drk_passphrase_valid=1
8383
break
8484
else

initrd/etc/luks-functions

Lines changed: 63 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,6 @@ select_luks_container() {
363363
DEBUG "LUKS container device: $(echo $LUKS)"
364364
elif [ -z "$LUKS" ]; then
365365
main_luks_selection
366-
fi
367366
fi
368367
}
369368

@@ -420,21 +419,21 @@ luks_reencrypt() {
420419
TRACE_FUNC
421420
DEBUG "luks_containers: ${luks_containers[@]}"
422421

423-
for luks_container in "${luks_containers[@]}"; do
424-
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
425-
if [ -f /tmp/secret/luks_current_Disk_Recovery_Key_passphrase ]; then
426-
luks_current_Disk_Recovery_Key_passphrase=$(cat /tmp/secret/luks_current_Disk_Recovery_Key_passphrase)
427-
else
428-
msg=$(echo -e "This will replace the encrypted container content and its LUKS Disk Recovery Key.\n\nThe passphrase associated with this key will be asked from the user under the following conditions:\n 1-Every boot if no Disk Unlock Key was added to the TPM\n 2-If the TPM fails (hardware failure)\n 3-If the firmware has been tampered with/modified by the user\n\nThis process requires you to type the current LUKS Disk Recovery Key passphrase and will delete the LUKS TPM Disk Unlock Key slot, if set up, by setting a default boot LUKS key slot (1) if present.\n\nAt the next prompt, you may be asked to select which file corresponds to the LUKS device container.\n\nHit Enter to continue." | fold -w 70 -s)
429-
whiptail --title 'Reencrypt LUKS encrypted container ?' --msgbox "$msg" 0 80
430-
echo -e "\nEnter the current LUKS Disk Recovery Key passphrase:"
431-
read -r -s luks_current_Disk_Recovery_Key_passphrase
432-
echo -n "$luks_current_Disk_Recovery_Key_passphrase" >/tmp/secret/luks_current_Disk_Recovery_Key_passphrase
433-
fi
422+
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
423+
if [ -f /tmp/secret/luks_current_Disk_Recovery_Key_passphrase ]; then
424+
luks_current_Disk_Recovery_Key_passphrase=$(cat /tmp/secret/luks_current_Disk_Recovery_Key_passphrase)
434425
else
426+
msg=$(echo -e "This will replace the encrypted container content and its LUKS Disk Recovery Key.\n\nThe passphrase associated with this key will be asked from the user under the following conditions:\n 1-Every boot if no Disk Unlock Key was added to the TPM\n 2-If the TPM fails (hardware failure)\n 3-If the firmware has been tampered with/modified by the user\n\nThis process requires you to type the current LUKS Disk Recovery Key passphrase and will delete the LUKS TPM Disk Unlock Key slot, if set up, by setting a default boot LUKS key slot (1) if present.\n\nAt the next prompt, you may be asked to select which file corresponds to the LUKS device container.\n\nHit Enter to continue." | fold -w 70 -s)
427+
whiptail --title 'Reencrypt LUKS encrypted container ?' --msgbox "$msg" 0 80
428+
echo -e "\nEnter the current LUKS Disk Recovery Key passphrase:"
429+
read -r -s luks_current_Disk_Recovery_Key_passphrase
435430
echo -n "$luks_current_Disk_Recovery_Key_passphrase" >/tmp/secret/luks_current_Disk_Recovery_Key_passphrase
436431
fi
432+
else
433+
echo -n "$luks_current_Disk_Recovery_Key_passphrase" >/tmp/secret/luks_current_Disk_Recovery_Key_passphrase
434+
fi
437435

436+
for luks_container in "${luks_containers[@]}"; do
438437
DEBUG "$luks_container: Test unlocking of LUKS encrypted drive content with current LUKS Disk Recovery Key passphrase..."
439438
if ! DO_WITH_DEBUG cryptsetup open --test-passphrase "$luks_container" --key-file /tmp/secret/luks_current_Disk_Recovery_Key_passphrase >/dev/null 2>&1; then
440439
whiptail_error --title "$luks_container: Wrong current LUKS Disk Recovery Key passphrase?" --msgbox \
@@ -449,70 +448,61 @@ luks_reencrypt() {
449448
continue
450449
fi
451450

452-
DEBUG "Test opening ${luks_containers[@]} successful. Now testing key slots to determine which holds master key"
453-
for luks_container in "${luks_containers[@]}"; do
454-
DRK_KEYSLOT=-1
455-
DEBUG "$luks_container: Test unlocking of LUKS encrypted drive content with current LUKS Disk Recovery Key passphrase..."
456-
for i in $(seq 0 31); do
457-
DEBUG "Testing key slot $i on $luks_container"
458-
if DO_WITH_DEBUG cryptsetup open --test-passphrase $luks_container --key-slot $i --key-file /tmp/secret/luks_current_Disk_Recovery_Key_passphrase >/dev/null 2>&1; then
459-
DRK_KEYSLOT=$i
460-
DEBUG "$luks_container: Found key-slot $DRK_KEYSLOT that can be unlocked with the current passphrase. breaking loop"
461-
break
462-
else
463-
DEBUG "Key slot $i on $luks_container cannot be unlocked with the current passphrase"
464-
fi
465-
done
466-
467-
if [ $DRK_KEYSLOT -eq -1 ]; then
468-
whiptail_error --title "$luks_container: Wrong current LUKS Disk Recovery Key passphrase?" --msgbox \
469-
"If you previously changed it and do not remember it, you will have to reinstall the OS from an external drive.\n\nTo do so, place the ISO file and its signature file on root of an external drive, and select Options-> Boot from USB \n\nHit Enter to retry." 0 80
470-
TRACE_FUNC
471-
detect_boot_device
472-
mount -o remount,rw /boot
473-
rm -f /boot/kexec_key_devices.txt
474-
mount -o remount,ro /boot
475-
luks_secrets_cleanup
476-
unset LUKS
477-
continue
478-
fi
479-
480-
# Now reencrypt the LUKS container with the same key slot
481-
# Warn and launch actual reencryption
482-
echo -e "\nReencrypting $luks_container LUKS encrypted drive content with current Recovery Disk Key passphrase..."
483-
warn "DO NOT POWER DOWN MACHINE, UNPLUG AC OR REMOVE BATTERY DURING REENCRYPTION PROCESS"
484-
485-
# --perf-no_read_workqueue and/or --perf-no_write_workqueue improve encryption/reencrypton performance on kernel 5.10.9+
486-
# bypassing dm-crypt queues.
487-
# Ref https://github.com/cloudflare/linux/issues/1#issuecomment-729695518
488-
# --resilience=none disables the resilience feature of cryptsetup, which is enabled by default
489-
# --force-offline-reencrypt forces the reencryption to be done offline (no read/write operations on the device)
490-
# --disable-locks disables the lock feature of cryptsetup, which is enabled by default
491-
492-
if ! DO_WITH_DEBUG cryptsetup reencrypt \
493-
--perf-no_read_workqueue --perf-no_write_workqueue \
494-
--resilience=none --force-offline-reencrypt --disable-locks \
495-
"$luks_container" --key-slot "$DRK_KEYSLOT" \
496-
--key-file /tmp/secret/luks_current_Disk_Recovery_Key_passphrase; then
497-
whiptail_error --title "$luks_container: Wrong current LUKS Disk Recovery Key passphrase?" --msgbox \
498-
"If you previously changed it and do not remember it, you will have to reinstall the OS from an external drive.\n\nTo do so, place the ISO file and its signature file on root of an external drive, and select Options-> Boot from USB \n\nHit Enter to retry." 0 80
499-
TRACE_FUNC
500-
501-
#remove "known good" selected LUKS container so that next pass asks again user to select LUKS container.
502-
#maybe the container was not the right one
503-
detect_boot_device
504-
mount -o remount,rw /boot
505-
rm -f /boot/kexec_key_devices.txt
506-
mount -o remount,ro /boot
507-
luks_secrets_cleanup
508-
unset LUKS
451+
DEBUG "Test opening ${luks_container} successful. Now testing key slots to determine which holds master key"
452+
DRK_KEYSLOT=-1
453+
DEBUG "$luks_container: Test unlocking of LUKS encrypted drive content with current LUKS Disk Recovery Key passphrase..."
454+
for i in $(seq 0 31); do
455+
DEBUG "Testing key slot $i on $luks_container"
456+
if DO_WITH_DEBUG cryptsetup open --test-passphrase $luks_container --key-slot $i --key-file /tmp/secret/luks_current_Disk_Recovery_Key_passphrase >/dev/null 2>&1; then
457+
DRK_KEYSLOT=$i
458+
DEBUG "$luks_container: Found key-slot $DRK_KEYSLOT that can be unlocked with the current passphrase. breaking loop"
459+
break
509460
else
510-
#Reencryption was successful. Cleanup should be called only when done
511-
#Exporting successfully used passphrase possibly reused by oem-factory-reset
512-
export luks_current_Disk_Recovery_Key_passphrase
513-
export LUKS
461+
DEBUG "Key slot $i on $luks_container cannot be unlocked with the current passphrase"
514462
fi
515463
done
464+
465+
if [ $DRK_KEYSLOT -eq -1 ]; then
466+
whiptail_error --title "$luks_container: Wrong current LUKS Disk Recovery Key passphrase?" --msgbox \
467+
"If you previously changed it and do not remember it, you will have to reinstall the OS from an external drive.\n\nTo do so, place the ISO file and its signature file on root of an external drive, and select Options-> Boot from USB \n\nHit Enter to retry." 0 80
468+
TRACE_FUNC
469+
detect_boot_device
470+
mount -o remount,rw /boot
471+
rm -f /boot/kexec_key_devices.txt
472+
mount -o remount,ro /boot
473+
luks_secrets_cleanup
474+
unset LUKS
475+
continue
476+
fi
477+
478+
# --perf-no_read_workqueue and/or --perf-no_write_workqueue improve encryption/reencrypton performance on kernel 5.10.9+
479+
# bypassing dm-crypt queues.
480+
# Ref https://github.com/cloudflare/linux/issues/1#issuecomment-729695518
481+
# --resilience=none disables the resilience feature of cryptsetup, which is enabled by default
482+
# --force-offline-reencrypt forces the reencryption to be done offline (no read/write operations on the device)
483+
# --disable-locks disables the lock feature of cryptsetup, which is enabled by default
484+
485+
echo -e "\nReencrypting $luks_container LUKS encrypted drive content with current Recovery Disk Key passphrase..."
486+
warn "DO NOT POWER DOWN MACHINE, UNPLUG AC OR REMOVE BATTERY DURING REENCRYPTION PROCESS"
487+
488+
if ! DO_WITH_DEBUG cryptsetup reencrypt \
489+
--perf-no_read_workqueue --perf-no_write_workqueue \
490+
--resilience=none --force-offline-reencrypt --disable-locks \
491+
"$luks_container" --key-slot "$DRK_KEYSLOT" \
492+
--key-file /tmp/secret/luks_current_Disk_Recovery_Key_passphrase; then
493+
whiptail_error --title "$luks_container: Wrong current LUKS Disk Recovery Key passphrase?" --msgbox \
494+
"If you previously changed it and do not remember it, you will have to reinstall the OS from an external drive.\n\nTo do so, place the ISO file and its signature file on root of an external drive, and select Options-> Boot from USB \n\nHit Enter to retry." 0 80
495+
TRACE_FUNC
496+
detect_boot_device
497+
mount -o remount,rw /boot
498+
rm -f /boot/kexec_key_devices.txt
499+
mount -o remount,ro /boot
500+
luks_secrets_cleanup
501+
unset LUKS
502+
else
503+
export luks_current_Disk_Recovery_Key_passphrase
504+
export LUKS
505+
fi
516506
done
517507
}
518508

0 commit comments

Comments
 (0)