heads/initrd/bin/kexec-seal-key

258 lines
9.3 KiB
Plaintext
Raw Permalink Normal View History

#!/bin/bash
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
# This will generate a disk encryption key and seal / encrypt
# with the current PCRs and then store it in the TPM NVRAM.
# It will then need to be bundled into initrd that is booted.
set -e -o pipefail
. /etc/functions
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
find_drk_key_slot() {
local temp_drk_key_slot=""
local keyslot
for keyslot in "${luks_used_keyslots[@]}"; do
if [ -z "$temp_drk_key_slot" ]; then
DEBUG "Testing LUKS key slot $keyslot against $DISK_RECOVERY_KEY_FILE for Disk Recovery Key slot..."
if DO_WITH_DEBUG cryptsetup open --test-passphrase --key-slot "$keyslot" --key-file "$DISK_RECOVERY_KEY_FILE" "$dev"; then
temp_drk_key_slot="$keyslot"
DEBUG "Disk Recovery key slot is $temp_drk_key_slot"
break
fi
fi
done
echo "$temp_drk_key_slot"
}
TPM_INDEX=3
TPM_SIZE=312
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
DUK_KEY_FILE="/tmp/secret/secret.key"
TPM_SEALED="/tmp/secret/secret.sealed"
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
DISK_RECOVERY_KEY_FILE="/tmp/secret/recovery.key"
. /etc/functions
. /tmp/config
TRACE_FUNC
paramsdir=$1
if [ -z "$paramsdir" ]; then
die "Usage $0 /boot"
fi
KEY_DEVICES="$paramsdir/kexec_key_devices.txt"
KEY_LVM="$paramsdir/kexec_key_lvm.txt"
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
key_devices=$(cat "$KEY_DEVICES" | cut -d\ -f1 | tr '\n' ' ')
if [ ! -r "$KEY_DEVICES" ]; then
die "No devices defined for disk encryption"
else
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
DEBUG "Devices defined for disk encryption: $key_devices"
fi
if [ -r "$KEY_LVM" ]; then
# Activate the LVM volume group
VOLUME_GROUP=$(cat $KEY_LVM)
if [ -z "$VOLUME_GROUP" ]; then
die "No LVM volume group defined for activation"
fi
lvm vgchange -a y $VOLUME_GROUP ||
die "$VOLUME_GROUP: unable to activate volume group"
else
DEBUG "No LVM volume group defined for activation"
fi
DEBUG "$(pcrs)"
Addition of qemu-(fb)whiptail-tpm2(-hotp) boards -coreboot support of TPM v2.0 (shared config for TPM2 support across all 4 previous variations) -swtpm set to be launched under TPM v2.0 mode under board config -Documentation file under each board.md softlinks to qemu-coreboot-fbwhiptail-tpm1.md (which has been generalized) This is skeleton for TPM v2 integration under Heads ------------- WiP TODO: - libcurl cannot be built as a tpm2-tools dependency as of now not sure why. curl currently needs to be added in board config to be built - Note: tpm-reset (master and here) needs some review, no handle of no tpm use case. Caller is responsible to not call it otherwise does nothing - init tries to bind fd and fails currently - Note: Check if whiptail is different of fbwhiptail in clearing screen. As of now every clear seems to be removed, still whiptail clears previous console output - When no OS' /boot can be mounted, do not try to TPM reset (will fail) - seal-hotpkey is not working properly - setting disk unlock key asks for TPM ownership passphrase (sealing in NV requires ownership, but text is misleading user as if reowning TPM) - We should cache input, feed tpm behind the scene and wipe passphrase and state clearly that this is TPM disk unlock kye passphrase. - primary key from TPM2 is invalid most of the time from kexec-select-boot and verifying global hashes but is setuped correctly at disk unlock key setup - would be nice to take advantage of bash function tracing to understand where we are for debugging purposes, code takes ash in consideration only - tpmr says it implements nv calls but actually doesn't. Removing those falsely wrapped functions would help. - Implementing them would be better - REVIEW TODOS IN CODE - READD CIRCLECI CONFIG Current state: - TPM unseal works without disk unlock key and generates TOTP properly (was missing die condition at unseal to not produce always good TOTP even if invalid) - TPM disk encryption key fails. Hypothesis is that sealing with USB drivers loaded and measures in inconsistent with sealed with/without. - TPM disk unsealing happens without USB modules being loaded in non-HOTP setup. This fails. - Current tests are with fbwhiptail (no clear called so having traces on command line of what happens) - Testing with HOTP implementation for sealing/unsealing since that forces USB module loads on each boot to remove this from failing possibilities
2022-08-25 18:43:31 +00:00
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
luks_drk_passphrase_valid=0
for dev in $key_devices ; do
attempts=0
while [ $attempts -lt 3 ]; do
if [ "$luks_drk_passphrase_valid" == "0" ]; then
# Ask for the passphrase only once
read -s -p "Enter LUKS Disk Recovery Key (DRK) passphrase that can unlock: $key_devices: " disk_recovery_key_passphrase
#Using he provided passphrase as the DRK "keyfile" for unattended operations
echo -n "$disk_recovery_key_passphrase" >"$DISK_RECOVERY_KEY_FILE"
echo
fi
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
DEBUG "Testing $DISK_RECOVERY_KEY_FILE keyfile created from provided passphrase against $dev individual key slots"
if cryptsetup open $dev --test-passphrase --key-file "$DISK_RECOVERY_KEY_FILE" >/dev/null 2>&1; then
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 <insurgo@riseup.net>
2024-10-29 13:28:59 +00:00
echo "++++++ $dev: LUKS device unlocked successfully with the DRK passphrase"
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
luks_drk_passphrase_valid=1
break
else
attempts=$((attempts + 1))
if [ "$attempts" == "3" ] && [ "$luks_drk_passphrase_valid" == "0" ]; then
die "Failed to unlock LUKS device $dev with the provided passphrase. Exiting..."
elif [ "$attempts" != "3" ] && [ "$luks_drk_passphrase_valid" == "1" ]; then
#We failed unlocking with DRK passphrase another LUKS container
die "LUKS device $key_devices cannot all be unlocked with same passphrase. Please make $key_devices devices unlockable with the same passphrase. Exiting"
else
warn "Failed to unlock LUKS device $dev with the provided passphrase. Please try again."
fi
fi
done
done
attempts=0
while [ $attempts -lt 3 ]; do
read -s -p "New LUKS TPM Disk Unlock Key passphrase (DUK) for booting: " key_password
echo
read -s -p "Repeat LUKS TPM Disk Unlock Key (DUK) passphrase for booting: " key_password2
echo
if [ "$key_password" != "$key_password2" ]; then
attempts=$((attempts + 1))
if [ "$attempts" == "3" ]; then
die "Disk Unlock Key passphrases do not match. Exiting..."
else
warn "Disk Unlock Key passphrases do not match. Please try again."
fi
else
break
fi
done
# Generate key file
Uniformize vocabulary: LUKS TPM Disk Unlock Key & LUKS Disk Recovery Key When playing with long fbwhiptail/whiptail messages, this commit played around the long string using fold. ''' 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 ''' Which gave the exact output of what will be inside of the fbwhiptail prompt, fixed to 70 chars width: ''' This will replace the encrypted container content and its LUKS Disk Recovery Key. The passphrase associated with this key will be asked from the user under the following conditions: 1-Every boot if no Disk Unlock Key was added to the TPM 2-If the TPM fails (hardware failure) 3-If the firmware has been tampered with/modified by the user This 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. At the next prompt, you may be asked to select which file corresponds to the LUKS device container. Hit Enter to continue. ''' Therefore, for long prompts in the future, one can just deal with "\n 1-" alignments to be respected in prompts and have fold deal with cutting the length of strings properly. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-01-19 17:32:04 +00:00
echo "++++++ Generating new randomized 128 bytes key file that will be sealed/unsealed by LUKS TPM Disk Unlock Key passphrase"
dd \
if=/dev/urandom \
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
of="$DUK_KEY_FILE" \
bs=1 \
count=128 \
2>/dev/null ||
die "Unable to generate 128 random bytes"
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
previous_luks_header_version=0
for dev in $key_devices; do
# Check and store LUKS version of the devices to be used later
luks_version=$(cryptsetup luksDump "$dev" | grep "Version" | cut -d: -f2 | tr -d '[:space:]')
if [ "$luks_version" == "2" ] && [ "$previous_luks_header_version" == "1" ]; then
die "$dev: LUKSv2 device detected while LUKSv1 device was detected previously. Exiting..."
fi
if [ "$luks_version" == "1" ] && [ "$previous_luks_header_version" == "2" ]; then
die "$dev: LUKSv1 device detected while LUKSv2 device was detected previously. Exiting..."
fi
if [ "$luks_version" == "2" ]; then
# LUKSv2 last key slot is 31
duk_keyslot=31
regex="^\s+([0-9]+):\s*luks2"
sed_command="s/^\s\+\([0-9]\+\):\s*luks2/\1/g"
previous_luks_header_version=2
DEBUG "$dev: LUKSv2 device detected"
elif [ "$luks_version" == "1" ]; then
# LUKSv1 last key slot is 7
duk_keyslot=7
regex="Key Slot ([0-9]+): ENABLED"
sed_command='s/Key Slot \([0-9]\+\): ENABLED/\1/'
previous_luks_header_version=1
DEBUG "$dev: LUKSv1 device detected"
else
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
die "$dev: Unsupported LUKS version $luks_version"
fi
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
# drk_key_slot will be the slot number where the passphrase was tested against as valid. We will keep that slot
drk_key_slot="-1"
# Get all the key slots that are used on $dev
luks_used_keyslots=($(cryptsetup luksDump "$dev" | grep -E "$regex" | sed "$sed_command"))
DEBUG "$dev LUKS key slots: ${luks_used_keyslots[*]}"
#Find the key slot that can be unlocked with the provided passphrase
drk_key_slot=$(find_drk_key_slot)
# If we didn't find the DRK key slot, we exit (this should never happen)
if [ "$drk_key_slot" == "-1" ]; then
die "$dev: Unable to find a key slot that can be unlocked with provided passphrase. Exiting..."
fi
# If the key slot is not the expected DUK o FRK key slot, we will ask the user to confirm the wipe
for keyslot in "${luks_used_keyslots[@]}"; do
if [ "$keyslot" != "$drk_key_slot" ]; then
#set wipe_desired to no by default
wipe_desired="no"
if [ "$keyslot" != "$drk_key_slot" ] && [ "$keyslot" == "1" ]; then
wipe_desired="yes"
DEBUG "LUKS key slot $keyslot not DRK. Will wipe this DUK key slot silently"
elif [ "$keyslot" != "$drk_key_slot" ] && [ "$keyslot" != "$duk_keyslot" ]; then
# Heads expects key slot LUKSv1:7 or LUKSv2:31 to be used for TPM DUK setup.
# Ask user to confirm otherwise
warn "LUKS key slot $keyslot is not typical ($duk_keyslot expected) for TPM Disk Unlock Key setup"
read -p "Are you sure you want to wipe it? [y/N] " -n 1 -r
echo
# If user does not confirm, skip this slot
if [[ $REPLY =~ ^[Yy]$ ]]; then
wipe_desired="yes"
fi
elif [ "$keyslot" == "$duk_keyslot" ]; then
# If key slot is the expected DUK keyslot, we wipe it silently
DEBUG "LUKS key slot $keyslot is the expected DUK key slot. Will wipe this DUK key slot silently"
wipe_desired="yes"
fi
if [ "$wipe_desired" == "yes" ] && [ "$keyslot" != "$drk_key_slot" ]; then
echo "++++++ $dev: Wiping LUKS key slot $keyslot"
DO_WITH_DEBUG cryptsetup luksKillSlot \
--key-file "$DISK_RECOVERY_KEY_FILE" \
$dev $keyslot ||
warn "$dev: removal of LUKS slot $keyslot failed: Continuing"
fi
fi
done
echo "++++++ $dev: Adding LUKS TPM Disk Unlock Key to LUKS key slot $duk_keyslot"
DO_WITH_DEBUG cryptsetup luksAddKey \
--key-file "$DISK_RECOVERY_KEY_FILE" \
--new-key-slot $duk_keyslot \
$dev "$DUK_KEY_FILE" ||
die "$dev: Unable to add LUKS TPM Disk Unlock Key to LUKS key slot $duk_keyslot"
done
# Now that we have setup the new keys, measure the PCRs
# We don't care what ends up in PCR 6; we just want
# to get the /tmp/luksDump.txt file. We use PCR16
# since it should still be zero
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
echo "$key_devices" | xargs /bin/qubes-measure-luks ||
die "Unable to measure the LUKS headers"
pcrf="/tmp/secret/pcrf.bin"
tpmr pcrread 0 "$pcrf"
tpmr pcrread -a 1 "$pcrf"
tpmr pcrread -a 2 "$pcrf"
tpmr pcrread -a 3 "$pcrf"
# Note that PCR 4 needs to be set with the "normal-boot" path value, read it from event log.
tpmr calcfuturepcr 4 >>"$pcrf"
if [ "$CONFIG_USER_USB_KEYBOARD" = "y" -o -r /lib/modules/libata.ko -o -x /bin/hotp_verification ]; then
Uniformize vocabulary: LUKS TPM Disk Unlock Key & LUKS Disk Recovery Key When playing with long fbwhiptail/whiptail messages, this commit played around the long string using fold. ''' 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 ''' Which gave the exact output of what will be inside of the fbwhiptail prompt, fixed to 70 chars width: ''' This will replace the encrypted container content and its LUKS Disk Recovery Key. The passphrase associated with this key will be asked from the user under the following conditions: 1-Every boot if no Disk Unlock Key was added to the TPM 2-If the TPM fails (hardware failure) 3-If the firmware has been tampered with/modified by the user This 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. At the next prompt, you may be asked to select which file corresponds to the LUKS device container. Hit Enter to continue. ''' Therefore, for long prompts in the future, one can just deal with "\n 1-" alignments to be respected in prompts and have fold deal with cutting the length of strings properly. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-01-19 17:32:04 +00:00
DEBUG "Sealing LUKS TPM Disk Unlock Key with PCR5 involvement (additional kernel modules are loaded per board config)..."
# Here, we take pcr 5 into consideration if modules are expected to be measured+loaded
tpmr pcrread -a 5 "$pcrf"
else
Uniformize vocabulary: LUKS TPM Disk Unlock Key & LUKS Disk Recovery Key When playing with long fbwhiptail/whiptail messages, this commit played around the long string using fold. ''' 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 ''' Which gave the exact output of what will be inside of the fbwhiptail prompt, fixed to 70 chars width: ''' This will replace the encrypted container content and its LUKS Disk Recovery Key. The passphrase associated with this key will be asked from the user under the following conditions: 1-Every boot if no Disk Unlock Key was added to the TPM 2-If the TPM fails (hardware failure) 3-If the firmware has been tampered with/modified by the user This 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. At the next prompt, you may be asked to select which file corresponds to the LUKS device container. Hit Enter to continue. ''' Therefore, for long prompts in the future, one can just deal with "\n 1-" alignments to be respected in prompts and have fold deal with cutting the length of strings properly. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-01-19 17:32:04 +00:00
DEBUG "Sealing LUKS TPM Disk Unlock Key with PCR5=0 (NO additional kernel modules are loaded per board config)..."
#no kernel modules are expected to be measured+loaded
tpmr calcfuturepcr 5 >>"$pcrf"
fi
# Precompute the value for pcr 6
Uniformize vocabulary: LUKS TPM Disk Unlock Key & LUKS Disk Recovery Key When playing with long fbwhiptail/whiptail messages, this commit played around the long string using fold. ''' 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 ''' Which gave the exact output of what will be inside of the fbwhiptail prompt, fixed to 70 chars width: ''' This will replace the encrypted container content and its LUKS Disk Recovery Key. The passphrase associated with this key will be asked from the user under the following conditions: 1-Every boot if no Disk Unlock Key was added to the TPM 2-If the TPM fails (hardware failure) 3-If the firmware has been tampered with/modified by the user This 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. At the next prompt, you may be asked to select which file corresponds to the LUKS device container. Hit Enter to continue. ''' Therefore, for long prompts in the future, one can just deal with "\n 1-" alignments to be respected in prompts and have fold deal with cutting the length of strings properly. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-01-19 17:32:04 +00:00
DEBUG "Precomputing TPM future value for PCR6 sealing/unsealing of LUKS TPM Disk Unlock Key..."
tpmr calcfuturepcr 6 "/tmp/luksDump.txt" >>"$pcrf"
# We take into consideration user files in cbfs
tpmr pcrread -a 7 "$pcrf"
DO_WITH_DEBUG --mask-position 7 \
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
tpmr seal "$DUK_KEY_FILE" "$TPM_INDEX" 0,1,2,3,4,5,6,7 "$pcrf" \
Uniformize vocabulary: LUKS TPM Disk Unlock Key & LUKS Disk Recovery Key When playing with long fbwhiptail/whiptail messages, this commit played around the long string using fold. ''' 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 ''' Which gave the exact output of what will be inside of the fbwhiptail prompt, fixed to 70 chars width: ''' This will replace the encrypted container content and its LUKS Disk Recovery Key. The passphrase associated with this key will be asked from the user under the following conditions: 1-Every boot if no Disk Unlock Key was added to the TPM 2-If the TPM fails (hardware failure) 3-If the firmware has been tampered with/modified by the user This 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. At the next prompt, you may be asked to select which file corresponds to the LUKS device container. Hit Enter to continue. ''' Therefore, for long prompts in the future, one can just deal with "\n 1-" alignments to be respected in prompts and have fold deal with cutting the length of strings properly. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-01-19 17:32:04 +00:00
"$TPM_SIZE" "$key_password" || die "Unable to write LUKS TPM Disk Unlock Key to NVRAM"
# should be okay if this fails
shred -n 10 -z -u "$pcrf" 2>/dev/null ||
warn "Failed to delete pcrf file - continuing"
cryptsetup2 toolstack version bump and script fixes to support multi-LUKS containers (BTRFS QubesOS 4.2) cryptsetup2 2.6.1 is a new release that supports reencryption of Q4.2 release LUKS2 volumes created at installation. This is a critical feature for the Qubes OS 4.2 release for added data at rest protection Cryptsetup 2.6.x internal changes: - Argon2 used externally and internally: requires a lot of RAM and CPU to derivate passphrase to key validated in key slots. - This is used to rate limit efficiently bruteforcing of LUKS key slots, requiring each offline brute force attempt to consume ~15-30 seconds per attempt - OF course, strong passphrases are still recommended, but bruteforcing LUKSv2 containers with Argon2 would require immense time, ram and CPU even to bruteforce low entropy passphrase/PINs. - passphrase change doesn't permit LUKS key slot specification anymore: key slot rotates (new one consusumed per op: then old one wiped internally. EG: LUKS key slot 1 created, then 0 deleted) - reencryption doesn't permit old call arguments. No more direct-io; inadmissively slow through AIO (async) calls, need workarounds for good enough perfs (arguments + newer kernel with cloudfare fixes in tree) cryptsetup 2.6.1 requires: - lvm2 2.03.23, which is also included in this PR. - requires libaio, which is also included in this PR (could be hacked out but deep dependency at first sight: left in) - requires util-linux 2.39 - patches for reproducible builds are included for above 3 packages. luks-functions was updated to support the new cryptsetup2 version calls/changes - reencryption happen in direct-io, offline mode and without locking, requiring linux 5.10.9+ to bypass linux queues - from tests, this is best for performance and reliability in single-user mode - LUKS container ops now validate Disk Recovery Key (DRK) passphrase prior and DRK key slot prior of going forward if needed, failing early. - Heads don't expect DRK to be in static key slot anymore, and finds the DRK key slot dynamically. - If reencrytipn/passphrase change: make sure all LUKS containers on same block device can be unlocked with same DRK - Reencryption: requires to know which key slot to reencrypt. - Find LUKS key slot that unlocks with DRK passphrase unlock prior of reencrypt call - Passphrase change: no slot can be passed, but key slot of DRK rotates. kexec-seal-key - TPM LUKS Disk Unlock Key key slots have changed to be set in max slots per LUKS version (LUKSv1:7 /LUKSv2: 31) - If key slot != default LUKS version's keyslot outside of DRK key slot: prompt the user before wiping that key slot, otherwise wipe automatically - This takes for granted that the DRK key slot alone is needed on the system and Heads controls the LUKS key slots. - If user has something else going on, ie: Using USB Security dongle + TPM DUK, then the user will need to say no when wiping keys. - It was suggested to leave LUKS key slots outside of DRK alone, but then: what to do when all key slots would be used? - Alternative implementation could be to only prompt users to wipe keyslots other then DRK when key slots are all used (LUKSv1: 0-7, LUKSv2: 0-31) - But then cleanup would need to happen prior of operations (LUKS passphrase change, TPM DUK setup) and could be problematic. - LUKS containers now checked to be same LUKS version prior of permitting to set TPM DUK and will refuse to go forward of different versions. TODO: - async (AIO) calls are not used. direct-io is used instead. libaio could be hacked out - this could be subject to future work Notes: - time to deprecated legacy boards the do not enough space for the new space requirements - x230-legacy, x230-legacy-flash, x230-hotp-legacy - t430-legacy, t430-legacy-flash, t430-hotp-legacy already deprecated Unrelated: - typos fixes found along the way Signed-off-by: Thierry Laurion <insurgo@riseup.net>
2024-08-16 19:20:11 +00:00
shred -n 10 -z -u "$DUK_KEY_FILE" 2>/dev/null ||
warn "Failed to delete key file - continuing"
mount -o rw,remount $paramsdir || warn "Failed to remount $paramsdir in RW - continuing"
cp -f /tmp/luksDump.txt "$paramsdir/kexec_lukshdr_hash.txt" ||
warn "Failed to copy LUKS header hashes to /boot - continuing"
mount -o ro,remount $paramsdir || warn "Failed to remount $paramsdir in RO - continuing"