heads/initrd/etc/luks-functions

577 lines
26 KiB
Bash

#!/bin/bash
# LUKS related functions
. /etc/functions
. /etc/gui_functions
. /tmp/config
#List all LUKS devices on the system
list_luks_devices() {
TRACE_FUNC
#generate a list of devices to choose from that contain a LUKS header
lvm vgscan || true
blkid | cut -d ':' -f 1 | while read device; do
if cryptsetup isLuks $device; then echo $device; fi
done | sort
}
#Whiptail prompt asking user to select ratio of device to use for LUKS container between: 25, 50, 75
select_luks_container_size_percent() {
TRACE_FUNC
if [ -x /bin/whiptail ]; then
#whiptail prompt asking user to select ratio of device to use for LUKS container between: 25, 50, 75
#whiptail returns the percentage of the device to use for LUKS container
whiptail --title "Select LUKS container size percentage of device" --menu \
"Select LUKS container size percentage of device:" 0 80 10 \
"10" "10%" \
"25" "25%" \
"50" "50%" \
"75" "75%" \
2> /tmp/luks_container_size_percent \
|| die "Error selecting LUKS container size percentage of device"
else
#console prompt asking user to select ratio of device to use for LUKS container between: 10, 25, 50, 75
#console prompt returns the percentage of the device to use for LUKS container
echo "Select LUKS container size percentage of device:"
echo "1. 10%"
echo "2. 25%"
echo "3. 50%"
echo "4. 75%"
read -p "Choose your LUKS container size percentage of device [1-3]: " option_index
if [ "$option_index" = "1" ]; then
echo "10" > /tmp/luks_container_size_percent
elif [ "$option_index" = "2" ]; then
echo "25" > /tmp/luks_container_size_percent
elif [ "$option_index" = "3" ]; then
echo "50" > /tmp/luks_container_size_percent
elif [ "$option_index" = "4" ]; then
echo "75" > /tmp/luks_container_size_percent
else
die "Error selecting LUKS container size percentage of device"
fi
fi
}
# Partition a device interactively with two partitions: a LUKS container
# containing private ext4 partition and second public exFAT partition
# Size provisioning is done by percentage of the device
interactive_prepare_thumb_drive()
{
TRACE_FUNC
#Refactoring: only one parameter needed to be prompted for: the passphrase for LUKS container if not coming from oem-provisioning
#If no passphrase was provided, ask user to select passphrase for LUKS container
# if no device provided as parameter, we will ask user to select device to partition
# if no percentage provided as parameter, we will default to 10% of device to use for LUKS container
# we will validate parameters and not make them positional and print a usage function first
#Set defaults
DEVICE="" #Will list all usb storage devices if not provided as parameter
PERCENTAGE="10" #default to 10% of device to use for LUKS container (requires a LUKS partition bigger then 32mb!)
PASSPHRASE="" #Will prompt user for passphrase if not provided as parameter
#Parse parameters
while [ $# -gt 0 ]; do
case "$1" in
--device)
DEVICE=$2
shift 2
;;
--percentage)
PERCENTAGE=$2
shift 2
;;
--pass)
PASSPHRASE=$2
shift 2
;;
*)
echo "usage: prepare_thumb_drive [--device device] [--percentage percentage] [--pass passphrase]"
return 1
;;
esac
done
DEBUG "DEVICE to partition: $DEVICE"
DEBUG "PERCENTAGE of device that will be used for LUKS container: $PERCENTAGE"
#Output provided if passphrase is provided as parameter
DEBUG "PASSPHRASE for LUKS container: ${PASSPHRASE:+provided}"
#Prompt for passphrase if not provided as parameter
if [ -z "$PASSPHRASE" ]; then
#If no passphrase was provided, ask user to select passphrase for LUKS container
#console based no whiptail
while [[ ${#PASSPHRASE} -lt 8 ]]; do
{
echo -e "\nEnter passphrase for LUKS container (At least 8 characters long):"
#hide passphrase input from read command
read -r -s PASSPHRASE
#skip confirmation if passphrase is less then 8 characters long (continue)
if [[ ${#PASSPHRASE} -lt 8 ]]; then
echo -e "\nPassphrase must be at least 8 characters long. Please try again."
unset PASSPHRASE
continue
fi
#validate passphrase and ask user to re-enter if not at least 8 characters long
#confirm passphrase
echo -e "\nConfirm passphrase for LUKS container:"
#hide passphrase input from read command
read -r -s PASSPHRASE_CONFIRM
#compare passphrase and passphrase confirmation
if [ "$PASSPHRASE" != "$PASSPHRASE_CONFIRM" ]; then
echo -e "\nPassphrases do not match. Please try again."
unset PASSPHRASE
unset PASSPHRASE_CONFIRM
fi
};done
fi
#If no device was provided, ask user to select device to partition
if [ -z "$DEVICE" ]; then
#warn user to disconnect all external drives
if [ -x /bin/whiptail ]; then
whiptail_warning --title "WARNING: Disconnect all external drives" --msgbox \
"WARNING: Please disconnect all external drives before proceeding.\n\nHit Enter to continue." 0 80 \
|| die "User cancelled wiping and repartitioning of $DEVICE"
else
echo -e -n "Warning: Please disconnect all external drives before proceeding.\n\nHit Enter to continue?"
read -r -p " [Y/n] " response
#transform response to uppercase with bash parameter expansion
response=${response^^}
#continue if response different then uppercase N
if [[ $response =~ ^(N)$ ]]; then
die "User cancelled wiping and repartitioning of $DEVICE"
fi
fi
#enable usb
enable_usb
#enable usb storage
enable_usb_storage
#list all usb storage devices
list_usb_storage disks > /tmp/devices.txt
if [ $(cat /tmp/devices.txt | wc -l) -gt 0 ]; then
file_selector "/tmp/devices.txt" "Select device to partition"
if [ "$FILE" == "" ]; then
die "Error: No device selected"
else
DEVICE=$FILE
fi
else
die "Error: No device found"
fi
fi
#Check if device is a block device
if [ ! -b $DEVICE ]; then
die "Error: $DEVICE is not a block device"
fi
if [ -z "$PERCENTAGE" ]; then
#If no percentage was provided, ask user to select percentage of device to use for LUKS container
select_luks_container_size_percent
PERCENTAGE=$(cat /tmp/luks_container_size_percent)
fi
confirm_thumb_drive_format "$DEVICE" "$PERCENTAGE" ||
die "User cancelled wiping and repartitioning of $DEVICE"
prepare_thumb_drive "$DEVICE" "$PERCENTAGE" "$PASSPHRASE"
}
# Show a prompt to confirm formatting a flash drive with a percentage allocated
# to LUKS. interactive_prepare_thumb_drive() uses this; during OEM reset it is
# used separately before performing any reset actions
#
# parameters:
# $1 - block device of flash drive
# $2 - percent of device allocated to LUKS [1-99]
confirm_thumb_drive_format()
{
TRACE_FUNC
local DEVICE LUKS_PERCENTAGE DISK_SIZE_BYTES DISK_SIZE_DISPLAY LUKS_PERCENTAGE LUKS_SIZE_MB MSG
DEVICE="$1"
LUKS_PERCENTAGE="$2"
LUKS_SIZE_MB=
#Get disk size in bytes
DISK_SIZE_BYTES="$(blockdev --getsize64 "$DEVICE")"
DISK_SIZE_DISPLAY="$(display_size "$DISK_SIZE_BYTES")"
#Convert disk size to MB
DISK_SIZE_MB=$((DISK_SIZE_BYTES/1024/1024))
#Calculate percentage of device in MB
LUKS_SIZE_MB="$((DISK_SIZE_BYTES*LUKS_PERCENTAGE/100/1024/1024))"
MSG="WARNING: Wiping and repartitioning $DEVICE ($DISK_SIZE_DISPLAY) with $LUKS_SIZE_MB MB\n assigned to private LUKS ext4 partition,\n rest assigned to exFAT public partition.\n\nAre you sure you want to continue?"
if [ -x /bin/whiptail ]; then
whiptail_warning --title "WARNING: Wiping and repartitioning $DEVICE ($DISK_SIZE_DISPLAY)" --yesno \
"$MSG" 0 80
else
echo -e -n "$MSG"
read -r -p " [Y/n] " response
#transform response to uppercase with bash parameter expansion
response=${response^^}
#continue if response is Y, y, or empty, abort for anything else
if [ -n "$response" ] && [ "${response^^}" != Y ]; then
return 1
fi
fi
}
# Prepare a flash drive with a private LUKS-encrypted ext4 partition and a
# public exFAT partition. This is not interactive - during OEM reset, any
# selections/confirmations must occur before OEM reset starts resetting the
# system.
#
# $1 - block device of flash drive
# $2 - percentage of flash drive to allocate to LUKS [1-99]
# $3 - passphrase for LUKS container
prepare_thumb_drive()
{
TRACE_FUNC
local DEVICE PERCENTAGE PASSPHRASE DISK_SIZE_BYTES PERCENTAGE_MB
DEVICE="$1"
PERCENTAGE="$2"
PASSPHRASE="$3"
#Get disk size in bytes
DISK_SIZE_BYTES="$(blockdev --getsize64 "$DEVICE")"
#Calculate percentage of device in MB
PERCENTAGE_MB="$((DISK_SIZE_BYTES*PERCENTAGE/100/1024/1024))"
echo -e "Preparing $DEVICE with $PERCENTAGE_MB MB for private LUKS container while rest of device will be assigned to exFAT public partition...\n"
echo "Please wait..."
DEBUG "Creating empty DOS partition table on device through fdisk to start clean"
echo -e "o\nw\n" | fdisk $DEVICE >/dev/null 2>&1 || die "Error creating partition table"
DEBUG "partition device with two partitions: first one being the percent applied and rest for second partition through fdisk"
echo -e "n\np\n1\n\n+"$PERCENTAGE_MB"M\nn\np\n2\n\n\nw\n" | fdisk $DEVICE >/dev/null 2>&1 || die "Error partitioning device"
DEBUG "cryptsetup luksFormat first partition with LUKS container aes-xts-plain64 cipher with sha256 hash and 512 bit key"
DEBUG "Creating ${PERCENTAGE_MB}MB LUKS container on ${DEVICE}1..."
DO_WITH_DEBUG cryptsetup --batch-mode -c aes-xts-plain64 -h sha256 -s 512 -y luksFormat ${DEVICE}1 \
--key-file <(echo -n "${PASSPHRASE}") > /dev/null 2>&1 \
|| die "Error formatting LUKS container"
DEBUG "Opening LUKS device and mapping under /dev/mapper/private..."
DO_WITH_DEBUG cryptsetup open ${DEVICE}1 private --key-file <(echo -n "${PASSPHRASE}") > /dev/null 2>&1 \
|| die "Error opening LUKS container"
DEBUG "Formatting LUKS container mapped under /dev/mapper/private as an ext4 partition..."
mke2fs -t ext4 -L private /dev/mapper/private >/dev/null 2>&1 || die "Error formatting LUKS container's ext4 filesystem"
DEBUG "Closing LUKS device /dev/mapper/private..."
cryptsetup close private > /dev/null 2>&1 || die "Error closing LUKS container"
DEBUG "Formatting second partition ${DEVICE}2 with exfat filesystem..."
mkfs.exfat -L public ${DEVICE}2 >/dev/null 2>&1 || die "Error formatting second partition with exfat filesystem"
echo "Done."
}
select_luks_container()
{
#TODO: extend logic to prompt for block devices with model if multiple LUKS are found on block device instead of partitions
# Then feed luks with those partitions so that reencrypt and passphrase change can use passphrase to test all selected
TRACE_FUNC
if [ -s /boot/kexec_key_devices.txt ]; then
DEBUG "Reusing known good LUKS container device from /boot/kexec_key_devices.txt"
LUKS=$(cut -d ' ' -f1 /boot/kexec_key_devices.txt)
DEBUG "LUKS container device: $(echo $LUKS)"
# LUKS variable not exported yet, prompt for LUKS device
elif [ -z "$LUKS" ]; then
list_luks_devices > /tmp/luks_devices.txt
#if /tmp/luks_devices.txt exists and is not empty
if [ -s /tmp/luks_devices.txt ]; then
file_selector "/tmp/luks_devices.txt" "Select LUKS container device"
if [ "$FILE" == "" ]; then
return 1
else
#TODO: What about BRTFS multi LUKS setup of QubesOS?
# if multiple LUKS containers are found on same block device
# select all of the luks containers on same block device instead of just one
# note that block devices for example under /dev/sda will be /dev/sda1, /dev/sda2, etc
# so we need to select all of the partitions on the same block device from /tmp/luks_devices.txt
# and then export them to LUKS variable
# then reencrypt and passphrase change functions will loop on all of the LUKS containers
# and test passphrase on all of them
if grep -q "$(echo $FILE | sed 's/[0-9]*$//')" /tmp/luks_devices.txt; then
DEBUG "Multiple LUKS containers found on same block device, selecting them all"
LUKS=$(grep $(echo $FILE | sed 's/[0-9]*$//') /tmp/luks_devices.txt)
else
DEBUG "Single LUKS container found on block device, assigning to LUKS variable"
LUKS=$FILE
fi
fi
else
warn "No encrypted device found"
return 1
fi
fi
}
test_luks_current_disk_recovery_key_passphrase()
{
#TODO: reuse/generalize usage of this function. Tests for LUKS are still done 4 times independently of this helper
TRACE_FUNC
while :; do
select_luks_container || return 1
# LUKS contains multiline string of LUKS containers on same block device
# transform it into words of a same string separated by space
PRINTABLE_LUKS=$(echo $LUKS)
TRACE_FUNC
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
# if no external provisioning provides current LUKS Disk Recovery Key passphrase
echo -e "\nEnter the current LUKS Disk Recovery Key passphrase (Configured at OS installation or by OEM):"
read -r luks_current_Disk_Recovery_Key_passphrase
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/secret/luks_current_Disk_Recovery_Key_passphrase
else
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/secret/luks_current_Disk_Recovery_Key_passphrase
fi
# test all LUKS containers on same block device as returned by select_luks_container
echo -e "\n$PRINTABLE_LUKS: Test unlocking of LUKS encrypted drive content with current LUKS Disk Recovery Key passphrase..."
# Loop on all LUKS containers on same block device
for luks_container in $LUKS; do
DEBUG "$luks_container: Test unlocking of LUKS encrypted drive content with current LUKS Disk Recovery Key passphrase..."
DO_WITH_DEBUG cryptsetup open --test-passphrase "$luks_container" --key-file /tmp/secret/luks_current_Disk_Recovery_Key_passphrase
# Validate past cryptsetup reencrypt attempts
if [ $? -ne 0 ]; then
# if we have more than one LUKS container and passphrase test unsuccessful, tell user how to change passphrase
if [ $(echo $LUKS | wc -w) -gt 1 ]; then
#TODO remove this once whiptail_error whiptail_warning can take titles with double quotes
#whiptail_warning --title 'tes' --msgbox 'test' 0 80
#whiptail_error --title 'error' --msgbox 'error' 0 80
#Neither work today. Not related to this PR... Using whiptail without coloring.
msg=$(echo -e "All $PRINTABLE_LUKS must unlock with the same Disk Recovery Key passphrase for the current operation to succeed.\n\nTo change individual LUKS container passphrase, do so from 'Options-> Change LUKS Disk Recovery Key passphrase'\n\nThen retry this operation." | fold -w 70 -s)
whiptail --title "$luks_container"': Wrong current LUKS Disk Recovery Key passphrase?' \
--msgbox "$msg" 0 80
TRACE_FUNC
luks_secrets_cleanup
die "$PRINTABLE_LUKS individual containers NEED to share the same Disk Recovery Key passphrase"
# We exited to caller, LUKS still set. TODO: problem? Should we call all cleaning functions on die?
fi
whiptail --title "$luks_container: Wrong current LUKS Disk Recovery Key passphrase?" --msgbox \
"If you previously changed it and do not remember it, you will have to\n reinstall the OS from a an external drive.\n\nTo do so, place the ISO file and its signature file on root of an\n external drive, and select Options-> Boot from USB \n\nHit Enter to retry." 0 80
TRACE_FUNC
detect_boot_device
mount -o remount,rw /boot
rm -f /boot/kexec_key_devices.txt
mount -o remount,ro /boot
luks_secrets_cleanup
# remove "known good" selected LUKS container so that next pass asks again user to select LUKS container.
# maybe the container was not the right one
unset LUKS
else
# LuksOpen test was successful. Cleanup should be called only when done
# Exporting successfully used passphrase possibly reused by oem-factory-reset
echo "$luks_container: unlocking LUKS container with current Disk Recovery Key passphrase successful"
# Exporting successfully used passphrase possibly reused by oem-factory-reset
export luks_current_Disk_Recovery_Key_passphrase
fi
done
# exit while loop if LUKS variable is not empty
if [ -n "$LUKS" ]; then
# We export the LUKS volume(s) that was/were validated via passphrase test
export LUKS
TRACE_FUNC
DEBUG "LUKS container(s) $PRINTABLE_LUKS exported to be reused"
break;
fi
done
}
luks_reencrypt() {
TRACE_FUNC
#TODO: REFACTOR This and luks passphrase change function needs to loop on same drive discovered luks containers so that reencrypt/passwd change is done on all luks containers of same drive
# Ideal would be to list luks devices and then try keep and append LUKS devices to a list of devices to reencrypt or change passphrase
# then loop on that list of devices that could be opened and reencrypt/change passphrase for all the devices that could be tested opened with that passphrase
select_luks_container || return 1
# Split the $LUKS variable into an array of LUKS containers
luks_containers=($LUKS)
TRACE_FUNC
DEBUG "luks_containers: ${luks_containers[@]}"
for luks_container in "${luks_containers[@]}"; do
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
#if no external provisioning provides current LUKS Disk Recovery Key passphrase
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)
whiptail --title 'Reencrypt LUKS encrypted container ?' \
--msgbox "$msg" 0 80
echo -e "\nEnter the current LUKS Disk Recovery Key passphrase:"
read -r luks_current_Disk_Recovery_Key_passphrase
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/secret/luks_current_Disk_Recovery_Key_passphrase
else
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/secret/luks_current_Disk_Recovery_Key_passphrase
fi
DEBUG "$luks_container: Test unlocking of LUKS encrypted drive content with current LUKS Disk Recovery Key passphrase..."
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
whiptail --title "$luks_container: Wrong current LUKS Disk Recovery Key passphrase?" --msgbox \
"If you previously changed it and do not remember it, you will have to\n reinstall the OS from a an external drive.\n\nTo do so, place the ISO file and its signature file on root of an\n external drive, and select Options-> Boot from USB \n\nHit Enter to retry." 0 80
# Remove "known good" selected LUKS container so that next pass asks again user to select LUKS container.
# Maybe the container was not the right one
TRACE_FUNC
detect_boot_device
mount -o remount,rw /boot
rm -f /boot/kexec_key_devices.txt
mount -o remount,ro /boot
luks_secrets_cleanup
unset LUKS
continue
fi
DEBUG "Test opening ${luks_containers[@]} successful. Now testing key slots to determine which holds master key"
for luks_container in "${luks_containers[@]}"; do
# First obtain which luks1/luks2 key-slot can be unlocked with the key-file
DRK_KEYSLOT=-1
DEBUG "$luks_container: Test unlocking of LUKS encrypted drive content with current LUKS Disk Recovery Key passphrase..."
for i in $(seq 0 31); do
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
DRK_KEYSLOT=$i
DEBUG "$luks_container: Found key-slot $DRK_KEYSLOT that can be unlocked with the current passphrase. breaking loop"
break
fi
done
# Validate if a key slot was found
if [ $DRK_KEYSLOT -eq -1 ]; then
whiptail --title "$luks_container: Wrong current LUKS Disk Recovery Key passphrase?" --msgbox \
"If you previously changed it and do not remember it, you will have to\n reinstall the OS from a an external drive.\n\nTo do so, place the ISO file and its signature file on root of an\n external drive, and select Options-> Boot from USB \n\nHit Enter to retry." 0 80
# Remove "known good" selected LUKS container so that next pass asks again user to select LUKS container.
# Maybe the container was not the right one
TRACE_FUNC
detect_boot_device
mount -o remount,rw /boot
rm -f /boot/kexec_key_devices.txt
mount -o remount,ro /boot
luks_secrets_cleanup
unset LUKS
continue
fi
# Now reencrypt the LUKS container with the same key slot
# Warn and launch actual reencryption
echo -e "\nReencrypting $luks_container LUKS encrypted drive content with current Recovery Disk Key passphrase..."
warn "DO NOT POWER DOWN MACHINE, UNPLUG AC OR REMOVE BATTERY DURING REENCRYPTION PROCESS"
# --perf-no_read_workqueue and/or --perf-no_write_workqueue improve encryption/reencrypton performance on kernel 5.10.9+
# bypassing dm-crypt queues.
# Ref https://github.com/cloudflare/linux/issues/1#issuecomment-729695518
# --resilience=none disables the resilience feature of cryptsetup, which is enabled by default
# --force-offline-reencrypt forces the reencryption to be done offline (no read/write operations on the device)
# --disable-locks disables the lock feature of cryptsetup, which is enabled by default
#if ! DO_WITH_DEBUG cryptsetup reencrypt \
#--perf-no_read_workqueue --perf-no_write_workqueue \
#--resilience=none --force-offline-reencrypt --disable-locks \
#"$luks_container" --key-slot "$DRK_KEYSLOT" \
#--key-file /tmp/secret/luks_current_Disk_Recovery_Key_passphrase; then
if ! DO_WITH_DEBUG echo "fake cryptsetup reencrypt call"; then
whiptail --title "$luks_container: Wrong current LUKS Disk Recovery Key passphrase?" --msgbox \
"If you previously changed it and do not remember it, you will have to\n reinstall the OS from a an external drive.\n\nTo do so, place the ISO file and its signature file on root of an\n external drive, and select Options-> Boot from USB \n\nHit Enter to retry." 0 80
TRACE_FUNC
#remove "known good" selected LUKS container so that next pass asks again user to select LUKS container.
#maybe the container was not the right one
detect_boot_device
mount -o remount,rw /boot
rm -f /boot/kexec_key_devices.txt
mount -o remount,ro /boot
luks_secrets_cleanup
unset LUKS
else
#Reencryption was successful. Cleanup should be called only when done
#Exporting successfully used passphrase possibly reused by oem-factory-reset
export luks_current_Disk_Recovery_Key_passphrase
export LUKS
fi
done
done
}
luks_change_passphrase()
{
TRACE_FUNC
select_luks_container || return 1
# Split the $LUKS variable into an array of LUKS containers
luks_containers=($LUKS)
TRACE_FUNC
DEBUG "luks_containers: ${luks_containers[@]}"
# Loop through each LUKS container
for luks_container in "${luks_containers[@]}"; do
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ] || [ -z "$luks_new_Disk_Recovery_Key_passphrase" ]; then
whiptail --title 'Changing LUKS Disk Recovery Key passphrase' --msgbox \
"Please enter the current LUKS Disk Recovery Key passphrase (slot 0).\nThen choose a strong passphrase of your own.\n\n**DICEWARE passphrase methodology is STRONGLY ADVISED.**\n\nHit Enter to continue" 0 80
echo -e "\nEnter your desired replacement for the actual LUKS Disk Recovery Key passphrase (At least 8 characters long):"
while [[ ${#luks_new_Disk_Recovery_Key_passphrase} -lt 8 ]]; do
read -r luks_new_Disk_Recovery_Key_passphrase
done
echo -e "\nEnter the current LUKS Disk Recovery Key passphrase (Configured at OS installation or by OEM):"
read -r luks_current_Disk_Recovery_Key_passphrase
fi
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/secret/luks_current_Disk_Recovery_Key_passphrase
echo -n "$luks_new_Disk_Recovery_Key_passphrase" > /tmp/secret/luks_new_Disk_Recovery_Key_passphrase
DEBUG "$luks_container: Test unlocking of LUKS encrypted drive content with current LUKS Disk Recovery Key passphrase..."
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
whiptail --title "$luks_container: Wrong current LUKS Disk Recovery Key passphrase?" --msgbox \
"If you previously changed it and do not remember it, you will have to\n reinstall the OS from an external drive.\n\nTo do so, place the ISO file and its signature file on root of an\n external drive, and select Options-> Boot from USB \n\nHit Enter to retry." 0 80
TRACE_FUNC
detect_boot_device
mount -o remount,rw /boot
rm -f /boot/kexec_key_devices.txt
mount -o remount,ro /boot
luks_secrets_cleanup
unset LUKS
continue
fi
echo -e "\nChanging $luks_container LUKS encrypted disk passphrase to the new LUKS Disk Recovery Key passphrase..."
if ! DO_WITH_DEBUG cryptsetup luksChangeKey "$luks_container" --key-file=/tmp/secret/luks_current_Disk_Recovery_Key_passphrase /tmp/secret/luks_new_Disk_Recovery_Key_passphrase; then
whiptail --title 'Failed to change LUKS passphrase' --msgbox \
"Failed to change the passphrase for $luks_container.\nPlease try again." 0 80
continue
fi
echo "Success changing passphrase for $luks_container."
done
# Export the new passphrase if all containers were processed successfully
luks_current_Disk_Recovery_Key_passphrase=$luks_new_Disk_Recovery_Key_passphrase
export luks_current_Disk_Recovery_Key_passphrase
export luks_new_Disk_Recovery_Key_passphrase
export LUKS
}
luks_secrets_cleanup()
{
TRACE_FUNC
#Cleanup
shred -n 10 -z -u /tmp/secret/luks_new_Disk_Recovery_Key_passphrase 2>/dev/null || true
shred -n 10 -z -u /tmp/secret/luks_current_Disk_Recovery_Key_passphrase 2>/dev/null || true
#Unset variables (when in same boot)
unset luks_current_Disk_Recovery_Key_passphrase
unset luks_new_Disk_Recovery_Key_passphrase
#TODO: refactor logic of selec_luks_conatainer, where to put
#unset LUKS
}