Signed-off-by: Thierry Laurion <insurgo@riseup.net>
This commit is contained in:
Thierry Laurion 2023-10-18 13:15:48 -04:00
parent e1d972be37
commit b1e5c638cd
No known key found for this signature in database
GPG Key ID: E7B4A71658E36A93
6 changed files with 917 additions and 480 deletions

View File

@ -6,10 +6,13 @@ export CONFIG_COREBOOT=y
export CONFIG_COREBOOT_VERSION=4.19 export CONFIG_COREBOOT_VERSION=4.19
export CONFIG_LINUX_VERSION=5.10.5 export CONFIG_LINUX_VERSION=5.10.5
#Enable only one RESTRICTED/BASIC boot modes below to test them manually (we cannot inject config under QEMU (no internal flashing) #Enable only one RESTRICTED/BASIC boot modes below to test them manually (we cannot inject config under QEMU (no internal flashing))
#export CONFIG_RESTRICTED_BOOT=y #export CONFIG_RESTRICTED_BOOT=y
#export CONFIG_BASIC=y #export CONFIG_BASIC=y
#Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing))
export CONFIG_HAVE_GPG_KEY_BACKUP=y
#Enable DEBUG output #Enable DEBUG output
export CONFIG_DEBUG_OUTPUT=y export CONFIG_DEBUG_OUTPUT=y
export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y

View File

@ -7,6 +7,9 @@ set -e -o pipefail
TRACE "Under /bin/media-scan" TRACE "Under /bin/media-scan"
#Booting from external media should be authenticated if supported
gpg_auth
# Unmount any previous boot device # Unmount any previous boot device
if grep -q /boot /proc/mounts ; then if grep -q /boot /proc/mounts ; then
umount /boot \ umount /boot \

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,51 @@ preserve_rom() {
done done
} }
gpg_auth() {
TRACE "Under /etc/ash_functions:gpg_auth"
if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" = "y" ]; then
# If we have a GPG key backup, we can use it to authenticate even if the card is lost
echo >&2 "!!!!! Please authenticate with OpenPGP card/backup media to prove you are the owner of this machine !!!!!"
# Wipe any existing nonce and signature
shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true
confirm_gpg_card
# Perform a signing-based challenge-response,
# to authencate that the card plugged in holding
# the key to sign the list of boot files.
CR_NONCE="/tmp/secret/cr_nonce"
CR_SIG="$CR_NONCE.sig"
# Generate a random nonce
dd \
if=/dev/urandom \
of="$CR_NONCE" \
count=1 \
bs=20 \
2>/dev/null \
|| die "Unable to generate 20 random bytes"
# Sign the nonce
for tries in 1 2 3; do
if gpg --digest-algo SHA256 \
--detach-sign \
-o "$CR_SIG" \
"$CR_NONCE" \
&& gpgv "$CR_SIG" "$CR_NONCE" \
; then
shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true
return 0
else
shred -n 10 -z -u "$CR_SIG" 2>/dev/null || true
continue
fi
done
return 1
fi
}
recovery() { recovery() {
TRACE "Under /etc/ash_functions:recovery" TRACE "Under /etc/ash_functions:recovery"
echo >&2 "!!!!! $*" echo >&2 "!!!!! $*"
@ -82,6 +127,9 @@ recovery() {
do do
echo >&2 "!!!!! Starting recovery shell" echo >&2 "!!!!! Starting recovery shell"
sleep 1 sleep 1
#Going to recovery shell should be authenticated if supported
gpg_auth
if [ -x /bin/setsid ]; then if [ -x /bin/setsid ]; then
/bin/setsid -c /bin/sh /bin/setsid -c /bin/sh

View File

@ -191,19 +191,73 @@ list_usb_storage() {
confirm_gpg_card() { confirm_gpg_card() {
TRACE "Under /etc/functions:confirm_gpg_card" TRACE "Under /etc/functions:confirm_gpg_card"
#Skip prompts if we are currently using a known GPG key material Thumb drive backup and keys are unlocked pinentry
#TODO: probably export CONFIG_GPG_KEY_BACKUP_IN_USE but not under /etc/user.config?
#Toggle to come in next PR, but currently we don't have a way to toggle it back to n if config.user flashed back in rom
if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]]; then
return
fi
if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" ]; then
message="Please confirm that your GPG card is inserted(Y/n) or your GPG key material (b)backup thumbdrive is inserted [Y/n/b]: "
else
# Generic message if no known key material backup
message+="Please confirm that your GPG card is inserted [Y/n]: "
fi
read \ read \
-n 1 \ -n 1 \
-p "Please confirm that your GPG card is inserted [Y/n]: " \ -p "$message" \
card_confirm card_confirm
echo echo
if [ "$card_confirm" != "y" \ if [ "$card_confirm" != "y" \
-a "$card_confirm" != "Y" \ -a "$card_confirm" != "Y" \
-a "$card_confirm" != "b" \
-a -n "$card_confirm" ] \ -a -n "$card_confirm" ] \
; then ; then
die "gpg card not confirmed" die "gpg card not confirmed"
fi fi
# If user has known GPG key material Thumb drive backup and asked to use it
if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$card_confirm" == "b" ]]; then
#Only mount and import GPG key material thumb drive backup once
if [ ! "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]; then
CR_NONCE="/tmp/secret/cr_nonce"
CR_SIG="$CR_NONCE.sig"
#Wipe any previous CR_NONCE and CR_SIG
shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true
#Prompt user for provisioned GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys
echo
read -s -p "Please enter GPG Admin PIN needed to use the GPG backup thumb drive: " gpg_admin_pin
#prompt user to select the proper encrypted partition, which should the first one on next prompt
echo -e "Please select encrypted LUKS container partition (not the public one)\n"
mount-usb --pass "$gpg_admin_pin" || die "Unable to mount USB with GPG Admin PIN"
warn "Testing detach-sign operation and verifiying against fused public key in ROM..."
gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --import /media/subkeys.sec >/dev/null 2>&1 ||
die "Unable to import GPG private subkeys"
#Do a detach signature to ensure gpg material is usable and cache passphrase to sign /boot from caller functions
dd if=/dev/urandom of="$CR_NONCE" bs=20 count=1 >/dev/null 2>&1 ||
die "Unable to create dummy file to sign"
gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --detach-sign "$CR_NONCE" >/dev/null 2>&1 ||
die "Unable to sign dummy file with GPG private signing subkey"
#verify detached signature against public key in rom
gpg --verify "$CR_SIG" "$CR_NONCE" || die "Unable to verify dummy file with GPG public key in ROM: public key mismatch"
#Wipe any previous CR_NONCE and CR_SIG
shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true
#TODO: maybe just an export instead of setting /etc/user.config otherwise could be flashed in weird corner case situation
set_user_config CONFIG_GPG_KEY_BACKUP_IN_USE y
umount /media || die "Unable to unmount USB"
return
fi
#Else if user has known GPG key material Thumb drive backup and already asked to use it
if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]]; then
return
fi
fi
# setup the USB so we can reach the GPG card # setup the USB so we can reach the GPG card
enable_usb enable_usb

View File

@ -6,25 +6,20 @@
. /tmp/config . /tmp/config
#List all LUKS devices on the system #List all LUKS devices on the system
list_luks_devices() list_luks_devices() {
{
#generate a list of devices to choose from that contain a LUKS header #generate a list of devices to choose from that contain a LUKS header
lvm vgscan||true lvm vgscan || true
blkid | cut -d ':' -f 1 | while read device blkid | cut -d ':' -f 1 | while read device; do
do cryptsetup isLuks $device cryptsetup isLuks $device
if [ $? -eq 0 ]; then if [ $(echo $?) == 0 ]; then echo $device; fi
echo "$device" done | sort
fi
done | sort
} }
#Whiptail prompt asking user to select ratio of device to use for LUKS container between: 25, 50, 75
#Whiptail prompt asking user to select ratio of device to use for LUKS container between: 10, 25, 50, 75 select_luks_container_size_percent() {
select_luks_container_size_percent()
{
TRACE "Under /etc/luks-functions:select_luks_container_size_percent()" TRACE "Under /etc/luks-functions:select_luks_container_size_percent()"
if [ -x /bin/whiptail ]; then if [ -x /bin/whiptail ]; then
#whiptail prompt asking user to select ratio of device to use for LUKS container between: 10, 25, 50, 75 #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 returns the percentage of the device to use for LUKS container
whiptail --title "Select LUKS container size percentage of device" --menu \ whiptail --title "Select LUKS container size percentage of device" --menu \
"Select LUKS container size percentage of device:" 0 80 10 \ "Select LUKS container size percentage of device:" 0 80 10 \
@ -57,7 +52,7 @@ select_luks_container_size_percent()
fi fi
} }
#Partition a device with two partitions: a first one being a LUKS container containing private ext4 partition and second public exfat partition #Partition a device with two partitions: a first one being a LUKS container containing private ext4 partition and second public exfat partition
# Size provisioning is done by percentage of the device # Size provisioning is done by percentage of the device
prepare_thumb_drive() prepare_thumb_drive()
{ {
@ -84,12 +79,12 @@ prepare_thumb_drive()
PERCENTAGE=$2 PERCENTAGE=$2
shift 2 shift 2
;; ;;
--passphrase) --pass)
PASSPHRASE=$2 PASSPHRASE=$2
shift 2 shift 2
;; ;;
*) *)
echo "usage: prepare_thumb_drive [--device device] [--percentage percentage] [--passphrase passphrase]" echo "usage: prepare_thumb_drive [--device device] [--percentage percentage] [--pass passphrase]"
;; ;;
esac esac
done done
@ -184,7 +179,7 @@ prepare_thumb_drive()
DISK_SIZE_MB=$((DISK_SIZE_BYTES/1024/1024)) DISK_SIZE_MB=$((DISK_SIZE_BYTES/1024/1024))
#Get size in bytes from percentage and apply percentage to DISK_SIZE_MB #Get size in bytes from percentage and apply percentage to DISK_SIZE_MB
PERCENTAGE_MB="$((DISK_SIZE_MB*PERCENTAGE/100))" PERCENTAGE_MB="$((DISK_SIZE_MB*PERCENTAGE/100))"
#Console and whiptail $BG_COLOR_WARNING prompt (Y/n) validate one last time wiping and repartitioning of $device of total size $DISK_SIZE_MB with $PERCENTAGE_MB assigned to LUKS encrypted private partition #Console and whiptail $BG_COLOR_WARNING prompt (Y/n) validate one last time wiping and repartitioning of $device of total size $DISK_SIZE_MB with $PERCENTAGE_MB assigned to LUKS encrypted private partition
if [ -x /bin/whiptail ]; then if [ -x /bin/whiptail ]; then
whiptail $BG_COLOR_WARNING --title "WARNING: Wiping and repartitioning $DEVICE of $DISK_SIZE_MB MB" --yesno \ whiptail $BG_COLOR_WARNING --title "WARNING: Wiping and repartitioning $DEVICE of $DISK_SIZE_MB MB" --yesno \
@ -201,13 +196,12 @@ prepare_thumb_drive()
fi fi
fi fi
echo -e "Preparing $DEVICE with $PERCENTAGE_MB MB for private LUKS container and rest of disk with exfat\ echo -e "Preparing $DEVICE with $PERCENTAGE_MB MB for private LUKS container and rest of disk with exfat for public partition (This may take a while)..." | fold -s
\n for public partition (This may take a while)..." | fold -s
DEBUG "Creating empty DOS partition table on device through fdisk to start clean" 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" 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" 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" 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 "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..." 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 \ 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 \ --key-file <(echo -n "${PASSPHRASE}") > /dev/null 2>&1 \
@ -216,11 +210,11 @@ prepare_thumb_drive()
DO_WITH_DEBUG cryptsetup open ${DEVICE}1 private --key-file <(echo -n "${PASSPHRASE}") > /dev/null 2>&1 \ DO_WITH_DEBUG cryptsetup open ${DEVICE}1 private --key-file <(echo -n "${PASSPHRASE}") > /dev/null 2>&1 \
|| die "Error opening LUKS container" || die "Error opening LUKS container"
DEBUG "Formatting LUKS container mapped under /dev/mapper/private as an ext4 partition..." 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" 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..." DEBUG "Closing LUKS device /dev/mapper/private..."
cryptsetup close private > /dev/null 2>&1 || die "Error closing LUKS container" cryptsetup close private > /dev/null 2>&1 || die "Error closing LUKS container"
DEBUG "Formatting second partition ${DEVICE}2 with exfat filesystem..." 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" mkfs.exfat -L public ${DEVICE}2 >/dev/null 2>&1 || die "Error formatting second partition with exfat filesystem"
echo "Done." echo "Done."
} }
@ -242,7 +236,7 @@ select_luks_container()
LUKS=$FILE LUKS=$FILE
detect_boot_device detect_boot_device
mount -o remount,rw /boot mount -o remount,rw /boot
echo "$LUKS $(cryptsetup luksUUID $LUKS)" > /boot/kexec_key_devices.txt echo "$LUKS $(cryptsetup luksUUID $LUKS)" >/boot/kexec_key_devices.txt
mount -o remount,ro /boot mount -o remount,ro /boot
fi fi
else else
@ -255,17 +249,17 @@ select_luks_container()
test_luks_current_disk_recovery_key_passphrase() test_luks_current_disk_recovery_key_passphrase()
{ {
TRACE "Under /etc/luks-functions:test_luks_current_disk_recovery_key_passphrase()" TRACE "Under /etc/luks-functions:test_luks_current_disk_recovery_key_passphrase()"
while : ; do while :; do
select_luks_container || return 1 select_luks_container || return 1
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
#if no external provisioning provides current Disk Recovery Key passphrase #if no external provisioning provides current Disk Recovery Key passphrase
echo -e "\nEnter current Disk Recovery Key passphrase (Provisioned at OS installation or by OEM):" echo -e "\nEnter current Disk Recovery Key passphrase (Provisioned at OS installation or by OEM):"
read -r luks_current_Disk_Recovery_Key_passphrase read -r luks_current_Disk_Recovery_Key_passphrase
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/luks_current_Disk_Recovery_Key_passphrase echo -n "$luks_current_Disk_Recovery_Key_passphrase" >/tmp/luks_current_Disk_Recovery_Key_passphrase
warn "Test opening "$LUKS" LUKS encrypted drive content with current Recovery Disk Key passphrase..." warn "Test opening "$LUKS" LUKS encrypted drive content with current Recovery Disk Key passphrase..."
cryptsetup open $LUKS test --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase cryptsetup open $LUKS test --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase
else else
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/luks_current_Disk_Recovery_Key_passphrase echo -n "$luks_current_Disk_Recovery_Key_passphrase" >/tmp/luks_current_Disk_Recovery_Key_passphrase
warn "Test opening "$LUKS" LUKS encrypted drive content with current Recovery Disk Key passphrase..." warn "Test opening "$LUKS" LUKS encrypted drive content with current Recovery Disk Key passphrase..."
cryptsetup open $LUKS test --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase cryptsetup open $LUKS test --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase
fi fi
@ -273,7 +267,7 @@ test_luks_current_disk_recovery_key_passphrase()
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
whiptail --title 'Invalid Actual LUKS Disk Recovery Key passphrase?' --msgbox \ whiptail --title 'Invalid Actual LUKS Disk Recovery Key passphrase?' --msgbox \
"If you previously changed it and do not remember it, you will have to\n reinstall OS from a an external drive.\n\nTo do so, place ISO file and its signature file on root of external drive,\n and select Options-> Boot from USB \n\nHit Enter to retry." 30 60 "If you previously changed it and do not remember it, you will have to\n reinstall OS from a an external drive.\n\nTo do so, place ISO file and its signature file on root of external drive,\n and select Options-> Boot from USB \n\nHit Enter to retry." 30 60
shred -n 10 -z -u /tmp/luks_current_Disk_Recovery_Key_passphrase 2> /dev/null shred -n 10 -z -u /tmp/luks_current_Disk_Recovery_Key_passphrase 2>/dev/null
#unsetting luks_current_Disk_Recovery_Key_passphrase so we prompt for it again Disk Recovery Key passphrase prompt on next round #unsetting luks_current_Disk_Recovery_Key_passphrase so we prompt for it again Disk Recovery Key passphrase prompt on next round
unset luks_current_Disk_Recovery_Key_passphrase unset luks_current_Disk_Recovery_Key_passphrase
#remove "known good" selected luks container so that next pass asks again user to select luks container. #remove "known good" selected luks container so that next pass asks again user to select luks container.
@ -285,7 +279,7 @@ test_luks_current_disk_recovery_key_passphrase()
else else
#LuksOpen test was successful. Cleanup should be called only when done #LuksOpen test was successful. Cleanup should be called only when done
#Exporting successfully used passphrase possibly reused by oem-factory-reset #Exporting successfully used passphrase possibly reused by oem-factory-reset
#We close the volume #We close the volume
cryptsetup close test cryptsetup close test
export luks_current_Disk_Recovery_Key_passphrase export luks_current_Disk_Recovery_Key_passphrase
@ -294,108 +288,108 @@ test_luks_current_disk_recovery_key_passphrase()
done done
} }
luks_reencrypt(){ luks_reencrypt() {
TRACE "Under /etc/luks-functions:luks_reencrypt()" TRACE "Under /etc/luks-functions:luks_reencrypt()"
while : ; do while :; do
select_luks_container || return 1 select_luks_container || return 1
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
#if no external provisioning provides current Disk Recovery Key passphrase #if no external provisioning provides current Disk Recovery Key passphrase
whiptail --title 'Reencrypt LUKS disk encrypted container ?' \ whiptail --title 'Reencrypt LUKS disk encrypted container ?' \
--msgbox "This will replace the encrypted container content and its Disk Recovery Key.\n\nThe passphrase associated with this key will be asked from the user in the\nfollowing 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/upgraded/modified by the user\n\nThis process requires you to type the current Disk Recovery Key passphrase\nand will delete TPM Disk unlock key slot if set up by setting a default boot\n LUKS header (slot 1) if present.\n\nAt the next prompt, you may be asked to select which file corresponds to\nthe LUKS device container.\n\nHit Enter to continue." 0 80 --msgbox "This will replace the encrypted container content and its Disk Recovery Key.\n\nThe passphrase associated with this key will be asked from the user in the\nfollowing 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/upgraded/modified by the user\n\nThis process requires you to type the current Disk Recovery Key passphrase\nand will delete TPM Disk unlock key slot if set up by setting a default boot\n LUKS header (slot 1) if present.\n\nAt the next prompt, you may be asked to select which file corresponds to\nthe LUKS device container.\n\nHit Enter to continue." 0 80
echo -e "\nEnter current Disk Recovery Key passphrase (Provisioned at OS installation or by OEM):" echo -e "\nEnter current Disk Recovery Key passphrase (Provisioned at OS installation or by OEM):"
read -r luks_current_Disk_Recovery_Key_passphrase read -r luks_current_Disk_Recovery_Key_passphrase
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/luks_current_Disk_Recovery_Key_passphrase echo -n "$luks_current_Disk_Recovery_Key_passphrase" >/tmp/luks_current_Disk_Recovery_Key_passphrase
warn "Reencrypting "$LUKS" LUKS encrypted drive content with current Recovery Disk Key passphrase..." warn "Reencrypting "$LUKS" LUKS encrypted drive content with current Recovery Disk Key passphrase..."
cryptsetup-reencrypt -B 64 --use-directio "$LUKS" --key-slot 0 --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase cryptsetup-reencrypt -B 64 --use-directio "$LUKS" --key-slot 0 --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase
else else
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/luks_current_Disk_Recovery_Key_passphrase echo -n "$luks_current_Disk_Recovery_Key_passphrase" >/tmp/luks_current_Disk_Recovery_Key_passphrase
warn "Reencrypting "$LUKS" LUKS encrypted drive content with current Recovery Disk Key passphrase..." warn "Reencrypting "$LUKS" LUKS encrypted drive content with current Recovery Disk Key passphrase..."
cryptsetup-reencrypt -B 64 --use-directio "$LUKS" --key-slot 0 --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase cryptsetup-reencrypt -B 64 --use-directio "$LUKS" --key-slot 0 --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase
fi fi
#Validate past cryptsetup-reencrypt attempts #Validate past cryptsetup-reencrypt attempts
if [ $(echo $?) -ne 0 ]; then if [ $(echo $?) -ne 0 ]; then
whiptail --title 'Invalid Actual LUKS Disk Recovery Key passphrase?' --msgbox \ whiptail --title 'Invalid Actual LUKS Disk Recovery Key passphrase?' --msgbox \
"If you previously changed it and do not remember it, you will have to\n reinstall OS from a an external drive.\n\nTo do so, place ISO file and its signature file on root of external drive,\n and select Options-> Boot from USB \n\nHit Enter to retry." 30 60 "If you previously changed it and do not remember it, you will have to\n reinstall OS from a an external drive.\n\nTo do so, place ISO file and its signature file on root of external drive,\n and select Options-> Boot from USB \n\nHit Enter to retry." 30 60
shred -n 10 -z -u /tmp/luks_current_Disk_Recovery_Key_passphrase 2> /dev/null shred -n 10 -z -u /tmp/luks_current_Disk_Recovery_Key_passphrase 2>/dev/null
#unsetting luks_current_Disk_Recovery_Key_passphrase so we prompt for it again Disk Recovery Key passphrase prompt on next round #unsetting luks_current_Disk_Recovery_Key_passphrase so we prompt for it again Disk Recovery Key passphrase prompt on next round
unset luks_current_Disk_Recovery_Key_passphrase unset luks_current_Disk_Recovery_Key_passphrase
#remove "known good" selected luks container so that next pass asks again user to select luks container. #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 #maybe the container was not the right one
detect_boot_device detect_boot_device
mount -o remount,rw /boot mount -o remount,rw /boot
rm -f /boot/kexec_key_devices.txt rm -f /boot/kexec_key_devices.txt
mount -o remount,ro /boot mount -o remount,ro /boot
else else
#Reencryption was successful. Cleanup should be called only when done #Reencryption was successful. Cleanup should be called only when done
#Exporting successfully used passphrase possibly reused by oem-factory-reset #Exporting successfully used passphrase possibly reused by oem-factory-reset
export luks_current_Disk_Recovery_Key_passphrase export luks_current_Disk_Recovery_Key_passphrase
break; break;
fi fi
done done
} }
luks_change_passphrase() luks_change_passphrase()
{ {
TRACE "Under /etc/luks-functions:luks_change_passphrase()" TRACE "Under /etc/luks-functions:luks_change_passphrase()"
while : ; do while :; do
select_luks_container || return 1 select_luks_container || return 1
#if actual or new Disk Recovery Key is not provisioned by oem-provisioning file #if actual or new Disk Recovery Key is not provisioned by oem-provisioning file
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ] || [ -z "$luks_new_Disk_Recovery_Key_passphrase" ] ; then 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 \ whiptail --title 'Changing LUKS Disk Recovery Key passphrase' --msgbox \
"Please enter current 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" 30 60 "Please enter current 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" 30 60
if [ -z "$luks_new_Disk_Recovery_Key_passphrase" ] ; then if [ -z "$luks_new_Disk_Recovery_Key_passphrase" ]; then
echo -e "\nEnter desired replacement for actual Disk Recovery Key passphrase (At least 8 characters long):" echo -e "\nEnter desired replacement for actual Disk Recovery Key passphrase (At least 8 characters long):"
while [[ ${#luks_new_Disk_Recovery_Key_passphrase} -lt 8 ]]; do while [[ ${#luks_new_Disk_Recovery_Key_passphrase} -lt 8 ]]; do
{ {
read -r luks_new_Disk_Recovery_Key_passphrase read -r luks_new_Disk_Recovery_Key_passphrase
};done };done
fi
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
echo -e "\nEnter current Disk Recovery Key passphrase (Provisioned at OS installation or by OEM):"
read -r luks_current_Disk_Recovery_Key_passphrase
fi
export luks_current_Disk_Recovery_Key_passphrase
export luks_new_Disk_Recovery_Key_passphrase
echo -n "$luks_new_Disk_Recovery_Key_passphrase" >/tmp/luks_new_Disk_Recovery_Key_passphrase
echo -n "$luks_current_Disk_Recovery_Key_passphrase" >/tmp/luks_current_Disk_Recovery_Key_passphrase
warn "Changing "$LUKS" LUKS encrypted disk passphrase to new Disk Recovery Key passphrase..."
cryptsetup luksChangeKey "$LUKS" --key-slot 0 --key-file=/tmp/luks_current_Disk_Recovery_Key_passphrase /tmp/luks_new_Disk_Recovery_Key_passphrase
else
#If current and new Disk Recovery Key were exported
echo -n "$luks_new_Disk_Recovery_Key_passphrase" >/tmp/luks_new_Disk_Recovery_Key_passphrase
echo -n "$luks_current_Disk_Recovery_Key_passphrase" >/tmp/luks_current_Disk_Recovery_Key_passphrase
warn "Changing "$LUKS" LUKS encrypted disk passphrase to new Disk Recovery Key passphrase..."
cryptsetup luksChangeKey "$LUKS" --key-slot 0 --key-file=/tmp/luks_current_Disk_Recovery_Key_passphrase /tmp/luks_new_Disk_Recovery_Key_passphrase
fi fi
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ];then
echo -e "\nEnter current Disk Recovery Key passphrase (Provisioned at OS installation or by OEM):" #Validate past cryptsetup attempts
read -r luks_current_Disk_Recovery_Key_passphrase if [ $(echo $?) -ne 0 ]; then
fi #Cryptsetup luksChangeKey was unsuccessful
export luks_current_Disk_Recovery_Key_passphrase whiptail --title 'Invalid LUKS passphrase?' --msgbox \
export luks_new_Disk_Recovery_Key_passphrase "The LUKS Disk Recovery Key passphrase was provided to you by the OEM over\n secure communication channel.\n\nIf you previously changed it and do not remember it,\n you will have to reinstall OS from a USB drive.\nTo do so, put OS ISO file and it's signature file on root of USB drive,\n And select Boot from USB\n\nHit Enter to continue." 30 60
echo -n "$luks_new_Disk_Recovery_Key_passphrase" > /tmp/luks_new_Disk_Recovery_Key_passphrase unset luks_current_Disk_Recovery_Key_passphrase
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/luks_current_Disk_Recovery_Key_passphrase unset luks_new_Disk_Recovery_Key_passphrase
warn "Changing "$LUKS" LUKS encrypted disk passphrase to new Disk Recovery Key passphrase..." #remove "known good" selected luks container so that next pass asks again user to select LUKS container.
cryptsetup luksChangeKey "$LUKS" --key-slot 0 --key-file=/tmp/luks_current_Disk_Recovery_Key_passphrase /tmp/luks_new_Disk_Recovery_Key_passphrase #maybe the container was not the right one
else detect_boot_device
#If current and new Disk Recovery Key were exported mount -o remount,rw /boot
echo -n "$luks_new_Disk_Recovery_Key_passphrase" > /tmp/luks_new_Disk_Recovery_Key_passphrase rm -f /boot/kexec_key_devices.txt
echo -n "$luks_current_Disk_Recovery_Key_passphrase" > /tmp/luks_current_Disk_Recovery_Key_passphrase mount -o remount,ro /boot
warn "Changing "$LUKS" LUKS encrypted disk passphrase to new Disk Recovery Key passphrase..." else
cryptsetup luksChangeKey "$LUKS" --key-slot 0 --key-file=/tmp/luks_current_Disk_Recovery_Key_passphrase /tmp/luks_new_Disk_Recovery_Key_passphrase #Cryptsetup was successful.
fi #Cleanup should be called seperately.
#Exporting successfully used passphrase possibly reused by oem-factory-reset
#Validate past cryptsetup attempts export luks_new_Disk_Recovery_Key_passphrase
if [ $(echo $?) -ne 0 ]; then
#Cryptsetup luksChangeKey was unsuccessful
whiptail --title 'Invalid LUKS passphrase?' --msgbox \
"The LUKS Disk Recovery Key passphrase was provided to you by the OEM over\n secure communication channel.\n\nIf you previously changed it and do not remember it,\n you will have to reinstall OS from a USB drive.\nTo do so, put OS ISO file and it's signature file on root of USB drive,\n And select Boot from USB\n\nHit Enter to continue." 30 60
unset luks_current_Disk_Recovery_Key_passphrase
unset luks_new_Disk_Recovery_Key_passphrase
#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
else
#Cryptsetup was successful.
#Cleanup should be called seperately.
#Exporting successfully used passphrase possibly reused by oem-factory-reset
export luks_new_Disk_Recovery_Key_passphrase
break; break;
fi fi
done done
} }
luks_secrets_cleanup() luks_secrets_cleanup()
{ {
#Cleanup #Cleanup
shred -n 10 -z -u /tmp/luks_new_Disk_Recovery_Key_passphrase 2> /dev/null || true shred -n 10 -z -u /tmp/luks_new_Disk_Recovery_Key_passphrase 2>/dev/null || true
shred -n 10 -z -u /tmp/luks_current_Disk_Recovery_Key_passphrase 2> /dev/null || true shred -n 10 -z -u /tmp/luks_current_Disk_Recovery_Key_passphrase 2>/dev/null || true
unset luks_current_Disk_Recovery_Key_passphrase unset luks_current_Disk_Recovery_Key_passphrase
unset luks_new_Disk_Recovery_Key_passphrase unset luks_new_Disk_Recovery_Key_passphrase
} }