mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-18 20:47:55 +00:00
Merge pull request #1515 from tlaurion/inmemory_keygen-gpg_backup_usable_for_RSA_only-copy_to_card_working_for_RSA_only-gpg_auth_for_recovery_and_sub_boot
GPG User Authentication: In-memory gpg keygen + keytocard and GPG key material backup enabling (plus a lot of code cleanup and UX improvements)
This commit is contained in:
commit
133da0e48e
@ -30,7 +30,6 @@ CONFIG_LINUX_USB=y
|
||||
export CONFIG_TPM=y
|
||||
export CONFIG_TPM_NO_LUKS_DISK_UNLOCK=y
|
||||
export CONFIG_TOTP_SKIP_QRCODE=y
|
||||
export CONFIG_OEMRESET_OFFER_DEFAULTS=y
|
||||
export CONFIG_BOOTSCRIPT=/bin/gui-init
|
||||
export CONFIG_BOOT_REQ_HASH=n
|
||||
export CONFIG_BOOT_REQ_ROLLBACK=n
|
||||
|
@ -30,7 +30,6 @@ CONFIG_LINUX_USB=y
|
||||
export CONFIG_TPM=y
|
||||
export CONFIG_TPM_NO_LUKS_DISK_UNLOCK=y
|
||||
export CONFIG_TOTP_SKIP_QRCODE=y
|
||||
export CONFIG_OEMRESET_OFFER_DEFAULTS=y
|
||||
export CONFIG_BOOTSCRIPT=/bin/gui-init
|
||||
export CONFIG_BOOT_REQ_HASH=n
|
||||
export CONFIG_BOOT_REQ_ROLLBACK=n
|
||||
|
@ -28,7 +28,6 @@ CONFIG_LINUX_USB=y
|
||||
export CONFIG_TPM=y
|
||||
export CONFIG_TPM_NO_LUKS_DISK_UNLOCK=y
|
||||
export CONFIG_TOTP_SKIP_QRCODE=y
|
||||
export CONFIG_OEMRESET_OFFER_DEFAULTS=y
|
||||
|
||||
export CONFIG_BOOTSCRIPT=/bin/gui-init
|
||||
export CONFIG_BOOT_REQ_HASH=n
|
||||
|
@ -30,7 +30,6 @@ CONFIG_LINUX_USB=y
|
||||
export CONFIG_TPM=y
|
||||
export CONFIG_TPM_NO_LUKS_DISK_UNLOCK=y
|
||||
export CONFIG_TOTP_SKIP_QRCODE=y
|
||||
export CONFIG_OEMRESET_OFFER_DEFAULTS=y
|
||||
export CONFIG_BOOTSCRIPT=/bin/gui-init
|
||||
export CONFIG_BOOT_REQ_HASH=n
|
||||
export CONFIG_BOOT_REQ_ROLLBACK=n
|
||||
|
@ -31,7 +31,6 @@ CONFIG_LINUX_USB=y
|
||||
export CONFIG_TPM=y
|
||||
export CONFIG_TPM_NO_LUKS_DISK_UNLOCK=y
|
||||
export CONFIG_TOTP_SKIP_QRCODE=y
|
||||
export CONFIG_OEMRESET_OFFER_DEFAULTS=y
|
||||
export CONFIG_BOOTSCRIPT=/bin/gui-init
|
||||
export CONFIG_BOOT_REQ_HASH=n
|
||||
export CONFIG_BOOT_REQ_ROLLBACK=n
|
||||
|
@ -29,7 +29,6 @@ CONFIG_LINUX_USB=y
|
||||
export CONFIG_TPM=y
|
||||
export CONFIG_TPM_NO_LUKS_DISK_UNLOCK=y
|
||||
export CONFIG_TOTP_SKIP_QRCODE=y
|
||||
export CONFIG_OEMRESET_OFFER_DEFAULTS=y
|
||||
|
||||
export CONFIG_BOOTSCRIPT=/bin/gui-init
|
||||
export CONFIG_BOOT_REQ_HASH=n
|
||||
|
@ -32,7 +32,6 @@ CONFIG_OPENSSL=y
|
||||
CONFIG_PRIMARY_KEY_TYPE=ecc
|
||||
export CONFIG_TPM_NO_LUKS_DISK_UNLOCK=y
|
||||
export CONFIG_TOTP_SKIP_QRCODE=y
|
||||
export CONFIG_OEMRESET_OFFER_DEFAULTS=y
|
||||
|
||||
export CONFIG_BOOTSCRIPT=/bin/gui-init
|
||||
export CONFIG_BOOT_REQ_HASH=n
|
||||
|
@ -30,7 +30,6 @@ CONFIG_LINUX_USB=y
|
||||
export CONFIG_TPM=n
|
||||
export CONFIG_TPM_NO_LUKS_DISK_UNLOCK=y
|
||||
export CONFIG_TOTP_SKIP_QRCODE=y
|
||||
export CONFIG_OEMRESET_OFFER_DEFAULTS=y
|
||||
|
||||
export CONFIG_BOOTSCRIPT=/bin/gui-init
|
||||
export CONFIG_BOOT_REQ_HASH=n
|
||||
|
@ -30,7 +30,6 @@ CONFIG_LINUX_USB=y
|
||||
export CONFIG_TPM=n
|
||||
export CONFIG_TPM_NO_LUKS_DISK_UNLOCK=y
|
||||
export CONFIG_TOTP_SKIP_QRCODE=y
|
||||
export CONFIG_OEMRESET_OFFER_DEFAULTS=y
|
||||
|
||||
export CONFIG_BOOTSCRIPT=/bin/gui-init
|
||||
export CONFIG_BOOT_REQ_HASH=n
|
||||
|
@ -41,9 +41,11 @@ Bootstrapping a working system
|
||||
* Then Heads will indicate that there is no TOTP code yet, at this point shut down (Continue to main menu -> Power off)
|
||||
5. Get the public key that was saved to the virtual USB flash drive
|
||||
* `sudo mkdir /media/fd_heads_gpg`
|
||||
* `sudo mount ./build/x86/qemu-coreboot-fbwhiptail-tpm1-hotp/usb_fd.raw /media/fd_heads_gpg`
|
||||
* `sudo losetup --find --partscan ./build/x86/qemu-coreboot-fbwhiptail-tpm1-hotp/usb_fd.raw`
|
||||
* `sudo mount /dev/loop0p2 /media/fd_heads_gpg` to mount the second partition (public) or if only one partition, /dev/loop0p1
|
||||
* Look in `/media/fd_heads_gpg` and copy the most recent public key
|
||||
* `sudo umount /media/fd_heads_gpg`
|
||||
* `sudo losetup --detach /dev/loop0`
|
||||
6. Inject the GPG key into the Heads image and run again
|
||||
* `make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp PUBKEY_ASC=<path_to_key.asc> inject_gpg`
|
||||
* `make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp USB_TOKEN=LibremKey PUBKEY_ASC=<path_to_key.asc> run`
|
||||
|
@ -10,6 +10,9 @@ export CONFIG_LINUX_VERSION=5.10.5
|
||||
#export CONFIG_RESTRICTED_BOOT=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
|
||||
export CONFIG_DEBUG_OUTPUT=y
|
||||
export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y
|
||||
|
@ -10,6 +10,9 @@ export CONFIG_LINUX_VERSION=5.10.5
|
||||
#export CONFIG_RESTRICTED_BOOT=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
|
||||
export CONFIG_DEBUG_OUTPUT=y
|
||||
export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y
|
||||
|
@ -6,10 +6,13 @@ export CONFIG_COREBOOT=y
|
||||
export CONFIG_COREBOOT_VERSION=4.19
|
||||
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_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
|
||||
export CONFIG_DEBUG_OUTPUT=y
|
||||
export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y
|
||||
|
@ -10,6 +10,9 @@ export CONFIG_LINUX_VERSION=5.10.5
|
||||
#export CONFIG_RESTRICTED_BOOT=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
|
||||
export CONFIG_DEBUG_OUTPUT=y
|
||||
export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1548,7 +1548,7 @@ CONFIG_DEVPORT=y
|
||||
# CONFIG_HPET is not set
|
||||
# CONFIG_HANGCHECK_TIMER is not set
|
||||
CONFIG_TCG_TPM=y
|
||||
CONFIG_HW_RANDOM_TPM=n
|
||||
# CONFIG_HW_RANDOM_TPM is not set
|
||||
CONFIG_TCG_TIS_CORE=y
|
||||
CONFIG_TCG_TIS=y
|
||||
# CONFIG_TCG_TIS_I2C is not set
|
||||
@ -2768,7 +2768,8 @@ CONFIG_VFAT_FS=y
|
||||
CONFIG_FAT_DEFAULT_CODEPAGE=437
|
||||
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
|
||||
# CONFIG_FAT_DEFAULT_UTF8 is not set
|
||||
# CONFIG_EXFAT_FS is not set
|
||||
CONFIG_EXFAT_FS=y
|
||||
CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8"
|
||||
# CONFIG_NTFS_FS is not set
|
||||
# CONFIG_NTFS3_FS is not set
|
||||
# end of DOS/FAT/EXFAT/NT Filesystems
|
||||
|
@ -1,3 +1,7 @@
|
||||
#mount /boot in read-only by default
|
||||
mount /boot
|
||||
#verify detached signature of /boot content
|
||||
find /boot/kexec*.txt | gpg --verify /boot/kexec.sig -
|
||||
#remove invalid kexec_* signed files
|
||||
mount /dev/sda1 /boot && mount -o remount,rw /boot && rm /boot/kexec* && mount -o remount,ro /boot
|
||||
#Generate keys from GPG smartcard:
|
||||
|
@ -24,6 +24,7 @@ for cbfsname in `echo $cbfsfiles`; do
|
||||
TMPFILE=/tmp/cbfs.$$
|
||||
echo "$filename" > $TMPFILE
|
||||
cat $filename >> $TMPFILE
|
||||
DEBUG "Extending TPM PCR $CONFIG_PCR with $filename"
|
||||
tpmr extend -ix "$CONFIG_PCR" -if $TMPFILE \
|
||||
|| die "$filename: tpm extend failed"
|
||||
fi
|
||||
|
@ -151,12 +151,12 @@ prompt_update_checksums()
|
||||
|
||||
generate_totp_hotp()
|
||||
{
|
||||
tpm_password="$1" # May be empty, will prompt if needed and empty
|
||||
TRACE "Under /bin/gui-init:generate_totp_hotp"
|
||||
TRACE "Under /bin/gui-init:generate_totp_hotp"
|
||||
tpm_owner_password="$1" # May be empty, will prompt if needed and empty
|
||||
if [ "$CONFIG_TPM" != "y" ] && [ -x /bin/hotp_verification ]; then
|
||||
echo "Generating new HOTP secret"
|
||||
/bin/seal-hotpkey
|
||||
elif echo -e "Generating new TOTP secret...\n\n" && /bin/seal-totp "$BOARD_NAME" "$tpm_password"; then
|
||||
elif echo -e "Generating new TOTP secret...\n\n" && /bin/seal-totp "$BOARD_NAME" "$tpm_owner_password"; then
|
||||
echo
|
||||
if [ -x /bin/hotp_verification ]; then
|
||||
if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then
|
||||
@ -229,8 +229,7 @@ update_totp()
|
||||
g )
|
||||
if (whiptail $BG_COLOR_WARNING --title 'Generate new TOTP/HOTP secret' \
|
||||
--yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 0 80) then
|
||||
generate_totp_hotp && update_totp && BG_COLOR_MAIN_MENU=""
|
||||
reseal_tpm_disk_decryption_key
|
||||
generate_totp_hotp && update_totp && BG_COLOR_MAIN_MENU="" && reseal_tpm_disk_decryption_key
|
||||
fi
|
||||
;;
|
||||
i )
|
||||
@ -238,8 +237,7 @@ update_totp()
|
||||
return 1
|
||||
;;
|
||||
p )
|
||||
reset_tpm && update_totp && BG_COLOR_MAIN_MENU=""
|
||||
reseal_tpm_disk_decryption_key
|
||||
reset_tpm && update_totp && BG_COLOR_MAIN_MENU="" && reseal_tpm_disk_decryption_key
|
||||
;;
|
||||
x )
|
||||
recovery "User requested recovery shell"
|
||||
@ -300,8 +298,7 @@ update_hotp()
|
||||
g )
|
||||
if (whiptail $BG_COLOR_WARNING --title 'Generate new TOTP/HOTP secret' \
|
||||
--yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 0 80) then
|
||||
generate_totp_hotp && BG_COLOR_MAIN_MENU=""
|
||||
reseal_tpm_disk_decryption_key
|
||||
generate_totp_hotp && BG_COLOR_MAIN_MENU="" && reseal_tpm_disk_decryption_key
|
||||
fi
|
||||
;;
|
||||
i )
|
||||
@ -316,7 +313,7 @@ update_hotp()
|
||||
|
||||
clean_boot_check()
|
||||
{
|
||||
TRACE "Under /bin/gui-init:mount_boot"
|
||||
TRACE "Under /bin/gui-init:clean_boot_check"
|
||||
# assume /boot mounted
|
||||
if ! grep -q /boot /proc/mounts ; then
|
||||
return
|
||||
@ -526,12 +523,10 @@ show_tpm_totp_hotp_options_menu()
|
||||
option=$(cat /tmp/whiptail)
|
||||
case "$option" in
|
||||
g )
|
||||
generate_totp_hotp
|
||||
reseal_tpm_disk_decryption_key
|
||||
generate_totp_hotp && reseal_tpm_disk_decryption_key
|
||||
;;
|
||||
r )
|
||||
reset_tpm
|
||||
reseal_tpm_disk_decryption_key
|
||||
reset_tpm && reseal_tpm_disk_decryption_key
|
||||
;;
|
||||
t )
|
||||
prompt_totp_mismatch
|
||||
@ -572,7 +567,7 @@ reset_tpm()
|
||||
return 1
|
||||
fi
|
||||
|
||||
tpmr reset "$key_password"
|
||||
tpmr reset "$tpm_owner_password"
|
||||
|
||||
# now that the TPM is reset, remove invalid TPM counter files
|
||||
mount_boot
|
||||
@ -582,7 +577,7 @@ reset_tpm()
|
||||
rm -f /boot/kexec_primhdl_hash.txt
|
||||
|
||||
# create Heads TPM counter before any others
|
||||
check_tpm_counter /boot/kexec_rollback.txt "" "$key_password" \
|
||||
check_tpm_counter /boot/kexec_rollback.txt "" "$tpm_owner_password" \
|
||||
|| die "Unable to find/create tpm counter"
|
||||
counter="$TPM_COUNTER"
|
||||
|
||||
@ -593,7 +588,7 @@ reset_tpm()
|
||||
|| die "Unable to create rollback file"
|
||||
mount -o ro,remount /boot
|
||||
|
||||
generate_totp_hotp "$key_password"
|
||||
generate_totp_hotp "$tpm_owner_password"
|
||||
else
|
||||
echo "Returning to the main menu"
|
||||
fi
|
||||
|
@ -49,6 +49,7 @@ if ! kexec-unseal-key "$INITRD_DIR/secret.key"; then
|
||||
fi
|
||||
|
||||
# Override PCR 4 so that user can't read the key
|
||||
DEBUG "Extending TPM PCR 4 to prevent further secret unsealing"
|
||||
tpmr extend -ix 4 -ic generic ||
|
||||
die 'Unable to scramble PCR'
|
||||
|
||||
@ -92,7 +93,6 @@ if [ "$unseal_failed" = "n" ]; then
|
||||
done
|
||||
else
|
||||
# No crypttab files were found under selected default boot option's initrd file
|
||||
# TODO: cpio -t is unfit here :( it just extracts early cpio header and not the whole file. Replace with something else
|
||||
# Meanwhile, force crypttab to be created from scratch on both possible locations: /etc/crypttab and /cryptroot/crypttab
|
||||
crypttab_files="etc/crypttab cryptroot/crypttab"
|
||||
for crypttab_file in $crypttab_files; do
|
||||
|
@ -276,8 +276,9 @@ if [ ! -d $paramsdir ]; then
|
||||
fi
|
||||
|
||||
if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
|
||||
sha256sum /tmp/primary.handle >"$PRIMHASH_FILE" ||
|
||||
sha256sum /tmp/secret/primary.handle >"$PRIMHASH_FILE" ||
|
||||
die "ERROR: Failed to Hash TPM2 primary key handle!"
|
||||
DEBUG "TPM2 primary key handle hash saved to $PRIMHASH_FILE"
|
||||
fi
|
||||
|
||||
rm $paramsdir/kexec_default.*.txt 2>/dev/null || true
|
||||
|
@ -42,7 +42,6 @@ DEBUG "kexec-save-key prior of last override: paramsdir: $paramsdir, paramsdev:
|
||||
if [ -n "$lvm_volume_group" ]; then
|
||||
lvm vgchange -a y $lvm_volume_group ||
|
||||
die "Failed to activate the LVM group"
|
||||
#TODO: why reuse key_devices for lvm devices?
|
||||
for dev in /dev/$lvm_volume_group/*; do
|
||||
key_devices="$key_devices $dev"
|
||||
done
|
||||
|
@ -72,20 +72,21 @@ dd \
|
||||
|
||||
# Count the number of slots used on each device
|
||||
for dev in $(cat "$KEY_DEVICES" | cut -d\ -f1); do
|
||||
DEBUG "Checking number of slots used on $dev"
|
||||
DEBUG "Checking number of slots used on $dev LUKS header"
|
||||
#check if the device is a LUKS device with luks[1,2]
|
||||
slots_used=$(cryptsetup luksDump $dev | grep -c 'luks[0-9]*' || die "Unable to get number of slots used on $dev")
|
||||
DEBUG "Number of slots used on $dev: $slots_used"
|
||||
DEBUG "Number of slots used on $dev LUKS header: $slots_used"
|
||||
# If slot1 is the only one used, warn and die with proper messages
|
||||
if [ $slots_used -eq 1 ]; then
|
||||
# Check if slot 1 is the only one existing
|
||||
if cryptsetup luksDump $dev | grep -q "Slot 1: ENABLED"; then
|
||||
warn "Slot 1 is the only one existing on $dev. Heads cannot use it to store TPM sealed LUKS Disk Unlock Key"
|
||||
die "Slot 1 should not be the only slot existing on $dev. Fix your custom setup"
|
||||
warn "Slot 1 is the only one existing on $dev LUKS header. Heads cannot use it to store TPM sealed LUKS Disk Unlock Key"
|
||||
warn "Slot 1 should not be the only slot existing on $dev LUKS header. Slot 0 should be used to store Disk Recovery Key/passphrase"
|
||||
die "You can safely fix this before continuing through Heads recovery shell: cryptsetup luksAddKey $dev"
|
||||
fi
|
||||
else
|
||||
DEBUG "Slot 1 is not the only existing slot on $dev"
|
||||
DEBUG "$dev Slot 1 will be used to store LUKS Disk Unlock Key that TPM will seal/unseal with TPM Disk Unlock Key passphrase"
|
||||
DEBUG "Slot 1 is not the only existing slot on $dev LUKS header."
|
||||
DEBUG "$dev LUKS header's slot 1 will store LUKS Disk Unlock Key that TPM will seal/unseal with TPM Disk Unlock Key passphrase"
|
||||
fi
|
||||
done
|
||||
|
||||
@ -136,7 +137,7 @@ tpmr pcrread -a 7 "$pcrf"
|
||||
|
||||
DO_WITH_DEBUG --mask-position 7 \
|
||||
tpmr seal "$KEY_FILE" "$TPM_INDEX" 0,1,2,3,4,5,6,7 "$pcrf" \
|
||||
"$TPM_SIZE" "$key_password"
|
||||
"$TPM_SIZE" "$key_password" || die "Unable to write TPM Disk Unlock Key to NVRAM"
|
||||
|
||||
# should be okay if this fails
|
||||
shred -n 10 -z -u "$pcrf" 2>/dev/null ||
|
||||
@ -144,7 +145,7 @@ shred -n 10 -z -u "$pcrf" 2>/dev/null ||
|
||||
shred -n 10 -z -u "$KEY_FILE" 2>/dev/null ||
|
||||
warn "Failed to delete key file - continuing"
|
||||
|
||||
mount -o rw,remount $paramsdir || die "Failed to remount $paramsdir in RW - continuing"
|
||||
mount -o rw,remount $paramsdir || warn "Failed to remount $paramsdir in RW - continuing"
|
||||
cp -f /tmp/luksDump.txt "$paramsdir/kexec_lukshdr_hash.txt" ||
|
||||
die "Failed to copy LUKS header hashes to /boot - continuing"
|
||||
mount -o ro,remount $paramsdir || die "Failed to remount $paramsdir in RO - continuing"
|
||||
warn "Failed to copy LUKS header hashes to /boot - continuing"
|
||||
mount -o ro,remount $paramsdir || warn "Failed to remount $paramsdir in RO - continuing"
|
||||
|
@ -19,18 +19,25 @@ force_boot="n"
|
||||
skip_confirm="n"
|
||||
while getopts "b:d:p:a:r:c:uimgfs" arg; do
|
||||
case $arg in
|
||||
b) bootdir="$OPTARG" ;;
|
||||
d) paramsdev="$OPTARG" ;;
|
||||
p) paramsdir="$OPTARG" ;;
|
||||
a) add="$OPTARG" ;;
|
||||
r) remove="$OPTARG" ;;
|
||||
c) config="$OPTARG" ;;
|
||||
u) unique="y" ;;
|
||||
m) force_menu="y" ;;
|
||||
i) valid_hash="y"; valid_rollback="y" ;;
|
||||
g) gui_menu="y" ;;
|
||||
f) force_boot="y"; valid_hash="y"; valid_rollback="y" ;;
|
||||
s) skip_confirm="y" ;;
|
||||
b) bootdir="$OPTARG" ;;
|
||||
d) paramsdev="$OPTARG" ;;
|
||||
p) paramsdir="$OPTARG" ;;
|
||||
a) add="$OPTARG" ;;
|
||||
r) remove="$OPTARG" ;;
|
||||
c) config="$OPTARG" ;;
|
||||
u) unique="y" ;;
|
||||
m) force_menu="y" ;;
|
||||
i)
|
||||
valid_hash="y"
|
||||
valid_rollback="y"
|
||||
;;
|
||||
g) gui_menu="y" ;;
|
||||
f)
|
||||
force_boot="y"
|
||||
valid_hash="y"
|
||||
valid_rollback="y"
|
||||
;;
|
||||
s) skip_confirm="y" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
@ -53,24 +60,25 @@ paramsdir="${paramsdir%%/}"
|
||||
PRIMHASH_FILE="$paramsdir/kexec_primhdl_hash.txt"
|
||||
if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
|
||||
if [ -r "$PRIMHASH_FILE" ]; then
|
||||
sha256sum -c "$PRIMHASH_FILE" \
|
||||
|| {
|
||||
echo "FATAL: Hash of TPM2 primary key handle mismatch!";
|
||||
warn "If you have not intentionally regenerated TPM2 primary key,";
|
||||
warn "your system may have been compromised";
|
||||
}
|
||||
sha256sum -c "$PRIMHASH_FILE" ||
|
||||
{
|
||||
echo "FATAL: Hash of TPM2 primary key handle mismatch!"
|
||||
warn "If you have not intentionally regenerated TPM2 primary key,"
|
||||
warn "your system may have been compromised"
|
||||
DEBUG "Hash of TPM2 primary key handle mismatched for $PRIMHASH_FILE"
|
||||
}
|
||||
else
|
||||
warn "Hash of TPM2 primary key handle does not exist"
|
||||
warn "Please rebuild the boot hash tree"
|
||||
default_failed="y"
|
||||
DEBUG "Hash of TPM2 primary key handle does not exist under $PRIMHASH_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
verify_global_hashes()
|
||||
{
|
||||
verify_global_hashes() {
|
||||
echo "+++ Checking verified boot hash file "
|
||||
# Check the hashes of all the files
|
||||
if verify_checksums "$bootdir" "$gui_menu" ; then
|
||||
if verify_checksums "$bootdir" "$gui_menu"; then
|
||||
echo "+++ Verified boot hashes "
|
||||
valid_hash='y'
|
||||
valid_global_hash='y'
|
||||
@ -82,44 +90,43 @@ verify_global_hashes()
|
||||
fi
|
||||
die "$TMP_HASH_FILE: boot hash mismatch"
|
||||
fi
|
||||
# If user enables it, check root hashes before boot as well
|
||||
if [[ "$CONFIG_ROOT_CHECK_AT_BOOT" = "y" && "$force_menu" == "n" ]]; then
|
||||
if root-hashes-gui.sh -c; then
|
||||
echo "+++ Verified root hashes, continuing boot "
|
||||
# if user re-signs, it wipes out saved options, so scan the boot directory and generate
|
||||
if [ ! -r "$TMP_MENU_FILE" ]; then
|
||||
scan_options
|
||||
fi
|
||||
else
|
||||
# root-hashes-gui.sh handles the GUI error menu, just die here
|
||||
if [ "$gui_menu" = "y" ]; then
|
||||
whiptail $BG_COLOR_ERROR --title 'ERROR: Root Hash Mismatch' \
|
||||
--msgbox "The root hash check failed!\nExiting to a recovery shell" 0 80
|
||||
fi
|
||||
die "root hash mismatch, see /tmp/hash_output_mismatches for details"
|
||||
fi
|
||||
fi
|
||||
# If user enables it, check root hashes before boot as well
|
||||
if [[ "$CONFIG_ROOT_CHECK_AT_BOOT" = "y" && "$force_menu" == "n" ]]; then
|
||||
if root-hashes-gui.sh -c; then
|
||||
echo "+++ Verified root hashes, continuing boot "
|
||||
# if user re-signs, it wipes out saved options, so scan the boot directory and generate
|
||||
if [ ! -r "$TMP_MENU_FILE" ]; then
|
||||
scan_options
|
||||
fi
|
||||
else
|
||||
# root-hashes-gui.sh handles the GUI error menu, just die here
|
||||
if [ "$gui_menu" = "y" ]; then
|
||||
whiptail $BG_COLOR_ERROR --title 'ERROR: Root Hash Mismatch' \
|
||||
--msgbox "The root hash check failed!\nExiting to a recovery shell" 0 80
|
||||
fi
|
||||
die "root hash mismatch, see /tmp/hash_output_mismatches for details"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
verify_rollback_counter()
|
||||
{
|
||||
TPM_COUNTER=`grep counter $TMP_ROLLBACK_FILE | cut -d- -f2`
|
||||
verify_rollback_counter() {
|
||||
TPM_COUNTER=$(grep counter $TMP_ROLLBACK_FILE | cut -d- -f2)
|
||||
if [ -z "$TPM_COUNTER" ]; then
|
||||
die "$TMP_ROLLBACK_FILE: TPM counter not found?"
|
||||
fi
|
||||
|
||||
read_tpm_counter $TPM_COUNTER \
|
||||
|| die "Failed to read TPM counter"
|
||||
read_tpm_counter $TPM_COUNTER ||
|
||||
die "Failed to read TPM counter"
|
||||
|
||||
sha256sum -c $TMP_ROLLBACK_FILE \
|
||||
|| die "Invalid TPM counter state"
|
||||
sha256sum -c $TMP_ROLLBACK_FILE ||
|
||||
die "Invalid TPM counter state"
|
||||
|
||||
valid_rollback="y"
|
||||
}
|
||||
|
||||
first_menu="y"
|
||||
get_menu_option() {
|
||||
num_options=`cat $TMP_MENU_FILE | wc -l`
|
||||
num_options=$(cat $TMP_MENU_FILE | wc -l)
|
||||
if [ $num_options -eq 0 ]; then
|
||||
die "No boot options"
|
||||
fi
|
||||
@ -129,13 +136,12 @@ get_menu_option() {
|
||||
elif [ "$gui_menu" = "y" ]; then
|
||||
MENU_OPTIONS=""
|
||||
n=0
|
||||
while read option
|
||||
do
|
||||
while read option; do
|
||||
parse_option
|
||||
n=`expr $n + 1`
|
||||
n=$(expr $n + 1)
|
||||
name=$(echo $name | tr " " "_")
|
||||
MENU_OPTIONS="$MENU_OPTIONS $n ${name} "
|
||||
done < $TMP_MENU_FILE
|
||||
done <$TMP_MENU_FILE
|
||||
|
||||
whiptail --title "Select your boot option" \
|
||||
--menu "Choose the boot option [1-$n, a to abort]:" 0 80 8 \
|
||||
@ -146,12 +152,11 @@ get_menu_option() {
|
||||
else
|
||||
echo "+++ Select your boot option:"
|
||||
n=0
|
||||
while read option
|
||||
do
|
||||
while read option; do
|
||||
parse_option
|
||||
n=`expr $n + 1`
|
||||
n=$(expr $n + 1)
|
||||
echo "$n. $name [$kernel]"
|
||||
done < $TMP_MENU_FILE
|
||||
done <$TMP_MENU_FILE
|
||||
|
||||
read \
|
||||
-p "Choose the boot option [1-$n, a to abort]: " \
|
||||
@ -163,7 +168,7 @@ get_menu_option() {
|
||||
fi
|
||||
first_menu="n"
|
||||
|
||||
option=`head -n $option_index $TMP_MENU_FILE | tail -1`
|
||||
option=$(head -n $option_index $TMP_MENU_FILE | tail -1)
|
||||
parse_option
|
||||
}
|
||||
|
||||
@ -172,7 +177,7 @@ confirm_menu_option() {
|
||||
default_text="Make default"
|
||||
[[ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" = "y" ]] && default_text="${default_text} and boot"
|
||||
whiptail $BG_COLOR_WARNING --title "Confirm boot details" \
|
||||
--menu "Confirm the boot details for $name:\n\n$(echo $kernel| fold -s -w 80) \n\n" 0 80 8 \
|
||||
--menu "Confirm the boot details for $name:\n\n$(echo $kernel | fold -s -w 80) \n\n" 0 80 8 \
|
||||
-- 'd' "${default_text}" 'y' "Boot one time" \
|
||||
2>/tmp/whiptail || die "Aborting boot attempt"
|
||||
|
||||
@ -190,8 +195,8 @@ confirm_menu_option() {
|
||||
}
|
||||
|
||||
parse_option() {
|
||||
name=`echo $option | cut -d\| -f1`
|
||||
kernel=`echo $option | cut -d\| -f3`
|
||||
name=$(echo $option | cut -d\| -f1)
|
||||
kernel=$(echo $option | cut -d\| -f3)
|
||||
}
|
||||
|
||||
scan_options() {
|
||||
@ -202,7 +207,7 @@ scan_options() {
|
||||
die "Failed to parse any boot options"
|
||||
fi
|
||||
if [ "$unique" = 'y' ]; then
|
||||
sort -r $option_file | uniq > $TMP_MENU_FILE
|
||||
sort -r $option_file | uniq >$TMP_MENU_FILE
|
||||
else
|
||||
cp $option_file $TMP_MENU_FILE
|
||||
fi
|
||||
@ -224,7 +229,7 @@ save_default_option() {
|
||||
-d "$paramsdev" \
|
||||
-p "$paramsdir" \
|
||||
-i "$option_index" \
|
||||
; then
|
||||
; then
|
||||
echo "+++ Saved defaults to device"
|
||||
sleep 2
|
||||
default_failed="n"
|
||||
@ -242,11 +247,11 @@ default_select() {
|
||||
# Attempt boot with expected parameters
|
||||
|
||||
# Check that entry matches that which is expected from menu
|
||||
default_index=`basename "$TMP_DEFAULT_FILE" | cut -d. -f 2`
|
||||
default_index=$(basename "$TMP_DEFAULT_FILE" | cut -d. -f 2)
|
||||
|
||||
# Check to see if entries have changed - useful for detecting grub update
|
||||
expectedoption=`cat $TMP_DEFAULT_FILE`
|
||||
option=`head -n $default_index $TMP_MENU_FILE | tail -1`
|
||||
expectedoption=$(cat $TMP_DEFAULT_FILE)
|
||||
option=$(head -n $default_index $TMP_MENU_FILE | tail -1)
|
||||
if [ "$option" != "$expectedoption" ]; then
|
||||
if [ "$gui_menu" = "y" ]; then
|
||||
whiptail $BG_COLOR_ERROR --title 'ERROR: Boot Entry Has Changed' \
|
||||
@ -261,7 +266,7 @@ default_select() {
|
||||
# Enforce that default option hashes are valid
|
||||
echo "+++ Checking verified default boot hash file "
|
||||
# Check the hashes of all the files
|
||||
if ( cd $bootdir && sha256sum -c "$TMP_DEFAULT_HASH_FILE" > /tmp/hash_output ); then
|
||||
if (cd $bootdir && sha256sum -c "$TMP_DEFAULT_HASH_FILE" >/tmp/hash_output); then
|
||||
echo "+++ Verified default boot hashes "
|
||||
valid_hash='y'
|
||||
else
|
||||
@ -282,10 +287,9 @@ user_select() {
|
||||
# No default expected boot parameters, ask user
|
||||
|
||||
option_confirm=""
|
||||
while [ "$option_confirm" != "y" -a "$option_confirm" != "d" ]
|
||||
do
|
||||
while [ "$option_confirm" != "y" -a "$option_confirm" != "d" ]; do
|
||||
get_menu_option
|
||||
# In force boot mode, no need offer the option to set a default, just boot
|
||||
# In force boot mode, no need offer the option to set a default, just boot
|
||||
if [[ "$force_boot" = "y" || "$skip_confirm" = "y" ]]; then
|
||||
do_boot
|
||||
else
|
||||
@ -305,8 +309,8 @@ user_select() {
|
||||
echo "+++ Rebooting to start the new default option"
|
||||
sleep 2
|
||||
if [ "$CONFIG_DEBUG_OUTPUT" != "y" ]; then
|
||||
reboot \
|
||||
|| die "!!! Failed to reboot system"
|
||||
reboot ||
|
||||
die "!!! Failed to reboot system"
|
||||
else
|
||||
DEBUG "Rebooting is required prior of booting default boot entry"
|
||||
# Instead of rebooting, drop to a recovery shell
|
||||
@ -319,8 +323,7 @@ user_select() {
|
||||
do_boot
|
||||
}
|
||||
|
||||
do_boot()
|
||||
{
|
||||
do_boot() {
|
||||
if [ "$CONFIG_BASIC" != y ] && [ "$CONFIG_BOOT_REQ_ROLLBACK" = "y" ] && [ "$valid_rollback" = "n" ]; then
|
||||
die "!!! Missing required rollback counter state"
|
||||
fi
|
||||
@ -330,31 +333,31 @@ do_boot()
|
||||
fi
|
||||
|
||||
if [ "$CONFIG_BASIC" != y ] && [ "$CONFIG_TPM" = "y" ] && [ -r "$TMP_KEY_DEVICES" ]; then
|
||||
INITRD=`kexec-boot -b "$bootdir" -e "$option" -i` \
|
||||
|| die "!!! Failed to extract the initrd from boot option"
|
||||
INITRD=$(kexec-boot -b "$bootdir" -e "$option" -i) ||
|
||||
die "!!! Failed to extract the initrd from boot option"
|
||||
if [ -z "$INITRD" ]; then
|
||||
die "!!! No initrd file found in boot option"
|
||||
fi
|
||||
|
||||
kexec-insert-key $INITRD \
|
||||
|| die "!!! Failed to insert disk key into a new initrd"
|
||||
kexec-insert-key $INITRD ||
|
||||
die "!!! Failed to insert disk key into a new initrd"
|
||||
|
||||
kexec-boot -b "$bootdir" -e "$option" \
|
||||
-a "$add" -r "$remove" -o "/tmp/secret/initrd.cpio" \
|
||||
|| die "!!! Failed to boot w/ options: $option"
|
||||
-a "$add" -r "$remove" -o "/tmp/secret/initrd.cpio" ||
|
||||
die "!!! Failed to boot w/ options: $option"
|
||||
else
|
||||
kexec-boot -b "$bootdir" -e "$option" -a "$add" -r "$remove" \
|
||||
|| die "!!! Failed to boot w/ options: $option"
|
||||
kexec-boot -b "$bootdir" -e "$option" -a "$add" -r "$remove" ||
|
||||
die "!!! Failed to boot w/ options: $option"
|
||||
fi
|
||||
}
|
||||
|
||||
while true; do
|
||||
if [ "$force_boot" = "y" -o "$CONFIG_BASIC" = "y" ]; then
|
||||
check_config $paramsdir force
|
||||
check_config $paramsdir force
|
||||
else
|
||||
check_config $paramsdir
|
||||
check_config $paramsdir
|
||||
fi
|
||||
TMP_DEFAULT_FILE=`find /tmp/kexec/kexec_default.*.txt 2>/dev/null | head -1` || true
|
||||
TMP_DEFAULT_FILE=$(find /tmp/kexec/kexec_default.*.txt 2>/dev/null | head -1) || true
|
||||
TMP_MENU_FILE="/tmp/kexec/kexec_menu.txt"
|
||||
TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt"
|
||||
TMP_TREE_FILE="/tmp/kexec/kexec_tree.txt"
|
||||
@ -363,8 +366,8 @@ while true; do
|
||||
TMP_KEY_DEVICES="/tmp/kexec/kexec_key_devices.txt"
|
||||
TMP_KEY_LVM="/tmp/kexec/kexec_key_lvm.txt"
|
||||
|
||||
# Allow a way for users to ignore warnings and boot into their systems
|
||||
# even if hashes don't match
|
||||
# Allow a way for users to ignore warnings and boot into their systems
|
||||
# even if hashes don't match
|
||||
if [ "$force_boot" = "y" ]; then
|
||||
scan_options
|
||||
if [ "$CONFIG_BASIC" != "y" ]; then
|
||||
@ -378,8 +381,9 @@ while true; do
|
||||
if [ "$CONFIG_TPM" = "y" ]; then
|
||||
if [ ! -r "$TMP_KEY_DEVICES" ]; then
|
||||
# Extend PCR4 as soon as possible
|
||||
tpmr extend -ix 4 -ic generic \
|
||||
|| die "Failed to extend PCR 4"
|
||||
DEBUG "Extending TPM PCR 4 to prevent further secret unsealing"
|
||||
tpmr extend -ix 4 -ic generic ||
|
||||
die "Failed to extend PCR 4"
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -412,7 +416,7 @@ while true; do
|
||||
-a "$force_menu" = "n" \
|
||||
-a -r "$TMP_DEFAULT_FILE" \
|
||||
-a -r "$TMP_DEFAULT_HASH_FILE" ] \
|
||||
; then
|
||||
; then
|
||||
default_select
|
||||
default_failed="y"
|
||||
else
|
||||
|
@ -7,6 +7,9 @@ set -e -o pipefail
|
||||
|
||||
TRACE "Under /bin/media-scan"
|
||||
|
||||
#Booting from external media should be authenticated if supported
|
||||
gpg_auth || die "GPG authentication failed"
|
||||
|
||||
# Unmount any previous boot device
|
||||
if grep -q /boot /proc/mounts ; then
|
||||
umount /boot \
|
||||
|
@ -184,7 +184,7 @@ if cryptsetup isLuks "$USB_MOUNT_DEVICE"; then
|
||||
|| die "ERROR: Failed to open ${USB_MOUNT_DEVICE} LUKS device"
|
||||
fi
|
||||
|
||||
warn "Note that you cannot boot from a mounted encrypted device."
|
||||
warn "Note that you cannot boot from a mounted encrypted device"
|
||||
DEBUG "Setting USB_MOUNT_DEVICE=/dev/mapper/"usb_mount_$(basename "$USB_MOUNT_DEVICE")""
|
||||
USB_MOUNT_DEVICE="/dev/mapper/"usb_mount_$(basename "$USB_MOUNT_DEVICE")""
|
||||
else
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,11 +14,11 @@ for dev in "$@"; do
|
||||
die "$dev: Unable to read LUKS header"
|
||||
done
|
||||
|
||||
DEBUG "Hashing luks headers into /tmp/luksDump.txt"
|
||||
sha256sum /tmp/lukshdr-* >/tmp/luksDump.txt || die "Unable to hash luks headers"
|
||||
DEBUG "Hashing LUKS headers into /tmp/luksDump.txt"
|
||||
sha256sum /tmp/lukshdr-* >/tmp/luksDump.txt || die "Unable to hash LUKS headers"
|
||||
DEBUG "Removing /tmp/lukshdr-*"
|
||||
rm /tmp/lukshdr-*
|
||||
|
||||
DEBUG "Extending PCR 6 with /tmp/luksDump.txt"
|
||||
DEBUG "Extending TPM PCR 6 with hash of LUKS headers from /tmp/luksDump.txt"
|
||||
tpmr extend -ix 6 -if /tmp/luksDump.txt ||
|
||||
die "Unable to extend PCR"
|
||||
|
@ -3,14 +3,23 @@
|
||||
|
||||
TRACE "Under /bin/reboot"
|
||||
|
||||
if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then
|
||||
#Generalize user prompt to continue reboot or go to recovery shell
|
||||
read -r -n 1 -s -p "Press any key to continue reboot or 'r' to go to recovery shell: " REPLY
|
||||
echo
|
||||
if [ "$REPLY" = "r" ] || [ "$REPLY" = "R" ]; then
|
||||
recovery "Reboot call bypassed to go into recovery shell to debug"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Shut down TPM
|
||||
if [ "$CONFIG_TPM" = "y" ]; then
|
||||
tpmr shutdown
|
||||
fi
|
||||
|
||||
# Run special EC-based poweroff for Nitropad-Nxx
|
||||
if [ "${CONFIG_BOARD%_*}" = nitropad-nv41 || "${CONFIG_BOARD%_*}" = nitropad-ns51 ]; then
|
||||
/bin/nitropad-shutdown.sh
|
||||
if [ "${CONFIG_BOARD%_*}" = nitropad-nv41 ] || [ "${CONFIG_BOARD%_*}" = nitropad-ns51 ]; then
|
||||
/bin/nitropad-shutdown.sh
|
||||
fi
|
||||
|
||||
# Sync all mounted filesystems
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Retrieve the sealed TOTP secret and initialize a USB Security dongle with it
|
||||
# Retrieve the sealed TOTP secret and initialize a USB Security Dongle with it
|
||||
|
||||
. /etc/functions
|
||||
|
||||
|
@ -25,10 +25,10 @@ dd \
|
||||
of="$TOTP_SECRET" \
|
||||
count=1 \
|
||||
bs=20 \
|
||||
2>/dev/null \
|
||||
|| die "Unable to generate 20 random bytes"
|
||||
2>/dev/null ||
|
||||
die "Unable to generate 20 random bytes"
|
||||
|
||||
secret="`base32 < $TOTP_SECRET`"
|
||||
secret="$(base32 <$TOTP_SECRET)"
|
||||
pcrf="/tmp/secret/pcrf.bin"
|
||||
DEBUG "Sealing TOTP with actual state of PCR0-3"
|
||||
tpmr pcrread 0 "$pcrf"
|
||||
@ -36,20 +36,22 @@ tpmr pcrread -a 1 "$pcrf"
|
||||
tpmr pcrread -a 2 "$pcrf"
|
||||
tpmr pcrread -a 3 "$pcrf"
|
||||
DEBUG "Sealing TOTP with boot state of PCR4 (Going to recovery shell extends PCR4)"
|
||||
# pcr 4 is expected to either:
|
||||
# pcr 4 is expected to either:
|
||||
# zero on bare coreboot+linuxboot on x86 (boot mode: init)
|
||||
# already extended on ppc64 per BOOTKERNEL (skiboot) which boots heads.
|
||||
# Read from event log to catch both cases, even when called from recovery shell.
|
||||
tpmr calcfuturepcr 4 >> "$pcrf"
|
||||
tpmr calcfuturepcr 4 >>"$pcrf"
|
||||
# pcr 5 (kernel modules loaded) is not measured at sealing/unsealing of totp
|
||||
DEBUG "Sealing TOTP neglecting PCR5 involvement (Dynamically loaded kernel modules are not firmware integrity attestation related)"
|
||||
# pcr 6 (drive luks header) is not measured at sealing/unsealing of totp
|
||||
# pcr 6 (drive LUKS header) is not measured at sealing/unsealing of totp
|
||||
DEBUG "Sealing TOTP without PCR6 involvement (LUKS header consistency is not firmware integrity attestation related)"
|
||||
# pcr 7 is containing measurements of user injected stuff in cbfs
|
||||
tpmr pcrread -a 7 "$pcrf"
|
||||
tpmr seal "$TOTP_SECRET" "$TPM_NVRAM_SPACE" 0,1,2,3,4,7 "$pcrf" 312 "" "$TPM_PASSWORD" \
|
||||
|| die "Unable to write sealed secret to NVRAM"
|
||||
shred -n 10 -z -u "$TOTP_SEALED" 2> /dev/null
|
||||
#Make sure we clear the TPM Owner Password from memory in case it failed to be used to seal TOTP
|
||||
tpmr seal "$TOTP_SECRET" "$TPM_NVRAM_SPACE" 0,1,2,3,4,7 "$pcrf" 312 "" "$TPM_PASSWORD" ||
|
||||
die "Unable to write sealed secret to NVRAM from seal-totp"
|
||||
#Make sure we clear TPM TOTP sealed if we succeed to seal TOTP
|
||||
shred -n 10 -z -u "$TOTP_SEALED" 2>/dev/null
|
||||
|
||||
url="otpauth://totp/$HOST?secret=$secret"
|
||||
secret=""
|
||||
|
@ -7,4 +7,4 @@ echo '*****'
|
||||
|
||||
prompt_new_owner_password
|
||||
|
||||
tpmr reset "$key_password"
|
||||
tpmr reset "$tpm_owner_password"
|
||||
|
443
initrd/bin/tpmr
443
initrd/bin/tpmr
@ -5,9 +5,9 @@
|
||||
|
||||
SECRET_DIR="/tmp/secret"
|
||||
PRIMARY_HANDLE="0x81000000"
|
||||
ENC_SESSION_FILE="enc.ctx"
|
||||
DEC_SESSION_FILE="dec.ctx"
|
||||
PRIMARY_HANDLE_FILE="primary.handle"
|
||||
ENC_SESSION_FILE="$SECRET_DIR/enc.ctx"
|
||||
DEC_SESSION_FILE="$SECRET_DIR/dec.ctx"
|
||||
PRIMARY_HANDLE_FILE="$SECRET_DIR/primary.handle"
|
||||
|
||||
# PCR size in bytes. Set when we determine what TPM version is in use.
|
||||
# TPM1 PCRs are always 20 bytes. TPM2 is allowed to provide multiple PCR banks
|
||||
@ -115,7 +115,7 @@ extend_pcr_state() {
|
||||
shift
|
||||
if is_hash "$alg" "$next"; then
|
||||
extend="$next"
|
||||
else
|
||||
else
|
||||
extend="$("${alg}sum" <"$next" | cut -d' ' -f1)"
|
||||
fi
|
||||
state="$(echo "$state$extend" | hex2bin | "${alg}sum" | cut -d' ' -f1)"
|
||||
@ -127,7 +127,7 @@ extend_pcr_state() {
|
||||
# different arguments for grep. Those formats are shown below as heredocs to
|
||||
# keep all the data, including whitespaces:
|
||||
# 1) TPM2 log, which can hold multiple hash algorithms at once:
|
||||
: << 'EOF'
|
||||
: <<'EOF'
|
||||
TPM2 log:
|
||||
Specification: 2.00
|
||||
Platform class: PC Client
|
||||
@ -140,7 +140,7 @@ TPM2 log entry 1:
|
||||
Event data: FMAP: FMAP
|
||||
EOF
|
||||
# 2) TPM1.2 log (aka TCPA), digest is always SHA1:
|
||||
: << 'EOF'
|
||||
: <<'EOF'
|
||||
TCPA log:
|
||||
Specification: 1.21
|
||||
Platform class: PC Client
|
||||
@ -152,7 +152,7 @@ TCPA log entry 1:
|
||||
EOF
|
||||
# 3) coreboot-specific format:
|
||||
# 3.5) older versions printed 'coreboot TCPA log', even though it isn't TCPA
|
||||
: << 'EOF'
|
||||
: <<'EOF'
|
||||
coreboot TPM log:
|
||||
|
||||
PCR-2 27c4f1fa214480c8626397a15981ef3a9323717f SHA1 [FMAP: FMAP]
|
||||
@ -194,25 +194,25 @@ $0 ~ pcr {
|
||||
# is returned in binary form.
|
||||
replay_pcr() {
|
||||
TRACE "Under /bin/tpmr:replay_pcr"
|
||||
if [ -z "$2" ] ; then
|
||||
>&2 echo "No PCR number passed"
|
||||
if [ -z "$2" ]; then
|
||||
echo >&2 "No PCR number passed"
|
||||
return
|
||||
fi
|
||||
if [ "$2" -ge 8 ] ; then
|
||||
>&2 echo "Illegal PCR number ($2)"
|
||||
if [ "$2" -ge 8 ]; then
|
||||
echo >&2 "Illegal PCR number ($2)"
|
||||
return
|
||||
fi
|
||||
local log=`cbmem -L`
|
||||
local log=$(cbmem -L)
|
||||
local alg="$1"
|
||||
local pcr="$2"
|
||||
local alg_digits=0
|
||||
# SHA-1 hashes are 40 chars
|
||||
if [ "$alg" = "sha1" ] ; then alg_digits=40; fi
|
||||
if [ "$alg" = "sha1" ]; then alg_digits=40; fi
|
||||
# SHA-256 hashes are 64 chars
|
||||
if [ "$alg" = "sha256" ] ; then alg_digits=64; fi
|
||||
if [ "$alg" = "sha256" ]; then alg_digits=64; fi
|
||||
shift 2
|
||||
replayed_pcr=$(extend_pcr_state $alg $(printf "%.${alg_digits}d" 0) \
|
||||
$(echo "$log" | awk -v alg=$alg -v pcr=$pcr -f <(echo $AWK_PROG)) $@)
|
||||
$(echo "$log" | awk -v alg=$alg -v pcr=$pcr -f <(echo $AWK_PROG)) $@)
|
||||
echo $replayed_pcr | hex2bin
|
||||
DEBUG "Replayed cbmem -L clean boot state of PCR=$pcr ALG=$alg : $replayed_pcr"
|
||||
# To manually introspect current PCR values:
|
||||
@ -225,24 +225,28 @@ replay_pcr() {
|
||||
# PCR-5, depending on which modules are loaded for given board:
|
||||
# tpmr calcfuturepcr 5 module0.ko module1.ko module2.ko | xxd -p
|
||||
# PCR-6 and PCR-7: similar to 5, but with different files passed
|
||||
# (6: luks header, 7: user related cbfs files loaded from cbfs-init)
|
||||
# (6: LUKS header, 7: user related cbfs files loaded from cbfs-init)
|
||||
}
|
||||
|
||||
tpm2_extend() {
|
||||
TRACE "Under /bin/tpmr:tpm2_extend"
|
||||
while true; do
|
||||
case "$1" in
|
||||
-ix)
|
||||
index="$2"
|
||||
shift 2;;
|
||||
-ic)
|
||||
hash="$(echo -n "$2"|sha256sum|cut -d' ' -f1)"
|
||||
shift 2;;
|
||||
-if)
|
||||
hash="$(sha256sum "$2"|cut -d' ' -f1)"
|
||||
shift 2;;
|
||||
*)
|
||||
break;;
|
||||
-ix)
|
||||
index="$2"
|
||||
shift 2
|
||||
;;
|
||||
-ic)
|
||||
hash="$(echo -n "$2" | sha256sum | cut -d' ' -f1)"
|
||||
shift 2
|
||||
;;
|
||||
-if)
|
||||
hash="$(sha256sum "$2" | cut -d' ' -f1)"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
tpm2 pcrextend "$index:sha256=$hash"
|
||||
@ -253,57 +257,78 @@ tpm2_counter_read() {
|
||||
TRACE "Under /bin/tpmr:tpm2_counter_read"
|
||||
while true; do
|
||||
case "$1" in
|
||||
-ix)
|
||||
index="$2"
|
||||
shift 2;;
|
||||
*)
|
||||
break;;
|
||||
-ix)
|
||||
index="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
echo "$index: `tpm2 nvread 0x$index | xxd -pc8`"
|
||||
echo "$index: $(tpm2 nvread 0x$index | xxd -pc8)"
|
||||
}
|
||||
|
||||
tpm2_counter_inc() {
|
||||
TRACE "Under /bin/tpmr:tpm2_counter_inc"
|
||||
while true; do
|
||||
case "$1" in
|
||||
-ix)
|
||||
index="$2"
|
||||
shift 2;;
|
||||
-pwdc)
|
||||
pwd="$2"
|
||||
shift 2;;
|
||||
*)
|
||||
break;;
|
||||
-ix)
|
||||
index="$2"
|
||||
shift 2
|
||||
;;
|
||||
-pwdc)
|
||||
pwd="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
tpm2 nvincrement "0x$index" > /dev/console
|
||||
echo "$index: `tpm2 nvread 0x$index | xxd -pc8`"
|
||||
tpm2 nvincrement "0x$index" >/dev/console
|
||||
echo "$index: $(tpm2 nvread 0x$index | xxd -pc8)"
|
||||
}
|
||||
|
||||
tpm2_counter_cre() {
|
||||
TRACE "Under /bin/tpmr:tpm2_counter_cre"
|
||||
tpm1_counter_create() {
|
||||
TRACE "Under /bin/tpmr:tpm1_counter_create"
|
||||
# tpmr handles the TPM owner password (from cache or prompt), but all
|
||||
# other parameters for TPM1 are passed directly, and TPM2 mimics the
|
||||
# TPM1 interface.
|
||||
prompt_tpm_owner_password
|
||||
if ! tpm counter_create -pwdo "$(cat "/tmp/secret/tpm_owner_password")" "$@"; then
|
||||
DEBUG "Failed to create counter from tpm1_counter_create. Wiping /tmp/secret/tpm_owner_password"
|
||||
shred -n 10 -z -u /tmp/secret/tpm_owner_password
|
||||
die "Unable to create counter from tpm1_counter_create"
|
||||
fi
|
||||
}
|
||||
|
||||
tpm2_counter_create() {
|
||||
TRACE "Under /bin/tpmr:tpm2_counter_create"
|
||||
while true; do
|
||||
case "$1" in
|
||||
-pwdo)
|
||||
pwdo="$2"
|
||||
shift 2;;
|
||||
-pwdof)
|
||||
pwdo="file:$2"
|
||||
shift 2;;
|
||||
-pwdc)
|
||||
pwd="$2"
|
||||
shift 2;;
|
||||
-la)
|
||||
label="$2"
|
||||
shift 2;;
|
||||
*)
|
||||
break;;
|
||||
-pwdc)
|
||||
pwd="$2"
|
||||
shift 2
|
||||
;;
|
||||
-la)
|
||||
label="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
rand_index="1`dd if=/dev/urandom bs=1 count=3 | xxd -pc3`"
|
||||
prompt_tpm_owner_password
|
||||
rand_index="1$(dd if=/dev/urandom bs=1 count=3 | xxd -pc3)"
|
||||
tpm2 nvdefine -C o -s 8 -a "ownerread|authread|authwrite|nt=1" \
|
||||
-P "$(tpm2_password_hex "$pwdo")" "0x$rand_index" > /dev/console
|
||||
-P "$(tpm2_password_hex "$(cat "/tmp/secret/tpm_owner_password")")" "0x$rand_index" >/dev/console ||
|
||||
{
|
||||
DEBUG "Failed to create counter from tpm2_counter_create. Wiping /tmp/secret/tpm_owner_password"
|
||||
shred -n 10 -z -u /tmp/secret/tpm_owner_password
|
||||
die "Unable to create counter from tpm2_counter_create"
|
||||
}
|
||||
echo "$rand_index: (valid after an increment)"
|
||||
}
|
||||
|
||||
@ -311,20 +336,20 @@ tpm2_startsession() {
|
||||
TRACE "Under /bin/tpmr:tpm2_startsession"
|
||||
mkdir -p "$SECRET_DIR"
|
||||
tpm2 flushcontext -Q \
|
||||
--transient-object \
|
||||
|| die "tpm2_flushcontext: unable to flush transient handles"
|
||||
--transient-object ||
|
||||
die "tpm2_flushcontext: unable to flush transient handles"
|
||||
|
||||
tpm2 flushcontext -Q \
|
||||
--loaded-session \
|
||||
|| die "tpm2_flushcontext: unable to flush sessions"
|
||||
--loaded-session ||
|
||||
die "tpm2_flushcontext: unable to flush sessions"
|
||||
|
||||
tpm2 flushcontext -Q \
|
||||
--saved-session \
|
||||
|| die "tpm2_flushcontext: unable to flush saved session"
|
||||
tpm2 readpublic -Q -c "$PRIMARY_HANDLE" -t "/tmp/$PRIMARY_HANDLE_FILE"
|
||||
tpm2 startauthsession -Q -c "/tmp/$PRIMARY_HANDLE_FILE" --hmac-session -S "/tmp/$ENC_SESSION_FILE"
|
||||
tpm2 startauthsession -Q -c "/tmp/$PRIMARY_HANDLE_FILE" --hmac-session -S "/tmp/$DEC_SESSION_FILE"
|
||||
tpm2 sessionconfig -Q --disable-encrypt "/tmp/$DEC_SESSION_FILE"
|
||||
--saved-session ||
|
||||
die "tpm2_flushcontext: unable to flush saved session"
|
||||
tpm2 readpublic -Q -c "$PRIMARY_HANDLE" -t "$PRIMARY_HANDLE_FILE"
|
||||
tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$ENC_SESSION_FILE"
|
||||
tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$DEC_SESSION_FILE"
|
||||
tpm2 sessionconfig -Q --disable-encrypt "$DEC_SESSION_FILE"
|
||||
}
|
||||
|
||||
# Use cleanup_session() with at_exit to release a TPM2 session and delete the
|
||||
@ -354,27 +379,27 @@ cleanup_shred() {
|
||||
# tpm2_destroy: Destroy a sealed file in the TPM. The mechanism differs by
|
||||
# TPM version - TPM2 evicts the file object, so it no longer exists.
|
||||
tpm2_destroy() {
|
||||
index="$1" # Index of the sealed file
|
||||
size="$2" # Size of zeroes to overwrite for TPM1 (unused in TPM2)
|
||||
index="$1" # Index of the sealed file
|
||||
size="$2" # Size of zeroes to overwrite for TPM1 (unused in TPM2)
|
||||
|
||||
# Pad with up to 6 zeros, i.e. '0x81000001', '0x81001234', etc.
|
||||
handle="$(printf "0x81%6s" "$index" | tr ' ' 0)"
|
||||
|
||||
# remove possible data occupying this handle
|
||||
tpm2 evictcontrol -Q -C p -c "$handle" 2>/dev/null \
|
||||
|| die "Unable to evict secret"
|
||||
tpm2 evictcontrol -Q -C p -c "$handle" 2>/dev/null ||
|
||||
die "Unable to evict secret from TPM NVRAM"
|
||||
}
|
||||
|
||||
# tpm1_destroy: Destroy a sealed file in the TPM. The mechanism differs by
|
||||
# TPM version - TPM1 overwrites the file with zeroes, since this can be done
|
||||
# without authorization. (Deletion requires authorization.)
|
||||
tpm1_destroy() {
|
||||
index="$1" # Index of the sealed file
|
||||
size="$2" # Size of zeroes to overwrite for TPM1
|
||||
index="$1" # Index of the sealed file
|
||||
size="$2" # Size of zeroes to overwrite for TPM1
|
||||
|
||||
dd if=/dev/zero bs="$size" count=1 of=/tmp/wipe-totp-zero
|
||||
tpm nv_writevalue -in "$index" -if /tmp/wipe-totp-zero \
|
||||
|| die "Unable to wipe sealed secret"
|
||||
tpm nv_writevalue -in "$index" -if /tmp/wipe-totp-zero ||
|
||||
die "Unable to wipe sealed secret from TPM NVRAM"
|
||||
}
|
||||
|
||||
# tpm2_seal: Seal a file against PCR values and, optionally, a password.
|
||||
@ -388,13 +413,13 @@ tpm2_seal() {
|
||||
index="$2"
|
||||
pcrl="$3" #0,1,2,3,4,5,6,7 (does not include algorithm prefix)
|
||||
pcrf="$4"
|
||||
sealed_size="$5" # Not used for TPM2
|
||||
pass="$6" # May be empty to seal with no password
|
||||
tpm_password="$7" # Owner password - will prompt if needed and not empty
|
||||
# Owner password is always needed for TPM2.
|
||||
sealed_size="$5" # Not used for TPM2
|
||||
pass="$6" # May be empty to seal with no password
|
||||
tpm_password="$7" # Owner password - will prompt if needed and not empty
|
||||
# TPM Owner Password is always needed for TPM2.
|
||||
|
||||
mkdir -p "$SECRET_DIR"
|
||||
bname="`basename $file`"
|
||||
bname="$(basename $file)"
|
||||
|
||||
# Pad with up to 6 zeros, i.e. '0x81000001', '0x81001234', etc.
|
||||
handle="$(printf "0x81%6s" "$index" | tr ' ' 0)"
|
||||
@ -403,8 +428,8 @@ tpm2_seal() {
|
||||
|
||||
# Create a policy requiring both PCRs and the object's authentication
|
||||
# value using a trial session.
|
||||
TRIAL_SESSION=/tmp/sealfile_trial.session
|
||||
AUTH_POLICY=/tmp/sealfile_auth.policy
|
||||
TRIAL_SESSION="$SECRET_DIR/sealfile_trial.session"
|
||||
AUTH_POLICY="$SECRET_DIR/sealfile_auth.policy"
|
||||
rm -f "$TRIAL_SESSION" "$AUTH_POLICY"
|
||||
tpm2 startauthsession -g sha256 -S "$TRIAL_SESSION"
|
||||
# We have to clean up the session
|
||||
@ -430,25 +455,30 @@ tpm2_seal() {
|
||||
# (The default is to allow either policy auth _or_ password auth. In
|
||||
# this case the policy includes the password, and we don't want to allow
|
||||
# the password on its own.)
|
||||
tpm2 create -Q -C "/tmp/$PRIMARY_HANDLE_FILE" \
|
||||
tpm2 create -Q -C "$PRIMARY_HANDLE_FILE" \
|
||||
-i "$file" \
|
||||
-u "$SECRET_DIR/$bname.priv" \
|
||||
-r "$SECRET_DIR/$bname.pub" \
|
||||
-L "$AUTH_POLICY" \
|
||||
-S "/tmp/$DEC_SESSION_FILE" \
|
||||
-S "$DEC_SESSION_FILE" \
|
||||
-a "fixedtpm|fixedparent|adminwithpolicy" \
|
||||
"${CREATE_PASS_ARGS[@]}"
|
||||
|
||||
tpm2 load -Q -C "/tmp/$PRIMARY_HANDLE_FILE" \
|
||||
tpm2 load -Q -C "$PRIMARY_HANDLE_FILE" \
|
||||
-u "$SECRET_DIR/$bname.priv" -r "$SECRET_DIR/$bname.pub" \
|
||||
-c "$SECRET_DIR/$bname.seal.ctx"
|
||||
prompt_tpm_password
|
||||
prompt_tpm_owner_password
|
||||
# remove possible data occupying this handle
|
||||
tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_password")" \
|
||||
tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_owner_password")" \
|
||||
-c "$handle" 2>/dev/null || true
|
||||
DO_WITH_DEBUG --mask-position 6 \
|
||||
tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_password")" \
|
||||
-c "$SECRET_DIR/$bname.seal.ctx" "$handle"
|
||||
tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_owner_password")" \
|
||||
-c "$SECRET_DIR/$bname.seal.ctx" "$handle" ||
|
||||
{
|
||||
DEBUG "Failed to write sealed secret to NVRAM from tpm2_seal. Wiping /tmp/secret/tpm_owner_password"
|
||||
shred -n 10 -z -u /tmp/secret/tpm_owner_password
|
||||
die "Unable to write sealed secret to TPM NVRAM"
|
||||
}
|
||||
}
|
||||
tpm1_seal() {
|
||||
TRACE "Under /bin/tpmr:tpm1_seal"
|
||||
@ -457,8 +487,8 @@ tpm1_seal() {
|
||||
pcrl="$3" #0,1,2,3,4,5,6,7 (does not include algorithm prefix)
|
||||
pcrf="$4"
|
||||
sealed_size="$5"
|
||||
pass="$6" # May be empty to seal with no password
|
||||
tpm_password="$7" # Owner password - will prompt if needed and not empty
|
||||
pass="$6" # May be empty to seal with no password
|
||||
tpm_password="$7" # Owner password - will prompt if needed and not empty
|
||||
|
||||
sealed_file="$SECRET_DIR/tpm1_seal_sealed.bin"
|
||||
at_exit cleanup_shred "$sealed_file"
|
||||
@ -477,8 +507,8 @@ tpm1_seal() {
|
||||
# Read each PCR_SIZE block from the file and pass as hex
|
||||
POLICY_ARGS+=(-ix "$pcr"
|
||||
"$(dd if="$pcrf" skip="$pcr_file_index" bs="$PCR_SIZE" count=1 status=none | xxd -p | tr -d ' ')"
|
||||
)
|
||||
pcr_file_index=$((pcr_file_index+1))
|
||||
)
|
||||
pcr_file_index=$((pcr_file_index + 1))
|
||||
done
|
||||
|
||||
tpm sealfile2 \
|
||||
@ -487,25 +517,28 @@ tpm1_seal() {
|
||||
-hk 40000000 \
|
||||
"${POLICY_ARGS[@]}"
|
||||
|
||||
# try it without the owner password first
|
||||
# try it without the TPM Owner Password first
|
||||
if ! tpm nv_writevalue -in "$index" -if "$sealed_file"; then
|
||||
# to create an nvram space we need the TPM owner password
|
||||
# to create an nvram space we need the TPM Owner Password
|
||||
# and the TPM physical presence must be asserted.
|
||||
#
|
||||
# The permissions are 0 since there is nothing special
|
||||
# about the sealed file
|
||||
tpm physicalpresence -s \
|
||||
|| warn "Unable to assert physical presence"
|
||||
tpm physicalpresence -s ||
|
||||
warn "Unable to assert physical presence"
|
||||
|
||||
prompt_tpm_password
|
||||
prompt_tpm_owner_password
|
||||
|
||||
tpm nv_definespace -in "$index" -sz "$sealed_size" \
|
||||
-pwdo "$tpm_password" -per 0 \
|
||||
|| warn "Unable to define NVRAM space; trying anyway"
|
||||
-pwdo "$tpm_password" -per 0 ||
|
||||
warn "Unable to define TPM NVRAM space; trying anyway"
|
||||
|
||||
|
||||
tpm nv_writevalue -in "$index" -if "$sealed_file" \
|
||||
|| die "Unable to write sealed secret to NVRAM"
|
||||
tpm nv_writevalue -in "$index" -if "$sealed_file" ||
|
||||
{
|
||||
DEBUG "Failed to write sealed secret to NVRAM from tpm1_seal. Wiping /tmp/secret/tpm_owner_password"
|
||||
shred -n 10 -z -u /tmp/secret/tpm_owner_password
|
||||
die "Unable to write sealed secret to TPM NVRAM"
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
@ -531,12 +564,13 @@ tpm2_unseal() {
|
||||
# If we don't have the primary handle (TPM hasn't been reset), tpm2 will
|
||||
# print nonsense error messages about an unexpected handle value. We
|
||||
# can't do anything without a primary handle.
|
||||
if [ ! -f "/tmp/$PRIMARY_HANDLE_FILE" ]; then
|
||||
if [ ! -f "$PRIMARY_HANDLE_FILE" ]; then
|
||||
DEBUG "tpm2_unseal: No primary handle, cannot attempt to unseal"
|
||||
warn "No TPM primary handle. You must reset TPM to seal secret to TPM NVRAM"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
POLICY_SESSION=/tmp/unsealfile_policy.session
|
||||
POLICY_SESSION="$SECRET_DIR/unsealfile_policy.session"
|
||||
rm -f "$POLICY_SESSION"
|
||||
tpm2 startauthsession -Q -g sha256 -S "$POLICY_SESSION" --policy-session
|
||||
at_exit cleanup_session "$POLICY_SESSION"
|
||||
@ -554,7 +588,7 @@ tpm2_unseal() {
|
||||
fi
|
||||
|
||||
tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \
|
||||
-S "/tmp/$ENC_SESSION_FILE" > "$file"
|
||||
-S "$ENC_SESSION_FILE" >"$file"
|
||||
}
|
||||
tpm1_unseal() {
|
||||
TRACE "Under /bin/tpmr:tpm1_unseal"
|
||||
@ -576,8 +610,8 @@ tpm1_unseal() {
|
||||
tpm nv_readvalue \
|
||||
-in "$index" \
|
||||
-sz "$sealed_size" \
|
||||
-of "$sealed_file" \
|
||||
|| die "Unable to read sealed file from TPM NVRAM"
|
||||
-of "$sealed_file" ||
|
||||
die "Unable to read sealed file from TPM NVRAM"
|
||||
|
||||
PASS_ARGS=()
|
||||
if [ "$pass" ]; then
|
||||
@ -593,15 +627,18 @@ tpm1_unseal() {
|
||||
|
||||
tpm2_reset() {
|
||||
TRACE "Under /bin/tpmr:tpm2_reset"
|
||||
key_password="$1"
|
||||
tpm_owner_password="$1"
|
||||
mkdir -p "$SECRET_DIR"
|
||||
# output TPM Owner Password to a file to be reused in this boot session until recovery shell/reboot
|
||||
DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password"
|
||||
echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password"
|
||||
tpm2 clear -c platform || warn "Unable to clear TPM on platform hierarchy"
|
||||
tpm2 changeauth -c owner "$(tpm2_password_hex "$key_password")"
|
||||
tpm2 changeauth -c endorsement "$(tpm2_password_hex "$key_password")"
|
||||
tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")"
|
||||
tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")"
|
||||
tpm2 createprimary -C owner -g sha256 -G "${CONFIG_PRIMARY_KEY_TYPE:-rsa}" \
|
||||
-c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$key_password")"
|
||||
-c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")"
|
||||
tpm2 evictcontrol -C owner -c "$SECRET_DIR/primary.ctx" "$PRIMARY_HANDLE" \
|
||||
-P "$(tpm2_password_hex "$key_password")"
|
||||
-P "$(tpm2_password_hex "$tpm_owner_password")"
|
||||
shred -u "$SECRET_DIR/primary.ctx"
|
||||
tpm2_startsession
|
||||
|
||||
@ -610,7 +647,7 @@ tpm2_reset() {
|
||||
# * --max-tries=10: Allow 10 failures before lockout. This allows the
|
||||
# user to quickly "burst" 10 failures without significantly impacting
|
||||
# the rate allowed for a dictionary attacker.
|
||||
# Most TPM2 flows ask for the owner password 2-4 times, so this allows
|
||||
# Most TPM2 flows ask for the TPM Owner Password 2-4 times, so this allows
|
||||
# a handful of mistypes and some headroom for an expected unseal
|
||||
# failure if firmware is updated.
|
||||
# Remember that an auth failure is also counted any time an unclean
|
||||
@ -626,7 +663,7 @@ tpm2_reset() {
|
||||
--max-tries=10 \
|
||||
--recovery-time=3600 \
|
||||
--lockout-recovery-time=0 \
|
||||
--auth="session:/tmp/$ENC_SESSION_FILE"
|
||||
--auth="session:$ENC_SESSION_FILE"
|
||||
|
||||
# Set a random DA lockout password, so the DA lockout can't be cleared
|
||||
# with a password. Heads doesn't offer dictionary attach reset, instead
|
||||
@ -639,15 +676,18 @@ tpm2_reset() {
|
||||
}
|
||||
tpm1_reset() {
|
||||
TRACE "Under /bin/tpmr:tpm1_reset"
|
||||
key_password="$1"
|
||||
|
||||
tpm_owner_password="$1"
|
||||
mkdir -p "$SECRET_DIR"
|
||||
# output tpm_owner_password to a file to be reused in this boot session until recovery shell/reboot
|
||||
DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password"
|
||||
echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password"
|
||||
# Make sure the TPM is ready to be reset
|
||||
tpm physicalpresence -s
|
||||
tpm physicalenable
|
||||
tpm physicalsetdeactivated -c
|
||||
tpm forceclear
|
||||
tpm physicalenable
|
||||
tpm takeown -pwdo "$key_password"
|
||||
tpm takeown -pwdo "$tpm_owner_password"
|
||||
|
||||
# And now turn it all back on
|
||||
tpm physicalpresence -s
|
||||
@ -660,20 +700,20 @@ tpm2_kexec_finalize() {
|
||||
TRACE "Under /bin/tpmr:tpm2_kexec_finalize"
|
||||
|
||||
# Flush sessions and transient objects
|
||||
tpm2 flushcontext -Q --transient-object \
|
||||
|| warn "tpm2_flushcontext: unable to flush transient handles"
|
||||
tpm2 flushcontext -Q --loaded-session \
|
||||
|| warn "tpm2_flushcontext: unable to flush sessions"
|
||||
tpm2 flushcontext -Q --saved-session \
|
||||
|| warn "tpm2_flushcontext: unable to flush saved session"
|
||||
tpm2 flushcontext -Q --transient-object ||
|
||||
warn "tpm2_flushcontext: unable to flush transient handles"
|
||||
tpm2 flushcontext -Q --loaded-session ||
|
||||
warn "tpm2_flushcontext: unable to flush sessions"
|
||||
tpm2 flushcontext -Q --saved-session ||
|
||||
warn "tpm2_flushcontext: unable to flush saved session"
|
||||
|
||||
# Add a random passphrase to platform hierarchy to prevent TPM2 from
|
||||
# being cleared in the OS.
|
||||
# This passphrase is only effective before the next boot.
|
||||
echo "Locking TPM2 platform hierarchy..."
|
||||
randpass=$(dd if=/dev/urandom bs=4 count=1 status=none | xxd -p)
|
||||
tpm2 changeauth -c platform "$randpass" \
|
||||
|| warn "Failed to lock platform hierarchy of TPM2"
|
||||
tpm2 changeauth -c platform "$randpass" ||
|
||||
warn "Failed to lock platform hierarchy of TPM2"
|
||||
}
|
||||
|
||||
tpm2_shutdown() {
|
||||
@ -693,72 +733,101 @@ fi
|
||||
# TPM1 - most commands forward directly to tpm, but some are still wrapped for
|
||||
# consistency with tpm2.
|
||||
if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then
|
||||
PCR_SIZE=20 # TPM1 PCRs are always SHA-1
|
||||
PCR_SIZE=20 # TPM1 PCRs are always SHA-1
|
||||
subcmd="$1"
|
||||
# Don't shift yet, for most commands we will just forward to tpm.
|
||||
case "$subcmd" in
|
||||
pcrread)
|
||||
shift; tpm1_pcrread "$@";;
|
||||
pcrsize)
|
||||
echo "$PCR_SIZE";;
|
||||
calcfuturepcr)
|
||||
shift; replay_pcr "sha1" "$@";;
|
||||
destroy)
|
||||
shift; tpm1_destroy "$@";;
|
||||
seal)
|
||||
shift; tpm1_seal "$@";;
|
||||
startsession)
|
||||
;; # Nothing on TPM1.
|
||||
unseal)
|
||||
shift; tpm1_unseal "$@";;
|
||||
reset)
|
||||
shift; tpm1_reset "$@";;
|
||||
kexec_finalize)
|
||||
;; # Nothing on TPM1.
|
||||
shutdown)
|
||||
;; # Nothing on TPM1.
|
||||
*)
|
||||
DEBUG "Direct translation from tpmr to tpm1 call"
|
||||
DO_WITH_DEBUG exec tpm "$@"
|
||||
;;
|
||||
pcrread)
|
||||
shift
|
||||
tpm1_pcrread "$@"
|
||||
;;
|
||||
pcrsize)
|
||||
echo "$PCR_SIZE"
|
||||
;;
|
||||
calcfuturepcr)
|
||||
shift
|
||||
replay_pcr "sha1" "$@"
|
||||
;;
|
||||
counter_create)
|
||||
shift
|
||||
tpm1_counter_create "$@"
|
||||
;;
|
||||
destroy)
|
||||
shift
|
||||
tpm1_destroy "$@"
|
||||
;;
|
||||
seal)
|
||||
shift
|
||||
tpm1_seal "$@"
|
||||
;;
|
||||
startsession) ;; # Nothing on TPM1.
|
||||
unseal)
|
||||
shift
|
||||
tpm1_unseal "$@"
|
||||
;;
|
||||
reset)
|
||||
shift
|
||||
tpm1_reset "$@"
|
||||
;;
|
||||
kexec_finalize) ;; # Nothing on TPM1.
|
||||
shutdown) ;; # Nothing on TPM1.
|
||||
*)
|
||||
DEBUG "Direct translation from tpmr to tpm1 call"
|
||||
DO_WITH_DEBUG exec tpm "$@"
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# TPM2 - all commands implemented as wrappers around tpm2
|
||||
PCR_SIZE=32 # We use the SHA-256 PCRs
|
||||
PCR_SIZE=32 # We use the SHA-256 PCRs
|
||||
subcmd="$1"
|
||||
shift 1
|
||||
case "$subcmd" in
|
||||
pcrread)
|
||||
tpm2_pcrread "$@";;
|
||||
pcrsize)
|
||||
echo "$PCR_SIZE";;
|
||||
calcfuturepcr)
|
||||
replay_pcr "sha256" "$@";;
|
||||
extend)
|
||||
tpm2_extend "$@";;
|
||||
counter_read)
|
||||
tpm2_counter_read "$@";;
|
||||
counter_increment)
|
||||
tpm2_counter_inc "$@";;
|
||||
counter_create)
|
||||
tpm2_counter_cre "$@";;
|
||||
destroy)
|
||||
tpm2_destroy "$@";;
|
||||
seal)
|
||||
tpm2_seal "$@";;
|
||||
startsession)
|
||||
tpm2_startsession "$@";;
|
||||
unseal)
|
||||
tpm2_unseal "$@";;
|
||||
reset)
|
||||
tpm2_reset "$@";;
|
||||
kexec_finalize)
|
||||
tpm2_kexec_finalize "$@";;
|
||||
shutdown)
|
||||
tpm2_shutdown "$@";;
|
||||
*)
|
||||
echo "Command $subcmd not wrapped!"
|
||||
exit 1
|
||||
pcrread)
|
||||
tpm2_pcrread "$@"
|
||||
;;
|
||||
pcrsize)
|
||||
echo "$PCR_SIZE"
|
||||
;;
|
||||
calcfuturepcr)
|
||||
replay_pcr "sha256" "$@"
|
||||
;;
|
||||
extend)
|
||||
tpm2_extend "$@"
|
||||
;;
|
||||
counter_read)
|
||||
tpm2_counter_read "$@"
|
||||
;;
|
||||
counter_increment)
|
||||
tpm2_counter_inc "$@"
|
||||
;;
|
||||
counter_create)
|
||||
tpm2_counter_create "$@"
|
||||
;;
|
||||
destroy)
|
||||
tpm2_destroy "$@"
|
||||
;;
|
||||
seal)
|
||||
tpm2_seal "$@"
|
||||
;;
|
||||
startsession)
|
||||
tpm2_startsession "$@"
|
||||
;;
|
||||
unseal)
|
||||
tpm2_unseal "$@"
|
||||
;;
|
||||
reset)
|
||||
tpm2_reset "$@"
|
||||
;;
|
||||
kexec_finalize)
|
||||
tpm2_kexec_finalize "$@"
|
||||
;;
|
||||
shutdown)
|
||||
tpm2_shutdown "$@"
|
||||
;;
|
||||
*)
|
||||
echo "Command $subcmd not wrapped!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
@ -8,14 +8,14 @@ TOTP_SECRET="/tmp/secret/totp.key"
|
||||
TRACE "Under /bin/unseal-totp"
|
||||
|
||||
if [ "$CONFIG_TPM" = "y" ]; then
|
||||
tpmr unseal 4d47 0,1,2,3,4,7 312 "$TOTP_SECRET" \
|
||||
|| die "Unable to unseal totp secret"
|
||||
tpmr unseal 4d47 0,1,2,3,4,7 312 "$TOTP_SECRET" ||
|
||||
die "Unable to unseal TOTP secret"
|
||||
fi
|
||||
|
||||
if ! totp -q < "$TOTP_SECRET"; then
|
||||
shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null
|
||||
if ! totp -q <"$TOTP_SECRET"; then
|
||||
shred -n 10 -z -u "$TOTP_SECRET" 2>/dev/null
|
||||
die 'Unable to compute TOTP hash?'
|
||||
fi
|
||||
|
||||
shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null
|
||||
shred -n 10 -z -u "$TOTP_SECRET" 2>/dev/null
|
||||
exit 0
|
||||
|
@ -53,6 +53,163 @@ preserve_rom() {
|
||||
done
|
||||
}
|
||||
|
||||
confirm_gpg_card() {
|
||||
TRACE "Under /etc/ash_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
|
||||
DEBUG "Using known GPG key material Thumb drive backup and keys are unlocked and useable through pinentry"
|
||||
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 \
|
||||
-n 1 \
|
||||
-p "$message" \
|
||||
card_confirm
|
||||
echo
|
||||
|
||||
if [ "$card_confirm" != "y" \
|
||||
-a "$card_confirm" != "Y" \
|
||||
-a "$card_confirm" != "b" \
|
||||
-a -n "$card_confirm" ] \
|
||||
; then
|
||||
die "gpg card not confirmed"
|
||||
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 configured GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys
|
||||
echo
|
||||
gpg_admin_pin=""
|
||||
while [ -z "$gpg_admin_pin" ]; do
|
||||
#TODO: change all passphrase prompts in codebase to include -r to prevent backslash escapes
|
||||
read -r -s -p "Please enter GPG Admin PIN needed to use the GPG backup thumb drive: " gpg_admin_pin
|
||||
echo
|
||||
done
|
||||
#prompt user to select the proper encrypted partition, which should the first one on next prompt
|
||||
warn "Please select encrypted LUKS on GPG key material backup thumb drive (not public labeled one)"
|
||||
mount-usb --pass "$gpg_admin_pin" || die "Unable to mount USB with provided GPG Admin PIN"
|
||||
echo "++++ 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 $CR_NONCE to be detach-signed with GPG private signing subkey"
|
||||
gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --detach-sign "$CR_NONCE" >/dev/null 2>&1 ||
|
||||
die "Unable to detach-sign $CR_NONCE with GPG private signing subkey using GPG Admin PIN"
|
||||
#verify detached signature against public key in rom
|
||||
gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 && \
|
||||
echo "++++ Local GPG keyring can be used to sign/encrypt/authenticate in this boot session ++++" || \
|
||||
die "Unable to verify $CR_SIG detached signature against public key in ROM"
|
||||
#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
|
||||
fi
|
||||
|
||||
# setup the USB so we can reach the USB Security Dongle's smartcard
|
||||
enable_usb
|
||||
|
||||
echo -e "\nVerifying presence of GPG card...\n"
|
||||
# ensure we don't exit without retrying
|
||||
errexit=$(set -o | grep errexit | awk '{print $2}')
|
||||
set +e
|
||||
gpg --card-status >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
# prompt for reinsertion and try a second time
|
||||
read -n1 -r -p \
|
||||
"Can't access GPG key; remove and reinsert, then press Enter to retry. " \
|
||||
ignored
|
||||
# restore prev errexit state
|
||||
if [ "$errexit" = "on" ]; then
|
||||
set -e
|
||||
fi
|
||||
# retry card status
|
||||
gpg --card-status >/dev/null ||
|
||||
die "gpg card read failed"
|
||||
fi
|
||||
# restore prev errexit state
|
||||
if [ "$errexit" = "on" ]; then
|
||||
set -e
|
||||
fi
|
||||
}
|
||||
|
||||
gpg_auth() {
|
||||
if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" ]]; then
|
||||
TRACE "Under /etc/ash_functions:gpg_auth"
|
||||
# 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 smartcard/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
|
||||
|
||||
# In case of gpg_auth, we require confirmation of the card, so loop with confirm_gpg_card until we get it
|
||||
false
|
||||
while [ $? -ne 0 ]; do
|
||||
# Call confirm_gpg_card in subshell to ensure GPG key material presence
|
||||
( confirm_gpg_card )
|
||||
done
|
||||
|
||||
# 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" > /dev/null 2>&1 \
|
||||
&& gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 \
|
||||
; then
|
||||
shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true
|
||||
DEBUG "Under /etc/ash_functions:gpg_auth: success"
|
||||
return 0
|
||||
else
|
||||
shred -n 10 -z -u "$CR_SIG" 2>/dev/null || true
|
||||
if [ "$tries" -lt 3 ]; then
|
||||
echo >&2 "!!!!! GPG authentication failed, please try again !!!!!"
|
||||
continue
|
||||
else
|
||||
die "GPG authentication failed, please reboot and try again"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
recovery() {
|
||||
TRACE "Under /etc/ash_functions:recovery"
|
||||
echo >&2 "!!!!! $*"
|
||||
@ -70,6 +227,7 @@ recovery() {
|
||||
. /tmp/config
|
||||
|
||||
if [ "$CONFIG_TPM" = "y" ]; then
|
||||
DEBUG "Extending TPM PCR 4 for recovery shell access"
|
||||
tpmr extend -ix 4 -ic recovery
|
||||
fi
|
||||
|
||||
@ -80,9 +238,12 @@ recovery() {
|
||||
fi
|
||||
while [ true ]
|
||||
do
|
||||
#Going to recovery shell should be authenticated if supported
|
||||
gpg_auth
|
||||
|
||||
echo >&2 "!!!!! Starting recovery shell"
|
||||
sleep 1
|
||||
|
||||
|
||||
if [ -x /bin/setsid ]; then
|
||||
/bin/setsid -c /bin/sh
|
||||
else
|
||||
@ -102,6 +263,57 @@ combine_configs() {
|
||||
cat /etc/config* > /tmp/config
|
||||
}
|
||||
|
||||
replace_config() {
|
||||
TRACE "Under /etc/functions:replace_config"
|
||||
CONFIG_FILE=$1
|
||||
CONFIG_OPTION=$2
|
||||
NEW_SETTING=$3
|
||||
|
||||
touch $CONFIG_FILE
|
||||
# first pull out the existing option from the global config and place in a tmp file
|
||||
awk "gsub(\"^export ${CONFIG_OPTION}=.*\",\"export ${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >${CONFIG_FILE}.tmp
|
||||
awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >>${CONFIG_FILE}.tmp
|
||||
|
||||
# then copy any remaining settings from the existing config file, minus the option you changed
|
||||
grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >>${CONFIG_FILE}.tmp || true
|
||||
sort ${CONFIG_FILE}.tmp | uniq >${CONFIG_FILE}
|
||||
rm -f ${CONFIG_FILE}.tmp
|
||||
}
|
||||
|
||||
# Set a config variable in a specific file to a given value - replace it if it
|
||||
# exists, or add it. If added, the variable will be exported.
|
||||
set_config() {
|
||||
CONFIG_FILE="$1"
|
||||
CONFIG_OPTION="$2"
|
||||
NEW_SETTING="$3"
|
||||
|
||||
if grep -q "$CONFIG_OPTION" "$CONFIG_FILE"; then
|
||||
replace_config "$CONFIG_FILE" "$CONFIG_OPTION" "$NEW_SETTING"
|
||||
else
|
||||
echo "export $CONFIG_OPTION=\"$NEW_SETTING\"" >>"$CONFIG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Set a value in config.user, re-combine configs, and update configs in the
|
||||
# environment.
|
||||
set_user_config() {
|
||||
CONFIG_OPTION="$1"
|
||||
NEW_SETTING="$2"
|
||||
|
||||
set_config /etc/config.user "$CONFIG_OPTION" "$NEW_SETTING"
|
||||
combine_configs
|
||||
. /tmp/config
|
||||
}
|
||||
|
||||
# Load a config value to a variable, defaulting to empty. Does not fail if the
|
||||
# config is not set (since it would expand to empty by default).
|
||||
load_config_value() {
|
||||
local config_name="$1"
|
||||
if grep -q "$config_name=" /tmp/config; then
|
||||
grep "$config_name=" /tmp/config | tail -n1 | cut -f2 -d '=' | tr -d '"'
|
||||
fi
|
||||
}
|
||||
|
||||
enable_usb()
|
||||
{
|
||||
TRACE "Under /etc/ash_functions:enable_usb"
|
||||
|
@ -96,16 +96,15 @@ reseal_tpm_disk_decryption_key() {
|
||||
fi
|
||||
|
||||
if [ -s /boot/kexec_key_devices.txt ] || [ -s /boot/kexec_key_lvm.txt ]; then
|
||||
warn "A TPM Disk Unlock Key previously sealed is now invalid since firmware measurements could not unseal TOTP"
|
||||
echo "Renewing LUKS Disk Unlock Key to be unsealed by TPM Disk Unlock Key passphrase"
|
||||
warn "TPM sealed Disk Unlock Key secret needs to be resealed alongside TOTP/HOTP secret"
|
||||
echo "Resealing TPM LUKS Disk Unlock Key to be unsealed by TPM Disk Unlock Key passphrase"
|
||||
while ! kexec-seal-key /boot; do
|
||||
warn "Recovery Disk Encryption key passphrase invalid. Try again!"
|
||||
warn "Recovery Disk Encryption key passphrase/TPM Owner Password may be invalid. Please try again"
|
||||
done
|
||||
warn "LUKS header hash changed under /boot/kexec_luks_hdr_hash.txt"
|
||||
echo "Updating checksums and signing all files under /boot/kexec.sig"
|
||||
while ! update_checksums; do
|
||||
warn "Checksums were not signed. Bad GPG PIN provided?"
|
||||
warn "Please update checksums and provide a valid GPG PIN"
|
||||
warn "Checksums were not signed. Preceding errors should explain possible causes"
|
||||
done
|
||||
warn "Rebooting in 3 seconds to enable booting default boot option"
|
||||
sleep 3
|
||||
@ -119,6 +118,7 @@ reseal_tpm_disk_decryption_key() {
|
||||
# be detected. If USB storage was already enabled, no wait occurs, this would
|
||||
# have happened already when USB storage was enabled.
|
||||
enable_usb_storage() {
|
||||
TRACE "Under /etc/functions:enable_usb_storage"
|
||||
if ! lsmod | grep -q usb_storage; then
|
||||
timeout=0
|
||||
echo "Scanning for USB storage devices..."
|
||||
@ -189,83 +189,59 @@ list_usb_storage() {
|
||||
done
|
||||
}
|
||||
|
||||
confirm_gpg_card() {
|
||||
TRACE "Under /etc/functions:confirm_gpg_card"
|
||||
read \
|
||||
-n 1 \
|
||||
-p "Please confirm that your GPG card is inserted [Y/n]: " \
|
||||
card_confirm
|
||||
echo
|
||||
# Prompt for a TPM Owner Password if it is not already cached in /tmp/secret/tpm_owner_password.
|
||||
# Sets tpm_owner_password variable reused in flow, and cache file used until recovery shell is accessed.
|
||||
# Tools should optionally accept a TPM password on the command line, since some flows need
|
||||
# it multiple times and only one prompt is ideal.
|
||||
prompt_tpm_owner_password() {
|
||||
TRACE "Under /etc/functions:prompt_tpm_owner_password"
|
||||
|
||||
if [ "$card_confirm" != "y" \
|
||||
-a "$card_confirm" != "Y" \
|
||||
-a -n "$card_confirm" ] \
|
||||
; then
|
||||
die "gpg card not confirmed"
|
||||
fi
|
||||
|
||||
# setup the USB so we can reach the GPG card
|
||||
enable_usb
|
||||
|
||||
echo -e "\nVerifying presence of GPG card...\n"
|
||||
# ensure we don't exit without retrying
|
||||
errexit=$(set -o | grep errexit | awk '{print $2}')
|
||||
set +e
|
||||
gpg --card-status >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
# prompt for reinsertion and try a second time
|
||||
read -n1 -r -p \
|
||||
"Can't access GPG key; remove and reinsert, then press Enter to retry. " \
|
||||
ignored
|
||||
# restore prev errexit state
|
||||
if [ "$errexit" = "on" ]; then
|
||||
set -e
|
||||
fi
|
||||
# retry card status
|
||||
gpg --card-status >/dev/null ||
|
||||
die "gpg card read failed"
|
||||
fi
|
||||
# restore prev errexit state
|
||||
if [ "$errexit" = "on" ]; then
|
||||
set -e
|
||||
fi
|
||||
}
|
||||
|
||||
# Prompt for an owner password if it is not already set in tpm_password. Sets
|
||||
# tpm_password. Tools should optionally accept a TPM password on the command
|
||||
# line, since some flows need it multiple times and only one prompt is ideal.
|
||||
prompt_tpm_password() {
|
||||
if [ -n "$tpm_password" ]; then
|
||||
if [ -s /tmp/secret/tpm_owner_password ]; then
|
||||
DEBUG "/tmp/secret/tpm_owner_password already cached in file. Reusing"
|
||||
tpm_owner_password=$(cat /tmp/secret/tpm_owner_password)
|
||||
return 0
|
||||
fi
|
||||
|
||||
read -s -p "TPM Owner password: " tpm_password
|
||||
read -s -p "TPM Owner Password: " tpm_owner_password
|
||||
echo # new line after password prompt
|
||||
|
||||
# Cache the password externally to be reused by who needs it
|
||||
DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_owner_password"
|
||||
mkdir -p /tmp/secret || die "Unable to create /tmp/secret"
|
||||
echo -n "$tpm_owner_password" >/tmp/secret/tpm_owner_password || die "Unable to cache TPM owner_password under /tmp/secret/tpm_owner_password"
|
||||
}
|
||||
|
||||
# Prompt for a new owner password when resetting the TPM. Returned in
|
||||
# key_password. The password must be 1-32 characters and must be entered twice,
|
||||
# Prompt for a new TPM Owner Password when resetting the TPM.
|
||||
# Returned in tpm_owner_passpword and cached under /tpm/secret/tpm_owner_password
|
||||
# The password must be 1-32 characters and must be entered twice,
|
||||
# the script will loop until this is met.
|
||||
prompt_new_owner_password() {
|
||||
local key_password2
|
||||
key_password=1
|
||||
key_password2=2
|
||||
while [ "$key_password" != "$key_password2" ] || [ "${#key_password}" -gt 32 ] || [ -z "$key_password" ]; do
|
||||
read -s -p "New TPM owner passphrase (2 words suggested, 1-32 characters max): " key_password
|
||||
TRACE "Under /etc/functions:prompt_new_owner_password"
|
||||
local tpm_owner_password2
|
||||
tpm_owner_password=1
|
||||
tpm_owner_password2=2
|
||||
while [ "$tpm_owner_password" != "$tpm_owner_password2" ] || [ "${#tpm_owner_password}" -gt 32 ] || [ -z "$tpm_owner_password" ]; do
|
||||
read -s -p "New TPM Owner Password (2 words suggested, 1-32 characters max): " tpm_owner_password
|
||||
echo
|
||||
|
||||
read -s -p "Repeat chosen TPM owner passphrase: " key_password2
|
||||
read -s -p "Repeat chosen TPM Owner Password: " tpm_owner_password2
|
||||
echo
|
||||
|
||||
if [ "$key_password" != "$key_password2" ]; then
|
||||
if [ "$tpm_owner_password" != "$tpm_owner_password2" ]; then
|
||||
echo "Passphrases entered do not match. Try again!"
|
||||
echo
|
||||
fi
|
||||
done
|
||||
|
||||
# Cache the password externally to be reused by who needs it
|
||||
DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_owner_password"
|
||||
mkdir -p /tmp/secret || die "Unable to create /tmp/secret"
|
||||
echo -n "$tpm_owner_password" >/tmp/secret/tpm_owner_password || die "Unable to cache TPM password under /tmp/secret"
|
||||
}
|
||||
|
||||
check_tpm_counter() {
|
||||
TRACE "Under /etc/functions:check_tpm_counter"
|
||||
|
||||
LABEL=${2:-3135106223}
|
||||
tpm_password="$3"
|
||||
# if the /boot.hashes file already exists, read the TPM counter ID
|
||||
@ -274,13 +250,11 @@ check_tpm_counter() {
|
||||
TPM_COUNTER=$(grep counter- "$1" | cut -d- -f2)
|
||||
else
|
||||
warn "$1 does not exist; creating new TPM counter"
|
||||
prompt_tpm_password
|
||||
tpmr counter_create \
|
||||
-pwdo "$tpm_password" \
|
||||
-pwdc '' \
|
||||
-la $LABEL |
|
||||
tee /tmp/counter ||
|
||||
die "Unable to create TPM counter"
|
||||
die "Unable to create TPM counter"
|
||||
TPM_COUNTER=$(cut -d: -f1 </tmp/counter)
|
||||
fi
|
||||
|
||||
@ -299,7 +273,7 @@ increment_tpm_counter() {
|
||||
TRACE "Under /etc/functions:increment_tpm_counter"
|
||||
tpmr counter_increment -ix "$1" -pwdc '' |
|
||||
tee /tmp/counter-$1 ||
|
||||
die "Counter increment failed"
|
||||
die "TPM counter increment failed for rollback prevention. Please reset the TPM"
|
||||
}
|
||||
|
||||
check_config() {
|
||||
@ -360,40 +334,6 @@ replace_config() {
|
||||
rm -f ${CONFIG_FILE}.tmp
|
||||
}
|
||||
|
||||
# Set a config variable in a specific file to a given value - replace it if it
|
||||
# exists, or add it. If added, the variable will be exported.
|
||||
set_config() {
|
||||
CONFIG_FILE="$1"
|
||||
CONFIG_OPTION="$2"
|
||||
NEW_SETTING="$3"
|
||||
|
||||
if grep -q "$CONFIG_OPTION" "$CONFIG_FILE"; then
|
||||
replace_config "$CONFIG_FILE" "$CONFIG_OPTION" "$NEW_SETTING"
|
||||
else
|
||||
echo "export $CONFIG_OPTION=\"$NEW_SETTING\"" >>"$CONFIG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Set a value in config.user, re-combine configs, and update configs in the
|
||||
# environment.
|
||||
set_user_config() {
|
||||
CONFIG_OPTION="$1"
|
||||
NEW_SETTING="$2"
|
||||
|
||||
set_config /etc/config.user "$CONFIG_OPTION" "$NEW_SETTING"
|
||||
combine_configs
|
||||
. /tmp/config
|
||||
}
|
||||
|
||||
# Load a config value to a variable, defaulting to empty. Does not fail if the
|
||||
# config is not set (since it would expand to empty by default).
|
||||
load_config_value() {
|
||||
local config_name="$1"
|
||||
if grep -q "$config_name=" /tmp/config; then
|
||||
grep "$config_name=" /tmp/config | tail -n1 | cut -f2 -d '=' | tr -d '"'
|
||||
fi
|
||||
}
|
||||
|
||||
# Generate a secret for TPM-less HOTP by reading the ROM. Output is the
|
||||
# sha256sum of the ROM (binary, not printable), which can be truncated to the
|
||||
# supported secret length.
|
||||
@ -608,6 +548,7 @@ detect_boot_device() {
|
||||
}
|
||||
|
||||
scan_boot_options() {
|
||||
TRACE "Under /etc/functions:scan_boot_options"
|
||||
local bootdir config option_file
|
||||
bootdir="$1"
|
||||
config="$2"
|
||||
|
@ -34,54 +34,100 @@ mount_usb()
|
||||
fi
|
||||
}
|
||||
|
||||
# Create display text for a size in bytes in either MB or GB, unit selected
|
||||
# automatically, rounded to nearest
|
||||
display_size() {
|
||||
local size_bytes unit_divisor unit_symbol
|
||||
size_bytes="$1"
|
||||
|
||||
# If it's less than 1 GB, display MB
|
||||
if [ "$((size_bytes))" -lt "$((1024*1024*1024))" ]; then
|
||||
unit_divisor=$((1024*1024))
|
||||
unit_symbol="MB"
|
||||
else
|
||||
unit_divisor=$((1024*1024*1024))
|
||||
unit_symbol="GB"
|
||||
fi
|
||||
|
||||
# Divide by the unit divisor and round to nearest
|
||||
echo "$(( (size_bytes + unit_divisor/2) / unit_divisor )) $unit_symbol"
|
||||
}
|
||||
|
||||
# Create display text for the size of a block device using MB or GB, rounded to
|
||||
# nearest
|
||||
display_block_device_size() {
|
||||
local block_dev disk_size_bytes
|
||||
block_dev="$1"
|
||||
|
||||
# Obtain size of thumb drive to be wiped with fdisk
|
||||
if ! disk_size_bytes="$(blockdev --getsize64 "$block_dev")"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
display_size "$disk_size_bytes"
|
||||
}
|
||||
|
||||
# Display a menu to select a file from a list. Pass the name of a file
|
||||
# containing the list.
|
||||
# --show-size: Append sizes of files listed. Currently only supports block
|
||||
# devices.
|
||||
# $1: Name of file listing files that can be chosen (one per line)
|
||||
# $2: Optional prompt message
|
||||
# $3: Optional prompt title
|
||||
#
|
||||
# Success: Sets FILE with the selected file
|
||||
# User aborted: Exits successfully with FILE empty
|
||||
# No entries in list: Displays error and exits unsuccessfully
|
||||
file_selector()
|
||||
{
|
||||
TRACE "under gui_functions:file_selector"
|
||||
FILE=""
|
||||
FILE_LIST=$1
|
||||
MENU_MSG=${2:-"Choose the file"}
|
||||
MENU_TITLE=${3:-"Select your File"}
|
||||
TRACE "under gui_functions:file_selector"
|
||||
|
||||
# create file menu options
|
||||
if [ `cat "$FILE_LIST" | wc -l` -gt 0 ]; then
|
||||
option=""
|
||||
while [ -z "$option" ]
|
||||
do
|
||||
MENU_OPTIONS=""
|
||||
n=0
|
||||
while read option
|
||||
do
|
||||
n=`expr $n + 1`
|
||||
option=$(echo $option | tr " " "_")
|
||||
MENU_OPTIONS="$MENU_OPTIONS $n ${option}"
|
||||
done < $FILE_LIST
|
||||
local FILE_LIST MENU_MSG MENU_TITLE CHOICE_ARGS SHOW_SIZE OPTION_SIZE option_index
|
||||
|
||||
MENU_OPTIONS="$MENU_OPTIONS a Abort"
|
||||
whiptail --title "${MENU_TITLE}" \
|
||||
--menu "${MENU_MSG} [1-$n, a to abort]:" 20 120 8 \
|
||||
-- $MENU_OPTIONS \
|
||||
2>/tmp/whiptail || die "Aborting"
|
||||
FILE=""
|
||||
|
||||
option_index=$(cat /tmp/whiptail)
|
||||
if [ "$1" = "--show-size" ]; then
|
||||
SHOW_SIZE=y
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ "$option_index" = "a" ]; then
|
||||
option="a"
|
||||
return
|
||||
fi
|
||||
FILE_LIST=$1
|
||||
MENU_MSG=${2:-"Choose the file"}
|
||||
MENU_TITLE=${3:-"Select your File"}
|
||||
|
||||
option=`head -n $option_index $FILE_LIST | tail -1`
|
||||
if [ "$option" == "a" ]; then
|
||||
return
|
||||
fi
|
||||
done
|
||||
if [ -n "$option" ]; then
|
||||
FILE=$option
|
||||
fi
|
||||
else
|
||||
whiptail $BG_COLOR_ERROR --title 'ERROR: No Files Found' \
|
||||
--msgbox "No Files found matching the pattern. Aborting." 0 80
|
||||
exit 1
|
||||
fi
|
||||
CHOICE_ARGS=()
|
||||
n=0
|
||||
while read option; do
|
||||
n="$((++n))"
|
||||
|
||||
if [ "$SHOW_SIZE" = "y" ] && OPTION_SIZE="$(display_block_device_size "$option")"; then
|
||||
option="$option - $OPTION_SIZE"
|
||||
fi
|
||||
CHOICE_ARGS+=("$n" "$option")
|
||||
done < "$FILE_LIST"
|
||||
|
||||
if [ "${#CHOICE_ARGS[@]}" -eq 0 ]; then
|
||||
whiptail $BG_COLOR_ERROR --title 'ERROR: No Files Found' \
|
||||
--msgbox "No Files found matching the pattern. Aborting." 0 80
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CHOICE_ARGS+=(a Abort)
|
||||
|
||||
# create file menu options
|
||||
option_index=""
|
||||
while [ -z "$option_index" ]; do
|
||||
whiptail --title "${MENU_TITLE}" \
|
||||
--menu "${MENU_MSG} [1-$n, a to abort]:" 20 120 8 \
|
||||
-- "${CHOICE_ARGS[@]}" \
|
||||
2>/tmp/whiptail || die "Aborting"
|
||||
|
||||
option_index=$(cat /tmp/whiptail)
|
||||
|
||||
if [ "$option_index" != "a" ]; then
|
||||
FILE="$(head -n "$option_index" "$FILE_LIST" | tail -1)"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
show_system_info()
|
||||
|
@ -6,25 +6,19 @@
|
||||
. /tmp/config
|
||||
|
||||
#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
|
||||
lvm vgscan||true
|
||||
blkid | cut -d ':' -f 1 | while read device
|
||||
do cryptsetup isLuks $device
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "$device"
|
||||
fi
|
||||
done | sort
|
||||
lvm vgscan || true
|
||||
blkid | cut -d ':' -f 1 | while read device; do
|
||||
if cryptsetup isLuks $device; then echo $device; fi
|
||||
done | sort
|
||||
}
|
||||
|
||||
|
||||
#Whiptail prompt asking user to select ratio of device to use for LUKS container between: 10, 25, 50, 75
|
||||
select_luks_container_size_percent()
|
||||
{
|
||||
#Whiptail prompt asking user to select ratio of device to use for LUKS container between: 25, 50, 75
|
||||
select_luks_container_size_percent() {
|
||||
TRACE "Under /etc/luks-functions:select_luks_container_size_percent()"
|
||||
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 --title "Select LUKS container size percentage of device" --menu \
|
||||
"Select LUKS container size percentage of device:" 0 80 10 \
|
||||
@ -57,11 +51,12 @@ select_luks_container_size_percent()
|
||||
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 interactively with two partitions: a LUKS container
|
||||
# containing private ext4 partition and second public exFAT partition
|
||||
# Size provisioning is done by percentage of the device
|
||||
prepare_thumb_drive()
|
||||
interactive_prepare_thumb_drive()
|
||||
{
|
||||
TRACE "Under /etc/luks-functions:prepare_thumb_drive()"
|
||||
TRACE "Under /etc/luks-functions:interactive_prepare_thumb_drive()"
|
||||
#Refactoring: only one parameter needed to be prompted for: the passphrase for LUKS container if not coming from oem-provisioning
|
||||
#If no passphrase was provided, ask user to select passphrase for LUKS container
|
||||
# if no device provided as parameter, we will ask user to select device to partition
|
||||
@ -84,12 +79,13 @@ prepare_thumb_drive()
|
||||
PERCENTAGE=$2
|
||||
shift 2
|
||||
;;
|
||||
--passphrase)
|
||||
--pass)
|
||||
PASSPHRASE=$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]"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@ -177,37 +173,82 @@ prepare_thumb_drive()
|
||||
PERCENTAGE=$(cat /tmp/luks_container_size_percent)
|
||||
fi
|
||||
|
||||
confirm_thumb_drive_format "$DEVICE" "$PERCENTAGE" ||
|
||||
die "User cancelled wiping and repartitioning of $DEVICE"
|
||||
|
||||
#Get disk size in bytes from fdisk
|
||||
prepare_thumb_drive "$DEVICE" "$PERCENTAGE" "$PASSPHRASE"
|
||||
}
|
||||
|
||||
# Show a prompt to confirm formatting a flash drive with a percentage allocated
|
||||
# to LUKS. interactive_prepare_thumb_drive() uses this; during OEM reset it is
|
||||
# used separately before performing any reset actions
|
||||
#
|
||||
# parameters:
|
||||
# $1 - block device of flash drive
|
||||
# $2 - percent of device allocated to LUKS [1-99]
|
||||
confirm_thumb_drive_format()
|
||||
{
|
||||
TRACE "Under /etc/luks-functions:confirm_thumb_drive_format()"
|
||||
local DEVICE LUKS_PERCENTAGE DISK_SIZE_BYTES DISK_SIZE_DISPLAY LUKS_PERCENTAGE LUKS_SIZE_MB MSG
|
||||
|
||||
DEVICE="$1"
|
||||
LUKS_PERCENTAGE="$2"
|
||||
|
||||
LUKS_SIZE_MB=
|
||||
|
||||
#Get disk size in bytes
|
||||
DISK_SIZE_BYTES="$(blockdev --getsize64 "$DEVICE")"
|
||||
DISK_SIZE_DISPLAY="$(display_size "$DISK_SIZE_BYTES")"
|
||||
#Convert disk size to MB
|
||||
DISK_SIZE_MB=$((DISK_SIZE_BYTES/1024/1024))
|
||||
#Get size in bytes from percentage and apply percentage to DISK_SIZE_MB
|
||||
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
|
||||
#Calculate percentage of device in MB
|
||||
LUKS_SIZE_MB="$((DISK_SIZE_BYTES*LUKS_PERCENTAGE/100/1024/1024))"
|
||||
|
||||
MSG="WARNING: Wiping and repartitioning $DEVICE ($DISK_SIZE_DISPLAY) with $LUKS_SIZE_MB MB\n assigned to private LUKS ext4 partition,\n rest assigned to exFAT public partition.\n\nAre you sure you want to continue?"
|
||||
if [ -x /bin/whiptail ]; then
|
||||
whiptail $BG_COLOR_WARNING --title "WARNING: Wiping and repartitioning $DEVICE of $DISK_SIZE_MB MB" --yesno \
|
||||
"WARNING: Wiping and repartitioning $DEVICE with $PERCENTAGE_MB MB assigned to private LUKS contained private ext4 partition, rest assigned to extfat public partition.\n\nAre you sure you want to continue?" 0 80 \
|
||||
|| die "User cancelled wiping and repartitioning of $DEVICE"
|
||||
whiptail $BG_COLOR_WARNING --title "WARNING: Wiping and repartitioning $DEVICE ($DISK_SIZE_DISPLAY)" --yesno \
|
||||
"$MSG" 0 80
|
||||
else
|
||||
echo -e -n "Warning: Wiping and repartitioning $DEVICE with $PERCENTAGE_MB MB assigned to private LUKS contained private ext4 partition, rest assigned to extfat public partition.\n\nAre you sure you want to continue?"
|
||||
echo -e -n "$MSG"
|
||||
read -r -p " [Y/n] " response
|
||||
#transform response to uppercase with bash parameter expansion
|
||||
response=${response^^}
|
||||
#continue if response different then uppercase N
|
||||
if [[ $response =~ ^(N)$ ]]; then
|
||||
die "User cancelled wiping and repartitioning of $DEVICE"
|
||||
#continue if response is Y, y, or empty, abort for anything else
|
||||
if [ -n "$response" ] && [ "${response^^}" != Y ]; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
echo -e "Preparing $DEVICE with $PERCENTAGE_MB MB for private LUKS container and rest of disk with exfat\
|
||||
\n for public partition (This may take a while)..." | fold -s
|
||||
# Prepare a flash drive with a private LUKS-encrypted ext4 partition and a
|
||||
# public exFAT partition. This is not interactive - during OEM reset, any
|
||||
# selections/confirmations must occur before OEM reset starts resetting the
|
||||
# system.
|
||||
#
|
||||
# $1 - block device of flash drive
|
||||
# $2 - percentage of flash drive to allocate to LUKS [1-99]
|
||||
# $3 - passphrase for LUKS container
|
||||
prepare_thumb_drive()
|
||||
{
|
||||
TRACE "Under /etc/luks-functions:prepare_thumb_drive()"
|
||||
|
||||
local DEVICE PERCENTAGE PASSPHRASE DISK_SIZE_BYTES PERCENTAGE_MB
|
||||
DEVICE="$1"
|
||||
PERCENTAGE="$2"
|
||||
PASSPHRASE="$3"
|
||||
|
||||
#Get disk size in bytes
|
||||
DISK_SIZE_BYTES="$(blockdev --getsize64 "$DEVICE")"
|
||||
#Calculate percentage of device in MB
|
||||
PERCENTAGE_MB="$((DISK_SIZE_BYTES*PERCENTAGE/100/1024/1024))"
|
||||
|
||||
echo -e "Preparing $DEVICE with $PERCENTAGE_MB MB for private LUKS container while rest of device will be assigned to exFAT public partition...\n"
|
||||
echo "Please wait..."
|
||||
DEBUG "Creating empty DOS partition table on device through fdisk to start clean"
|
||||
echo -e "o\nw\n" | fdisk $DEVICE > /dev/null 2>&1 || die "Error creating partition table"
|
||||
echo -e "o\nw\n" | fdisk $DEVICE >/dev/null 2>&1 || die "Error creating partition table"
|
||||
DEBUG "partition device with two partitions: first one being the percent applied and rest for second partition through fdisk"
|
||||
echo -e "n\np\n1\n\n+"$PERCENTAGE_MB"M\nn\np\n2\n\n\nw\n" | fdisk $DEVICE > /dev/null 2>&1 || die "Error partitioning device"
|
||||
DEBUG "cryptsetup luksFormat first partition with LUKS container aes-xts-plain64 cipher with sha256 hash and 512 bit key"
|
||||
echo -e "n\np\n1\n\n+"$PERCENTAGE_MB"M\nn\np\n2\n\n\nw\n" | fdisk $DEVICE >/dev/null 2>&1 || die "Error partitioning device"
|
||||
DEBUG "cryptsetup luksFormat first partition with LUKS container aes-xts-plain64 cipher with sha256 hash and 512 bit key"
|
||||
DEBUG "Creating ${PERCENTAGE_MB}MB LUKS container on ${DEVICE}1..."
|
||||
DO_WITH_DEBUG cryptsetup --batch-mode -c aes-xts-plain64 -h sha256 -s 512 -y luksFormat ${DEVICE}1 \
|
||||
--key-file <(echo -n "${PASSPHRASE}") > /dev/null 2>&1 \
|
||||
@ -216,11 +257,11 @@ prepare_thumb_drive()
|
||||
DO_WITH_DEBUG cryptsetup open ${DEVICE}1 private --key-file <(echo -n "${PASSPHRASE}") > /dev/null 2>&1 \
|
||||
|| die "Error opening LUKS container"
|
||||
DEBUG "Formatting LUKS container mapped under /dev/mapper/private as an ext4 partition..."
|
||||
mke2fs -t ext4 -L private /dev/mapper/private > /dev/null 2>&1 || die "Error formatting LUKS container's ext4 filesystem"
|
||||
mke2fs -t ext4 -L private /dev/mapper/private >/dev/null 2>&1 || die "Error formatting LUKS container's ext4 filesystem"
|
||||
DEBUG "Closing LUKS device /dev/mapper/private..."
|
||||
cryptsetup close private > /dev/null 2>&1 || die "Error closing LUKS container"
|
||||
DEBUG "Formatting second partition ${DEVICE}2 with exfat filesystem..."
|
||||
mkfs.exfat -L public ${DEVICE}2 > /dev/null 2>&1 || die "Error formatting second partition with exfat filesystem"
|
||||
mkfs.exfat -L public ${DEVICE}2 >/dev/null 2>&1 || die "Error formatting second partition with exfat filesystem"
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
@ -242,11 +283,11 @@ select_luks_container()
|
||||
LUKS=$FILE
|
||||
detect_boot_device
|
||||
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
|
||||
fi
|
||||
else
|
||||
warn "No encrypted device found."
|
||||
warn "No encrypted device found"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
@ -255,17 +296,17 @@ select_luks_container()
|
||||
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
|
||||
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
|
||||
#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 (Configured at OS installation or by OEM):"
|
||||
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..."
|
||||
cryptsetup open $LUKS test --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase
|
||||
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..."
|
||||
cryptsetup open $LUKS test --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase
|
||||
fi
|
||||
@ -273,10 +314,10 @@ test_luks_current_disk_recovery_key_passphrase()
|
||||
if [ $? -eq 0 ]; then
|
||||
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
|
||||
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
|
||||
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
|
||||
detect_boot_device
|
||||
mount -o remount,rw /boot
|
||||
@ -285,7 +326,7 @@ test_luks_current_disk_recovery_key_passphrase()
|
||||
else
|
||||
#LuksOpen test was successful. Cleanup should be called only when done
|
||||
#Exporting successfully used passphrase possibly reused by oem-factory-reset
|
||||
|
||||
|
||||
#We close the volume
|
||||
cryptsetup close test
|
||||
export luks_current_Disk_Recovery_Key_passphrase
|
||||
@ -294,108 +335,108 @@ test_luks_current_disk_recovery_key_passphrase()
|
||||
done
|
||||
}
|
||||
|
||||
luks_reencrypt(){
|
||||
TRACE "Under /etc/luks-functions:luks_reencrypt()"
|
||||
while : ; do
|
||||
select_luks_container || return 1
|
||||
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
|
||||
#if no external provisioning provides current Disk Recovery Key passphrase
|
||||
whiptail --title 'Reencrypt LUKS disk encrypted container ?' \
|
||||
luks_reencrypt() {
|
||||
TRACE "Under /etc/luks-functions:luks_reencrypt()"
|
||||
while :; do
|
||||
select_luks_container || return 1
|
||||
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
|
||||
#if no external provisioning provides current Disk Recovery Key passphrase
|
||||
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
|
||||
echo -e "\nEnter current Disk Recovery Key passphrase (Provisioned at OS installation or by OEM):"
|
||||
read -r 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..."
|
||||
cryptsetup-reencrypt -B 64 --use-directio "$LUKS" --key-slot 0 --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase
|
||||
else
|
||||
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..."
|
||||
cryptsetup-reencrypt -B 64 --use-directio "$LUKS" --key-slot 0 --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase
|
||||
fi
|
||||
#Validate past cryptsetup-reencrypt attempts
|
||||
if [ $(echo $?) -ne 0 ]; then
|
||||
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
|
||||
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
|
||||
unset luks_current_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
|
||||
#Reencryption was successful. Cleanup should be called only when done
|
||||
#Exporting successfully used passphrase possibly reused by oem-factory-reset
|
||||
export luks_current_Disk_Recovery_Key_passphrase
|
||||
echo -e "\nEnter current Disk Recovery Key passphrase (Configured at OS installation or by OEM):"
|
||||
read -r luks_current_Disk_Recovery_Key_passphrase
|
||||
echo -n "$luks_current_Disk_Recovery_Key_passphrase" >/tmp/luks_current_Disk_Recovery_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
|
||||
else
|
||||
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..."
|
||||
cryptsetup-reencrypt -B 64 --use-directio "$LUKS" --key-slot 0 --key-file /tmp/luks_current_Disk_Recovery_Key_passphrase
|
||||
fi
|
||||
#Validate past cryptsetup-reencrypt attempts
|
||||
if [ $(echo $?) -ne 0 ]; then
|
||||
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
|
||||
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
|
||||
unset luks_current_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
|
||||
#Reencryption was successful. Cleanup should be called only when done
|
||||
#Exporting successfully used passphrase possibly reused by oem-factory-reset
|
||||
export luks_current_Disk_Recovery_Key_passphrase
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
luks_change_passphrase()
|
||||
{
|
||||
TRACE "Under /etc/luks-functions:luks_change_passphrase()"
|
||||
while : ; do
|
||||
select_luks_container || return 1
|
||||
#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
|
||||
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
|
||||
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):"
|
||||
while [[ ${#luks_new_Disk_Recovery_Key_passphrase} -lt 8 ]]; do
|
||||
{
|
||||
read -r luks_new_Disk_Recovery_Key_passphrase
|
||||
while :; do
|
||||
select_luks_container || return 1
|
||||
#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
|
||||
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
|
||||
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):"
|
||||
while [[ ${#luks_new_Disk_Recovery_Key_passphrase} -lt 8 ]]; do
|
||||
{
|
||||
read -r luks_new_Disk_Recovery_Key_passphrase
|
||||
};done
|
||||
fi
|
||||
if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then
|
||||
echo -e "\nEnter current Disk Recovery Key passphrase (Configured 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
|
||||
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
|
||||
|
||||
#Validate past cryptsetup attempts
|
||||
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
|
||||
|
||||
#Validate past cryptsetup attempts
|
||||
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;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
luks_secrets_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_current_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
|
||||
unset luks_current_Disk_Recovery_Key_passphrase
|
||||
unset luks_new_Disk_Recovery_Key_passphrase
|
||||
}
|
||||
|
13
initrd/init
13
initrd/init
@ -60,6 +60,14 @@ if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then
|
||||
#DEBUG and TRACE calls will output to /dev/kmsg, outputting both on dmesg and on console
|
||||
dmesg -n 8 || true
|
||||
DEBUG "Debug output enabled from board CONFIG_DEBUG_OUTPUT=y option (/etc/config)"
|
||||
else
|
||||
# Board config did't have CONFIG_DEBUG_OUTPUT=y defined
|
||||
# config.user extracted and combined from CBFS had CONFIG_DEBUG_OUTPUT=y
|
||||
# Output only print messages with a priority of 4 (warnings) or lower (errors and critical) kernel messages to console
|
||||
# This way, "debug" kernel command line option will have all kernel messages output on console prior of this point
|
||||
# This is useful to debug boot issues but permits qemu board to boot without flooding console with kernel messages by disabling CONFIG_DEBUG_OUTPUT=y in qemu board config
|
||||
dmesg -n 4 || true
|
||||
DEBUG "Debug output enabled from /etc/config.user's CONFIG_DEBUG_OUTPUT=y after combine_configs (Config menu enabled Debug)"
|
||||
fi
|
||||
|
||||
TRACE "Under init"
|
||||
@ -160,6 +168,11 @@ if [ "$boot_option" = "r" ]; then
|
||||
recovery 'User requested recovery shell'
|
||||
# just in case...
|
||||
exit
|
||||
elif [ "$boot_option" = "o" ]; then
|
||||
# Launch OEM Factory Reset/Re-Ownership
|
||||
oem-factory-reset
|
||||
# just in case...
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "$CONFIG_BASIC" = "y" ]; then
|
||||
|
@ -30,16 +30,16 @@ if [ ! -r /sys/class/tpm/tpm0/pcrs -o ! -x /bin/tpm ]; then
|
||||
fi
|
||||
|
||||
if [ -z "$tpm_missing" ]; then
|
||||
DEBUG "Extending PCR $MODULE_PCR with $MODULE"
|
||||
DEBUG "Extending TPM PCR $MODULE_PCR with $MODULE prior of usage"
|
||||
tpmr extend -ix "$MODULE_PCR" -if "$MODULE" \
|
||||
|| die "$MODULE: tpm extend failed"
|
||||
fi
|
||||
|
||||
if [ ! -z "$*" -a -z "$tpm_missing" ]; then
|
||||
DEBUG "Extending PCR $MODULE_PCR with $*"
|
||||
DEBUG "Extending TPM PCR $MODULE_PCR with $*"
|
||||
TMPFILE=/tmp/insmod.$$
|
||||
echo "$@" > $TMPFILE
|
||||
DEBUG "Extending PCR $MODULE_PCR with $TMPFILE"
|
||||
DEBUG "Extending TPM PCR $MODULE_PCR with $MODULE prior of usage"
|
||||
tpmr extend -ix "$MODULE_PCR" -if $TMPFILE \
|
||||
|| die "$MODULE: tpm extend on arguments failed"
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user