From b1e5c638cdd824718415b211b22caaf5fbe8ab3a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 18 Oct 2023 13:15:48 -0400 Subject: [PATCH 01/69] WiP Signed-off-by: Thierry Laurion --- .../qemu-coreboot-whiptail-tpm1.config | 5 +- initrd/bin/media-scan | 3 + initrd/bin/oem-factory-reset | 1055 +++++++++++------ initrd/etc/ash_functions | 48 + initrd/etc/functions | 56 +- initrd/etc/luks-functions | 230 ++-- 6 files changed, 917 insertions(+), 480 deletions(-) diff --git a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config index eb4d75af..25de9fbb 100644 --- a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config +++ b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config @@ -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 diff --git a/initrd/bin/media-scan b/initrd/bin/media-scan index 4a23a934..bc416c21 100755 --- a/initrd/bin/media-scan +++ b/initrd/bin/media-scan @@ -7,6 +7,9 @@ set -e -o pipefail TRACE "Under /bin/media-scan" +#Booting from external media should be authenticated if supported +gpg_auth + # Unmount any previous boot device if grep -q /boot /proc/mounts ; then umount /boot \ diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 73158347..18ae18ad 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -35,11 +35,12 @@ MAX_HOTP_GPG_PIN_LENGTH=25 # What are the Security components affected by custom passwords CUSTOM_PASS_AFFECTED_COMPONENTS="" -RSA_KEY_LENGTH=3072 +# Default RSA key length +#TODO change it back to 3076. Canokey cannot be tested easily and Nitrokey prov1 I have doesn't key-attr to 3076 +RSA_KEY_LENGTH=2048 -GPG_ALGO="rsa" GPG_USER_NAME="OEM Key" -GPG_KEY_NAME=`date +%Y%m%d%H%M%S` +GPG_KEY_NAME=$(date +%Y%m%d%H%M%S) GPG_USER_MAIL="oem-${GPG_KEY_NAME}@example.com" GPG_USER_COMMENT="OEM-generated key" SKIP_BOOT="n" @@ -48,16 +49,15 @@ SKIP_BOOT="n" die() { - local msg=$1 - if [ -n "$msg" ]; then - echo -e "\n$msg" - fi - kill -s TERM $TOP_PID - exit 1 + local msg=$1 + if [ -n "$msg" ]; then + echo -e "\n$msg" + fi + kill -s TERM $TOP_PID + exit 1 } -whiptail_error() -{ +whiptail_error() { local msg=$1 if [ "$msg" = "" ]; then die "whiptail error: An error msg is required" @@ -65,86 +65,377 @@ whiptail_error() whiptail $BG_COLOR_ERROR --msgbox "${msg}\n\n" $HEIGHT $WIDTH $BG_COLOR_ERROR --title "Error" } -whiptail_error_die() -{ +whiptail_error_die() { whiptail_error "$@" die } -gpg_key_reset() -{ +#Generate a gpg master key: passwordless, no expiration date, RSA 4096 bits +#This key will be used to sign 3 subkeys: encryption, authentication and signing +#The master key will be stored on the disk, and the subkeys on the smartcard +generate_inmemory_RSA_master_and_subkeys() { + TRACE "Under oem-factory-reset:generate_inmemory_RSA_master_and_subkeys" + echo "Generating GPG key material in memory:" + + echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits master key..." + # Generate GPG master key + { + echo "Key-Type: RSA" + echo "Key-Length: ${RSA_KEY_LENGTH}" + echo "Key-Usage: sign" + echo "Name-Real: ${GPG_USER_NAME}" + echo "Name-Comment: ${GPG_USER_COMMENT}" + echo "Name-Email: ${GPG_USER_MAIL}" + echo "Expire-Date: 0" + echo "Passphrase: ${ADMIN_PIN}" + echo "%commit" + } | gpg --batch --gen-key \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key generation failed!\n\n$ERROR" + fi + + echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits signing subkey..." + # Add signing subkey + { + echo addkey + echo 4 # RSA (sign only) + echo ${RSA_KEY_LENGTH} + echo 0 # no expiration + echo ${ADMIN_PIN} + echo y # confirm + echo save + } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key signing subkey generation failed!\n\n$ERROR" + fi + + echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits encryption subkey..." + #Add encryption subkey + { + echo addkey + echo 6 # RSA (encrypt only) + echo ${RSA_KEY_LENGTH} + echo 0 # no expiration + echo ${ADMIN_PIN} + echo y # confirm + echo save + } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key encryption subkey generation failed!\n\n$ERROR" + fi + + echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits authentication subkey..." + #Add authentication subkey + { + #Authentication subkey needs gpg in expert mode to select RSA custom mode (8) + # in order to disable encryption and signing capabilities of subkey + # and then enable authentication capability + echo addkey + echo 8 # RSA (own capabilite) + echo S # disable signing capability + echo E # disable encryption capability + echo A # enable authentication capability + echo Q # quit + echo ${RSA_KEY_LENGTH} + echo 0 # no expiration + echo ${ADMIN_PIN} + echo y # confirm + echo save + } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --expert --edit-key "${GPG_USER_MAIL}" \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key authentication subkey generation failed!\n\n$ERROR" + fi + + DEBUG "Setting public key to ultimate trust..." + #Set the public key to the ultimate trust + { + echo trust + echo 5 # ultimate + echo y # confirm + echo save + } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key setting public key to ultimate trust failed!\n\n$ERROR" + fi +} + +#Function to move current gpg keyring subkeys to card (keytocard) +# This is aimed to be used after having generated master key and subkeys in memory and having backuped them to a LUKS container +# This function will keytocard the subkeys from the master key in the keyring +# The master key will be kept in the keyring +# The master key was already used to sign the subkeys, so it is not needed anymore +# Delete the master key from the keyring once key to card is done (already backuped on LUKS private partition) +keytocard_subkeys_to_smartcard() { + TRACE "Under oem-factory-reset:keytocard_subkeys_to_smartcard" + + #make sure usb ready and usb dongle ready to communicate with + enable_usb + enable_usb_storage + gpg --card-status >/dev/null 2>&1 || die "Error getting GPG card status" + + DEBUG "Factory resetting the smartcard..." + gpg_key_factory_reset + + DEBUG "Moving subkeys to smartcard..." + + #keytocard all subkeys + { + echo "key 1" #Select Signature key + echo "keytocard" + echo "1" # Signature key + echo "$ADMIN_PIN" #Smartcard admin pin + echo "$ADMIN_PIN" #Subkey PIN + echo "0" #No expiration date + echo "key 1" + echo "key 2" + echo "keytocard" + echo "2" # Encryption key + echo "$ADMIN_PIN" + echo "$ADMIN_PIN" + echo "key 2" + echo "key 3" + echo "keytocard" + echo "3" # Authentication key + echo "$ADMIN_PIN" + echo "$ADMIN_PIN" + echo "key 3" + echo "save" + } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --expert --edit-key "${GPG_USER_MAIL}" \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key moving subkeys to smartcard failed!\n\n$ERROR" + fi + DEBUG "Moving subkeys to smartcard done." +} + +#Whiptail prompt to disconnect any external USB storage device +prompt_disconnect_external_USB_storage_device() { + TRACE "Under oem-factory-reset:disconnect_external_USB_storage_device" + #Whiptail $BG_COLOR_WARNING warning about removing any external USB storage device currently connected + whiptail $BG_COLOR_WARNING --title 'WARNING: Please disconnect any external USB storage device' \ + --msgbox "An external USB storage device will be WIPED next.\n\nPlease disconnect all external USB storage devices." 0 80 || + die "Error displaying warning about removing any external USB storage device currently connected" + +} + +#Whiptail prompt to insert to be wiped thumb drive +prompt_insert_to_be_wiped_thumb_drive() { + TRACE "Under oem-factory-reset:prompt_insert_to_be_wiped_thumb_drive" + #Whiptail warning about having only desired to be wiped thumb drive inserted + whiptail $BG_COLOR_WARNING --title 'WARNING: Please insert the thumb drive to be wiped' \ + --msgbox "The thumb drive will be WIPED next.\n\nPlease have connected only the thumb drive to be wiped." 0 80 || + die "Error displaying warning about having only desired to be wiped thumb drive inserted" +} + +#list blkid devices (removing partition numbers) +list_blkid_devices() { + TRACE "Under oem-factory-reset:list_blkid_devices" + blkid | cut -d: -f1 | sed 's/[0-9]$//' +} + +#export master key and subkeys to thumbdrive's private LUKS contained partition +export_master_key_subkeys_and_revocation_key_to_private_LUKS_container() { + TRACE "Under oem-factory-reset:export_master_key_subkeys_and_revocation_key_to_private_LUKS_container" + + #Sanity check on passed arguments + while [ $# -gt 0 ]; do + case "$1" in + --mode) + mode="$2" + shift + shift + ;; + --device) + device="$2" + shift + shift + ;; + --mountpoint) + mountpoint="$2" + shift + shift + ;; + --pass) + pass="$2" + shift + shift + ;; + *) + die "Error: unknown argument: $1" + ;; + esac + done + + mount-usb --mode "$mode" --device "$device" --mountpoint "$mountpoint" --pass "$pass" || die "Error mounting thumb drive's private partition" + + #Export master key and subkeys to thumb drive + DEBUG "Exporting master key and subkeys to private LUKS container's partition..." + gpg --export-secret-key --armor --pinentry-mode loopback --passphrase-file <(echo -n "${pass}") "${GPG_USER_MAIL}" >"$mountpoint"/privkey.sec || + die "Error exporting master key to private LUKS container's partition" + gpg --export-secret-subkeys --armor --pinentry-mode loopback --passphrase-file <(echo -n "${pass}") "${GPG_USER_MAIL}" >"$mountpoint"/subkeys.sec || + die "Error exporting subkeys to private LUKS container's partition" + #copy whole keyring to thumb drive, including revocation key and trust database + cp -af ~/.gnupg "$mountpoint"/.gnupg || die "Error copying whole keyring to private LUKS container's partition" + #Unmount private LUKS container's mount point + umount "$mountpoint" || die "Error unmounting private LUKS container's mount point" +} + +#Export public key to thumb drive's public partition +export_public_key_to_thumbdrive_public_partition() { + TRACE "Under oem-factory-reset:export_public_key_to_thumbdrive_public_partition" + + #Sanity check on passed arguments + while [ $# -gt 0 ]; do + case "$1" in + --mode) + mode="$2" + shift + shift + ;; + --device) + device="$2" + shift + shift + ;; + --mountpoint) + mountpoint="$2" + shift + shift + ;; + *) + die "Error: unknown argument: $1" + ;; + esac + done + + #pass non-empty arguments to --pass, --mountpoint, --device, --mode + mount-usb --device "$device" --mode "$mode" --mountpoint "$mountpoint" || die "Error mounting thumb drive's public partition" + + gpg --export --armor "${GPG_USER_MAIL}" >"$mountpoint"/pubkey.asc || die "Error exporting public key to thumb drive's public partition" + + umount "$mountpoint" || die "Error unmounting thumb drive's public partition" +} + +#Wipe a thumb drive and export master key and subkeys to it +wipe_thumb_drive_and_copy_gpg_key_material() { + TRACE "Under oem-factory-reset:wipe_thumb_drive_and_copy_gpg_key_material" + prompt_disconnect_external_USB_storage_device + actual_devices=$(list_blkid_devices) + #enable usb storage + enable_usb + enable_usb_storage + prompt_insert_to_be_wiped_thumb_drive + new_devices=$(list_blkid_devices) + thumb_drive=$(echo "$new_devices" | grep -v "$actual_devices" | uniq) + if [ -z "$thumb_drive" ]; then + whiptail_error_die "No new thumb drive detected! Aborting." + fi + select_luks_container_size_percent + #Wipe thumb drive with a LUKS container of size $(cat /tmp/luks_container_size_percent) + prepare_thumb_drive --device "$thumb_drive" --percentage "$(cat /tmp/luks_container_size_percent)" --pass "$ADMIN_PIN" + #Export master key and subkeys to thumb drive first partition + export_master_key_subkeys_and_revocation_key_to_private_LUKS_container --mode rw --device "$thumb_drive"1 --mountpoint /media --pass "$ADMIN_PIN" + #Export public key to thumb drive's public partition + export_public_key_to_thumbdrive_public_partition --mode rw --device "$thumb_drive"2 --mountpoint /media +} + +gpg_key_factory_reset() { + TRACE "Under oem-factory-reset:gpg_key_factory_reset" + + #enable usb storage + enable_usb + # Factory reset GPG card + DEBUG "GPG factory reset..." { echo admin echo factory-reset echo y echo yes } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ - > /tmp/gpg_card_edit_output 2>&1 + >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then - ERROR=`cat /tmp/gpg_card_edit_output` + ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key factory reset failed!\n\n$ERROR" fi # If Nitrokey Storage is inserted, reset AES keys as well - if lsusb | grep -q "20a0:4109" && [ -x /bin/hotp_verification ] ; then + if lsusb | grep -q "20a0:4109" && [ -x /bin/hotp_verification ]; then /bin/hotp_verification regenerate ${ADMIN_PIN_DEF} fi # Toggle forced sig (good security practice, forcing PIN request for each signature request) if gpg --card-status | grep "Signature PIN" | grep -q "not forced"; then + DEBUG "GPG toggling forcesig on since off..." { echo admin echo forcesig echo ${ADMIN_PIN_DEF} } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ - > /tmp/gpg_card_edit_output 2>&1 + >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then - ERROR=`cat /tmp/gpg_card_edit_output` + ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key forcesig toggle on failed!\n\n$ERROR" fi fi # use p256 for key generation if requested - if [ "$GPG_ALGO" = "p256" ];then - { - echo admin - echo key-attr - echo 2 # ECC - echo 3 # P-256 - echo ${ADMIN_PIN_DEF} - echo 2 # ECC - echo 3 # P-256 - echo ${ADMIN_PIN_DEF} - echo 2 # ECC - echo 3 # P-256 - echo ${ADMIN_PIN_DEF} - } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit --expert \ - > /tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=`cat /tmp/gpg_card_edit_output` - whiptail_error_die "Setting key to NIST-P256 in USB security dongle failed." - fi + if [ "$GPG_ALGO" = "p256" ]; then + { + echo admin + echo key-attr + echo 2 # ECC + echo 3 # P-256 + echo ${ADMIN_PIN_DEF} + echo 2 # ECC + echo 3 # P-256 + echo ${ADMIN_PIN_DEF} + echo 2 # ECC + echo 3 # P-256 + echo ${ADMIN_PIN_DEF} + } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit --expert \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "Setting key to NIST-P256 in USB security dongle failed." + fi # fallback to RSA key generation by default else - # Set RSA key length - { - echo admin - echo key-attr - echo 1 # RSA - echo ${RSA_KEY_LENGTH} #Signing key size set to RSA_KEY_LENGTH - echo ${ADMIN_PIN_DEF} - echo 1 # RSA - echo ${RSA_KEY_LENGTH} #Encryption key size set to RSA_KEY_LENGTH - echo ${ADMIN_PIN_DEF} - echo 1 # RSA - echo ${RSA_KEY_LENGTH} #Authentication key size set to RSA_KEY_LENGTH - echo ${ADMIN_PIN_DEF} - } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ - > /tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=`cat /tmp/gpg_card_edit_output` - whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB security dongle failed." - fi + DEBUG "GPG setting RSA key length to ${RSA_KEY_LENGTH} bits..." + # Set RSA key length + { + echo admin + echo key-attr + echo 1 # RSA + echo ${RSA_KEY_LENGTH} #Signing key size set to RSA_KEY_LENGTH + echo ${ADMIN_PIN_DEF} + echo 1 # RSA + echo ${RSA_KEY_LENGTH} #Encryption key size set to RSA_KEY_LENGTH + echo ${ADMIN_PIN_DEF} + echo 1 # RSA + echo ${RSA_KEY_LENGTH} #Authentication key size set to RSA_KEY_LENGTH + echo ${ADMIN_PIN_DEF} + } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB security dongle failed." + fi fi +} + +generate_OEM_gpg_keys() { # Generate OEM GPG keys + TRACE "Under oem-factory-reset:generate_OEM_gpg_keys" + DEBUG "Generating GPG keys to RSA ${RSA_KEY_LENGTH} bits in smartcard..." { echo admin echo generate @@ -157,15 +448,16 @@ gpg_key_reset() echo ${GPG_USER_COMMENT} echo ${USER_PIN_DEF} } | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ - > /tmp/gpg_card_edit_output 2>&1 + >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then - ERROR=`cat /tmp/gpg_card_edit_output` + ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR" fi } -gpg_key_change_pin() -{ +gpg_key_change_pin() { + TRACE "Under oem-factory-reset:gpg_key_change_pin" + DEBUG "Changing GPG key PINs..." # 1 = user PIN, 3 = admin PIN PIN_TYPE=$1 PIN_ORIG=$2 @@ -181,17 +473,17 @@ gpg_key_change_pin() echo q echo q } | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ - > /tmp/gpg_card_edit_output 2>&1 + >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then - ERROR=`cat /tmp/gpg_card_edit_output | fold -s` + ERROR=$(cat /tmp/gpg_card_edit_output | fold -s) whiptail_error_die "GPG Key PIN change failed!\n\n$ERROR" fi } -generate_checksums() -{ +generate_checksums() { + TRACE "Under oem-factory-reset:generate_checksums" # ensure /boot mounted - if ! grep -q /boot /proc/mounts ; then + if ! grep -q /boot /proc/mounts; then mount -o rw /boot || whiptail_error_die "Unable to mount /boot" else mount -o remount,rw /boot || whiptail_error_die "Unable to mount /boot" @@ -206,27 +498,27 @@ generate_checksums() rm /boot/kexec* 2>/dev/null # create Heads TPM counter - if [ "$CONFIG_TPM" = "y" ];then - if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then - tpmr counter_create \ - -pwdo "$TPM_PASS" \ - -pwdc '' \ - -la -3135106223 \ - | tee /tmp/counter \ - || whiptail_error_die "Unable to create TPM counter" - TPM_COUNTER=`cut -d: -f1 < /tmp/counter` + if [ "$CONFIG_TPM" = "y" ]; then + if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then + tpmr counter_create \ + -pwdo "$TPM_PASS" \ + -pwdc '' \ + -la -3135106223 | + tee /tmp/counter || + whiptail_error_die "Unable to create TPM counter" + TPM_COUNTER=$(cut -d: -f1 /dev/null 2>&1 \ - || whiptail_error_die "Unable to increment tpm counter" + # increment TPM counter + increment_tpm_counter $TPM_COUNTER >/dev/null 2>&1 || + whiptail_error_die "Unable to increment tpm counter" - # create rollback file - sha256sum /tmp/counter-$TPM_COUNTER > /boot/kexec_rollback.txt 2>/dev/null \ - || whiptail_error_die "Unable to create rollback file" - else - ## needs to exist for initial call to unseal-hotp - echo "0" > /boot/kexec_hotp_counter - fi + # create rollback file + sha256sum /tmp/counter-$TPM_COUNTER >/boot/kexec_rollback.txt 2>/dev/null || + whiptail_error_die "Unable to create rollback file" + else + ## needs to exist for initial call to unseal-hotp + echo "0" >/boot/kexec_hotp_counter + fi fi # set default boot option only if no TPM Disk Unlock Key previously set @@ -238,26 +530,26 @@ generate_checksums() ( set -e -o pipefail cd /boot - find ./ -type f ! -path './kexec*' -print0 \ - | xargs -0 sha256sum > /boot/kexec_hashes.txt 2>/dev/null - print_tree > /boot/kexec_tree.txt + find ./ -type f ! -path './kexec*' -print0 | + xargs -0 sha256sum >/boot/kexec_hashes.txt 2>/dev/null + print_tree >/boot/kexec_tree.txt ) [ $? -eq 0 ] || whiptail_error_die "Error generating kexec hashes" - param_files=`find /boot/kexec*.txt` - [ -z "$param_files" ] \ - && whiptail_error_die "No kexec parameter files to sign" + param_files=$(find /boot/kexec*.txt) + [ -z "$param_files" ] && + whiptail_error_die "No kexec parameter files to sign" # sign kexec boot files if sha256sum $param_files 2>/dev/null | gpg \ - --pinentry-mode loopback \ - --passphrase "$USER_PIN" \ - --digest-algo SHA256 \ - --detach-sign \ - -a \ - > /boot/kexec.sig 2>/tmp/error; then + --pinentry-mode loopback \ + --passphrase "$USER_PIN" \ + --digest-algo SHA256 \ + --detach-sign \ + -a \ + >/boot/kexec.sig 2>/tmp/error; then # successful - update the validated params - if ! check_config /boot >/dev/null 2>/tmp/error ; then + if ! check_config /boot >/dev/null 2>/tmp/error; then cat /tmp/error ret=1 else @@ -271,14 +563,14 @@ generate_checksums() # done writing to /boot, switch back to RO mount -o ro,remount /boot - if [ $ret = 1 ] ; then + if [ $ret = 1 ]; then ERROR=$(tail -n 1 /tmp/error | fold -s) whiptail_error_die "Error signing kexec boot files:\n\n$ERROR" fi } -set_default_boot_option() -{ +set_default_boot_option() { + TRACE "Under oem-factory-reset:set_default_boot_option" option_file="/tmp/kexec_options.txt" tmp_menu_file="/tmp/kexec/kexec_menu.txt" hash_file="/boot/kexec_default_hashes.txt" @@ -286,25 +578,25 @@ set_default_boot_option() mkdir -p /tmp/kexec/ rm $option_file 2>/dev/null # parse boot options from grub.cfg - for i in `find /boot -name "grub.cfg"`; do - kexec-parse-boot "/boot" "$i" >> $option_file + for i in $(find /boot -name "grub.cfg"); do + kexec-parse-boot "/boot" "$i" >>$option_file done # FC29/30+ may use BLS format grub config files # https://fedoraproject.org/wiki/Changes/BootLoaderSpecByDefault # only parse these if $option_file is still empty if [ ! -s $option_file ] && [ -d "/boot/loader/entries" ]; then - for i in `find /boot -name "grub.cfg"`; do - kexec-parse-bls "/boot" "$i" "/boot/loader/entries" >> $option_file - done + for i in $(find /boot -name "grub.cfg"); do + kexec-parse-bls "/boot" "$i" "/boot/loader/entries" >>$option_file + done fi - [ ! -s $option_file ] \ - && whiptail_error_die "Failed to parse any boot options" + [ ! -s $option_file ] && + whiptail_error_die "Failed to parse any boot options" # sort boot options - sort -r $option_file | uniq > $tmp_menu_file + sort -r $option_file | uniq >$tmp_menu_file ## save first option as default - entry=`head -n 1 $tmp_menu_file | tail -1` + entry=$(head -n 1 $tmp_menu_file | tail -1) # clear existing default configs rm "/boot/kexec_default.*.txt" 2>/dev/null @@ -313,73 +605,72 @@ set_default_boot_option() index=$(grep -n "$entry" $option_file | cut -f1 -d ':') # write new config - echo "$entry" > /boot/kexec_default.$index.txt + echo "$entry" >/boot/kexec_default.$index.txt # validate boot option - ( cd /boot && /bin/kexec-boot -b "/boot" -e "$entry" -f \ - | xargs sha256sum > $hash_file 2>/dev/null ) \ - || whiptail_error_die "Failed to create hashes of boot files" + (cd /boot && /bin/kexec-boot -b "/boot" -e "$entry" -f | + xargs sha256sum >$hash_file 2>/dev/null) || + whiptail_error_die "Failed to create hashes of boot files" } -report_integrity_measurements() -{ +report_integrity_measurements() { + TRACE "Under oem-factory-reset:report_integrity_measurements" #check for GPG key in keyring - GPG_KEY_COUNT=`gpg -k 2>/dev/null | wc -l` - if [ $GPG_KEY_COUNT -ne 0 ]; then + GPG_KEY_COUNT=$(gpg -k 2>/dev/null | wc -l) + if [ "$GPG_KEY_COUNT" -ne 0 ]; then # Check and report TOTP # update the TOTP code every thirty seconds - date=`date "+%Y-%m-%d %H:%M:%S %Z"` - seconds=`date "+%s"` - half=`expr \( $seconds % 60 \) / 30` + date=$(date "+%Y-%m-%d %H:%M:%S %Z") + seconds=$(date "+%s") + half=$(expr \( "$seconds" % 60 \) / 30) if [ "$CONFIG_TPM" != "y" ]; then TOTP="NO TPM" elif [ "$half" != "$last_half" ]; then - last_half=$half; - TOTP=`unseal-totp` > /dev/null 2>&1 + last_half=$half + TOTP=$(unseal-totp) >/dev/null 2>&1 fi # Check and report on HOTP status if [ -x /bin/hotp_verification ]; then - HOTP=`unseal-hotp` > /dev/null 2>&1 + HOTP=$(unseal-hotp) >/dev/null 2>&1 enable_usb - if ! hotp_verification info > /dev/null 2>&1 ; then + if ! hotp_verification info >/dev/null 2>&1; then whiptail $CONFIG_WARNING_BG_COLOR --title 'WARNING: Please insert your HOTP enabled USB Security dongle' --msgbox "Your HOTP enabled USB Security dongle was not detected.\n\nPlease remove it and insert it again." 0 80 fi # Don't output HOTP codes to screen, so as to make replay attacks harder hotp_verification check $HOTP case "$?" in - 0 ) - HOTP="Success" - ;; - 4 ) - HOTP="Invalid code" - MAIN_MENU_BG_COLOR=$CONFIG_ERROR_BG_COLOR - ;; - * ) - HOTP="Error checking code, Insert USB Security dongle and retry" - MAIN_MENU_BG_COLOR=$CONFIG_WARNING_BG_COLOR - ;; - esac - else - HOTP='N/A' + 0) + HOTP="Success" + ;; + 4) + HOTP="Invalid code" + MAIN_MENU_BG_COLOR=$CONFIG_ERROR_BG_COLOR + ;; + *) + HOTP="Error checking code, Insert USB Security dongle and retry" + MAIN_MENU_BG_COLOR=$CONFIG_WARNING_BG_COLOR + ;; + esac + else + HOTP='N/A' fi # Check for detached signed digest and report on /boot integrity status check_config /boot force TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" - if ( cd /boot && sha256sum -c "$TMP_HASH_FILE" > /tmp/hash_output ); then + if (cd /boot && sha256sum -c "$TMP_HASH_FILE" >/tmp/hash_output); then HASH="OK" - else - HASH="ALTERED" + else + HASH="ALTERED" fi - #Show results - whiptail $MAIN_MENU_BG_COLOR --title "Measured Integrity Report" --msgbox "$date\nTOTP: $TOTP | HOTP: $HOTP\n/BOOT INTEGRITY: $HASH\n\nPress OK to continue or Ctrl+Alt+Delete to reboot" 0 80 + #Show results + whiptail $MAIN_MENU_BG_COLOR --title "Measured Integrity Report" --msgbox "$date\nTOTP: $TOTP | HOTP: $HOTP\n/BOOT INTEGRITY: $HASH\n\nPress OK to continue or Ctrl+Alt+Delete to reboot" 0 80 fi } -usb_security_token_capabilities_check() -{ +usb_security_token_capabilities_check() { TRACE "Under /bin/oem-factory-reset:usb_security_token_capabilities_check" enable_usb @@ -389,10 +680,11 @@ usb_security_token_capabilities_check() DEBUG "Setting GPG_ALGO to (board-)configured: $CONFIG_GPG_ALGO" fi # ... overwrite with usb-token capability - if lsusb | grep -q "20a0:42b2"; then - GPG_ALGO="p256" - DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" - fi + #TODO: revert. Testing test firmware for Nitrokey 3 which is supposed to support RSA 3076 now + #if lsusb | grep -q "20a0:42b2"; then + # GPG_ALGO="p256" + # DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" + #fi } ## main script start @@ -425,7 +717,7 @@ $TPM_STR * Sign all of the files in /boot with the new GPG key\n\n It requires that you already have an OS installed on a\n dedicated /boot partition. Do you wish to continue?" \ - $HEIGHT $WIDTH $CONTINUE $CANCEL $CLEAR $bg_color --title "$title_text" ; then + $HEIGHT $WIDTH $CONTINUE $CANCEL $CLEAR $bg_color --title "$title_text"; then exit 1 fi @@ -437,139 +729,162 @@ usb_security_token_capabilities_check use_defaults=n if [ "$CONFIG_OEMRESET_OFFER_DEFAULTS" = y ]; then - echo -e -n "Would you like to use default configuration options?\nIf N, you will be prompted for each option [Y/n]: " - read -n 1 use_defaults + echo -e -n "Would you like to use default configuration options?\nIf N, you will be prompted for each option [Y/n]: " + read -n 1 use_defaults fi if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then - # Re-ownership of encrypted disk key, content and passphrase - echo -e -n "\n\nWould you like to change the current LUKS Disk Recovery Key passphrase?\n (Highly recommended if you didn't install the Operating System yourself, so that past provisioned passphrase would not permit to access content.\n Note that without re-encrypting disk, a backuped header could be restored to access encrypted content with old passphrase) [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ];then - luks_new_Disk_Recovery_Key_passphrase_desired=1 - echo -e "\n" - fi + #Give general guidance to user on how to answer prompts + echo "The following questionnaire will help you to configure the security components of your system." + echo "You will be prompted for each option to answer a single letter at prompts (Y/n/m)." + echo "If you don't know what to answer, just press Enter to use default value which is shown between [] brackets as the uppercase letter." - echo -e -n "Would you like to re-encrypt LUKS encrypted container and generate new Disk Recovery key?\n (Highly recommended if you didn't install the operating system yourself: this would prevent any LUKS backuped header to be restored to access encrypted data) [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ];then - test_luks_current_disk_recovery_key_passphrase - luks_new_Disk_Recovery_Key_desired=1 - echo -e "\n" - fi + # Re-ownership of encrypted disk key, content and passphrase + echo -e -n "\n\nWould you like to change the current LUKS Disk Recovery Key passphrase?\n (Highly recommended if you didn't install the Operating System yourself, so that past provisioned passphrase would not permit to access content.\n Note that without re-encrypting disk, a backuped header could be restored to access encrypted content with old passphrase) [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ]; then + luks_new_Disk_Recovery_Key_passphrase_desired=1 + echo -e "\n" + fi - # Adapt message to be given to user in terms of security components that will be applied. - if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -o -n "$luks_new_Disk_Recovery_Key_passphrase" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS="LUKS Disk Recovery Key passphrase" - fi - if [ "$CONFIG_TPM" = "y" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS="$CUSTOM_PASS_AFFECTED_COMPONENTS + echo -e -n "Would you like to re-encrypt LUKS encrypted container and generate new Disk Recovery key?\n (Highly recommended if you didn't install the operating system yourself: this would prevent any LUKS backuped header to be restored to access encrypted data) [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ]; then + test_luks_current_disk_recovery_key_passphrase + luks_new_Disk_Recovery_Key_desired=1 + echo -e "\n" + fi + + #Prompt to ask if user wants to generate GPG key material in memory or on smartcard + echo -e -n "Would you like to generate GPG key material in (m)emory or (S)olely on the security element of the USB security dongle? [m/S]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "m" \ + -o "$prompt_output" == "M" ] \ + ; then + GPG_GEN_KEY_IN_MEMORY=1 + #TODO: present steps clearer for user + echo "Master key and subkeys will be generated in memory, backuped to dedicated LUKS container and then subkeys imported to factory resetted smartcard." + else + GPG_GEN_KEY_IN_MEMORY=0 + fi + + # TODO: add LUKS container passphrase = ADMIN_PIN in security components provisioned + # Adapt message to be given to user in terms of security components that will be applied. + if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -o -n "$luks_new_Disk_Recovery_Key_passphrase" ]; then + CUSTOM_PASS_AFFECTED_COMPONENTS="LUKS Disk Recovery Key passphrase" + fi + if [ "$CONFIG_TPM" = "y" ]; then + CUSTOM_PASS_AFFECTED_COMPONENTS="$CUSTOM_PASS_AFFECTED_COMPONENTS TPM Ownership password" - fi - CUSTOM_PASS_AFFECTED_COMPONENTS="$CUSTOM_PASS_AFFECTED_COMPONENTS + fi + CUSTOM_PASS_AFFECTED_COMPONENTS="$CUSTOM_PASS_AFFECTED_COMPONENTS GPG Admin PIN GPG User PIN" - # Inform user of security components affected for the following prompts - echo -e "The following security components will be provisioned with defaults or chosen PINs/passwords: + # Inform user of security components affected for the following prompts + echo -e "The following security components will be provisioned with defaults or chosen PINs/passwords: $CUSTOM_PASS_AFFECTED_COMPONENTS\n" - # Prompt to change default passwords - echo -e -n "Would you like to set a single custom password that will be provisioned to previously stated security components? [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ]; then - echo -e "\nThe chosen custom password must be between 8 and $MAX_HOTP_GPG_PIN_LENGTH characters in length.\n" - echo - while [[ ${#CUSTOM_SINGLE_PASS} -lt 8 ]] || [[ ${#CUSTOM_SINGLE_PASS} -gt $MAX_HOTP_GPG_PIN_LENGTH ]] ; do - echo -e -n "Enter the custom password: " - read CUSTOM_SINGLE_PASS - done - echo - TPM_PASS=$CUSTOM_SINGLE_PASS - USER_PIN=$CUSTOM_SINGLE_PASS - ADMIN_PIN=$CUSTOM_SINGLE_PASS - - # Only set if user said desired. Matches rest of logic - if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - luks_new_Disk_Recovery_Key_passphrase=$CUSTOM_SINGLE_PASS - fi - else - echo -e -n "Would you like to set distinct PINs/passwords to be provisioned to previously stated security components? [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ]; then - echo -e "\nThey must be each at least 8 characters in length.\n" - echo - if [ "$CONFIG_TPM" = "y" ]; then - while [[ ${#TPM_PASS} -lt 8 ]] ; do - echo -e -n "Enter desired TPM Ownership password: " - read TPM_PASS - done - fi - while [[ ${#ADMIN_PIN} -lt 8 ]] || [[ ${#ADMIN_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]] ; do - echo -e -n "\nThis PIN should be between 8 to $MAX_HOTP_GPG_PIN_LENGTH characters in length.\n" - echo -e -n "Enter desired GPG Admin PIN: " - read ADMIN_PIN - done - while [[ ${#USER_PIN} -lt 8 ]] || [[ ${#USER_PIN} -gt 64 ]]; do - echo -e -n "\nThis PIN should be between 8 to 64 characters in length.\n" - echo -e -n "Enter desired GPG User PIN: " - read USER_PIN - done - echo - fi - fi + # Prompt to change default passwords + echo -e -n "Would you like to set a single custom password that will be provisioned to previously stated security components? [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ]; then + echo -e "\nThe chosen custom password must be between 8 and $MAX_HOTP_GPG_PIN_LENGTH characters in length.\n" + echo + while [[ ${#CUSTOM_SINGLE_PASS} -lt 8 ]] || [[ ${#CUSTOM_SINGLE_PASS} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do + echo -e -n "Enter the custom password: " + read CUSTOM_SINGLE_PASS + done + echo + TPM_PASS=$CUSTOM_SINGLE_PASS + USER_PIN=$CUSTOM_SINGLE_PASS + ADMIN_PIN=$CUSTOM_SINGLE_PASS - if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -a -z "$luks_new_Disk_Recovery_Key_passphrase" ]; then - # We catch here if changing LUKS Disk Recovery Key passphrase was desired - # but yet undone. This is if not being covered by the single password - echo -e "\nEnter desired replacement for current 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 - #We test that current Disk Recovery Key passphrase is known prior of going further - test_luks_current_disk_recovery_key_passphrase - echo -e "\n" - fi + # Only set if user said desired. Matches rest of logic + if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then + luks_new_Disk_Recovery_Key_passphrase=$CUSTOM_SINGLE_PASS + fi + else + echo -e -n "Would you like to set distinct PINs/passwords to be provisioned to previously stated security components? [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ]; then + echo -e "\nThey must be each at least 8 characters in length.\n" + echo + if [ "$CONFIG_TPM" = "y" ]; then + while [[ ${#TPM_PASS} -lt 8 ]]; do + echo -e -n "Enter desired TPM Ownership password: " + read TPM_PASS + done + fi + while [[ ${#ADMIN_PIN} -lt 8 ]] || [[ ${#ADMIN_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do + echo -e -n "\nThis PIN should be between 8 to $MAX_HOTP_GPG_PIN_LENGTH characters in length.\n" + echo -e -n "Enter desired GPG Admin PIN: " + read ADMIN_PIN + done + while [[ ${#USER_PIN} -lt 8 ]] || [[ ${#USER_PIN} -gt 64 ]]; do + echo -e -n "\nThis PIN should be between 8 to 64 characters in length.\n" + echo -e -n "Enter desired GPG User PIN: " + read USER_PIN + done + echo + fi + fi - # Prompt to change default GnuPG key information - echo -e -n "Would you like to set custom user information for the GnuPG key? [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ]; then - echo -e "\n\n" - echo -e "We will generate a GnuPG (PGP) keypair identifiable with the following text form:" - echo -e "Real Name (Comment) email@address.org" + if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -a -z "$luks_new_Disk_Recovery_Key_passphrase" ]; then + # We catch here if changing LUKS Disk Recovery Key passphrase was desired + # but yet undone. This is if not being covered by the single password + echo -e "\nEnter desired replacement for current 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 + #We test that current Disk Recovery Key passphrase is known prior of going further + test_luks_current_disk_recovery_key_passphrase + echo -e "\n" + fi - echo -e "\nEnter your Real Name (Optional):" - read -r GPG_USER_NAME + # Prompt to change default GnuPG key information + echo -e -n "Would you like to set custom user information for the GnuPG key? [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ]; then + echo -e "\n\n" + echo -e "We will generate a GnuPG (PGP) keypair identifiable with the following text form:" + echo -e "Real Name (Comment) email@address.org" - echo -e "\nEnter your email@adress.org:" - read -r GPG_USER_MAIL - while ! $(expr "$GPG_USER_MAIL" : '.*@' >/dev/null); do - { - echo -e "\nEnter your email@address.org:" - read -r GPG_USER_MAIL - };done + echo -e "\nEnter your Real Name (Optional):" + read -r GPG_USER_NAME - echo -e "\nEnter Comment (Optional, to distinguish this key from others with same previous attributes. Must be smaller then 60 characters):" - read -r GPG_USER_COMMENT - while [[ ${#GPG_USER_COMMENT} -gt 60 ]]; do - { - echo -e "\nEnter Comment (Optional, to distinguish this key from others with same previous attributes. Must be smaller then 60 characters):" - read -r GPG_USER_COMMENT - };done - fi -fi + echo -e "\nEnter your email@adress.org:" + read -r GPG_USER_MAIL + while ! $(expr "$GPG_USER_MAIL" : '.*@' >/dev/null); do + { + echo -e "\nEnter your email@address.org:" + read -r GPG_USER_MAIL + } + done + + echo -e "\nEnter Comment (Optional, to distinguish this key from others with same previous attributes. Must be smaller then 60 characters):" + read -r GPG_USER_COMMENT + while [[ ${#GPG_USER_COMMENT} -gt 60 ]]; do + { + echo -e "\nEnter Comment (Optional, to distinguish this key from others with same previous attributes. Must be smaller then 60 characters):" + read -r GPG_USER_COMMENT + } + done + fi +fi # If nothing is stored in custom variables, we set them to their defaults if [ "$TPM_PASS" == "" ]; then TPM_PASS=$TPM_PASS_DEF; fi @@ -578,42 +893,46 @@ if [ "$ADMIN_PIN" == "" ]; then ADMIN_PIN=$ADMIN_PIN_DEF; fi ## sanity check the USB, GPG key, and boot device before proceeding further -# Prompt to insert USB drive if desired -echo -e -n "\nWould you like to export your public key to an USB drive? [y/N]: " -read -n 1 prompt_output -echo -if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ] \ -; then - GPG_EXPORT=1 - # mount USB over /media only if not already mounted - if ! grep -q /media /proc/mounts ; then - # mount USB in rw - if ! mount-usb --mode rw 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Unable to mount USB on /media:\n\n${ERROR}" - fi +if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then + # Prompt to insert USB drive if desired + echo -e -n "\nWould you like to export your public key to an USB drive? [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ] \ + ; then + GPG_EXPORT=1 + # mount USB over /media only if not already mounted + if ! grep -q /media /proc/mounts; then + # mount USB in rw + if ! mount-usb --mode rw 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Unable to mount USB on /media:\n\n${ERROR}" + fi + else + #/media already mounted, make sure it is in r+w mode + if ! mount -o remount,rw /media 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Unable to remount in read+write USB on /media:\n\n${ERROR}" + fi + fi else - #/media already mounted, make sure it is in r+w mode - if ! mount -o remount,rw /media 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Unable to remount in read+write USB on /media:\n\n${ERROR}" - fi + GPG_EXPORT=0 + # needed for USB Security dongle below and is ensured via mount-usb in case of GPG_EXPORT=1 + enable_usb fi -else - GPG_EXPORT=0 - # needed for USB Security dongle below and is ensured via mount-usb in case of GPG_EXPORT=1 - enable_usb fi -# ensure USB Security Dongle connected -echo -e "\nChecking for USB Security Dongle...\n" -# USB kernel modules already loaded via mount-usb -if ! gpg --card-status >/dev/null 2>&1 ; then - whiptail_error "Can't access USB Security Dongle; \nPlease remove and reinsert, then press Enter." - if ! gpg --card-status >/dev/null 2>/tmp/error ; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Unable to detect USB Security Dongle:\n\n${ERROR}" +# ensure USB Security Dongle connected if GPG_GEN_KEY_IN_MEMORY=0 +if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then + echo -e "\nChecking for USB Security Dongle...\n" + enable_usb + if ! gpg --card-status >/dev/null 2>&1; then + whiptail_error "Can't access USB Security Dongle; \nPlease remove and reinsert, then press Enter." + if ! gpg --card-status >/dev/null 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Unable to detect USB Security Dongle:\n\n${ERROR}" + fi fi fi @@ -623,39 +942,39 @@ assert_signable # detect and set /boot device echo -e "\nDetecting and setting boot device...\n" -if ! detect_boot_device ; then - SKIP_BOOT="y" +if ! detect_boot_device; then + SKIP_BOOT="y" else - echo -e "Boot device set to $CONFIG_BOOT_DEV\n" + echo -e "Boot device set to $CONFIG_BOOT_DEV\n" fi # update configs if [[ "$SKIP_BOOT" == "n" ]]; then - replace_config /etc/config.user "CONFIG_BOOT_DEV" "$CONFIG_BOOT_DEV" - combine_configs + replace_config /etc/config.user "CONFIG_BOOT_DEV" "$CONFIG_BOOT_DEV" + combine_configs fi if [ -n "$luks_new_Disk_Recovery_Key_desired" -a -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - #Reencryption of disk, disk recovery key and Disk Recovery Key passphrase change is requested - luks_reencrypt - luks_change_passphrase + #Reencryption of disk, disk recovery key and Disk Recovery Key passphrase change is requested + luks_reencrypt + luks_change_passphrase elif [ -n "$luks_new_Disk_Recovery_Key_desired" -a -z "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - #Reencryption of disk was requested but not passphrase change - luks_reencrypt + #Reencryption of disk was requested but not passphrase change + luks_reencrypt elif [ -z "$luks_new_Disk_Recovery_Key_desired" -a -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - #Passphrase change is requested without disk reencryption - luks_change_passphrase + #Passphrase change is requested without disk reencryption + luks_change_passphrase fi ## reset TPM and set password if [ "$CONFIG_TPM" = "y" ]; then - echo -e "\nResetting TPM...\n" - tpmr reset "$TPM_PASS" >/dev/null 2>/tmp/error + echo -e "\nResetting TPM...\n" + tpmr reset "$TPM_PASS" >/dev/null 2>/tmp/error fi if [ $? -ne 0 ]; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error resetting TPM:\n\n${ERROR}" + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error resetting TPM:\n\n${ERROR}" fi # clear local keyring @@ -663,37 +982,53 @@ rm /.gnupg/*.gpg 2>/dev/null rm /.gnupg/*.kbx 2>/dev/null gpg --list-keys >/dev/null 2>&1 -## reset the GPG Key -echo -e "\nResetting GPG Key...\n(this will take around 3 minutes...)\n" -gpg_key_reset +#Generate key in memory and copy to smartcard +if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then + # Generate GPG master key + generate_inmemory_RSA_master_and_subkeys + #TODO seperate wiping and thumb drive functions with proper validation + wipe_thumb_drive_and_copy_gpg_key_material + #TODO seperate setting config + set_user_config CONFIG_HAVE_GPG_KEY_BACKUP Y + gpg_key_factory_reset + keytocard_subkeys_to_smartcard +else + #Generate GPG key and subkeys on smartcard + ## reset the GPG Key + echo -e "\nResetting GPG Key...\n(this will take around 3 minutes...)\n" + gpg_key_factory_reset + generate_OEM_gpg_keys +fi # parse name of generated key -GPG_GEN_KEY=`grep -A1 pub /tmp/gpg_card_edit_output | tail -n1 | sed -nr 's/^([ ])*//p'` +GPG_GEN_KEY=$(grep -A1 pub /tmp/gpg_card_edit_output | tail -n1 | sed -nr 's/^([ ])*//p') PUBKEY="/tmp/${GPG_GEN_KEY}.asc" -#Applying custom GPG PINs -if [ "$USER_PIN" != "" -o "$ADMIN_PIN" != "" ]; then - echo -e "\nChanging default GPG Admin PIN\n" - gpg_key_change_pin "3" "$ADMIN_PIN_DEF" "$ADMIN_PIN" - echo -e "\nChanging default GPG User PIN\n" - gpg_key_change_pin "1" "$USER_PIN_DEF" "$USER_PIN" -fi - -# export pubkey to file -if ! gpg --export --armor $GPG_GEN_KEY > "${PUBKEY}" 2>/tmp/error ; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "GPG Key gpg export to file failed!\n\n$ERROR" -fi - -## export pubkey to USB -if [ $GPG_EXPORT -ne 0 ]; then - echo -e "\nExporting generated key to USB...\n" - # copy to USB - if ! cp "${PUBKEY}" "/media/${GPG_GEN_KEY}.asc" 2>/tmp/error ; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Key export error: unable to copy ${GPG_GEN_KEY}.asc to /media:\n\n$ERROR" +#Applying custom GPG PINs if keys were not generated in memory +if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then + if [ "$USER_PIN" != "" -o "$ADMIN_PIN" != "" ]; then + echo -e "\nChanging default GPG Admin PIN\n" + gpg_key_change_pin "3" "$ADMIN_PIN_DEF" "$ADMIN_PIN" + echo -e "\nChanging default GPG User PIN\n" + gpg_key_change_pin "1" "$USER_PIN_DEF" "$USER_PIN" + fi + + # export pubkey to file + if ! gpg --export --armor "$GPG_GEN_KEY" >"${PUBKEY}" 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "GPG Key gpg export to file failed!\n\n$ERROR" + fi + + ## export pubkey to USB + if [ $GPG_EXPORT -ne 0 ]; then + echo -e "\nExporting generated key to USB...\n" + # copy to USB + if ! cp "${PUBKEY}" "/media/${GPG_GEN_KEY}.asc" 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Key export error: unable to copy ${GPG_GEN_KEY}.asc to /media:\n\n$ERROR" + fi + mount -o remount,ro /media 2>/dev/null fi - mount -o remount,ro /media 2>/dev/null fi ## flash generated key to ROM @@ -705,32 +1040,32 @@ if [ ! -s /tmp/oem-setup.rom ]; then fi # ensure key imported locally -if ! cat "$PUBKEY" | gpg --import >/dev/null 2>/tmp/error ; then +if ! cat "$PUBKEY" | gpg --import >/dev/null 2>/tmp/error; then ERROR=$(tail -n 1 /tmp/error | fold -s) whiptail_error_die "Error importing GPG key:\n\n$ERROR" fi # update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys -if ! gpg --list-keys --fingerprint --with-colons 2>/dev/null \ - | sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' \ - | gpg --import-ownertrust >/dev/null 2>/tmp/error ; then +if ! gpg --list-keys --fingerprint --with-colons 2>/dev/null | + sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' | + gpg --import-ownertrust >/dev/null 2>/tmp/error; then ERROR=$(tail -n 1 /tmp/error | fold -s) whiptail_error_die "Error importing GPG ownertrust:\n\n$ERROR" fi -if ! gpg --update-trust >/dev/null 2>/tmp/error ; then +if ! gpg --update-trust >/dev/null 2>/tmp/error; then ERROR=$(tail -n 1 /tmp/error | fold -s) whiptail_error_die "Error updating GPG ownertrust:\n\n$ERROR" fi # clear any existing heads/gpg files from current firmware -for i in `cbfs.sh -o /tmp/oem-setup.rom -l | grep -e "heads/"`; do - cbfs.sh -o /tmp/oem-setup.rom -d $i +for i in $(cbfs.sh -o /tmp/oem-setup.rom -l | grep -e "heads/"); do + cbfs.sh -o /tmp/oem-setup.rom -d "$i" done # add heads/gpg files to current firmware -if [ -e /.gnupg/pubring.kbx ];then +if [ -e /.gnupg/pubring.kbx ]; then cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx - if [ -e /.gnupg/pubring.gpg ];then + if [ -e /.gnupg/pubring.gpg ]; then rm /.gnupg/pubring.gpg fi -elif [ -e /.gnupg/pubring.gpg ];then +elif [ -e /.gnupg/pubring.gpg ]; then cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg fi if [ -e /.gnupg/trustdb.gpg ]; then @@ -742,30 +1077,30 @@ if [ -e /etc/config.user ]; then fi # flash updated firmware image echo -e "\nAdding generated key to current firmware and re-flashing...\n" -if ! /bin/flash.sh /tmp/oem-setup.rom >/dev/null 2>/tmp/error ; then +if ! /bin/flash.sh /tmp/oem-setup.rom >/dev/null 2>/tmp/error; then ERROR=$(tail -n 1 /tmp/error | fold -s) whiptail_error_die "Error flashing updated firmware image:\n\n$ERROR" fi ## sign files in /boot and generate checksums if [[ "$SKIP_BOOT" == "n" ]]; then - echo -e "\nSigning boot files and generating checksums...\n" - generate_checksums + echo -e "\nSigning boot files and generating checksums...\n" + generate_checksums fi # Prepare whiptail output of provisioned secrets if [ -z "$luks_new_Disk_Recovery_Key_passphrase" -o -z "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - luks_passphrase_changed="" + luks_passphrase_changed="" else - luks_passphrase_changed="LUKS Disk Recovery Key passphrase:\n + luks_passphrase_changed="LUKS Disk Recovery Key passphrase:\n $luks_new_Disk_Recovery_Key_passphrase" fi if [ "$CONFIG_TPM" = "y" ]; then - tpm_password_changed=" + tpm_password_changed=" TPM Owner Password: $TPM_PASS\n" else - tpm_password_changed="" + tpm_password_changed="" fi ## Show to user current provisioned secrets prior of rebooting diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index f819af06..7a32af09 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -53,6 +53,51 @@ preserve_rom() { done } +gpg_auth() { + TRACE "Under /etc/ash_functions:gpg_auth" + if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" = "y" ]; then + # If we have a GPG key backup, we can use it to authenticate even if the card is lost + echo >&2 "!!!!! Please authenticate with OpenPGP card/backup media to prove you are the owner of this machine !!!!!" + + # Wipe any existing nonce and signature + shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true + confirm_gpg_card + + # Perform a signing-based challenge-response, + # to authencate that the card plugged in holding + # the key to sign the list of boot files. + + CR_NONCE="/tmp/secret/cr_nonce" + CR_SIG="$CR_NONCE.sig" + + # Generate a random nonce + dd \ + if=/dev/urandom \ + of="$CR_NONCE" \ + count=1 \ + bs=20 \ + 2>/dev/null \ + || die "Unable to generate 20 random bytes" + + # Sign the nonce + for tries in 1 2 3; do + if gpg --digest-algo SHA256 \ + --detach-sign \ + -o "$CR_SIG" \ + "$CR_NONCE" \ + && gpgv "$CR_SIG" "$CR_NONCE" \ + ; then + shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true + return 0 + else + shred -n 10 -z -u "$CR_SIG" 2>/dev/null || true + continue + fi + done + return 1 + fi +} + recovery() { TRACE "Under /etc/ash_functions:recovery" echo >&2 "!!!!! $*" @@ -82,6 +127,9 @@ recovery() { do echo >&2 "!!!!! Starting recovery shell" sleep 1 + + #Going to recovery shell should be authenticated if supported + gpg_auth if [ -x /bin/setsid ]; then /bin/setsid -c /bin/sh diff --git a/initrd/etc/functions b/initrd/etc/functions index 2163587b..761efd96 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -191,19 +191,73 @@ list_usb_storage() { confirm_gpg_card() { TRACE "Under /etc/functions:confirm_gpg_card" + #Skip prompts if we are currently using a known GPG key material Thumb drive backup and keys are unlocked pinentry + #TODO: probably export CONFIG_GPG_KEY_BACKUP_IN_USE but not under /etc/user.config? + #Toggle to come in next PR, but currently we don't have a way to toggle it back to n if config.user flashed back in rom + if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]]; then + return + fi + + if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" ]; then + message="Please confirm that your GPG card is inserted(Y/n) or your GPG key material (b)backup thumbdrive is inserted [Y/n/b]: " + else + # Generic message if no known key material backup + message+="Please confirm that your GPG card is inserted [Y/n]: " + fi + read \ -n 1 \ - -p "Please confirm that your GPG card is inserted [Y/n]: " \ + -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 provisioned GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys + echo + read -s -p "Please enter GPG Admin PIN needed to use the GPG backup thumb drive: " gpg_admin_pin + #prompt user to select the proper encrypted partition, which should the first one on next prompt + echo -e "Please select encrypted LUKS container partition (not the public one)\n" + mount-usb --pass "$gpg_admin_pin" || die "Unable to mount USB with GPG Admin PIN" + warn "Testing detach-sign operation and verifiying against fused public key in ROM..." + gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --import /media/subkeys.sec >/dev/null 2>&1 || + die "Unable to import GPG private subkeys" + #Do a detach signature to ensure gpg material is usable and cache passphrase to sign /boot from caller functions + dd if=/dev/urandom of="$CR_NONCE" bs=20 count=1 >/dev/null 2>&1 || + die "Unable to create dummy file to sign" + gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --detach-sign "$CR_NONCE" >/dev/null 2>&1 || + die "Unable to sign dummy file with GPG private signing subkey" + #verify detached signature against public key in rom + gpg --verify "$CR_SIG" "$CR_NONCE" || die "Unable to verify dummy file with GPG public key in ROM: public key mismatch" + #Wipe any previous CR_NONCE and CR_SIG + shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true + #TODO: maybe just an export instead of setting /etc/user.config otherwise could be flashed in weird corner case situation + set_user_config CONFIG_GPG_KEY_BACKUP_IN_USE y + umount /media || die "Unable to unmount USB" + return + fi + #Else if user has known GPG key material Thumb drive backup and already asked to use it + if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]]; then + return + fi + fi + # setup the USB so we can reach the GPG card enable_usb diff --git a/initrd/etc/luks-functions b/initrd/etc/luks-functions index 67c937a9..8e90bc4d 100644 --- a/initrd/etc/luks-functions +++ b/initrd/etc/luks-functions @@ -6,25 +6,20 @@ . /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 + cryptsetup isLuks $device + if [ $(echo $?) == 0 ]; 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,7 +52,7 @@ 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 with two partitions: a first one being a LUKS container containing private ext4 partition and second public exfat partition # Size provisioning is done by percentage of the device prepare_thumb_drive() { @@ -84,12 +79,12 @@ 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]" ;; esac done @@ -184,7 +179,7 @@ prepare_thumb_drive() 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 if [ -x /bin/whiptail ]; then whiptail $BG_COLOR_WARNING --title "WARNING: Wiping and repartitioning $DEVICE of $DISK_SIZE_MB MB" --yesno \ @@ -201,13 +196,12 @@ prepare_thumb_drive() fi fi - 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 + echo -e "Preparing $DEVICE with $PERCENTAGE_MB MB for private LUKS container and rest of disk with exfat for public partition (This may take a while)..." | fold -s 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 +210,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,7 +236,7 @@ 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 @@ -255,17 +249,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):" 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,7 +267,7 @@ 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. @@ -285,7 +279,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 +288,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 (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 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 (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 - 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 } From 2c55338be5caf94c290d714c9f1e3fbd141886ae Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 19 Oct 2023 15:42:27 -0400 Subject: [PATCH 02/69] Wip: now supports both backup and copy to card and gpg_auth when backup exists. Might want to discuss that implementation. Some functions needed to be moved from functions to ash_functions so that gpg_auth can be called from recovery function. That might need to be discussed as well, recovery could be moved from ash_functions to functions instead. Signed-off-by: Thierry Laurion --- initrd/bin/mount-usb | 2 +- initrd/bin/oem-factory-reset | 37 ++++++--- initrd/etc/ash_functions | 156 +++++++++++++++++++++++++++++++++-- initrd/etc/functions | 96 --------------------- initrd/etc/luks-functions | 5 +- 5 files changed, 182 insertions(+), 114 deletions(-) diff --git a/initrd/bin/mount-usb b/initrd/bin/mount-usb index 771bebab..22846a24 100755 --- a/initrd/bin/mount-usb +++ b/initrd/bin/mount-usb @@ -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 diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 18ae18ad..bd26a795 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -940,6 +940,14 @@ assert_signable # Action time... +#TODO: Should we replace text from "Add a new GPG key" to "Replace current GPG key"? Should we wipe current keyring? +#Current logic is for factory reset, where re-ownership adds key to the keyring which is then copied over cbfs. +# In the all case, we should wipe the keyring since otherwise, USB security dongle is wiped but not the keyring which exposes past public keys +# this seems wrong +# clear local keyring +rm /.gnupg/* | true + + # detect and set /boot device echo -e "\nDetecting and setting boot device...\n" if ! detect_boot_device; then @@ -989,7 +997,7 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then #TODO seperate wiping and thumb drive functions with proper validation wipe_thumb_drive_and_copy_gpg_key_material #TODO seperate setting config - set_user_config CONFIG_HAVE_GPG_KEY_BACKUP Y + set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y gpg_key_factory_reset keytocard_subkeys_to_smartcard else @@ -1000,10 +1008,21 @@ else generate_OEM_gpg_keys fi -# parse name of generated key -GPG_GEN_KEY=$(grep -A1 pub /tmp/gpg_card_edit_output | tail -n1 | sed -nr 's/^([ ])*//p') +# Obtain GPG key ID +GPG_GEN_KEY=$(gpg --list-keys --with-colons | grep "^fpr" | cut -d: -f10 | head -n1) +#Where to export the public key PUBKEY="/tmp/${GPG_GEN_KEY}.asc" +DEBUG "GPG_GEN_KEY: $GPG_GEN_KEY" +DEBUG "PUBKEY: $PUBKEY" + +# export pubkey to file +if ! gpg --export --armor "$GPG_GEN_KEY" >"${PUBKEY}" 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "GPG Key gpg export to file failed!\n\n$ERROR" +fi + + #Applying custom GPG PINs if keys were not generated in memory if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then if [ "$USER_PIN" != "" -o "$ADMIN_PIN" != "" ]; then @@ -1013,12 +1032,6 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then gpg_key_change_pin "1" "$USER_PIN_DEF" "$USER_PIN" fi - # export pubkey to file - if ! gpg --export --armor "$GPG_GEN_KEY" >"${PUBKEY}" 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "GPG Key gpg export to file failed!\n\n$ERROR" - fi - ## export pubkey to USB if [ $GPG_EXPORT -ne 0 ]; then echo -e "\nExporting generated key to USB...\n" @@ -1055,11 +1068,13 @@ if ! gpg --update-trust >/dev/null 2>/tmp/error; then ERROR=$(tail -n 1 /tmp/error | fold -s) whiptail_error_die "Error updating GPG ownertrust:\n\n$ERROR" fi + # clear any existing heads/gpg files from current firmware for i in $(cbfs.sh -o /tmp/oem-setup.rom -l | grep -e "heads/"); do cbfs.sh -o /tmp/oem-setup.rom -d "$i" done # add heads/gpg files to current firmware + if [ -e /.gnupg/pubring.kbx ]; then cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx if [ -e /.gnupg/pubring.gpg ]; then @@ -1071,13 +1086,15 @@ fi if [ -e /.gnupg/trustdb.gpg ]; then cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg fi + # persist user config changes (boot device) if [ -e /etc/config.user ]; then cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/etc/config.user" -f /etc/config.user fi + # flash updated firmware image echo -e "\nAdding generated key to current firmware and re-flashing...\n" -if ! /bin/flash.sh /tmp/oem-setup.rom >/dev/null 2>/tmp/error; then +if ! /bin/flash.sh /tmp/oem-setup.rom 2>/tmp/error; then ERROR=$(tail -n 1 /tmp/error | fold -s) whiptail_error_die "Error flashing updated firmware image:\n\n$ERROR" fi diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 7a32af09..d877382f 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -53,9 +53,102 @@ 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 provisioned GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys + echo + read -s -p "Please enter GPG Admin PIN needed to use the GPG backup thumb drive: " gpg_admin_pin + #prompt user to select the proper encrypted partition, which should the first one on next prompt + echo -e "Please select encrypted LUKS container partition (not the public one)\n" + mount-usb --pass "$gpg_admin_pin" || die "Unable to mount USB with GPG Admin PIN" + warn "Testing detach-sign operation and verifiying against fused public key in ROM" + gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --import /media/subkeys.sec >/dev/null 2>&1 || + die "Unable to import GPG private subkeys" + #Do a detach signature to ensure gpg material is usable and cache passphrase to sign /boot from caller functions + dd if=/dev/urandom of="$CR_NONCE" bs=20 count=1 >/dev/null 2>&1 || + die "Unable to create $CR_NONCE to be 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 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" || 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 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 +} + gpg_auth() { - TRACE "Under /etc/ash_functions:gpg_auth" - if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" = "y" ]; then + 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 card/backup media to prove you are the owner of this machine !!!!!" @@ -88,9 +181,11 @@ gpg_auth() { && gpgv "$CR_SIG" "$CR_NONCE" \ ; 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 + echo >&2 "!!!!! GPG authentication failed, please try again !!!!!" continue fi done @@ -125,12 +220,12 @@ recovery() { fi while [ true ] do + #Going to recovery shell should be authenticated if supported + gpg_auth + echo >&2 "!!!!! Starting recovery shell" sleep 1 - #Going to recovery shell should be authenticated if supported - gpg_auth - if [ -x /bin/setsid ]; then /bin/setsid -c /bin/sh else @@ -150,6 +245,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" diff --git a/initrd/etc/functions b/initrd/etc/functions index 761efd96..23c8fc2b 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -189,102 +189,6 @@ list_usb_storage() { done } -confirm_gpg_card() { - TRACE "Under /etc/functions:confirm_gpg_card" - #Skip prompts if we are currently using a known GPG key material Thumb drive backup and keys are unlocked pinentry - #TODO: probably export CONFIG_GPG_KEY_BACKUP_IN_USE but not under /etc/user.config? - #Toggle to come in next PR, but currently we don't have a way to toggle it back to n if config.user flashed back in rom - if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]]; then - return - fi - - if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" ]; then - message="Please confirm that your GPG card is inserted(Y/n) or your GPG key material (b)backup thumbdrive is inserted [Y/n/b]: " - else - # Generic message if no known key material backup - message+="Please confirm that your GPG card is inserted [Y/n]: " - fi - - read \ - -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 provisioned GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys - echo - read -s -p "Please enter GPG Admin PIN needed to use the GPG backup thumb drive: " gpg_admin_pin - #prompt user to select the proper encrypted partition, which should the first one on next prompt - echo -e "Please select encrypted LUKS container partition (not the public one)\n" - mount-usb --pass "$gpg_admin_pin" || die "Unable to mount USB with GPG Admin PIN" - warn "Testing detach-sign operation and verifiying against fused public key in ROM..." - gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --import /media/subkeys.sec >/dev/null 2>&1 || - die "Unable to import GPG private subkeys" - #Do a detach signature to ensure gpg material is usable and cache passphrase to sign /boot from caller functions - dd if=/dev/urandom of="$CR_NONCE" bs=20 count=1 >/dev/null 2>&1 || - die "Unable to create dummy file to sign" - gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --detach-sign "$CR_NONCE" >/dev/null 2>&1 || - die "Unable to sign dummy file with GPG private signing subkey" - #verify detached signature against public key in rom - gpg --verify "$CR_SIG" "$CR_NONCE" || die "Unable to verify dummy file with GPG public key in ROM: public key mismatch" - #Wipe any previous CR_NONCE and CR_SIG - shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true - #TODO: maybe just an export instead of setting /etc/user.config otherwise could be flashed in weird corner case situation - set_user_config CONFIG_GPG_KEY_BACKUP_IN_USE y - umount /media || die "Unable to unmount USB" - return - fi - #Else if user has known GPG key material Thumb drive backup and already asked to use it - if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]]; then - return - fi - fi - - # setup the USB so we can reach the GPG card - 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. diff --git a/initrd/etc/luks-functions b/initrd/etc/luks-functions index 8e90bc4d..1a96c77f 100644 --- a/initrd/etc/luks-functions +++ b/initrd/etc/luks-functions @@ -196,7 +196,8 @@ prepare_thumb_drive() fi fi - echo -e "Preparing $DEVICE with $PERCENTAGE_MB MB for private LUKS container and rest of disk with exfat for public partition (This may take a while)..." | fold -s + echo -e "Preparing $DEVICE with $PERCENTAGE_MB MB for private LUKS container while rest of device will be assigned to extfat public partition...\n" + echo "Please wait..." DEBUG "Creating empty DOS partition table on device through fdisk to start clean" echo -e "o\nw\n" | fdisk $DEVICE >/dev/null 2>&1 || die "Error creating partition table" DEBUG "partition device with two partitions: first one being the percent applied and rest for second partition through fdisk" @@ -240,7 +241,7 @@ select_luks_container() mount -o remount,ro /boot fi else - warn "No encrypted device found." + warn "No encrypted device found" return 1 fi fi From eceb97aa4de5f4a1277bc5c659b5802063ce9a51 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 20 Oct 2023 14:12:16 -0400 Subject: [PATCH 03/69] WiP: provide proper info/warn/die messages explaining causes of errors linked to detach signing errors Signed-off-by: Thierry Laurion --- initrd/bin/kexec-seal-key | 13 ++++++------ initrd/etc/ash_functions | 20 ++++++++++-------- initrd/etc/functions | 43 ++++----------------------------------- 3 files changed, 23 insertions(+), 53 deletions(-) diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index fe36808c..c8a1891a 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -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 diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index d877382f..5c140531 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -96,20 +96,24 @@ confirm_gpg_card() { #Prompt user for provisioned GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys echo - read -s -p "Please enter GPG Admin PIN needed to use the GPG backup thumb drive: " gpg_admin_pin + #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 #prompt user to select the proper encrypted partition, which should the first one on next prompt - echo -e "Please select encrypted LUKS container partition (not the public one)\n" + 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 GPG Admin PIN" - warn "Testing detach-sign operation and verifiying against fused public key in ROM" + 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 signed with GPG private signing subkey" + 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 sign $CR_NONCE with GPG private signing subkey using GPG Admin PIN" + 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" || die "Unable to verify $CR_SIG detached signature against public key in ROM" + gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 && \ + echo "++++ Imported private subkeys match public key fused in rom and can be used under Heads" || \ + 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 @@ -177,8 +181,8 @@ gpg_auth() { if gpg --digest-algo SHA256 \ --detach-sign \ -o "$CR_SIG" \ - "$CR_NONCE" \ - && gpgv "$CR_SIG" "$CR_NONCE" \ + "$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" diff --git a/initrd/etc/functions b/initrd/etc/functions index 23c8fc2b..f9a45dea 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -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!" 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 @@ -257,7 +256,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 reflash firmware and choose TPM Reset reset option" } check_config() { @@ -318,40 +317,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. From 1f28c7144756f4a6a8c2b4ac830939306b16157d Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 20 Oct 2023 16:20:17 -0400 Subject: [PATCH 04/69] WiP: adapt dmesg in function of CONFIG_DEBUG_OUTPUT being enabled or not so and adapt further troubleshooting notes in code when keys cannot be accessed on media for whatever cause so user can understand what is happening when accessing GPG material on backup thumb drive Signed-off-by: Thierry Laurion --- .../qemu-coreboot-fbwhiptail-tpm1.config | 7 +++++-- .../qemu-coreboot-whiptail-tpm1.config | 4 ++-- initrd/etc/ash_functions | 2 +- initrd/init | 8 ++++++++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config b/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config index 94f543fd..f494f2b0 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config @@ -10,9 +10,12 @@ 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 +#export CONFIG_DEBUG_OUTPUT=y +#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y CONFIG_COREBOOT_CONFIG=config/coreboot-qemu-tpm1.config CONFIG_LINUX_CONFIG=config/linux-qemu.config diff --git a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config index 25de9fbb..bc485944 100644 --- a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config +++ b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config @@ -14,8 +14,8 @@ export CONFIG_LINUX_VERSION=5.10.5 export CONFIG_HAVE_GPG_KEY_BACKUP=y #Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#export CONFIG_DEBUG_OUTPUT=y +#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y CONFIG_COREBOOT_CONFIG=config/coreboot-qemu-tpm1.config CONFIG_LINUX_CONFIG=config/linux-qemu.config diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 5c140531..7703bc5c 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -103,7 +103,7 @@ confirm_gpg_card() { 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 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 || + gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --import /media/subkeys.sec || 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 || diff --git a/initrd/init b/initrd/init index 2acd93fe..a9297c23 100755 --- a/initrd/init +++ b/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" From 2697a6ad1f887e2d86804b99db473217132a15e6 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 20 Oct 2023 16:39:23 -0400 Subject: [PATCH 05/69] WiP: further removal of unecessary debug messages Signed-off-by: Thierry Laurion --- initrd/etc/ash_functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 7703bc5c..5c140531 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -103,7 +103,7 @@ confirm_gpg_card() { 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 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 || + 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 || From 88d00dfcb29135887fce558fdb798292851b4a8a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 23 Oct 2023 11:52:44 -0400 Subject: [PATCH 06/69] scripts: unify luks in text/prompts/messages to LUKS Signed-off-by: Thierry Laurion --- initrd/bin/qubes-measure-luks | 4 ++-- initrd/bin/seal-totp | 2 +- initrd/bin/tpmr | 2 +- initrd/etc/luks-functions | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/initrd/bin/qubes-measure-luks b/initrd/bin/qubes-measure-luks index 782dc8de..4d396ff6 100755 --- a/initrd/bin/qubes-measure-luks +++ b/initrd/bin/qubes-measure-luks @@ -14,8 +14,8 @@ 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-* diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index fa3a9d00..374e1eab 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -43,7 +43,7 @@ DEBUG "Sealing TOTP with boot state of PCR4 (Going to recovery shell extends PCR 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" diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index e7d0af66..1531969b 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -225,7 +225,7 @@ 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() { diff --git a/initrd/etc/luks-functions b/initrd/etc/luks-functions index 1a96c77f..76a3ef0a 100644 --- a/initrd/etc/luks-functions +++ b/initrd/etc/luks-functions @@ -271,7 +271,7 @@ test_luks_current_disk_recovery_key_passphrase() 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 @@ -314,7 +314,7 @@ luks_reencrypt() { 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 @@ -370,7 +370,7 @@ luks_change_passphrase() "The LUKS Disk Recovery Key passphrase was provided to you by the OEM over\n secure communication channel.\n\nIf you previously changed it and do not remember it,\n you will have to reinstall OS from a USB drive.\nTo do so, put OS ISO file and it's signature file on root of USB drive,\n And select Boot from USB\n\nHit Enter to continue." 30 60 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. + #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 From 2ae94405adb989f85bad447496366aa97fa7231d Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 23 Oct 2023 11:54:14 -0400 Subject: [PATCH 07/69] WiP: add export CONFIG_HAVE_GPG_KEY_BACKUP=y so whiptail-tpm2 can be used with GPG key material thumb drive backup Signed-off-by: Thierry Laurion --- .../qemu-coreboot-whiptail-tpm2.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config b/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config index a4a0b29c..92816b42 100644 --- a/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config +++ b/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config @@ -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 From 2ea62ff17e2b989fca4cb1fc215de9da8c02823d Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 23 Oct 2023 12:06:27 -0400 Subject: [PATCH 08/69] /etc/functions: add missing TRACE traces to get where TPM passphrase should be written to file and reused since not all in same functions/files for TPM2 Signed-off-by: Thierry Laurion --- initrd/etc/functions | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/initrd/etc/functions b/initrd/etc/functions index f9a45dea..7e90ae07 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -118,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..." @@ -192,6 +193,7 @@ list_usb_storage() { # 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() { + TRACE "Under /etc/functions:prompt_tpm_password" if [ -n "$tpm_password" ]; then return 0 fi @@ -204,6 +206,7 @@ prompt_tpm_password() { # key_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() { + TRACE "Under /etc/functions:prompt_new_owner_password" local key_password2 key_password=1 key_password2=2 @@ -531,6 +534,7 @@ detect_boot_device() { } scan_boot_options() { + TRACE "Under /etc/functions:scan_boot_options" local bootdir config option_file bootdir="$1" config="$2" From 754e3c916514b2ce13d7a61c4975448b97307b99 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 23 Oct 2023 13:11:49 -0400 Subject: [PATCH 09/69] bin/reboot: intercept reboot call when in DEBUG mode to type 'r' to go to recovery shell instead of rebooting Signed-off-by: Thierry Laurion --- initrd/bin/reboot | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/initrd/bin/reboot b/initrd/bin/reboot index 30f6b7d8..030a7ea6 100755 --- a/initrd/bin/reboot +++ b/initrd/bin/reboot @@ -3,6 +3,15 @@ TRACE "Under /bin/reboot" +if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then + #Generalize user prompt to continue reboot or go to recovery shell + read -p "Press any key to continue reboot or 'r' to go to recovery shell: " -n 1 -r + echo + if [[ $REPLY =~ ^[Rr]$ ]]; then + recovery "Reboot call bypassed to go into recovery shell to debug" + fi +fi + # Shut down TPM if [ "$CONFIG_TPM" = "y" ]; then tpmr shutdown From 911eb07565f5fefa5c8aa3b038a9c22833a46240 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 23 Oct 2023 13:13:39 -0400 Subject: [PATCH 10/69] TPM1/TPM2: unify wording for TPM Owner Password and cache it externally to /tmp/secret/tpm_password to be reused in a boot session until recovery shell access or reboot TODO: Why two functions prompt_tpm_password and prompt_new_owner_password Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 4 ++-- initrd/bin/tpmr | 12 +++++++++--- initrd/etc/functions | 17 ++++++++++++++--- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index bd26a795..b9e7ce4b 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -780,7 +780,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then fi if [ "$CONFIG_TPM" = "y" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS="$CUSTOM_PASS_AFFECTED_COMPONENTS -TPM Ownership password" +TPM Owner Password" fi CUSTOM_PASS_AFFECTED_COMPONENTS="$CUSTOM_PASS_AFFECTED_COMPONENTS GPG Admin PIN @@ -821,7 +821,7 @@ GPG User PIN" echo if [ "$CONFIG_TPM" = "y" ]; then while [[ ${#TPM_PASS} -lt 8 ]]; do - echo -e -n "Enter desired TPM Ownership password: " + echo -e -n "Enter desired TPM Owner Password: " read TPM_PASS done fi diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 1531969b..20ac4a47 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -391,7 +391,7 @@ tpm2_seal() { 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. + # TPM Owner Password is always needed for TPM2. mkdir -p "$SECRET_DIR" bname="`basename $file`" @@ -489,7 +489,7 @@ tpm1_seal() { # try it without the 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 @@ -595,6 +595,9 @@ tpm2_reset() { TRACE "Under /bin/tpmr:tpm2_reset" key_password="$1" mkdir -p "$SECRET_DIR" + # output TPM Owner Password key_password to a file to be reused in this boot session until recovery shell/reboot + DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_password" + echo "$key_password" > "$SECRET_DIR/tpm_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")" @@ -640,7 +643,10 @@ tpm2_reset() { tpm1_reset() { TRACE "Under /bin/tpmr:tpm1_reset" key_password="$1" - + mkdir -p "$SECRET_DIR" + # output key_password to a file to be reused in this boot session until recovery shell/reboot + DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_password" + echo "$key_password" > "$SECRET_DIR/tpm_password" # Make sure the TPM is ready to be reset tpm physicalpresence -s tpm physicalenable diff --git a/initrd/etc/functions b/initrd/etc/functions index 7e90ae07..816eb902 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -194,11 +194,17 @@ list_usb_storage() { # line, since some flows need it multiple times and only one prompt is ideal. prompt_tpm_password() { TRACE "Under /etc/functions:prompt_tpm_password" + #Caller might already have cached the password in tpm_password. If not, prompt for it and cache it externally if [ -n "$tpm_password" ]; then + DEBUG "tpm_password variable already set by caller. Reusing" + return 0 + elif [ -s /tmp/secret/tpm_password ]; then + DEBUG "/tmp/secret/tpm_password already cached in file. Reusing" + tpm_password=$(cat /tmp/secret/tpm_password) return 0 fi - read -s -p "TPM Owner password: " tpm_password + read -s -p "TPM Owner Password: " tpm_password echo # new line after password prompt } @@ -211,10 +217,10 @@ prompt_new_owner_password() { 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 + read -s -p "New TPM Owner Password (2 words suggested, 1-32 characters max): " key_password echo - read -s -p "Repeat chosen TPM owner passphrase: " key_password2 + read -s -p "Repeat chosen TPM Owner Password: " key_password2 echo if [ "$key_password" != "$key_password2" ]; then @@ -222,6 +228,11 @@ prompt_new_owner_password() { echo fi done + + # Cache the password externally to be reused by who needs it + DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_password" + mkdir -p /tmp/secret || die "Unable to create /tmp/secret" + echo "$key_password" > /tmp/secret/tpm_password || die "Unable to cache TPM password under /tmp/secret" } check_tpm_counter() { From 3fb84f0b425d75ff05b78c810b07aee111ac458c Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 23 Oct 2023 15:18:28 -0400 Subject: [PATCH 11/69] WiP: Clean cached /tmp/secret/tpm_password when sealing fails, otherwise reuse it on TPM Reset/TOTP+HOTP Sealing once for TPM1/TPM2+TPM Disk Unlock Key gui-init: make sure that reseal_tpm_disk_decryption_key happens only on successful TOTP/HOTP sealing, reusing cached TPM Owner password Signed-off-by: Thierry Laurion --- initrd/bin/gui-init | 15 +++++---------- initrd/bin/kexec-seal-key | 6 +++++- initrd/bin/seal-totp | 22 ++++++++++++++-------- initrd/bin/tpmr | 1 + initrd/bin/unseal-totp | 12 ++++++------ initrd/etc/functions | 9 +++++++-- 6 files changed, 38 insertions(+), 27 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 1ab178f3..a9bfc417 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -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 ) @@ -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 diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index c8a1891a..881797a5 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -137,7 +137,11 @@ 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" || { + shred -n 10 -z -u /tmp/secret/tpm_password 2>/dev/null + : + 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 || diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index 374e1eab..d3953ce4 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -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,26 @@ 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 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" || + { + shred -n 10 -z -u /tmp/secret/tpm_password 2>/dev/null + : + die "Unable to write sealed secret to NVRAM" + } +#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="" diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 20ac4a47..ddcf5e88 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -533,6 +533,7 @@ tpm2_unseal() { # can't do anything without a primary handle. if [ ! -f "/tmp/$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" exit 1 fi diff --git a/initrd/bin/unseal-totp b/initrd/bin/unseal-totp index 32db3192..ed8f18af 100755 --- a/initrd/bin/unseal-totp +++ b/initrd/bin/unseal-totp @@ -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" -fi + 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 diff --git a/initrd/etc/functions b/initrd/etc/functions index 816eb902..60ff97c7 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -99,7 +99,7 @@ reseal_tpm_disk_decryption_key() { 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" @@ -206,6 +206,11 @@ prompt_tpm_password() { read -s -p "TPM Owner Password: " tpm_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_password" + mkdir -p /tmp/secret || die "Unable to create /tmp/secret" + echo "$key_password" >/tmp/secret/tpm_password || die "Unable to cache TPM password under /tmp/secret" } # Prompt for a new owner password when resetting the TPM. Returned in @@ -232,7 +237,7 @@ prompt_new_owner_password() { # Cache the password externally to be reused by who needs it DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_password" mkdir -p /tmp/secret || die "Unable to create /tmp/secret" - echo "$key_password" > /tmp/secret/tpm_password || die "Unable to cache TPM password under /tmp/secret" + echo "$key_password" >/tmp/secret/tpm_password || die "Unable to cache TPM password under /tmp/secret" } check_tpm_counter() { From 15f1d0b77acf253d26ddcd5b028d86d4e99a60b0 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 23 Oct 2023 15:57:12 -0400 Subject: [PATCH 12/69] To Squash: changes to reboot were not ash compliant Signed-off-by: Thierry Laurion --- initrd/bin/reboot | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/initrd/bin/reboot b/initrd/bin/reboot index 030a7ea6..8df357c3 100755 --- a/initrd/bin/reboot +++ b/initrd/bin/reboot @@ -3,13 +3,13 @@ TRACE "Under /bin/reboot" -if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then - #Generalize user prompt to continue reboot or go to recovery shell - read -p "Press any key to continue reboot or 'r' to go to recovery shell: " -n 1 -r - echo - if [[ $REPLY =~ ^[Rr]$ ]]; then - recovery "Reboot call bypassed to go into recovery shell to debug" - fi +if [ “$CONFIG_DEBUG_OUTPUT” = “y” ]; then + #Generalize user prompt to continue reboot or go to recovery shell + read -r -p -n1 "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 From 729f2b17b822097a1a87fed034347cb21d68d65a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 23 Oct 2023 17:23:38 -0400 Subject: [PATCH 13/69] WiP to be squashed: we need to refactor prompt_tpm_password which is used both for TPM Owner Password prompt and caching reused for TPM disk unlock key passphrase which of course fails Signed-off-by: Thierry Laurion --- initrd/bin/kexec-seal-key | 4 ++++ initrd/bin/kexec-select-boot | 33 ++++++++++++++++++--------------- initrd/etc/functions | 3 +++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index 881797a5..4e0cb321 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -135,6 +135,10 @@ tpmr calcfuturepcr 6 "/tmp/luksDump.txt" >>"$pcrf" # We take into consideration user files in cbfs tpmr pcrread -a 7 "$pcrf" +DEBUG "TODO: REMOVE THIS: key_password=$key_password here" +DEBUG "TODO: REMOVE THIS: content of /tmp/secret/tpm_password: $(cat /tmp/secret/tpm_password) here" + + 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" || { diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 1562638c..6f4cdfc7 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -50,21 +50,24 @@ bootdir="${bootdir%%/}" paramsdev="${paramsdev%%/}" 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"; - } - else - warn "Hash of TPM2 primary key handle does not exist" - warn "Please rebuild the boot hash tree" - default_failed="y" - fi -fi + +#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"; +# } +# else +# warn "Hash of TPM2 primary key handle does not exist" +# warn "Please rebuild the boot hash tree" +# default_failed="y" +# fi +#fi +#TODO: Readd when this can work successfully by simply resealing TOTP/HOTP without having to reset TPM2, this is a major pain point for users +#And acutally don't work as intended, even more with TPM DUK verify_global_hashes() { diff --git a/initrd/etc/functions b/initrd/etc/functions index 60ff97c7..1227c66c 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -197,14 +197,17 @@ prompt_tpm_password() { #Caller might already have cached the password in tpm_password. If not, prompt for it and cache it externally if [ -n "$tpm_password" ]; then DEBUG "tpm_password variable already set by caller. Reusing" + DEBUG "TODO REMOVE THIS! tpm_password is $tpm_password here." return 0 elif [ -s /tmp/secret/tpm_password ]; then DEBUG "/tmp/secret/tpm_password already cached in file. Reusing" tpm_password=$(cat /tmp/secret/tpm_password) + DEBUG "TODO REMOVE THIS! tpm_password is $tpm_password here." return 0 fi read -s -p "TPM Owner Password: " tpm_password + #TODO: This function is called for both owner and TPM sealing calls. We should probably have a different prompt for each echo # new line after password prompt # Cache the password externally to be reused by who needs it From 27c457f04b566891bd8468d929e1dafd04585ba6 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 24 Oct 2023 11:19:49 -0400 Subject: [PATCH 14/69] TPM2 DUK and TOTP/HOTP reseal fix, refactoring and ifferenciating tpm_password into tpm_owner_password and reusing correctly i TODO: fix all TODO in PR prior of review + squash Signed-off-by: Thierry Laurion --- .../qemu-coreboot-whiptail-tpm1.config | 5 ++- initrd/bin/gui-init | 12 ++--- initrd/bin/kexec-seal-key | 4 +- initrd/bin/oem-factory-reset | 8 ++-- initrd/bin/seal-totp | 2 +- initrd/bin/tpm-reset | 2 +- initrd/bin/tpmr | 35 ++++++++------- initrd/etc/functions | 44 +++++++++---------- 8 files changed, 58 insertions(+), 54 deletions(-) diff --git a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config index bc485944..0b05dfaa 100644 --- a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config +++ b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config @@ -11,11 +11,12 @@ export CONFIG_LINUX_VERSION=5.10.5 #export CONFIG_BASIC=y #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) +#TODO: comment following line prior of pushing final version export CONFIG_HAVE_GPG_KEY_BACKUP=y #Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y CONFIG_COREBOOT_CONFIG=config/coreboot-qemu-tpm1.config CONFIG_LINUX_CONFIG=config/linux-qemu.config diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index a9bfc417..1434f570 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -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 @@ -567,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 @@ -577,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" @@ -588,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 diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index 4e0cb321..70985d1c 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -136,13 +136,13 @@ tpmr calcfuturepcr 6 "/tmp/luksDump.txt" >>"$pcrf" tpmr pcrread -a 7 "$pcrf" DEBUG "TODO: REMOVE THIS: key_password=$key_password here" -DEBUG "TODO: REMOVE THIS: content of /tmp/secret/tpm_password: $(cat /tmp/secret/tpm_password) here" +DEBUG "TODO: REMOVE THIS: content of /tmp/secret/tpm_owner_password: $(cat /tmp/secret/tpm_owner_password) here" 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" || { - shred -n 10 -z -u /tmp/secret/tpm_password 2>/dev/null + shred -n 10 -z -u /tmp/secret/tpm_owner_password 2>/dev/null : die "Unable to write TPM Disk Unlock Key to NVRAM" } diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index b9e7ce4b..1f44cc46 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -1114,16 +1114,16 @@ else fi if [ "$CONFIG_TPM" = "y" ]; then - tpm_password_changed=" + tpm_owner_password_changed=" TPM Owner Password: $TPM_PASS\n" else - tpm_password_changed="" + tpm_owner_password_changed="" fi ## Show to user current provisioned secrets prior of rebooting whiptail --msgbox " $luks_passphrase_changed - $tpm_password_changed + $tpm_owner_password_changed GPG Admin PIN: $ADMIN_PIN\n GPG User PIN: $USER_PIN\n\n" \ $HEIGHT $WIDTH --title "Provisioned secrets" @@ -1139,6 +1139,6 @@ whiptail --msgbox " # Clean LUKS secrets luks_secrets_cleanup unset luks_passphrase_changed -unset tpm_password_changed +unset tpm_owner_password_changed reboot diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index d3953ce4..9df8e85a 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -50,7 +50,7 @@ tpmr pcrread -a 7 "$pcrf" #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" || { - shred -n 10 -z -u /tmp/secret/tpm_password 2>/dev/null + shred -n 10 -z -u /tmp/secret/tpm_owner_password 2>/dev/null : die "Unable to write sealed secret to NVRAM" } diff --git a/initrd/bin/tpm-reset b/initrd/bin/tpm-reset index f8b0c6a8..5049bea0 100755 --- a/initrd/bin/tpm-reset +++ b/initrd/bin/tpm-reset @@ -7,4 +7,4 @@ echo '*****' prompt_new_owner_password -tpmr reset "$key_password" +tpmr reset "$tpm_owner_password" diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index ddcf5e88..e64ec2bf 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -393,6 +393,7 @@ tpm2_seal() { tpm_password="$7" # Owner password - will prompt if needed and not empty # TPM Owner Password is always needed for TPM2. + DEBUG "TODO REMOVE THIS. tpm2_seal: pass=$pass tpm_password=$tpm_password" mkdir -p "$SECRET_DIR" bname="`basename $file`" @@ -442,12 +443,12 @@ tpm2_seal() { tpm2 load -Q -C "/tmp/$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")" \ + tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_owner_password")" \ -c "$SECRET_DIR/$bname.seal.ctx" "$handle" } tpm1_seal() { @@ -497,7 +498,7 @@ tpm1_seal() { 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 \ @@ -554,6 +555,8 @@ tpm2_unseal() { UNSEAL_PASS_SUFFIX="+$(tpm2_password_hex "$pass")" fi + DEBUG "TODO REMOVE THIS. tpm2_unseal: pass=$pass UNSEAL_PASS_SUFFIX=$UNSEAL_PASS_SUFFIX" + tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \ -S "/tmp/$ENC_SESSION_FILE" > "$file" } @@ -594,18 +597,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 key_password to a file to be reused in this boot session until recovery shell/reboot - DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_password" - echo "$key_password" > "$SECRET_DIR/tpm_password" + 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 @@ -643,18 +646,18 @@ tpm2_reset() { } tpm1_reset() { TRACE "Under /bin/tpmr:tpm1_reset" - key_password="$1" + tpm_owner_password="$1" mkdir -p "$SECRET_DIR" - # output key_password to a file to be reused in this boot session until recovery shell/reboot - DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_password" - echo "$key_password" > "$SECRET_DIR/tpm_password" + # 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 diff --git a/initrd/etc/functions b/initrd/etc/functions index 1227c66c..5bea478d 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -192,28 +192,28 @@ list_usb_storage() { # 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() { - TRACE "Under /etc/functions:prompt_tpm_password" +prompt_tpm_owner_password() { + TRACE "Under /etc/functions:prompt_tpm_owner_password" #Caller might already have cached the password in tpm_password. If not, prompt for it and cache it externally - if [ -n "$tpm_password" ]; then - DEBUG "tpm_password variable already set by caller. Reusing" - DEBUG "TODO REMOVE THIS! tpm_password is $tpm_password here." + if [ -n "$tpm_owner_password" ]; then + DEBUG "tpm_owner_password variable already set by caller. Reusing" + DEBUG "TODO REMOVE THIS! tpm_owner_password is $tpm_owner_password here." return 0 - elif [ -s /tmp/secret/tpm_password ]; then - DEBUG "/tmp/secret/tpm_password already cached in file. Reusing" - tpm_password=$(cat /tmp/secret/tpm_password) - DEBUG "TODO REMOVE THIS! tpm_password is $tpm_password here." + elif [ -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) + DEBUG "TODO REMOVE THIS! tpm_owner_password is $tpm_owner_password here." return 0 fi - read -s -p "TPM Owner Password: " tpm_password + read -s -p "TPM Owner Password: " tpm_owner_password #TODO: This function is called for both owner and TPM sealing calls. We should probably have a different prompt for each 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_password" + DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_owner_password" mkdir -p /tmp/secret || die "Unable to create /tmp/secret" - echo "$key_password" >/tmp/secret/tpm_password || die "Unable to cache TPM password under /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 @@ -221,26 +221,26 @@ prompt_tpm_password() { # the script will loop until this is met. prompt_new_owner_password() { TRACE "Under /etc/functions: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 Password (2 words suggested, 1-32 characters max): " key_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 Password: " 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_password" + DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_owner_password" mkdir -p /tmp/secret || die "Unable to create /tmp/secret" - echo "$key_password" >/tmp/secret/tpm_password || die "Unable to cache TPM password under /tmp/secret" + echo -n "$tpm_owner_password" >/tmp/secret/tpm_owner_password || die "Unable to cache TPM password under /tmp/secret" } check_tpm_counter() { @@ -253,7 +253,7 @@ check_tpm_counter() { TPM_COUNTER=$(grep counter- "$1" | cut -d- -f2) else warn "$1 does not exist; creating new TPM counter" - prompt_tpm_password + prompt_tpm_owner_password tpmr counter_create \ -pwdo "$tpm_password" \ -pwdc '' \ From cf065eeba2c2cf0dd97ebe5ace7001ebc80fa073 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 24 Oct 2023 13:13:47 -0400 Subject: [PATCH 15/69] bin/reboot: fix parameter order so that we pause when in DEBUG before rebooting Signed-off-by: Thierry Laurion --- initrd/bin/reboot | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/initrd/bin/reboot b/initrd/bin/reboot index 8df357c3..f226a927 100755 --- a/initrd/bin/reboot +++ b/initrd/bin/reboot @@ -3,12 +3,12 @@ TRACE "Under /bin/reboot" -if [ “$CONFIG_DEBUG_OUTPUT” = “y” ]; then +if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then #Generalize user prompt to continue reboot or go to recovery shell - read -r -p -n1 "Press any key to continue reboot or ‘r’ to go to recovery shell: " REPLY + 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” + if [ "$REPLY" = "r" ] || [ "$REPLY" = "R" ]; then + recovery "Reboot call bypassed to go into recovery shell to debug" fi fi From b2cb9b49974086e600b44ef166a3b30cec2f8873 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 24 Oct 2023 13:14:39 -0400 Subject: [PATCH 16/69] .ash_history: add history command for manual detached signed integrity validation Signed-off-by: Thierry Laurion --- initrd/.ash_history | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/initrd/.ash_history b/initrd/.ash_history index 99690053..d3dab524 100644 --- a/initrd/.ash_history +++ b/initrd/.ash_history @@ -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: From 2b21623bc6794309a509e58d590ceec413a35e55 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 24 Oct 2023 13:16:16 -0400 Subject: [PATCH 17/69] qemu doc: add modify list/mount instructions to use losetup to map partitions to loop0pX and mount them to get public key Signed-off-by: Thierry Laurion --- .../qemu-coreboot-fbwhiptail-tpm1-hotp.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.md b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.md index 59ed50fe..7e9dffbf 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.md +++ b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.md @@ -41,7 +41,8 @@ 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` 6. Inject the GPG key into the Heads image and run again From 56b602974bb36d87360b2c77de62b4ed13a57fde Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 25 Oct 2023 17:01:01 -0400 Subject: [PATCH 18/69] WiP: NK3 with p256 ECC algo supported for in-memory keygen and key-to-card op. With this commit, one can provision NK3 with thumb drive backup which enables authenticated recovery shell and USB boot. Signed-off-by: Thierry Laurion --- .../qemu-coreboot-fbwhiptail-tpm1-hotp.md | 1 + .../qemu-coreboot-whiptail-tpm1.config | 2 +- initrd/bin/oem-factory-reset | 143 +++++++++++++----- 3 files changed, 110 insertions(+), 36 deletions(-) diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.md b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.md index 7e9dffbf..4dbec899 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.md +++ b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.md @@ -45,6 +45,7 @@ Bootstrapping a working system * `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= inject_gpg` * `make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp USB_TOKEN=LibremKey PUBKEY_ASC= run` diff --git a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config index 0b05dfaa..5353782e 100644 --- a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config +++ b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config @@ -12,7 +12,7 @@ export CONFIG_LINUX_VERSION=5.10.5 #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #TODO: comment following line prior of pushing final version -export CONFIG_HAVE_GPG_KEY_BACKUP=y +#export CONFIG_HAVE_GPG_KEY_BACKUP=y #Enable DEBUG output export CONFIG_DEBUG_OUTPUT=y diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 1f44cc46..3579c32f 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -35,6 +35,8 @@ MAX_HOTP_GPG_PIN_LENGTH=25 # What are the Security components affected by custom passwords CUSTOM_PASS_AFFECTED_COMPONENTS="" +# Default GPG Algorithm is RSA +GPG_ALGO="RSA" # Default RSA key length #TODO change it back to 3076. Canokey cannot be tested easily and Nitrokey prov1 I have doesn't key-attr to 3076 RSA_KEY_LENGTH=2048 @@ -70,7 +72,7 @@ whiptail_error_die() { die } -#Generate a gpg master key: passwordless, no expiration date, RSA 4096 bits +#Generate a gpg master key: no expiration date, RSA 4096 bits #This key will be used to sign 3 subkeys: encryption, authentication and signing #The master key will be stored on the disk, and the subkeys on the smartcard generate_inmemory_RSA_master_and_subkeys() { @@ -169,6 +171,63 @@ generate_inmemory_RSA_master_and_subkeys() { fi } +#Generate a gpg master key: no expiration date, p256 key (ECC) +#This key will be used to sign 3 subkeys: encryption, authentication and signing +#The master key will be stored on the disk, and the subkeys on the smartcard +generate_inmemory_p256_master_and_subkeys() { + DEBUG "Generating GPG key material in memory:" + gpg --expert --batch --pinentry-mode=loopback --passphrase ${ADMIN_PIN} --quick-generate-key "${GPG_USER_NAME} (${GPG_USER_COMMENT}) <${GPG_USER_MAIL}>" nistp256 cert 0 + + DEBUG "Getting master key fingerprint..." + MASTER_KEY_FP=$(gpg --list-secret-keys --with-colons | grep fpr | cut -d: -f10) + + DEBUG "MASTER_KEY_FP=${MASTER_KEY_FP}" + + DEBUG "Adding GPG nistp256 signing subkey to master key..." + { + echo addkey + echo 11 # ECC own set capability + echo Q # sign already present + echo 3 # P-256 + echo 0 # no expiration + echo save # save the key + } | gpg --command-fd=0 --passphrase ${ADMIN_PIN} --pinentry-mode=loopback --expert --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR_MSG=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "Failed to add ECC nistp256 signing key to master key\n\n${ERROR_MSG}" + fi + + DEBUG "Adding GPG nistp256 encryption subkey to master key..." + { + echo addkey + echo 12# ECC encrypt only + echo E # encrypt already present + echo 3 # P-256 + echo 0 # no expiration + echo save # save the key + } | gpg --command-fd=0 --passphrase ${ADMIN_PIN} --pinentry-mode=loopback --expert --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR_MSG=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "Failed to add ECC nistp256 encryption key to master key\n\n${ERROR_MSG}" + fi + + DEBUG "Adding GPG nistp256 authentication subkey to master key..." + { + echo addkey + echo 11 # ECC own set capability + echo S # deactivate sign + echo A # activate auth + echo Q # Quit + echo 3 # P-256 + echo 0 # no expiration + echo save # save the key + } | gpg --command-fd=0 --passphrase ${ADMIN_PIN} --pinentry-mode=loopback --expert --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR_MSG=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "Failed to add ECC nistp256 authentication key to master key\n\n${ERROR_MSG}" + fi +} + #Function to move current gpg keyring subkeys to card (keytocard) # This is aimed to be used after having generated master key and subkeys in memory and having backuped them to a LUKS container # This function will keytocard the subkeys from the master key in the keyring @@ -435,23 +494,27 @@ gpg_key_factory_reset() { generate_OEM_gpg_keys() { # Generate OEM GPG keys TRACE "Under oem-factory-reset:generate_OEM_gpg_keys" - DEBUG "Generating GPG keys to RSA ${RSA_KEY_LENGTH} bits in smartcard..." - { - echo admin - echo generate - echo n - echo ${ADMIN_PIN_DEF} - echo ${USER_PIN_DEF} - echo 0 - echo ${GPG_USER_NAME} - echo ${GPG_USER_MAIL} - echo ${GPG_USER_COMMENT} - echo ${USER_PIN_DEF} - } | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR" + + #TODO: finish refactoring to adapt to GPG_ALGO != RSA + if [ "$GPG_ALGO" = "RSA" ]; then + DEBUG "Generating GPG keys to RSA ${RSA_KEY_LENGTH} bits in smartcard..." + { + echo admin + echo generate + echo n + echo ${ADMIN_PIN_DEF} + echo ${USER_PIN_DEF} + echo 0 + echo ${GPG_USER_NAME} + echo ${GPG_USER_MAIL} + echo ${GPG_USER_COMMENT} + echo ${USER_PIN_DEF} + } | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR" + fi fi } @@ -680,11 +743,10 @@ usb_security_token_capabilities_check() { DEBUG "Setting GPG_ALGO to (board-)configured: $CONFIG_GPG_ALGO" fi # ... overwrite with usb-token capability - #TODO: revert. Testing test firmware for Nitrokey 3 which is supposed to support RSA 3076 now - #if lsusb | grep -q "20a0:42b2"; then - # GPG_ALGO="p256" - # DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" - #fi + if lsusb | grep -q "20a0:42b2"; then + GPG_ALGO="p256" + DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" + fi } ## main script start @@ -722,7 +784,8 @@ $TPM_STR fi # We show current integrity measurements status and time -report_integrity_measurements +#TODO: Reactivate this prior of PR review +#report_integrity_measurements # Determine gpg algorithm to be used, based on available usb-token usb_security_token_capabilities_check @@ -947,7 +1010,6 @@ assert_signable # clear local keyring rm /.gnupg/* | true - # detect and set /boot device echo -e "\nDetecting and setting boot device...\n" if ! detect_boot_device; then @@ -962,7 +1024,6 @@ if [[ "$SKIP_BOOT" == "n" ]]; then combine_configs fi - if [ -n "$luks_new_Disk_Recovery_Key_desired" -a -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then #Reencryption of disk, disk recovery key and Disk Recovery Key passphrase change is requested luks_reencrypt @@ -992,14 +1053,27 @@ gpg --list-keys >/dev/null 2>&1 #Generate key in memory and copy to smartcard if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then - # Generate GPG master key - generate_inmemory_RSA_master_and_subkeys - #TODO seperate wiping and thumb drive functions with proper validation - wipe_thumb_drive_and_copy_gpg_key_material - #TODO seperate setting config - set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y - gpg_key_factory_reset - keytocard_subkeys_to_smartcard + # TODO: Refactoring in progress for RSA and p256 support. Now just GPG_ALGO RSA + if [ "$GPG_ALGO" == "RSA" ]; then + # Generate GPG master key + generate_inmemory_RSA_master_and_subkeys + #TODO seperate wiping and thumb drive functions with proper validation + wipe_thumb_drive_and_copy_gpg_key_material + #TODO seperate setting config + set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y + gpg_key_factory_reset #TODO: do we currently double reset? I think so + keytocard_subkeys_to_smartcard + elif [ "$GPG_ALGO" == "p256" ]; then + generate_inmemory_p256_master_and_subkeys + #TODO seperate wiping and thumb drive functions with proper validation + wipe_thumb_drive_and_copy_gpg_key_material + #TODO seperate setting config + set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y + gpg_key_factory_reset #TODO: do we currently double reset? I think so + keytocard_subkeys_to_smartcard + else + die "Unsupported GPG_ALGO: $GPG_ALGO" + fi else #Generate GPG key and subkeys on smartcard ## reset the GPG Key @@ -1022,7 +1096,6 @@ if ! gpg --export --armor "$GPG_GEN_KEY" >"${PUBKEY}" 2>/tmp/error; then whiptail_error_die "GPG Key gpg export to file failed!\n\n$ERROR" fi - #Applying custom GPG PINs if keys were not generated in memory if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then if [ "$USER_PIN" != "" -o "$ADMIN_PIN" != "" ]; then From 9e838ad615209441985b1de1c07048456d926acc Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 26 Oct 2023 16:50:10 -0400 Subject: [PATCH 19/69] oem-factory-reset: make passphrases variables able to contain strings and validate things more solidly Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 289 ++++++++++++++++++----------------- 1 file changed, 145 insertions(+), 144 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 3579c32f..0bdecb08 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -38,8 +38,7 @@ CUSTOM_PASS_AFFECTED_COMPONENTS="" # Default GPG Algorithm is RSA GPG_ALGO="RSA" # Default RSA key length -#TODO change it back to 3076. Canokey cannot be tested easily and Nitrokey prov1 I have doesn't key-attr to 3076 -RSA_KEY_LENGTH=2048 +RSA_KEY_LENGTH=3072 GPG_USER_NAME="OEM Key" GPG_KEY_NAME=$(date +%Y%m%d%H%M%S) @@ -74,7 +73,7 @@ whiptail_error_die() { #Generate a gpg master key: no expiration date, RSA 4096 bits #This key will be used to sign 3 subkeys: encryption, authentication and signing -#The master key will be stored on the disk, and the subkeys on the smartcard +#The master key and subkeys will be copied to backup, and the subkeys moved from memory keyring to the smartcard generate_inmemory_RSA_master_and_subkeys() { TRACE "Under oem-factory-reset:generate_inmemory_RSA_master_and_subkeys" echo "Generating GPG key material in memory:" @@ -91,8 +90,7 @@ generate_inmemory_RSA_master_and_subkeys() { echo "Expire-Date: 0" echo "Passphrase: ${ADMIN_PIN}" echo "%commit" - } | gpg --batch --gen-key \ - >/tmp/gpg_card_edit_output 2>&1 + } | gpg --command-fd=0 --status-fd=1 --batch --gen-key >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key generation failed!\n\n$ERROR" @@ -173,55 +171,66 @@ generate_inmemory_RSA_master_and_subkeys() { #Generate a gpg master key: no expiration date, p256 key (ECC) #This key will be used to sign 3 subkeys: encryption, authentication and signing -#The master key will be stored on the disk, and the subkeys on the smartcard +#The master key and subkeys will be copied to backup, and the subkeys moved from memory keyring to the smartcard generate_inmemory_p256_master_and_subkeys() { - DEBUG "Generating GPG key material in memory:" - gpg --expert --batch --pinentry-mode=loopback --passphrase ${ADMIN_PIN} --quick-generate-key "${GPG_USER_NAME} (${GPG_USER_COMMENT}) <${GPG_USER_MAIL}>" nistp256 cert 0 + TRACE "Under oem-factory-reset:generate_inmemory_p256_master_and_subkeys" - DEBUG "Getting master key fingerprint..." + echo "Generating GPG p256 bits master key..." + { + echo "Key-Type: ECDSA" + echo "Key-Curve: nistp256" + echo "Key-Usage: cert" + echo "Name-Real: ${GPG_USER_NAME}" + echo "Name-Comment: ${GPG_USER_COMMENT}" + echo "Name-Email: ${GPG_USER_MAIL}" + echo "Expire-Date: 0" + echo "%commit" + } | gpg --expert --batch --pinentry-mode=loopback --passphrase=<(echo -n "${ADMIN_PIN}") --generate-key \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG p256 Key generation failed!\n\n$ERROR" + fi + + #Keep Master key fingerprint for add key calls MASTER_KEY_FP=$(gpg --list-secret-keys --with-colons | grep fpr | cut -d: -f10) - DEBUG "MASTER_KEY_FP=${MASTER_KEY_FP}" - - DEBUG "Adding GPG nistp256 signing subkey to master key..." + echo "Generating GPG nistp256 signing subkey..." { echo addkey - echo 11 # ECC own set capability - echo Q # sign already present - echo 3 # P-256 - echo 0 # no expiration - echo save # save the key - } | gpg --command-fd=0 --passphrase ${ADMIN_PIN} --pinentry-mode=loopback --expert --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + echo 11 # ECC own set capability + echo Q # sign already present + echo 3 # P-256 + echo 0 # no expiration + } | gpg --expert --command-fd=0 --status-fd=1 --passphrase=<(echo -n "${ADMIN_PIN}") --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR_MSG=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "Failed to add ECC nistp256 signing key to master key\n\n${ERROR_MSG}" fi - DEBUG "Adding GPG nistp256 encryption subkey to master key..." + echo "Generating GPG nistp256 encryption subkey..." { echo addkey echo 12# ECC encrypt only - echo E # encrypt already present - echo 3 # P-256 - echo 0 # no expiration - echo save # save the key - } | gpg --command-fd=0 --passphrase ${ADMIN_PIN} --pinentry-mode=loopback --expert --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + echo E # encrypt already present + echo 3 # P-256 + echo 0 # no expiration + } | gpg --expert --command-fd=0 --status-fd=1 --passphrase=<(echo -n "${ADMIN_PIN}") --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR_MSG=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "Failed to add ECC nistp256 encryption key to master key\n\n${ERROR_MSG}" fi - DEBUG "Adding GPG nistp256 authentication subkey to master key..." + echo "Generating GPG nistp256 authentication subkey..." { echo addkey - echo 11 # ECC own set capability - echo S # deactivate sign - echo A # activate auth - echo Q # Quit - echo 3 # P-256 - echo 0 # no expiration - echo save # save the key - } | gpg --command-fd=0 --passphrase ${ADMIN_PIN} --pinentry-mode=loopback --expert --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + echo 11 # ECC own set capability + echo S # deactivate sign + echo A # activate auth + echo Q # Quit + echo 3 # P-256 + echo 0 # no expiration + } | gpg --expert --command-fd=0 --status-fd=1 --passphrase=<(echo -n "${ADMIN_PIN}") --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR_MSG=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "Failed to add ECC nistp256 authentication key to master key\n\n${ERROR_MSG}" @@ -242,31 +251,29 @@ keytocard_subkeys_to_smartcard() { enable_usb_storage gpg --card-status >/dev/null 2>&1 || die "Error getting GPG card status" - DEBUG "Factory resetting the smartcard..." + echo "Factory resetting the smartcard..." gpg_key_factory_reset - DEBUG "Moving subkeys to smartcard..." - - #keytocard all subkeys + echo "Moving subkeys to smartcard..." { echo "key 1" #Select Signature key echo "keytocard" - echo "1" # Signature key - echo "$ADMIN_PIN" #Smartcard admin pin - echo "$ADMIN_PIN" #Subkey PIN - echo "0" #No expiration date + echo "1" # Signature key + echo "${ADMIN_PIN}" #Smartcard admin pin + echo "${ADMIN_PIN}" #Subkey PIN + echo "0" #No expiration date echo "key 1" echo "key 2" echo "keytocard" echo "2" # Encryption key - echo "$ADMIN_PIN" - echo "$ADMIN_PIN" + echo "${ADMIN_PIN}" + echo "${ADMIN_PIN}" echo "key 2" echo "key 3" echo "keytocard" echo "3" # Authentication key - echo "$ADMIN_PIN" - echo "$ADMIN_PIN" + echo "${ADMIN_PIN}" + echo "${ADMIN_PIN}" echo "key 3" echo "save" } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --expert --edit-key "${GPG_USER_MAIL}" \ @@ -275,7 +282,7 @@ keytocard_subkeys_to_smartcard() { ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key moving subkeys to smartcard failed!\n\n$ERROR" fi - DEBUG "Moving subkeys to smartcard done." + echo "Moving subkeys to smartcard done." } #Whiptail prompt to disconnect any external USB storage device @@ -326,7 +333,7 @@ export_master_key_subkeys_and_revocation_key_to_private_LUKS_container() { shift ;; --pass) - pass="$2" + pass="${2}" shift shift ;; @@ -340,14 +347,17 @@ export_master_key_subkeys_and_revocation_key_to_private_LUKS_container() { #Export master key and subkeys to thumb drive DEBUG "Exporting master key and subkeys to private LUKS container's partition..." - gpg --export-secret-key --armor --pinentry-mode loopback --passphrase-file <(echo -n "${pass}") "${GPG_USER_MAIL}" >"$mountpoint"/privkey.sec || + DEBUG "TODO DELETE THIS pass= ${pass} here" + + gpg --export-secret-key --armor --pinentry-mode loopback --passphrase=<(echo -n "${pass}") "${GPG_USER_MAIL}" >"$mountpoint"/privkey.sec || die "Error exporting master key to private LUKS container's partition" - gpg --export-secret-subkeys --armor --pinentry-mode loopback --passphrase-file <(echo -n "${pass}") "${GPG_USER_MAIL}" >"$mountpoint"/subkeys.sec || + gpg --export-secret-subkeys --armor --pinentry-mode loopback --passphrase=<(echo -n "${pass}") "${GPG_USER_MAIL}" >"$mountpoint"/subkeys.sec || die "Error exporting subkeys to private LUKS container's partition" #copy whole keyring to thumb drive, including revocation key and trust database cp -af ~/.gnupg "$mountpoint"/.gnupg || die "Error copying whole keyring to private LUKS container's partition" #Unmount private LUKS container's mount point umount "$mountpoint" || die "Error unmounting private LUKS container's mount point" + TRACE "Under oem-factory-reset:export_master_key_subkeys_and_revocation_key_to_private_LUKS_container done" } #Export public key to thumb drive's public partition @@ -402,9 +412,9 @@ wipe_thumb_drive_and_copy_gpg_key_material() { fi select_luks_container_size_percent #Wipe thumb drive with a LUKS container of size $(cat /tmp/luks_container_size_percent) - prepare_thumb_drive --device "$thumb_drive" --percentage "$(cat /tmp/luks_container_size_percent)" --pass "$ADMIN_PIN" + prepare_thumb_drive --device "$thumb_drive" --percentage "$(cat /tmp/luks_container_size_percent)" --pass "${ADMIN_PIN}" #Export master key and subkeys to thumb drive first partition - export_master_key_subkeys_and_revocation_key_to_private_LUKS_container --mode rw --device "$thumb_drive"1 --mountpoint /media --pass "$ADMIN_PIN" + export_master_key_subkeys_and_revocation_key_to_private_LUKS_container --mode rw --device "$thumb_drive"1 --mountpoint /media --pass "${ADMIN_PIN}" #Export public key to thumb drive's public partition export_public_key_to_thumbdrive_public_partition --mode rw --device "$thumb_drive"2 --mountpoint /media } @@ -416,7 +426,7 @@ gpg_key_factory_reset() { enable_usb # Factory reset GPG card - DEBUG "GPG factory reset..." + echo "GPG factory reset of smartcard..." { echo admin echo factory-reset @@ -467,7 +477,7 @@ gpg_key_factory_reset() { whiptail_error_die "Setting key to NIST-P256 in USB security dongle failed." fi # fallback to RSA key generation by default - else + elif [ "$GPG_ALGO" = "rsa" ]; then DEBUG "GPG setting RSA key length to ${RSA_KEY_LENGTH} bits..." # Set RSA key length { @@ -488,33 +498,33 @@ gpg_key_factory_reset() { ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB security dongle failed." fi + else + #Unknown GPG_ALGO + whiptail_error_die "Unknown GPG_ALGO: $GPG_ALGO" fi } generate_OEM_gpg_keys() { - # Generate OEM GPG keys TRACE "Under oem-factory-reset:generate_OEM_gpg_keys" - #TODO: finish refactoring to adapt to GPG_ALGO != RSA - if [ "$GPG_ALGO" = "RSA" ]; then - DEBUG "Generating GPG keys to RSA ${RSA_KEY_LENGTH} bits in smartcard..." - { - echo admin - echo generate - echo n - echo ${ADMIN_PIN_DEF} - echo ${USER_PIN_DEF} - echo 0 - echo ${GPG_USER_NAME} - echo ${GPG_USER_MAIL} - echo ${GPG_USER_COMMENT} - echo ${USER_PIN_DEF} - } | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR" - fi + #This function simply generates subkeys in smartcard following smarcard config from gpg_key_factory_reset + echo "Generating GPG keys in smartcard..." + { + echo admin + echo generate + echo n + echo ${ADMIN_PIN_DEF} + echo ${USER_PIN_DEF} + echo 0 + echo ${GPG_USER_NAME} + echo ${GPG_USER_MAIL} + echo ${GPG_USER_COMMENT} + echo ${USER_PIN_DEF} + } | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR" fi } @@ -606,7 +616,7 @@ generate_checksums() { # sign kexec boot files if sha256sum $param_files 2>/dev/null | gpg \ --pinentry-mode loopback \ - --passphrase "$USER_PIN" \ + --passphrase "${USER_PIN}" \ --digest-algo SHA256 \ --detach-sign \ -a \ @@ -784,7 +794,7 @@ $TPM_STR fi # We show current integrity measurements status and time -#TODO: Reactivate this prior of PR review +#TODO: readd prior of PR review request. Also make sure that check_config is called to check kexec.sig (detached signature validation) #report_integrity_measurements # Determine gpg algorithm to be used, based on available usb-token @@ -798,6 +808,7 @@ fi if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then #Give general guidance to user on how to answer prompts + echo echo "The following questionnaire will help you to configure the security components of your system." echo "You will be prompted for each option to answer a single letter at prompts (Y/n/m)." echo "If you don't know what to answer, just press Enter to use default value which is shown between [] brackets as the uppercase letter." @@ -830,8 +841,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then -o "$prompt_output" == "M" ] \ ; then GPG_GEN_KEY_IN_MEMORY=1 - #TODO: present steps clearer for user - echo "Master key and subkeys will be generated in memory, backuped to dedicated LUKS container and then subkeys imported to factory resetted smartcard." + echo "Master key and subkeys will be generated in memory, backuped to dedicated LUKS container and then subkeys copied to smartcard." else GPG_GEN_KEY_IN_MEMORY=0 fi @@ -866,13 +876,13 @@ GPG User PIN" read CUSTOM_SINGLE_PASS done echo - TPM_PASS=$CUSTOM_SINGLE_PASS - USER_PIN=$CUSTOM_SINGLE_PASS - ADMIN_PIN=$CUSTOM_SINGLE_PASS + TPM_PASS=${CUSTOM_SINGLE_PASS} + USER_PIN=${CUSTOM_SINGLE_PASS} + ADMIN_PIN=${CUSTOM_SINGLE_PASS} # Only set if user said desired. Matches rest of logic if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - luks_new_Disk_Recovery_Key_passphrase=$CUSTOM_SINGLE_PASS + luks_new_Disk_Recovery_Key_passphrase=${CUSTOM_SINGLE_PASS} fi else echo -e -n "Would you like to set distinct PINs/passwords to be provisioned to previously stated security components? [y/N]: " @@ -950,9 +960,9 @@ GPG User PIN" fi # If nothing is stored in custom variables, we set them to their defaults -if [ "$TPM_PASS" == "" ]; then TPM_PASS=$TPM_PASS_DEF; fi -if [ "$USER_PIN" == "" ]; then USER_PIN=$USER_PIN_DEF; fi -if [ "$ADMIN_PIN" == "" ]; then ADMIN_PIN=$ADMIN_PIN_DEF; fi +if [ "$TPM_PASS" == "" ]; then TPM_PASS=${TPM_PASS_DEF}; fi +if [ "$USER_PIN" == "" ]; then USER_PIN=${USER_PIN_DEF}; fi +if [ "$ADMIN_PIN" == "" ]; then ADMIN_PIN=${ADMIN_PIN_DEF}; fi ## sanity check the USB, GPG key, and boot device before proceeding further @@ -1003,12 +1013,10 @@ assert_signable # Action time... -#TODO: Should we replace text from "Add a new GPG key" to "Replace current GPG key"? Should we wipe current keyring? -#Current logic is for factory reset, where re-ownership adds key to the keyring which is then copied over cbfs. -# In the all case, we should wipe the keyring since otherwise, USB security dongle is wiped but not the keyring which exposes past public keys -# this seems wrong # clear local keyring -rm /.gnupg/* | true +rm -rf /.gnupg/* >/dev/null 2>&1 || true +# clear gpg-agent cache so that next gpg calls doesn't have past keyring in memory +killall gpg-agent >/dev/null 2>&1 || true # detect and set /boot device echo -e "\nDetecting and setting boot device...\n" @@ -1051,9 +1059,8 @@ rm /.gnupg/*.gpg 2>/dev/null rm /.gnupg/*.kbx 2>/dev/null gpg --list-keys >/dev/null 2>&1 -#Generate key in memory and copy to smartcard +#Generate keys in memory and copy to smartcard if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then - # TODO: Refactoring in progress for RSA and p256 support. Now just GPG_ALGO RSA if [ "$GPG_ALGO" == "RSA" ]; then # Generate GPG master key generate_inmemory_RSA_master_and_subkeys @@ -1061,7 +1068,6 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then wipe_thumb_drive_and_copy_gpg_key_material #TODO seperate setting config set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y - gpg_key_factory_reset #TODO: do we currently double reset? I think so keytocard_subkeys_to_smartcard elif [ "$GPG_ALGO" == "p256" ]; then generate_inmemory_p256_master_and_subkeys @@ -1069,14 +1075,12 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then wipe_thumb_drive_and_copy_gpg_key_material #TODO seperate setting config set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y - gpg_key_factory_reset #TODO: do we currently double reset? I think so keytocard_subkeys_to_smartcard else die "Unsupported GPG_ALGO: $GPG_ALGO" fi else - #Generate GPG key and subkeys on smartcard - ## reset the GPG Key + #Generate GPG key and subkeys on smartcard only echo -e "\nResetting GPG Key...\n(this will take around 3 minutes...)\n" gpg_key_factory_reset generate_OEM_gpg_keys @@ -1087,37 +1091,34 @@ GPG_GEN_KEY=$(gpg --list-keys --with-colons | grep "^fpr" | cut -d: -f10 | head #Where to export the public key PUBKEY="/tmp/${GPG_GEN_KEY}.asc" -DEBUG "GPG_GEN_KEY: $GPG_GEN_KEY" -DEBUG "PUBKEY: $PUBKEY" - # export pubkey to file if ! gpg --export --armor "$GPG_GEN_KEY" >"${PUBKEY}" 2>/tmp/error; then ERROR=$(tail -n 1 /tmp/error | fold -s) whiptail_error_die "GPG Key gpg export to file failed!\n\n$ERROR" fi -#Applying custom GPG PINs if keys were not generated in memory -if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then - if [ "$USER_PIN" != "" -o "$ADMIN_PIN" != "" ]; then - echo -e "\nChanging default GPG Admin PIN\n" - gpg_key_change_pin "3" "$ADMIN_PIN_DEF" "$ADMIN_PIN" - echo -e "\nChanging default GPG User PIN\n" - gpg_key_change_pin "1" "$USER_PIN_DEF" "$USER_PIN" - fi +#Applying custom GPG PINs to the smartcard if they were provided +if [ "$USER_PIN" != "" -o "$ADMIN_PIN" != "" ]; then + echo -e "\nChanging default GPG Admin PIN\n" + gpg_key_change_pin "3" "$ADMIN_PIN_DEF" "$ADMIN_PIN" + echo -e "\nChanging default GPG User PIN\n" + gpg_key_change_pin "1" "$USER_PIN_DEF" "$USER_PIN" +fi - ## export pubkey to USB - if [ $GPG_EXPORT -ne 0 ]; then - echo -e "\nExporting generated key to USB...\n" - # copy to USB - if ! cp "${PUBKEY}" "/media/${GPG_GEN_KEY}.asc" 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Key export error: unable to copy ${GPG_GEN_KEY}.asc to /media:\n\n$ERROR" - fi - mount -o remount,ro /media 2>/dev/null +## export pubkey to USB +if [ $GPG_EXPORT -ne 0 ]; then + echo -e "\nExporting generated key to USB...\n" + # copy to USB + if ! cp "${PUBKEY}" "/media/${GPG_GEN_KEY}.asc" 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Key export error: unable to copy ${GPG_GEN_KEY}.asc to /media:\n\n$ERROR" fi + mount -o remount,ro /media 2>/dev/null +fi fi ## flash generated key to ROM +# TODO: would be nice if we warned users that qemu boards will fail here and tell them what to do echo -e "\nReading current firmware...\n(this will take a minute or two)\n" /bin/flash.sh -r /tmp/oem-setup.rom >/dev/null 2>/tmp/error if [ ! -s /tmp/oem-setup.rom ]; then @@ -1142,34 +1143,34 @@ if ! gpg --update-trust >/dev/null 2>/tmp/error; then whiptail_error_die "Error updating GPG ownertrust:\n\n$ERROR" fi -# clear any existing heads/gpg files from current firmware -for i in $(cbfs.sh -o /tmp/oem-setup.rom -l | grep -e "heads/"); do - cbfs.sh -o /tmp/oem-setup.rom -d "$i" -done -# add heads/gpg files to current firmware + # clear any existing heads/gpg files from current firmware + for i in $(cbfs.sh -o /tmp/oem-setup.rom -l | grep -e "heads/"); do + cbfs.sh -o /tmp/oem-setup.rom -d "$i" + done + # add heads/gpg files to current firmware -if [ -e /.gnupg/pubring.kbx ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx - if [ -e /.gnupg/pubring.gpg ]; then - rm /.gnupg/pubring.gpg - fi -elif [ -e /.gnupg/pubring.gpg ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg -fi -if [ -e /.gnupg/trustdb.gpg ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg -fi + if [ -e /.gnupg/pubring.kbx ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx + if [ -e /.gnupg/pubring.gpg ]; then + rm /.gnupg/pubring.gpg + fi + elif [ -e /.gnupg/pubring.gpg ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg + fi + if [ -e /.gnupg/trustdb.gpg ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg + fi -# persist user config changes (boot device) -if [ -e /etc/config.user ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/etc/config.user" -f /etc/config.user -fi + # persist user config changes (boot device) + if [ -e /etc/config.user ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/etc/config.user" -f /etc/config.user + fi -# flash updated firmware image -echo -e "\nAdding generated key to current firmware and re-flashing...\n" -if ! /bin/flash.sh /tmp/oem-setup.rom 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error flashing updated firmware image:\n\n$ERROR" + # flash updated firmware image + echo -e "\nAdding generated key to current firmware and re-flashing...\n" + if ! /bin/flash.sh /tmp/oem-setup.rom 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error flashing updated firmware image:\n\n$ERROR" fi ## sign files in /boot and generate checksums @@ -1188,7 +1189,7 @@ fi if [ "$CONFIG_TPM" = "y" ]; then tpm_owner_password_changed=" - TPM Owner Password: $TPM_PASS\n" + TPM Owner Password: ${TPM_PASS}\n" else tpm_owner_password_changed="" fi @@ -1197,8 +1198,8 @@ fi whiptail --msgbox " $luks_passphrase_changed $tpm_owner_password_changed - GPG Admin PIN: $ADMIN_PIN\n - GPG User PIN: $USER_PIN\n\n" \ + GPG Admin PIN: ${ADMIN_PIN}\n + GPG User PIN: ${USER_PIN}\n\n" \ $HEIGHT $WIDTH --title "Provisioned secrets" ## all done -- reboot From 05fc4c1747e190c59d4a514f0bf039419453f058 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 26 Oct 2023 16:51:58 -0400 Subject: [PATCH 20/69] PCR extend ops inform users on what happens, otherwise we tpm commands output on screen without context Signed-off-by: Thierry Laurion --- initrd/bin/cbfs-init | 1 + initrd/bin/qubes-measure-luks | 2 +- initrd/sbin/insmod | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index 5343db7a..81948ef8 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -24,6 +24,7 @@ for cbfsname in `echo $cbfsfiles`; do TMPFILE=/tmp/cbfs.$$ echo "$filename" > $TMPFILE cat $filename >> $TMPFILE + echo " !!!!! Extending TPM PCR $CONFIG_PCR with $filename !!!!!" tpmr extend -ix "$CONFIG_PCR" -if $TMPFILE \ || die "$filename: tpm extend failed" fi diff --git a/initrd/bin/qubes-measure-luks b/initrd/bin/qubes-measure-luks index 4d396ff6..12248160 100755 --- a/initrd/bin/qubes-measure-luks +++ b/initrd/bin/qubes-measure-luks @@ -19,6 +19,6 @@ 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" +echo " !!!! Extending PCR 6 with hash of LUKS headers from /tmp/luksDump.txt !!!!" tpmr extend -ix 6 -if /tmp/luksDump.txt || die "Unable to extend PCR" diff --git a/initrd/sbin/insmod b/initrd/sbin/insmod index 39d205b0..34138ee5 100755 --- a/initrd/sbin/insmod +++ b/initrd/sbin/insmod @@ -30,7 +30,8 @@ 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" + echo + echo " !!!!! Extending TPM PCR $MODULE_PCR with $MODULE prior of usage !!!!!" tpmr extend -ix "$MODULE_PCR" -if "$MODULE" \ || die "$MODULE: tpm extend failed" fi @@ -39,7 +40,8 @@ if [ ! -z "$*" -a -z "$tpm_missing" ]; then DEBUG "Extending PCR $MODULE_PCR with $*" TMPFILE=/tmp/insmod.$$ echo "$@" > $TMPFILE - DEBUG "Extending PCR $MODULE_PCR with $TMPFILE" + echo + echo " !!!!! 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 From 7f5d9700b7c99b464156ed2e080fbf9a063e8e82 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 26 Oct 2023 16:52:38 -0400 Subject: [PATCH 21/69] gpg_auth function was not failing properly on failing, die instead Signed-off-by: Thierry Laurion --- initrd/etc/ash_functions | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 5c140531..bbf12387 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -189,8 +189,12 @@ gpg_auth() { return 0 else shred -n 10 -z -u "$CR_SIG" 2>/dev/null || true - echo >&2 "!!!!! GPG authentication failed, please try again !!!!!" - continue + 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 @@ -214,6 +218,7 @@ recovery() { . /tmp/config if [ "$CONFIG_TPM" = "y" ]; then + echo " !!!!! Extending TPM PCR 4 for recovery shell access !!!!!" tpmr extend -ix 4 -ic recovery fi From 9c3fb353585bab66729894b762a2cc4aaab1dd69 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 27 Oct 2023 11:15:48 -0400 Subject: [PATCH 22/69] initrd/bin/reboot: BugFix in nv41/ns50 condition check to call nitropad-shutdown.sh (otherwise output error on console for improper condition in ash Signed-off-by: Thierry Laurion --- initrd/bin/reboot | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/initrd/bin/reboot b/initrd/bin/reboot index f226a927..eb63f253 100755 --- a/initrd/bin/reboot +++ b/initrd/bin/reboot @@ -18,8 +18,8 @@ if [ "$CONFIG_TPM" = "y" ]; then 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 From 7cd44b6dc4e56e0732569975d02c51f712848866 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 27 Oct 2023 11:18:20 -0400 Subject: [PATCH 23/69] oem-factory-reset: further cleaning of code for proper validation and consistency checks for passphrases. Also skip flashing code on qemu boards with short explanation Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 128 +++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 51 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 0bdecb08..b840e3c6 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -251,7 +251,6 @@ keytocard_subkeys_to_smartcard() { enable_usb_storage gpg --card-status >/dev/null 2>&1 || die "Error getting GPG card status" - echo "Factory resetting the smartcard..." gpg_key_factory_reset echo "Moving subkeys to smartcard..." @@ -282,7 +281,8 @@ keytocard_subkeys_to_smartcard() { ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key moving subkeys to smartcard failed!\n\n$ERROR" fi - echo "Moving subkeys to smartcard done." + + TRACE "oem-factory-reset:keytocard_subkeys_to_smartcard done" } #Whiptail prompt to disconnect any external USB storage device @@ -357,7 +357,8 @@ export_master_key_subkeys_and_revocation_key_to_private_LUKS_container() { cp -af ~/.gnupg "$mountpoint"/.gnupg || die "Error copying whole keyring to private LUKS container's partition" #Unmount private LUKS container's mount point umount "$mountpoint" || die "Error unmounting private LUKS container's mount point" - TRACE "Under oem-factory-reset:export_master_key_subkeys_and_revocation_key_to_private_LUKS_container done" + + TRACE "oem-factory-reset:export_master_key_subkeys_and_revocation_key_to_private_LUKS_container done" } #Export public key to thumb drive's public partition @@ -390,10 +391,10 @@ export_public_key_to_thumbdrive_public_partition() { #pass non-empty arguments to --pass, --mountpoint, --device, --mode mount-usb --device "$device" --mode "$mode" --mountpoint "$mountpoint" || die "Error mounting thumb drive's public partition" - gpg --export --armor "${GPG_USER_MAIL}" >"$mountpoint"/pubkey.asc || die "Error exporting public key to thumb drive's public partition" - umount "$mountpoint" || die "Error unmounting thumb drive's public partition" + + TRACE "oem-factory-reset:export_public_key_to_thumbdrive_public_partition done" } #Wipe a thumb drive and export master key and subkeys to it @@ -417,6 +418,8 @@ wipe_thumb_drive_and_copy_gpg_key_material() { export_master_key_subkeys_and_revocation_key_to_private_LUKS_container --mode rw --device "$thumb_drive"1 --mountpoint /media --pass "${ADMIN_PIN}" #Export public key to thumb drive's public partition export_public_key_to_thumbdrive_public_partition --mode rw --device "$thumb_drive"2 --mountpoint /media + + TRACE "Under oem-factory-reset:wipe_thumb_drive_and_copy_gpg_key_material done" } gpg_key_factory_reset() { @@ -426,7 +429,7 @@ gpg_key_factory_reset() { enable_usb # Factory reset GPG card - echo "GPG factory reset of smartcard..." + echo "GPG factory reset of USB Security Dongle's smartcard..." { echo admin echo factory-reset @@ -502,13 +505,15 @@ gpg_key_factory_reset() { #Unknown GPG_ALGO whiptail_error_die "Unknown GPG_ALGO: $GPG_ALGO" fi + + TRACE "oem-factory-reset:gpg_key_factory_reset done" } generate_OEM_gpg_keys() { TRACE "Under oem-factory-reset:generate_OEM_gpg_keys" #This function simply generates subkeys in smartcard following smarcard config from gpg_key_factory_reset - echo "Generating GPG keys in smartcard..." + echo "Generating GPG keys in USB Security dongle's smartcard..." { echo admin echo generate @@ -526,15 +531,17 @@ generate_OEM_gpg_keys() { ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR" fi + + TRACE "oem-factory-reset:generate_OEM_gpg_keys done" } gpg_key_change_pin() { TRACE "Under oem-factory-reset:gpg_key_change_pin" - DEBUG "Changing GPG key PINs..." + DEBUG "Changing GPG key PIN" # 1 = user PIN, 3 = admin PIN PIN_TYPE=$1 - PIN_ORIG=$2 - PIN_NEW=$3 + PIN_ORIG=${2} + PIN_NEW=${3} # Change PIN { echo admin @@ -551,10 +558,13 @@ gpg_key_change_pin() { ERROR=$(cat /tmp/gpg_card_edit_output | fold -s) whiptail_error_die "GPG Key PIN change failed!\n\n$ERROR" fi + + TRACE "oem-factory-reset:gpg_key_change_pin done" } generate_checksums() { TRACE "Under oem-factory-reset:generate_checksums" + # ensure /boot mounted if ! grep -q /boot /proc/mounts; then mount -o rw /boot || whiptail_error_die "Unable to mount /boot" @@ -640,10 +650,13 @@ generate_checksums() { ERROR=$(tail -n 1 /tmp/error | fold -s) whiptail_error_die "Error signing kexec boot files:\n\n$ERROR" fi + + TRACE "oem-factory-reset:generate_checksums done" } set_default_boot_option() { TRACE "Under oem-factory-reset:set_default_boot_option" + option_file="/tmp/kexec_options.txt" tmp_menu_file="/tmp/kexec/kexec_menu.txt" hash_file="/boot/kexec_default_hashes.txt" @@ -684,10 +697,13 @@ set_default_boot_option() { (cd /boot && /bin/kexec-boot -b "/boot" -e "$entry" -f | xargs sha256sum >$hash_file 2>/dev/null) || whiptail_error_die "Failed to create hashes of boot files" + + TRACE "oem-factory-reset:set_default_boot_option done" } report_integrity_measurements() { TRACE "Under oem-factory-reset:report_integrity_measurements" + #check for GPG key in keyring GPG_KEY_COUNT=$(gpg -k 2>/dev/null | wc -l) if [ "$GPG_KEY_COUNT" -ne 0 ]; then @@ -741,6 +757,8 @@ report_integrity_measurements() { #Show results whiptail $MAIN_MENU_BG_COLOR --title "Measured Integrity Report" --msgbox "$date\nTOTP: $TOTP | HOTP: $HOTP\n/BOOT INTEGRITY: $HASH\n\nPress OK to continue or Ctrl+Alt+Delete to reboot" 0 80 fi + + TRACE "oem-factory-reset:report_integrity_measurements done" } usb_security_token_capabilities_check() { @@ -1067,14 +1085,14 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then #TODO seperate wiping and thumb drive functions with proper validation wipe_thumb_drive_and_copy_gpg_key_material #TODO seperate setting config - set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y + set_user_config "CONFIG_HAVE_GPG_KEY_BACKUP" "y" keytocard_subkeys_to_smartcard elif [ "$GPG_ALGO" == "p256" ]; then generate_inmemory_p256_master_and_subkeys #TODO seperate wiping and thumb drive functions with proper validation wipe_thumb_drive_and_copy_gpg_key_material #TODO seperate setting config - set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y + keytocard_subkeys_to_smartcard else die "Unsupported GPG_ALGO: $GPG_ALGO" @@ -1098,15 +1116,15 @@ if ! gpg --export --armor "$GPG_GEN_KEY" >"${PUBKEY}" 2>/tmp/error; then fi #Applying custom GPG PINs to the smartcard if they were provided -if [ "$USER_PIN" != "" -o "$ADMIN_PIN" != "" ]; then +if [ "${USER_PIN}" != "" -o "${ADMIN_PIN}" != "" ]; then echo -e "\nChanging default GPG Admin PIN\n" - gpg_key_change_pin "3" "$ADMIN_PIN_DEF" "$ADMIN_PIN" + gpg_key_change_pin "3" "${ADMIN_PIN_DEF}" "${ADMIN_PIN}" echo -e "\nChanging default GPG User PIN\n" - gpg_key_change_pin "1" "$USER_PIN_DEF" "$USER_PIN" + gpg_key_change_pin "1" "${USER_PIN_DEF}" "${USER_PIN}" fi ## export pubkey to USB -if [ $GPG_EXPORT -ne 0 ]; then +if [ "$GPG_EXPORT" != "0" ]; then echo -e "\nExporting generated key to USB...\n" # copy to USB if ! cp "${PUBKEY}" "/media/${GPG_GEN_KEY}.asc" 2>/tmp/error; then @@ -1115,16 +1133,6 @@ if [ $GPG_EXPORT -ne 0 ]; then fi mount -o remount,ro /media 2>/dev/null fi -fi - -## flash generated key to ROM -# TODO: would be nice if we warned users that qemu boards will fail here and tell them what to do -echo -e "\nReading current firmware...\n(this will take a minute or two)\n" -/bin/flash.sh -r /tmp/oem-setup.rom >/dev/null 2>/tmp/error -if [ ! -s /tmp/oem-setup.rom ]; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error reading current firmware:\n\n$ERROR" -fi # ensure key imported locally if ! cat "$PUBKEY" | gpg --import >/dev/null 2>/tmp/error; then @@ -1143,34 +1151,52 @@ if ! gpg --update-trust >/dev/null 2>/tmp/error; then whiptail_error_die "Error updating GPG ownertrust:\n\n$ERROR" fi - # clear any existing heads/gpg files from current firmware - for i in $(cbfs.sh -o /tmp/oem-setup.rom -l | grep -e "heads/"); do - cbfs.sh -o /tmp/oem-setup.rom -d "$i" - done - # add heads/gpg files to current firmware +# Do not attempt to flash the key to ROM if we are running in QEMU based on CONFIG_BOARD_NAME matching glob pattern containing qemu-* +# We check for qemu-* instead of ^qemu- because CONFIG_BOARD_NAME could be renamed to UNTESTED-qemu-* in a probable future +if [[ "$CONFIG_BOARD_NAME" == qemu-* ]]; then + warn "Skipping flash of GPG key to ROM because we are running in QEMU" + warn "Please review documentation md file under board directory on your building machine, and review board config options in .config file to enable configuration options you want to test in QEMU until internal flashing support is integrated." +else + #We are not running in QEMU, so flash the key to ROM - if [ -e /.gnupg/pubring.kbx ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx - if [ -e /.gnupg/pubring.gpg ]; then - rm /.gnupg/pubring.gpg - fi - elif [ -e /.gnupg/pubring.gpg ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg - fi - if [ -e /.gnupg/trustdb.gpg ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg - fi + ## flash generated key to ROM + # TODO: would be nice if we warned users that qemu boards will fail here and tell them what to do + echo -e "\nReading current firmware...\n(this will take a minute or two)\n" + /bin/flash.sh -r /tmp/oem-setup.rom >/dev/null 2>/tmp/error + if [ ! -s /tmp/oem-setup.rom ]; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error reading current firmware:\n\n$ERROR" + fi - # persist user config changes (boot device) - if [ -e /etc/config.user ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/etc/config.user" -f /etc/config.user - fi + # clear any existing heads/gpg files from current firmware + for i in $(cbfs.sh -o /tmp/oem-setup.rom -l | grep -e "heads/"); do + cbfs.sh -o /tmp/oem-setup.rom -d "$i" + done + # add heads/gpg files to current firmware - # flash updated firmware image - echo -e "\nAdding generated key to current firmware and re-flashing...\n" - if ! /bin/flash.sh /tmp/oem-setup.rom 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error flashing updated firmware image:\n\n$ERROR" + if [ -e /.gnupg/pubring.kbx ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx + if [ -e /.gnupg/pubring.gpg ]; then + rm /.gnupg/pubring.gpg + fi + elif [ -e /.gnupg/pubring.gpg ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg + fi + if [ -e /.gnupg/trustdb.gpg ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg + fi + + # persist user config changes (boot device) + if [ -e /etc/config.user ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/etc/config.user" -f /etc/config.user + fi + + # flash updated firmware image + echo -e "\nAdding generated key to current firmware and re-flashing...\n" + if ! /bin/flash.sh /tmp/oem-setup.rom 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error flashing updated firmware image:\n\n$ERROR" + fi fi ## sign files in /boot and generate checksums From 8a8634f6a3abb999b63f1e5754cee913c83b3ad9 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 30 Oct 2023 11:37:31 -0400 Subject: [PATCH 24/69] oem-factory-reset seal-hotpkey: unify prompts and vocabulary oem-factory-reset: bugfix, keytocard inverts prompts. First is keyring then smartcard. Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 302 +++++++++++++++++++---------------- initrd/bin/seal-hotpkey | 2 +- 2 files changed, 161 insertions(+), 143 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index b840e3c6..176d52a4 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -81,15 +81,15 @@ generate_inmemory_RSA_master_and_subkeys() { echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits master key..." # Generate GPG master key { - echo "Key-Type: RSA" - echo "Key-Length: ${RSA_KEY_LENGTH}" - echo "Key-Usage: sign" - echo "Name-Real: ${GPG_USER_NAME}" - echo "Name-Comment: ${GPG_USER_COMMENT}" - echo "Name-Email: ${GPG_USER_MAIL}" - echo "Expire-Date: 0" - echo "Passphrase: ${ADMIN_PIN}" - echo "%commit" + echo "Key-Type: RSA" # RSA key + echo "Key-Length: ${RSA_KEY_LENGTH}" # RSA key length + echo "Key-Usage: sign" # RSA key usage + echo "Name-Real: ${GPG_USER_NAME}" # User name + echo "Name-Comment: ${GPG_USER_COMMENT}" # User comment + echo "Name-Email: ${GPG_USER_MAIL}" # User email + echo "Expire-Date: 0" # No expiration date + echo "Passphrase: ${ADMIN_PIN}" # Admin PIN + echo "%commit" # Commit changes } | gpg --command-fd=0 --status-fd=1 --batch --gen-key >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR=$(cat /tmp/gpg_card_edit_output) @@ -99,13 +99,13 @@ generate_inmemory_RSA_master_and_subkeys() { echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits signing subkey..." # Add signing subkey { - echo addkey - echo 4 # RSA (sign only) - echo ${RSA_KEY_LENGTH} - echo 0 # no expiration - echo ${ADMIN_PIN} - echo y # confirm - echo save + echo addkey # add key in --edit-key mode + echo 4 # RSA (sign only) + echo ${RSA_KEY_LENGTH} # Signing key size set to RSA_KEY_LENGTH + echo 0 # No expiration date + echo ${ADMIN_PIN} # Local keyring admin pin + echo y # confirm + echo save # save changes and commit to keyring } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then @@ -116,13 +116,13 @@ generate_inmemory_RSA_master_and_subkeys() { echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits encryption subkey..." #Add encryption subkey { - echo addkey - echo 6 # RSA (encrypt only) - echo ${RSA_KEY_LENGTH} - echo 0 # no expiration - echo ${ADMIN_PIN} - echo y # confirm - echo save + echo addkey # add key in --edit-key mode + echo 6 # RSA (encrypt only) + echo ${RSA_KEY_LENGTH} # Encryption key size set to RSA_KEY_LENGTH + echo 0 # No expiration date + echo ${ADMIN_PIN} # Local keyring admin pin + echo y # confirm + echo save # save changes and commit to keyring } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then @@ -136,17 +136,17 @@ generate_inmemory_RSA_master_and_subkeys() { #Authentication subkey needs gpg in expert mode to select RSA custom mode (8) # in order to disable encryption and signing capabilities of subkey # and then enable authentication capability - echo addkey - echo 8 # RSA (own capabilite) - echo S # disable signing capability - echo E # disable encryption capability - echo A # enable authentication capability - echo Q # quit - echo ${RSA_KEY_LENGTH} - echo 0 # no expiration - echo ${ADMIN_PIN} - echo y # confirm - echo save + echo addkey # add key in --edit-key mode + echo 8 # RSA (set your own capabilities) + echo S # disable sign capability + echo E # disable encryption capability + echo A # enable authentication capability + echo Q # Quit + echo ${RSA_KEY_LENGTH} # Authentication key size set to RSA_KEY_LENGTH + echo 0 # No expiration date + echo ${ADMIN_PIN} # Local keyring admin pin + echo y # confirm + echo save # save changes and commit to keyring } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --expert --edit-key "${GPG_USER_MAIL}" \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then @@ -157,10 +157,10 @@ generate_inmemory_RSA_master_and_subkeys() { DEBUG "Setting public key to ultimate trust..." #Set the public key to the ultimate trust { - echo trust - echo 5 # ultimate - echo y # confirm - echo save + echo trust # trust key in --edit-key mode + echo 5 # ultimate trust + echo y # confirm + echo save # save changes and commit to keyring } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then @@ -177,15 +177,16 @@ generate_inmemory_p256_master_and_subkeys() { echo "Generating GPG p256 bits master key..." { - echo "Key-Type: ECDSA" - echo "Key-Curve: nistp256" - echo "Key-Usage: cert" - echo "Name-Real: ${GPG_USER_NAME}" - echo "Name-Comment: ${GPG_USER_COMMENT}" - echo "Name-Email: ${GPG_USER_MAIL}" - echo "Expire-Date: 0" - echo "%commit" - } | gpg --expert --batch --pinentry-mode=loopback --passphrase=<(echo -n "${ADMIN_PIN}") --generate-key \ + echo "Key-Type: ECDSA" # ECDSA key + echo "Key-Curve: nistp256" # ECDSA key curve + echo "Key-Usage: cert" # ECDSA key usage + echo "Name-Real: ${GPG_USER_NAME}" # User name + echo "Name-Comment: ${GPG_USER_COMMENT}" # User comment + echo "Name-Email: ${GPG_USER_MAIL}" # User email + echo "Passphrase: ${ADMIN_PIN}" # Local keyring admin pin + echo "Expire-Date: 0" # No expiration date + echo "%commit" # Commit changes + } | gpg --expert --batch --command-fd=0 --status-fd=1 --pinentry-mode=loopback --generate-key \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR=$(cat /tmp/gpg_card_edit_output) @@ -197,44 +198,56 @@ generate_inmemory_p256_master_and_subkeys() { echo "Generating GPG nistp256 signing subkey..." { - echo addkey - echo 11 # ECC own set capability - echo Q # sign already present - echo 3 # P-256 - echo 0 # no expiration - } | gpg --expert --command-fd=0 --status-fd=1 --passphrase=<(echo -n "${ADMIN_PIN}") --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + echo addkey # add key in --edit-key mode + echo 11 # ECC own set capability + echo Q # sign already present, do not modify + echo 3 # P-256 + echo 0 # no expiration + echo ${ADMIN_PIN} # Local keyring admin pin + echo save # save changes and commit to keyring + } | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR_MSG=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "Failed to add ECC nistp256 signing key to master key\n\n${ERROR_MSG}" fi + DEBUG "TODO REMOVE THIS: output of signing subkey generation /tmp/gpg_card_edit_output $(cat /tmp/gpg_card_edit_output)" + echo "Generating GPG nistp256 encryption subkey..." { echo addkey - echo 12# ECC encrypt only - echo E # encrypt already present - echo 3 # P-256 - echo 0 # no expiration - } | gpg --expert --command-fd=0 --status-fd=1 --passphrase=<(echo -n "${ADMIN_PIN}") --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + echo 12 # ECC own set capability + echo Q # Quit + echo 3 # P-256 + echo 0 # no expiration + echo ${ADMIN_PIN} # Local keyring admin pin + echo save # save changes and commit to keyring + } | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR_MSG=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "Failed to add ECC nistp256 encryption key to master key\n\n${ERROR_MSG}" fi + DEBUG "TODO REMOVE THIS: output of encryption subkey generation /tmp/gpg_card_edit_output $(cat /tmp/gpg_card_edit_output)" + echo "Generating GPG nistp256 authentication subkey..." { - echo addkey - echo 11 # ECC own set capability - echo S # deactivate sign - echo A # activate auth - echo Q # Quit - echo 3 # P-256 - echo 0 # no expiration - } | gpg --expert --command-fd=0 --status-fd=1 --passphrase=<(echo -n "${ADMIN_PIN}") --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + echo addkey # add key in --edit-key mode + echo 11 # ECC own set capability + echo S # deactivate sign + echo A # activate auth + echo Q # Quit + echo 3 # P-256 + echo 0 # no expiration + echo ${ADMIN_PIN} # Local keyring admin pin + echo save # save changes and commit to keyring + } | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR_MSG=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "Failed to add ECC nistp256 authentication key to master key\n\n${ERROR_MSG}" fi + + DEBUG "TODO REMOVE THIS: output of authentication subkey generation /tmp/gpg_card_edit_output $(cat /tmp/gpg_card_edit_output)" } #Function to move current gpg keyring subkeys to card (keytocard) @@ -246,41 +259,46 @@ generate_inmemory_p256_master_and_subkeys() { keytocard_subkeys_to_smartcard() { TRACE "Under oem-factory-reset:keytocard_subkeys_to_smartcard" - #make sure usb ready and usb dongle ready to communicate with + #make sure usb ready and USB Security Dongle ready to communicate with enable_usb enable_usb_storage gpg --card-status >/dev/null 2>&1 || die "Error getting GPG card status" gpg_key_factory_reset + DEBUG "TODO REMOVE THIS: ADMIN_PIN_DEF=${ADMIN_PIN_DEF} ADMIN_PIN=${ADMIN_PIN}" + echo "Moving subkeys to smartcard..." { - echo "key 1" #Select Signature key - echo "keytocard" - echo "1" # Signature key - echo "${ADMIN_PIN}" #Smartcard admin pin - echo "${ADMIN_PIN}" #Subkey PIN - echo "0" #No expiration date - echo "key 1" - echo "key 2" - echo "keytocard" - echo "2" # Encryption key - echo "${ADMIN_PIN}" - echo "${ADMIN_PIN}" - echo "key 2" - echo "key 3" - echo "keytocard" - echo "3" # Authentication key - echo "${ADMIN_PIN}" - echo "${ADMIN_PIN}" - echo "key 3" - echo "save" - } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --expert --edit-key "${GPG_USER_MAIL}" \ + echo "key 1" #Toggle on Signature key in --edit-key mode on local keyring + echo "keytocard" #Move Signature key to smartcard + echo "1" #Select Signature key keyslot on smartcard + echo "${ADMIN_PIN}" #Local keyring Subkey PIN + echo "${ADMIN_PIN_DEF}" #Smartcard Admin PIN + echo "0" #No expiration date + echo "key 1" #Toggle off Signature key + echo "key 2" #Toggle on Encryption key + echo "keytocard" #Move Encryption key to smartcard + echo "2" #Select Encryption key keyslot on smartcard + echo "${ADMIN_PIN}" #Local keyring Subkey PIN + echo "${ADMIN_PIN_DEF}" #Smartcard Admin PIN + echo "key 2" #Toggle off Encryption key + echo "key 3" #Toggle on Authentication key + echo "keytocard" #Move Authentication key to smartcard + echo "3" #Select Authentication key keyslot on smartcard + echo "${ADMIN_PIN}" #Local keyring Subkey PIN + echo "${ADMIN_PIN_DEF}" #Smartcard Admin PIN + echo "key 3" #Toggle off Authentication key + echo "save" #Save changes and commit to keyring + } | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key moving subkeys to smartcard failed!\n\n$ERROR" fi + #TODO: Clarify in code that since reset gpg is done, passwd is default and then cange_pass is done + + DEBUG "TODO REMOVE THIS. Ouput of /tmp/gpg_card_edit_output: $(cat /tmp/gpg_card_edit_output)" TRACE "oem-factory-reset:keytocard_subkeys_to_smartcard done" } @@ -349,9 +367,9 @@ export_master_key_subkeys_and_revocation_key_to_private_LUKS_container() { DEBUG "Exporting master key and subkeys to private LUKS container's partition..." DEBUG "TODO DELETE THIS pass= ${pass} here" - gpg --export-secret-key --armor --pinentry-mode loopback --passphrase=<(echo -n "${pass}") "${GPG_USER_MAIL}" >"$mountpoint"/privkey.sec || + "gpg --export-secret-key --armor --pinentry-mode loopback --passphrase="${pass}" "${GPG_USER_MAIL}" >"$mountpoint"/privkey.sec || die "Error exporting master key to private LUKS container's partition" - gpg --export-secret-subkeys --armor --pinentry-mode loopback --passphrase=<(echo -n "${pass}") "${GPG_USER_MAIL}" >"$mountpoint"/subkeys.sec || + gpg --export-secret-subkeys --armor --pinentry-mode loopback --passphrase="${pass}" "${GPG_USER_MAIL}" >"$mountpoint"/subkeys.sec || die "Error exporting subkeys to private LUKS container's partition" #copy whole keyring to thumb drive, including revocation key and trust database cp -af ~/.gnupg "$mountpoint"/.gnupg || die "Error copying whole keyring to private LUKS container's partition" @@ -431,10 +449,10 @@ gpg_key_factory_reset() { # Factory reset GPG card echo "GPG factory reset of USB Security Dongle's smartcard..." { - echo admin - echo factory-reset - echo y - echo yes + echo admin # admin menu + echo factory-reset # factory reset smartcard + echo y # confirm + echo yes # confirm } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then @@ -449,9 +467,9 @@ gpg_key_factory_reset() { if gpg --card-status | grep "Signature PIN" | grep -q "not forced"; then DEBUG "GPG toggling forcesig on since off..." { - echo admin - echo forcesig - echo ${ADMIN_PIN_DEF} + echo admin # admin menu + echo forcesig # toggle forcesig + echo ${ADMIN_PIN_DEF} # local keyring PIN } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then @@ -462,22 +480,22 @@ gpg_key_factory_reset() { # use p256 for key generation if requested if [ "$GPG_ALGO" = "p256" ]; then { - echo admin - echo key-attr - echo 2 # ECC - echo 3 # P-256 - echo ${ADMIN_PIN_DEF} - echo 2 # ECC - echo 3 # P-256 - echo ${ADMIN_PIN_DEF} - echo 2 # ECC - echo 3 # P-256 - echo ${ADMIN_PIN_DEF} - } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit --expert \ + echo admin # admin menu + echo key-attr # key attributes + echo 2 # ECC + echo 3 # P-256 + echo ${ADMIN_PIN_DEF} # local keyring PIN + echo 2 # ECC + echo 3 # P-256 + echo ${ADMIN_PIN_DEF} # local keyring PIN + echo 2 # ECC + echo 3 # P-256 + echo ${ADMIN_PIN_DEF} # local keyring PIN + } | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "Setting key to NIST-P256 in USB security dongle failed." + whiptail_error_die "Setting key to NIST-P256 in USB Security Dongle failed." fi # fallback to RSA key generation by default elif [ "$GPG_ALGO" = "rsa" ]; then @@ -488,18 +506,18 @@ gpg_key_factory_reset() { echo key-attr echo 1 # RSA echo ${RSA_KEY_LENGTH} #Signing key size set to RSA_KEY_LENGTH - echo ${ADMIN_PIN_DEF} + echo ${ADMIN_PIN_DEF} #Local keyring PIN echo 1 # RSA echo ${RSA_KEY_LENGTH} #Encryption key size set to RSA_KEY_LENGTH - echo ${ADMIN_PIN_DEF} + echo ${ADMIN_PIN_DEF} #Local keyring PIN echo 1 # RSA echo ${RSA_KEY_LENGTH} #Authentication key size set to RSA_KEY_LENGTH - echo ${ADMIN_PIN_DEF} + echo ${ADMIN_PIN_DEF} #Local keyring PIN } | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB security dongle failed." + whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB Security Dongle failed." fi else #Unknown GPG_ALGO @@ -513,18 +531,18 @@ generate_OEM_gpg_keys() { TRACE "Under oem-factory-reset:generate_OEM_gpg_keys" #This function simply generates subkeys in smartcard following smarcard config from gpg_key_factory_reset - echo "Generating GPG keys in USB Security dongle's smartcard..." + echo "Generating GPG keys in USB Security Dongle's smartcard..." { - echo admin - echo generate - echo n - echo ${ADMIN_PIN_DEF} - echo ${USER_PIN_DEF} - echo 0 - echo ${GPG_USER_NAME} - echo ${GPG_USER_MAIL} - echo ${GPG_USER_COMMENT} - echo ${USER_PIN_DEF} + echo admin # admin menu + echo generate # generate keys + echo n # Do not export keys + echo ${ADMIN_PIN_DEF} # Default admin PIN since we just factory reset + echo ${USER_PIN_DEF} # Default user PIN since we just factory reset + echo 0 # No key expiration + echo ${GPG_USER_NAME} # User name + echo ${GPG_USER_MAIL} # User email + echo ${GPG_USER_COMMENT} # User comment + echo ${USER_PIN_DEF} # Default user PIN since we just factory reset } | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then @@ -544,13 +562,13 @@ gpg_key_change_pin() { PIN_NEW=${3} # Change PIN { - echo admin - echo passwd - echo ${PIN_TYPE} - echo ${PIN_ORIG} - echo ${PIN_NEW} - echo ${PIN_NEW} - echo q + echo admin # admin menu + echo passwd # change PIN + echo ${PIN_TYPE} # 1 = user PIN, 3 = admin PIN + echo ${PIN_ORIG} # old PIN + echo ${PIN_NEW} # new PIN + echo ${PIN_NEW} # confirm new PIN + echo q # quit echo q } | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ >/tmp/gpg_card_edit_output 2>&1 @@ -724,7 +742,7 @@ report_integrity_measurements() { HOTP=$(unseal-hotp) >/dev/null 2>&1 enable_usb if ! hotp_verification info >/dev/null 2>&1; then - whiptail $CONFIG_WARNING_BG_COLOR --title 'WARNING: Please insert your HOTP enabled USB Security dongle' --msgbox "Your HOTP enabled USB Security dongle was not detected.\n\nPlease remove it and insert it again." 0 80 + whiptail $CONFIG_WARNING_BG_COLOR --title 'WARNING: Please insert your HOTP enabled USB Security Dongle' --msgbox "Your HOTP enabled USB Security Dongle was not detected.\n\nPlease remove it and insert it again." 0 80 fi # Don't output HOTP codes to screen, so as to make replay attacks harder hotp_verification check $HOTP @@ -737,7 +755,7 @@ report_integrity_measurements() { MAIN_MENU_BG_COLOR=$CONFIG_ERROR_BG_COLOR ;; *) - HOTP="Error checking code, Insert USB Security dongle and retry" + HOTP="Error checking code, Insert USB Security Dongle and retry" MAIN_MENU_BG_COLOR=$CONFIG_WARNING_BG_COLOR ;; esac @@ -757,7 +775,7 @@ report_integrity_measurements() { #Show results whiptail $MAIN_MENU_BG_COLOR --title "Measured Integrity Report" --msgbox "$date\nTOTP: $TOTP | HOTP: $HOTP\n/BOOT INTEGRITY: $HASH\n\nPress OK to continue or Ctrl+Alt+Delete to reboot" 0 80 fi - + TRACE "oem-factory-reset:report_integrity_measurements done" } @@ -852,7 +870,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then fi #Prompt to ask if user wants to generate GPG key material in memory or on smartcard - echo -e -n "Would you like to generate GPG key material in (m)emory or (S)olely on the security element of the USB security dongle? [m/S]: " + echo -e -n "Would you like to generate GPG key material in (m)emory or (S)olely on the security element of the USB Security Dongle? [m/S]: " read -n 1 prompt_output echo if [ "$prompt_output" == "m" \ @@ -1009,7 +1027,7 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then fi else GPG_EXPORT=0 - # needed for USB Security dongle below and is ensured via mount-usb in case of GPG_EXPORT=1 + # needed for USB Security Dongle below and is ensured via mount-usb in case of GPG_EXPORT=1 enable_usb fi fi @@ -1031,10 +1049,10 @@ assert_signable # Action time... -# clear local keyring -rm -rf /.gnupg/* >/dev/null 2>&1 || true # clear gpg-agent cache so that next gpg calls doesn't have past keyring in memory killall gpg-agent >/dev/null 2>&1 || true +# clear local keyring +rm -rf /.gnupg/* >/dev/null 2>&1 || true # detect and set /boot device echo -e "\nDetecting and setting boot device...\n" @@ -1075,6 +1093,7 @@ fi # clear local keyring rm /.gnupg/*.gpg 2>/dev/null rm /.gnupg/*.kbx 2>/dev/null +# initialize gpg wth empty keyring gpg --list-keys >/dev/null 2>&1 #Generate keys in memory and copy to smartcard @@ -1092,7 +1111,6 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then #TODO seperate wiping and thumb drive functions with proper validation wipe_thumb_drive_and_copy_gpg_key_material #TODO seperate setting config - keytocard_subkeys_to_smartcard else die "Unsupported GPG_ALGO: $GPG_ALGO" @@ -1154,8 +1172,8 @@ fi # Do not attempt to flash the key to ROM if we are running in QEMU based on CONFIG_BOARD_NAME matching glob pattern containing qemu-* # We check for qemu-* instead of ^qemu- because CONFIG_BOARD_NAME could be renamed to UNTESTED-qemu-* in a probable future if [[ "$CONFIG_BOARD_NAME" == qemu-* ]]; then - warn "Skipping flash of GPG key to ROM because we are running in QEMU" - warn "Please review documentation md file under board directory on your building machine, and review board config options in .config file to enable configuration options you want to test in QEMU until internal flashing support is integrated." + warn "Skipping flash of GPG key to ROM because we are running in QEMU" + warn "Please review documentation md file under board directory on your building machine, and review board config options in .config file to enable configuration options you want to test in QEMU until internal flashing support is integrated." else #We are not running in QEMU, so flash the key to ROM diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 80aab66b..20615237 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -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 From c3a5359a85835f870025c89565b45d38295a8a1d Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 30 Oct 2023 11:43:44 -0400 Subject: [PATCH 25/69] Squash: remove DEBUG that were TODO for removal Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 21 +++------------------ initrd/bin/tpmr | 3 --- initrd/etc/functions | 2 -- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 176d52a4..251c6a4f 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -211,8 +211,6 @@ generate_inmemory_p256_master_and_subkeys() { whiptail_error_die "Failed to add ECC nistp256 signing key to master key\n\n${ERROR_MSG}" fi - DEBUG "TODO REMOVE THIS: output of signing subkey generation /tmp/gpg_card_edit_output $(cat /tmp/gpg_card_edit_output)" - echo "Generating GPG nistp256 encryption subkey..." { echo addkey @@ -228,8 +226,6 @@ generate_inmemory_p256_master_and_subkeys() { whiptail_error_die "Failed to add ECC nistp256 encryption key to master key\n\n${ERROR_MSG}" fi - DEBUG "TODO REMOVE THIS: output of encryption subkey generation /tmp/gpg_card_edit_output $(cat /tmp/gpg_card_edit_output)" - echo "Generating GPG nistp256 authentication subkey..." { echo addkey # add key in --edit-key mode @@ -247,8 +243,7 @@ generate_inmemory_p256_master_and_subkeys() { whiptail_error_die "Failed to add ECC nistp256 authentication key to master key\n\n${ERROR_MSG}" fi - DEBUG "TODO REMOVE THIS: output of authentication subkey generation /tmp/gpg_card_edit_output $(cat /tmp/gpg_card_edit_output)" -} + } #Function to move current gpg keyring subkeys to card (keytocard) # This is aimed to be used after having generated master key and subkeys in memory and having backuped them to a LUKS container @@ -266,8 +261,6 @@ keytocard_subkeys_to_smartcard() { gpg_key_factory_reset - DEBUG "TODO REMOVE THIS: ADMIN_PIN_DEF=${ADMIN_PIN_DEF} ADMIN_PIN=${ADMIN_PIN}" - echo "Moving subkeys to smartcard..." { echo "key 1" #Toggle on Signature key in --edit-key mode on local keyring @@ -296,9 +289,6 @@ keytocard_subkeys_to_smartcard() { ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key moving subkeys to smartcard failed!\n\n$ERROR" fi - #TODO: Clarify in code that since reset gpg is done, passwd is default and then cange_pass is done - - DEBUG "TODO REMOVE THIS. Ouput of /tmp/gpg_card_edit_output: $(cat /tmp/gpg_card_edit_output)" TRACE "oem-factory-reset:keytocard_subkeys_to_smartcard done" } @@ -1101,16 +1091,13 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then if [ "$GPG_ALGO" == "RSA" ]; then # Generate GPG master key generate_inmemory_RSA_master_and_subkeys - #TODO seperate wiping and thumb drive functions with proper validation wipe_thumb_drive_and_copy_gpg_key_material - #TODO seperate setting config + #TODO seperate setting config. Recovery shell under qemu without reboot doesn't prompt for PIN set_user_config "CONFIG_HAVE_GPG_KEY_BACKUP" "y" keytocard_subkeys_to_smartcard elif [ "$GPG_ALGO" == "p256" ]; then generate_inmemory_p256_master_and_subkeys - #TODO seperate wiping and thumb drive functions with proper validation wipe_thumb_drive_and_copy_gpg_key_material - #TODO seperate setting config keytocard_subkeys_to_smartcard else die "Unsupported GPG_ALGO: $GPG_ALGO" @@ -1172,13 +1159,11 @@ fi # Do not attempt to flash the key to ROM if we are running in QEMU based on CONFIG_BOARD_NAME matching glob pattern containing qemu-* # We check for qemu-* instead of ^qemu- because CONFIG_BOARD_NAME could be renamed to UNTESTED-qemu-* in a probable future if [[ "$CONFIG_BOARD_NAME" == qemu-* ]]; then - warn "Skipping flash of GPG key to ROM because we are running in QEMU" - warn "Please review documentation md file under board directory on your building machine, and review board config options in .config file to enable configuration options you want to test in QEMU until internal flashing support is integrated." + warn "Skipping flash of GPG key to ROM because we are running in QEMU without internal flashing support." else #We are not running in QEMU, so flash the key to ROM ## flash generated key to ROM - # TODO: would be nice if we warned users that qemu boards will fail here and tell them what to do echo -e "\nReading current firmware...\n(this will take a minute or two)\n" /bin/flash.sh -r /tmp/oem-setup.rom >/dev/null 2>/tmp/error if [ ! -s /tmp/oem-setup.rom ]; then diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index e64ec2bf..a93d597c 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -393,7 +393,6 @@ tpm2_seal() { tpm_password="$7" # Owner password - will prompt if needed and not empty # TPM Owner Password is always needed for TPM2. - DEBUG "TODO REMOVE THIS. tpm2_seal: pass=$pass tpm_password=$tpm_password" mkdir -p "$SECRET_DIR" bname="`basename $file`" @@ -555,8 +554,6 @@ tpm2_unseal() { UNSEAL_PASS_SUFFIX="+$(tpm2_password_hex "$pass")" fi - DEBUG "TODO REMOVE THIS. tpm2_unseal: pass=$pass UNSEAL_PASS_SUFFIX=$UNSEAL_PASS_SUFFIX" - tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \ -S "/tmp/$ENC_SESSION_FILE" > "$file" } diff --git a/initrd/etc/functions b/initrd/etc/functions index 5bea478d..6e3bd70e 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -197,12 +197,10 @@ prompt_tpm_owner_password() { #Caller might already have cached the password in tpm_password. If not, prompt for it and cache it externally if [ -n "$tpm_owner_password" ]; then DEBUG "tpm_owner_password variable already set by caller. Reusing" - DEBUG "TODO REMOVE THIS! tpm_owner_password is $tpm_owner_password here." return 0 elif [ -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) - DEBUG "TODO REMOVE THIS! tpm_owner_password is $tpm_owner_password here." return 0 fi From e6eeb571b06f4aadceb776104f3da612ac21ef39 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 30 Oct 2023 12:31:31 -0400 Subject: [PATCH 26/69] oem-factory-reset: simplify provisioned secret output at end of wizard, including GPG key material output passphrase (uses strings+=string) Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 45 ++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 251c6a4f..453d062e 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -355,7 +355,6 @@ export_master_key_subkeys_and_revocation_key_to_private_LUKS_container() { #Export master key and subkeys to thumb drive DEBUG "Exporting master key and subkeys to private LUKS container's partition..." - DEBUG "TODO DELETE THIS pass= ${pass} here" "gpg --export-secret-key --armor --pinentry-mode loopback --passphrase="${pass}" "${GPG_USER_MAIL}" >"$mountpoint"/privkey.sec || die "Error exporting master key to private LUKS container's partition" @@ -872,18 +871,21 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then GPG_GEN_KEY_IN_MEMORY=0 fi + CUSTOM_PASS_AFFECTED_COMPONENTS="" # TODO: add LUKS container passphrase = ADMIN_PIN in security components provisioned # Adapt message to be given to user in terms of security components that will be applied. if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -o -n "$luks_new_Disk_Recovery_Key_passphrase" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS="LUKS Disk Recovery Key passphrase" + CUSTOM_PASS_AFFECTED_COMPONENTS+="LUKS Disk Recovery Key passphrase\n" fi if [ "$CONFIG_TPM" = "y" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS="$CUSTOM_PASS_AFFECTED_COMPONENTS -TPM Owner Password" + CUSTOM_PASS_AFFECTED_COMPONENTS+="TPM Owner Password\n" fi - CUSTOM_PASS_AFFECTED_COMPONENTS="$CUSTOM_PASS_AFFECTED_COMPONENTS -GPG Admin PIN -GPG User PIN" + if [ "$GPG_GEN_KEY_IN_MEMORY" = "1" ]; then + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key Material backup Thumb drive encrypted partition\n" + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup subkeys\n" + fi + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Admin PIN\n" + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG User PIN\n" # Inform user of security components affected for the following prompts echo -e "The following security components will be provisioned with defaults or chosen PINs/passwords: @@ -1208,27 +1210,30 @@ if [[ "$SKIP_BOOT" == "n" ]]; then generate_checksums fi +# passphrases set to be empty first +passphrases="\n" + # Prepare whiptail output of provisioned secrets -if [ -z "$luks_new_Disk_Recovery_Key_passphrase" -o -z "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - luks_passphrase_changed="" -else - luks_passphrase_changed="LUKS Disk Recovery Key passphrase:\n - $luks_new_Disk_Recovery_Key_passphrase" +if [ -n "$luks_new_Disk_Recovery_Key_passphrase" -o -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then + passphrases+="LUKS Disk Recovery Key passphrase: ${luks_new_Disk_Recovery_Key_passphrase}\n" fi if [ "$CONFIG_TPM" = "y" ]; then - tpm_owner_password_changed=" - TPM Owner Password: ${TPM_PASS}\n" -else - tpm_owner_password_changed="" + passphrases+="TPM Owner Password: ${TPM_PASS}\n" +fi + +#GPG PINs are in output inconditionally +passphrases+="GPG Admin PIN: ${ADMIN_PIN}\n" +passphrases+="GPG User PIN: ${USER_PIN}\n" + +#If user decided to generate keys in memory, we add the thumb drive passphrase +if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then + passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n" fi ## Show to user current provisioned secrets prior of rebooting whiptail --msgbox " - $luks_passphrase_changed - $tpm_owner_password_changed - GPG Admin PIN: ${ADMIN_PIN}\n - GPG User PIN: ${USER_PIN}\n\n" \ + $passphrases" \ $HEIGHT $WIDTH --title "Provisioned secrets" ## all done -- reboot From 867fb8d023895e22150c170a1fc62d8eb2d879d3 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 30 Oct 2023 12:56:27 -0400 Subject: [PATCH 27/69] RSA keygen adaptation testing with rsa 2048 in memory keygen and key to card missing pieces Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 453d062e..8b8b3557 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -38,7 +38,8 @@ CUSTOM_PASS_AFFECTED_COMPONENTS="" # Default GPG Algorithm is RSA GPG_ALGO="RSA" # Default RSA key length -RSA_KEY_LENGTH=3072 +RSA_KEY_LENGTH=2048 +#TODO: put back to 3076 GPG_USER_NAME="OEM Key" GPG_KEY_NAME=$(date +%Y%m%d%H%M%S) @@ -356,7 +357,7 @@ export_master_key_subkeys_and_revocation_key_to_private_LUKS_container() { #Export master key and subkeys to thumb drive DEBUG "Exporting master key and subkeys to private LUKS container's partition..." - "gpg --export-secret-key --armor --pinentry-mode loopback --passphrase="${pass}" "${GPG_USER_MAIL}" >"$mountpoint"/privkey.sec || + gpg --export-secret-key --armor --pinentry-mode loopback --passphrase="${pass}" "${GPG_USER_MAIL}" >"$mountpoint"/privkey.sec || die "Error exporting master key to private LUKS container's partition" gpg --export-secret-subkeys --armor --pinentry-mode loopback --passphrase="${pass}" "${GPG_USER_MAIL}" >"$mountpoint"/subkeys.sec || die "Error exporting subkeys to private LUKS container's partition" @@ -487,7 +488,7 @@ gpg_key_factory_reset() { whiptail_error_die "Setting key to NIST-P256 in USB Security Dongle failed." fi # fallback to RSA key generation by default - elif [ "$GPG_ALGO" = "rsa" ]; then + elif [ "$GPG_ALGO" = "RSA" ]; then DEBUG "GPG setting RSA key length to ${RSA_KEY_LENGTH} bits..." # Set RSA key length { @@ -778,10 +779,11 @@ usb_security_token_capabilities_check() { DEBUG "Setting GPG_ALGO to (board-)configured: $CONFIG_GPG_ALGO" fi # ... overwrite with usb-token capability - if lsusb | grep -q "20a0:42b2"; then - GPG_ALGO="p256" - DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" - fi + #if lsusb | grep -q "20a0:42b2"; then + # GPG_ALGO="p256" + # DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" + #TODO put back detection prior of PR review, as well as RSA=3076 + #fi } ## main script start From 38fc09797675bdadc5e9fee52c76bd827e99c149 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 30 Oct 2023 13:19:27 -0400 Subject: [PATCH 28/69] Squash: revert testing changes for RSA and unify once more USB Security dongle's usage Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 8b8b3557..189a0083 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -38,8 +38,7 @@ CUSTOM_PASS_AFFECTED_COMPONENTS="" # Default GPG Algorithm is RSA GPG_ALGO="RSA" # Default RSA key length -RSA_KEY_LENGTH=2048 -#TODO: put back to 3076 +RSA_KEY_LENGTH=3076 GPG_USER_NAME="OEM Key" GPG_KEY_NAME=$(date +%Y%m%d%H%M%S) @@ -437,7 +436,7 @@ gpg_key_factory_reset() { enable_usb # Factory reset GPG card - echo "GPG factory reset of USB Security Dongle's smartcard..." + echo "GPG factory reset of USB Security Dongle' smartcard..." { echo admin # admin menu echo factory-reset # factory reset smartcard @@ -521,7 +520,7 @@ generate_OEM_gpg_keys() { TRACE "Under oem-factory-reset:generate_OEM_gpg_keys" #This function simply generates subkeys in smartcard following smarcard config from gpg_key_factory_reset - echo "Generating GPG keys in USB Security Dongle's smartcard..." + echo "Generating GPG keys in USB Security Dongle' smartcard..." { echo admin # admin menu echo generate # generate keys @@ -779,11 +778,10 @@ usb_security_token_capabilities_check() { DEBUG "Setting GPG_ALGO to (board-)configured: $CONFIG_GPG_ALGO" fi # ... overwrite with usb-token capability - #if lsusb | grep -q "20a0:42b2"; then - # GPG_ALGO="p256" - # DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" - #TODO put back detection prior of PR review, as well as RSA=3076 - #fi + if lsusb | grep -q "20a0:42b2"; then + GPG_ALGO="p256" + DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" + fi } ## main script start @@ -883,8 +881,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS+="TPM Owner Password\n" fi if [ "$GPG_GEN_KEY_IN_MEMORY" = "1" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key Material backup Thumb drive encrypted partition\n" - CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup subkeys\n" + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup passphrase\n" fi CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Admin PIN\n" CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG User PIN\n" @@ -1108,7 +1105,7 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then fi else #Generate GPG key and subkeys on smartcard only - echo -e "\nResetting GPG Key...\n(this will take around 3 minutes...)\n" + echo -e "\nResetting USB Security Dongle's GPG smartcard...\n(this will take around 3 minutes...)\n" gpg_key_factory_reset generate_OEM_gpg_keys fi From ad1bff6b230eb2992483cc85856412a0470d63b4 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 30 Oct 2023 13:57:02 -0400 Subject: [PATCH 29/69] oem-factory-reset: make initial questionnaire more concise Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 189a0083..6bdaaf84 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -833,10 +833,10 @@ fi if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then #Give general guidance to user on how to answer prompts - echo - echo "The following questionnaire will help you to configure the security components of your system." - echo "You will be prompted for each option to answer a single letter at prompts (Y/n/m)." - echo "If you don't know what to answer, just press Enter to use default value which is shown between [] brackets as the uppercase letter." + echo -e "\n **** Factory Reset / Re-Ownership Questionnaire ****\n\n" + echo -e "The following questionnaire will help you configure the security components of your system.\n" + echo -e "Each prompt requires a single letter answer: eg. (Y/n/m).\n" + echo -e "If you don't know what to answer, pressing Enter will select the default answer for that prompt: eg. Y, above.\n" # Re-ownership of encrypted disk key, content and passphrase echo -e -n "\n\nWould you like to change the current LUKS Disk Recovery Key passphrase?\n (Highly recommended if you didn't install the Operating System yourself, so that past provisioned passphrase would not permit to access content.\n Note that without re-encrypting disk, a backuped header could be restored to access encrypted content with old passphrase) [y/N]: " @@ -871,7 +871,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then GPG_GEN_KEY_IN_MEMORY=0 fi - CUSTOM_PASS_AFFECTED_COMPONENTS="" + CUSTOM_PASS_AFFECTED_COMPONENTS="\n" # TODO: add LUKS container passphrase = ADMIN_PIN in security components provisioned # Adapt message to be given to user in terms of security components that will be applied. if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -o -n "$luks_new_Disk_Recovery_Key_passphrase" ]; then From a3086e9a1c6d98667417f90640e771d955eede90 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 30 Oct 2023 14:01:37 -0400 Subject: [PATCH 30/69] Remove TODO in code that were not relevant prior of first review Signed-off-by: Thierry Laurion --- .../qemu-coreboot-fbwhiptail-tpm1.config | 2 +- .../qemu-coreboot-fbwhiptail-tpm2.config | 7 +++++-- .../qemu-coreboot-whiptail-tpm1.config | 1 - .../qemu-coreboot-whiptail-tpm2.config | 6 +++--- initrd/bin/kexec-insert-key | 1 - initrd/bin/kexec-save-key | 1 - initrd/bin/kexec-seal-key | 4 ---- initrd/bin/oem-factory-reset | 4 +--- initrd/etc/functions | 1 - 9 files changed, 10 insertions(+), 17 deletions(-) diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config b/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config index f494f2b0..d84e5749 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config @@ -11,7 +11,7 @@ export CONFIG_LINUX_VERSION=5.10.5 #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 +#export CONFIG_HAVE_GPG_KEY_BACKUP=y #Enable DEBUG output #export CONFIG_DEBUG_OUTPUT=y diff --git a/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config b/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config index e809f14d..37693df9 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config @@ -10,9 +10,12 @@ 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 +#export CONFIG_DEBUG_OUTPUT=y +#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp export CONFIG_TPM2_CAPTURE_PCAP=y diff --git a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config index 5353782e..e03dc06f 100644 --- a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config +++ b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config @@ -11,7 +11,6 @@ export CONFIG_LINUX_VERSION=5.10.5 #export CONFIG_BASIC=y #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) -#TODO: comment following line prior of pushing final version #export CONFIG_HAVE_GPG_KEY_BACKUP=y #Enable DEBUG output diff --git a/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config b/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config index 92816b42..5b5e8b56 100644 --- a/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config +++ b/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config @@ -11,11 +11,11 @@ export CONFIG_LINUX_VERSION=5.10.5 #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 +#export CONFIG_HAVE_GPG_KEY_BACKUP=y #Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#export CONFIG_DEBUG_OUTPUT=y +#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp export CONFIG_TPM2_CAPTURE_PCAP=y diff --git a/initrd/bin/kexec-insert-key b/initrd/bin/kexec-insert-key index 4ea43ea2..ad0fbe12 100755 --- a/initrd/bin/kexec-insert-key +++ b/initrd/bin/kexec-insert-key @@ -92,7 +92,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 diff --git a/initrd/bin/kexec-save-key b/initrd/bin/kexec-save-key index 3ba8e932..87e36195 100755 --- a/initrd/bin/kexec-save-key +++ b/initrd/bin/kexec-save-key @@ -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 diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index 70985d1c..bff788d9 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -135,10 +135,6 @@ tpmr calcfuturepcr 6 "/tmp/luksDump.txt" >>"$pcrf" # We take into consideration user files in cbfs tpmr pcrread -a 7 "$pcrf" -DEBUG "TODO: REMOVE THIS: key_password=$key_password here" -DEBUG "TODO: REMOVE THIS: content of /tmp/secret/tpm_owner_password: $(cat /tmp/secret/tpm_owner_password) here" - - 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" || { diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 6bdaaf84..17669831 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -819,8 +819,7 @@ $TPM_STR fi # We show current integrity measurements status and time -#TODO: readd prior of PR review request. Also make sure that check_config is called to check kexec.sig (detached signature validation) -#report_integrity_measurements +report_integrity_measurements # Determine gpg algorithm to be used, based on available usb-token usb_security_token_capabilities_check @@ -872,7 +871,6 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then fi CUSTOM_PASS_AFFECTED_COMPONENTS="\n" - # TODO: add LUKS container passphrase = ADMIN_PIN in security components provisioned # Adapt message to be given to user in terms of security components that will be applied. if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -o -n "$luks_new_Disk_Recovery_Key_passphrase" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS+="LUKS Disk Recovery Key passphrase\n" diff --git a/initrd/etc/functions b/initrd/etc/functions index 6e3bd70e..cbe9c015 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -205,7 +205,6 @@ prompt_tpm_owner_password() { fi read -s -p "TPM Owner Password: " tpm_owner_password - #TODO: This function is called for both owner and TPM sealing calls. We should probably have a different prompt for each echo # new line after password prompt # Cache the password externally to be reused by who needs it From 2a04fb565097a234f526cb1d24a3ec11cb6f78e7 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 31 Oct 2023 11:42:57 -0400 Subject: [PATCH 31/69] oem-factory-reset: RSA default should be 3072, not 3076. squash Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 17669831..7e86f118 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -38,7 +38,7 @@ CUSTOM_PASS_AFFECTED_COMPONENTS="" # Default GPG Algorithm is RSA GPG_ALGO="RSA" # Default RSA key length -RSA_KEY_LENGTH=3076 +RSA_KEY_LENGTH=3072 GPG_USER_NAME="OEM Key" GPG_KEY_NAME=$(date +%Y%m%d%H%M%S) From 4d72eb3120404df939a2fba65d9daeebfa011a20 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 31 Oct 2023 11:45:06 -0400 Subject: [PATCH 32/69] oem-factory-reset: typo correction past tense Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 7e86f118..c417ec98 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -246,11 +246,11 @@ generate_inmemory_p256_master_and_subkeys() { } #Function to move current gpg keyring subkeys to card (keytocard) -# This is aimed to be used after having generated master key and subkeys in memory and having backuped them to a LUKS container +# This is aimed to be used after having generated master key and subkeys in memory and having backed up them to a LUKS container # This function will keytocard the subkeys from the master key in the keyring # The master key will be kept in the keyring # The master key was already used to sign the subkeys, so it is not needed anymore -# Delete the master key from the keyring once key to card is done (already backuped on LUKS private partition) +# Delete the master key from the keyring once key to card is done (already backed up on LUKS private partition) keytocard_subkeys_to_smartcard() { TRACE "Under oem-factory-reset:keytocard_subkeys_to_smartcard" @@ -838,7 +838,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then echo -e "If you don't know what to answer, pressing Enter will select the default answer for that prompt: eg. Y, above.\n" # Re-ownership of encrypted disk key, content and passphrase - echo -e -n "\n\nWould you like to change the current LUKS Disk Recovery Key passphrase?\n (Highly recommended if you didn't install the Operating System yourself, so that past provisioned passphrase would not permit to access content.\n Note that without re-encrypting disk, a backuped header could be restored to access encrypted content with old passphrase) [y/N]: " + echo -e -n "\n\nWould you like to change the current LUKS Disk Recovery Key passphrase?\n (Highly recommended if you didn't install the Operating System yourself, so that past provisioned passphrase would not permit to access content.\n Note that without re-encrypting disk, a backed up header could be restored to access encrypted content with old passphrase) [y/N]: " read -n 1 prompt_output echo if [ "$prompt_output" == "y" \ @@ -847,7 +847,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then echo -e "\n" fi - echo -e -n "Would you like to re-encrypt LUKS encrypted container and generate new Disk Recovery key?\n (Highly recommended if you didn't install the operating system yourself: this would prevent any LUKS backuped header to be restored to access encrypted data) [y/N]: " + echo -e -n "Would you like to re-encrypt LUKS encrypted container and generate new Disk Recovery key?\n (Highly recommended if you didn't install the operating system yourself: this would prevent any LUKS backed up header to be restored to access encrypted data) [y/N]: " read -n 1 prompt_output echo if [ "$prompt_output" == "y" \ @@ -865,7 +865,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then -o "$prompt_output" == "M" ] \ ; then GPG_GEN_KEY_IN_MEMORY=1 - echo "Master key and subkeys will be generated in memory, backuped to dedicated LUKS container and then subkeys copied to smartcard." + echo "Master key and subkeys will be generated in memory, backed up to dedicated LUKS container and then subkeys copied to smartcard." else GPG_GEN_KEY_IN_MEMORY=0 fi From 2aa9cfafb5d71c649c68f3acb3b1e4c605e7e382 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 31 Oct 2023 13:05:36 -0400 Subject: [PATCH 33/69] luks-functions: cleanup code of luks containers reported Signed-off-by: Thierry Laurion --- initrd/etc/luks-functions | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/initrd/etc/luks-functions b/initrd/etc/luks-functions index 76a3ef0a..b78985d0 100644 --- a/initrd/etc/luks-functions +++ b/initrd/etc/luks-functions @@ -10,8 +10,7 @@ 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 [ $(echo $?) == 0 ]; then echo $device; fi + if cryptsetup isLuks $device; then echo $device; fi done | sort } From 584c964064dc7bfb77fa9f8e0b48a480bc91aac4 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 31 Oct 2023 16:32:12 -0400 Subject: [PATCH 34/69] oem-factory-reset: now permits to generate in-memory key, backuped to encrypted disk without copy to card from questionnaire. Can be tested out of the box on Qemu without modification from end of wizard's reboot call, prompting for gpg_auth when in debug mode. Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 60 +++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index c417ec98..fd01d1d1 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -243,7 +243,7 @@ generate_inmemory_p256_master_and_subkeys() { whiptail_error_die "Failed to add ECC nistp256 authentication key to master key\n\n${ERROR_MSG}" fi - } +} #Function to move current gpg keyring subkeys to card (keytocard) # This is aimed to be used after having generated master key and subkeys in memory and having backed up them to a LUKS container @@ -616,7 +616,7 @@ generate_checksums() { set_default_boot_option fi - # generate hashes + DEBUG "Generating hashes" ( set -e -o pipefail cd /boot @@ -630,7 +630,14 @@ generate_checksums() { [ -z "$param_files" ] && whiptail_error_die "No kexec parameter files to sign" - # sign kexec boot files + if [ "$GPG_GEN_KEY_IN_MEMORY" = "1" -a "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "0" ]; then + #The local keyring is still valid since no key has been moved to smartcard + #Local keyring passwd is ADMIN_PIN. We need to set USER_PIN to ADMIN_PIN + DEBUG "Setting GPG User PIN to GPG Admin PIN so local keyring can be used to detach-sign kexec files next" + USER_PIN=$ADMIN_PIN + fi + + DEBUG "Detach-signing boot files under kexec.sig: $param_files" if sha256sum $param_files 2>/dev/null | gpg \ --pinentry-mode loopback \ --passphrase "${USER_PIN}" \ @@ -779,8 +786,8 @@ usb_security_token_capabilities_check() { fi # ... overwrite with usb-token capability if lsusb | grep -q "20a0:42b2"; then - GPG_ALGO="p256" - DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" + GPG_ALGO="p256" + DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" fi } @@ -834,7 +841,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then #Give general guidance to user on how to answer prompts echo -e "\n **** Factory Reset / Re-Ownership Questionnaire ****\n\n" echo -e "The following questionnaire will help you configure the security components of your system.\n" - echo -e "Each prompt requires a single letter answer: eg. (Y/n/m).\n" + echo -e "Each prompt requires a single letter answer: eg. (Y/n).\n" echo -e "If you don't know what to answer, pressing Enter will select the default answer for that prompt: eg. Y, above.\n" # Re-ownership of encrypted disk key, content and passphrase @@ -858,14 +865,23 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then fi #Prompt to ask if user wants to generate GPG key material in memory or on smartcard - echo -e -n "Would you like to generate GPG key material in (m)emory or (S)olely on the security element of the USB Security Dongle? [m/S]: " + echo -e -n "Would you like to format an encrypted USB Thumb drive to store GPG key material generated in memory?\n (Required to enable GPG authentication) [y/N]: " read -n 1 prompt_output echo - if [ "$prompt_output" == "m" \ - -o "$prompt_output" == "M" ] \ + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ] \ ; then GPG_GEN_KEY_IN_MEMORY=1 - echo "Master key and subkeys will be generated in memory, backed up to dedicated LUKS container and then subkeys copied to smartcard." + echo "Master key and subkeys will be generated in memory, backed up to dedicated LUKS container and then subkeys" + echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security Dongle' smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "n" \ + -o "$prompt_output" == "N" ]; then + GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=0 + else + GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=1 + fi else GPG_GEN_KEY_IN_MEMORY=0 fi @@ -1090,17 +1106,16 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then if [ "$GPG_ALGO" == "RSA" ]; then # Generate GPG master key generate_inmemory_RSA_master_and_subkeys - wipe_thumb_drive_and_copy_gpg_key_material - #TODO seperate setting config. Recovery shell under qemu without reboot doesn't prompt for PIN - set_user_config "CONFIG_HAVE_GPG_KEY_BACKUP" "y" - keytocard_subkeys_to_smartcard elif [ "$GPG_ALGO" == "p256" ]; then generate_inmemory_p256_master_and_subkeys - wipe_thumb_drive_and_copy_gpg_key_material - keytocard_subkeys_to_smartcard else die "Unsupported GPG_ALGO: $GPG_ALGO" fi + wipe_thumb_drive_and_copy_gpg_key_material + set_user_config "CONFIG_HAVE_GPG_KEY_BACKUP" "y" + if [ "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" == "1" ]; then + keytocard_subkeys_to_smartcard + fi else #Generate GPG key and subkeys on smartcard only echo -e "\nResetting USB Security Dongle's GPG smartcard...\n(this will take around 3 minutes...)\n" @@ -1120,11 +1135,14 @@ if ! gpg --export --armor "$GPG_GEN_KEY" >"${PUBKEY}" 2>/tmp/error; then fi #Applying custom GPG PINs to the smartcard if they were provided -if [ "${USER_PIN}" != "" -o "${ADMIN_PIN}" != "" ]; then - echo -e "\nChanging default GPG Admin PIN\n" - gpg_key_change_pin "3" "${ADMIN_PIN_DEF}" "${ADMIN_PIN}" - echo -e "\nChanging default GPG User PIN\n" - gpg_key_change_pin "1" "${USER_PIN_DEF}" "${USER_PIN}" +if [ -z "GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then + #Only apply smartcard PIN change if smartcard only or if keytocard op is expected + if [ "${USER_PIN}" != "" -o "${ADMIN_PIN}" != "" ]; then + echo -e "\nChanging default GPG Admin PIN\n" + gpg_key_change_pin "3" "${ADMIN_PIN_DEF}" "${ADMIN_PIN}" + echo -e "\nChanging default GPG User PIN\n" + gpg_key_change_pin "1" "${USER_PIN_DEF}" "${USER_PIN}" + fi fi ## export pubkey to USB From f5dc5ef5cd0026c45772ac7d8beffc7793d49e1b Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 1 Nov 2023 10:01:00 -0400 Subject: [PATCH 35/69] qemu boards: Put back DEBUG and TRACE on Signed-off-by: Thierry Laurion --- .../qemu-coreboot-fbwhiptail-tpm1.config | 4 ++-- .../qemu-coreboot-fbwhiptail-tpm2.config | 4 ++-- .../qemu-coreboot-whiptail-tpm2.config | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config b/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config index d84e5749..7dc4ea91 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config @@ -14,8 +14,8 @@ export CONFIG_LINUX_VERSION=5.10.5 #export CONFIG_HAVE_GPG_KEY_BACKUP=y #Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y CONFIG_COREBOOT_CONFIG=config/coreboot-qemu-tpm1.config CONFIG_LINUX_CONFIG=config/linux-qemu.config diff --git a/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config b/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config index 37693df9..c286f1a4 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config @@ -14,8 +14,8 @@ export CONFIG_LINUX_VERSION=5.10.5 #export CONFIG_HAVE_GPG_KEY_BACKUP=y #Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp export CONFIG_TPM2_CAPTURE_PCAP=y diff --git a/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config b/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config index 5b5e8b56..ea6f3d36 100644 --- a/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config +++ b/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config @@ -14,8 +14,8 @@ export CONFIG_LINUX_VERSION=5.10.5 #export CONFIG_HAVE_GPG_KEY_BACKUP=y #Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp export CONFIG_TPM2_CAPTURE_PCAP=y From c2c32c425b239fb15a39a7921490271883676304 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 1 Nov 2023 13:15:44 -0400 Subject: [PATCH 36/69] ash_functions: have gpg_auth calls to confirm_gpg_card in subshell loop to force successful authentication Signed-off-by: Thierry Laurion --- initrd/etc/ash_functions | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index bbf12387..99becfbb 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -101,7 +101,7 @@ confirm_gpg_card() { echo #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 GPG Admin PIN" + 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" @@ -112,7 +112,7 @@ confirm_gpg_card() { 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 "++++ Imported private subkeys match public key fused in rom and can be used under Heads" || \ + 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 @@ -123,7 +123,7 @@ confirm_gpg_card() { fi fi - # setup the USB so we can reach the GPG card + # setup the USB so we can reach the USB Security Dongle' smartcard enable_usb echo -e "\nVerifying presence of GPG card...\n" @@ -158,7 +158,13 @@ gpg_auth() { # Wipe any existing nonce and signature shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true - confirm_gpg_card + + # 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 From 2942d660dec087f25c55fc6f5ff1c07027de3e62 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 1 Nov 2023 14:10:42 -0400 Subject: [PATCH 37/69] oem-factory-reset: prmompt only for GPG User PIN when needed, warn users when no backup/when having only in-memory keygen backup without smartcard. Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 46 ++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index fd01d1d1..239c629b 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -872,20 +872,28 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then -o "$prompt_output" == "Y" ] \ ; then GPG_GEN_KEY_IN_MEMORY=1 - echo "Master key and subkeys will be generated in memory, backed up to dedicated LUKS container and then subkeys" + echo " ++++ Master key and subkeys will be generated in memory, backed up to dedicated LUKS container +++" echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security Dongle' smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: " read -n 1 prompt_output echo if [ "$prompt_output" == "n" \ -o "$prompt_output" == "N" ]; then + warn "Subkeys will NOT be copied to USB Security Dongle' smartcard." + warn "Your GPG key material backup thumb drive should be cloned to a second thumb drive for redundancy for production environements" GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=0 else + echo "++++ Subkeys will be copied to USB Security Dongle' smartcard ++++" + warn "Please keep your GPG key material backup thumb drive safe" GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=1 fi else + warn "GPG key material will be generated on USB Security Dongle' smartcard without backup" GPG_GEN_KEY_IN_MEMORY=0 fi + + # Dynamic messages to be given to user in terms of security components that will be applied + # based on previous answers CUSTOM_PASS_AFFECTED_COMPONENTS="\n" # Adapt message to be given to user in terms of security components that will be applied. if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -o -n "$luks_new_Disk_Recovery_Key_passphrase" ]; then @@ -895,10 +903,14 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS+="TPM Owner Password\n" fi if [ "$GPG_GEN_KEY_IN_MEMORY" = "1" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup passphrase\n" + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup passphrase (Same a GPG Admin PIN)\n" fi CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Admin PIN\n" - CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG User PIN\n" + # Only show GPG User PIN as affected component if GPG_GEN_KEY_IN_MEMORY=0 or GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=1 + if [ "$GPG_GEN_KEY_IN_MEMORY" = "0" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG User PIN\n" + fi + # Inform user of security components affected for the following prompts echo -e "The following security components will be provisioned with defaults or chosen PINs/passwords: @@ -921,7 +933,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then USER_PIN=${CUSTOM_SINGLE_PASS} ADMIN_PIN=${CUSTOM_SINGLE_PASS} - # Only set if user said desired. Matches rest of logic + # Only set if user said desired if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then luks_new_Disk_Recovery_Key_passphrase=${CUSTOM_SINGLE_PASS} fi @@ -944,11 +956,16 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then echo -e -n "Enter desired GPG Admin PIN: " read ADMIN_PIN done - while [[ ${#USER_PIN} -lt 8 ]] || [[ ${#USER_PIN} -gt 64 ]]; do - echo -e -n "\nThis PIN should be between 8 to 64 characters in length.\n" - echo -e -n "Enter desired GPG User PIN: " - read USER_PIN - done + #USER PIN not required in case of GPG_GEN_KEY_IN_MEMORY=1 while GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=0 + # That is, if keys were NOT generated in memory (on smartcard only) or + # if keys were generated in memory but are to be moved from local keyring to smartcard + if [ "$GPG_GEN_KEY_IN_MEMORY" = "0" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then + while [[ ${#USER_PIN} -lt 8 ]] || [[ ${#USER_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do + echo -e -n "\nThis PIN should be between 8 to $MAX_HOTP_GPG_PIN_LENGTH characters in length.\n" + echo -e -n "Enter desired GPG User PIN: " + read USER_PIN + done + fi echo fi fi @@ -1136,7 +1153,7 @@ fi #Applying custom GPG PINs to the smartcard if they were provided if [ -z "GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then - #Only apply smartcard PIN change if smartcard only or if keytocard op is expected + #Only apply smartcard PIN change if smartcard only or if keytocard op is expected next if [ "${USER_PIN}" != "" -o "${ADMIN_PIN}" != "" ]; then echo -e "\nChanging default GPG Admin PIN\n" gpg_key_change_pin "3" "${ADMIN_PIN_DEF}" "${ADMIN_PIN}" @@ -1177,6 +1194,8 @@ fi # We check for qemu-* instead of ^qemu- because CONFIG_BOARD_NAME could be renamed to UNTESTED-qemu-* in a probable future if [[ "$CONFIG_BOARD_NAME" == qemu-* ]]; then warn "Skipping flash of GPG key to ROM because we are running in QEMU without internal flashing support." + warn "Please review boards/qemu*/qemu*.md documentation to extract public key from raw disk and inject at build time" + warn "Also review boards/qemu*/qemu*.config to tweak CONFIG_* options you might want to turn on/off manually at build time" else #We are not running in QEMU, so flash the key to ROM @@ -1237,9 +1256,12 @@ if [ "$CONFIG_TPM" = "y" ]; then passphrases+="TPM Owner Password: ${TPM_PASS}\n" fi -#GPG PINs are in output inconditionally +#GPG PINs output passphrases+="GPG Admin PIN: ${ADMIN_PIN}\n" -passphrases+="GPG User PIN: ${USER_PIN}\n" +#USER PIN not required in case of GPG_GEN_KEY_IN_MEMORY=1 while GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=0 +if [ "$GPG_GEN_KEY_IN_MEMORY" = "0" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then + passphrases+="GPG User PIN: ${USER_PIN}\n" +fi #If user decided to generate keys in memory, we add the thumb drive passphrase if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then From af3287c00141b9bf53fb478ceff3ccd1e6cee3c4 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 1 Nov 2023 15:07:02 -0400 Subject: [PATCH 38/69] luks_functions: fix width of whiptail messages with newlines so its not cut in the middle Signed-off-by: Thierry Laurion --- initrd/etc/luks-functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/etc/luks-functions b/initrd/etc/luks-functions index b78985d0..9f2943a4 100644 --- a/initrd/etc/luks-functions +++ b/initrd/etc/luks-functions @@ -182,7 +182,7 @@ prepare_thumb_drive() #Console and whiptail $BG_COLOR_WARNING prompt (Y/n) validate one last time wiping and repartitioning of $device of total size $DISK_SIZE_MB with $PERCENTAGE_MB assigned to LUKS encrypted private partition if [ -x /bin/whiptail ]; then 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 \ + "WARNING: Wiping and repartitioning $DEVICE with $PERCENTAGE_MB MB\n assigned to private LUKS contained private ext4 partition,\n rest assigned to extfat public partition.\n\nAre you sure you want to continue?" 0 80 \ || die "User cancelled wiping and repartitioning of $DEVICE" 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?" From 921acd0f6f60b0cb217555976b079071cfc5b1ac Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 2 Nov 2023 11:30:59 -0400 Subject: [PATCH 39/69] tpmr: move TPM2 related secrets artifacts to /tmp/secret to be autowiped when recovery shell is accessed. If you want to see those, use qemu and have main console launching qemu under recovery shell prior of doing ops you want to see /tmp/secret/ artifacts before being deleted. We still have pcap under /tmp which is as expected Signed-off-by: Thierry Laurion --- initrd/bin/tpmr | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index a93d597c..52b183f0 100755 --- a/initrd/bin/tpmr +++ b/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 @@ -321,10 +321,10 @@ tpm2_startsession() { 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" + 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 @@ -403,8 +403,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,16 +430,16 @@ 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_owner_password @@ -531,13 +531,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" 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" @@ -555,7 +555,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" @@ -596,7 +596,7 @@ tpm2_reset() { TRACE "Under /bin/tpmr:tpm2_reset" tpm_owner_password="$1" mkdir -p "$SECRET_DIR" - # output TPM Owner Password key_password to a file to be reused in this boot session until recovery shell/reboot + # 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" @@ -630,7 +630,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 From 48c446cd7d85c7e4f87c20acd42e67ccf6286788 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 2 Nov 2023 11:38:50 -0400 Subject: [PATCH 40/69] functions: prompt_tpm_owner_password only reuses /tmp/secret/tpm_owner_password if already created by seal functions or itself. Sealing ops not being able to reuse the file shred it (kexec-seal-key and seal-totp) Signed-off-by: Thierry Laurion --- initrd/etc/functions | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index cbe9c015..2b5ebb0b 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -194,11 +194,8 @@ list_usb_storage() { # 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" - #Caller might already have cached the password in tpm_password. If not, prompt for it and cache it externally - if [ -n "$tpm_owner_password" ]; then - DEBUG "tpm_owner_password variable already set by caller. Reusing" - return 0 - elif [ -s /tmp/secret/tpm_owner_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 From 85266452fa932cf1a49b9d1114f56d86a961bb94 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 2 Nov 2023 12:08:52 -0400 Subject: [PATCH 41/69] oem-factory-reset ash_functions: fix USB Security Dongle' smartcard -> USB Security Dongle's smartcard Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 12 ++++++------ initrd/etc/ash_functions | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 239c629b..486e5577 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -436,7 +436,7 @@ gpg_key_factory_reset() { enable_usb # Factory reset GPG card - echo "GPG factory reset of USB Security Dongle' smartcard..." + echo "GPG factory reset of USB Security Dongle's smartcard..." { echo admin # admin menu echo factory-reset # factory reset smartcard @@ -520,7 +520,7 @@ generate_OEM_gpg_keys() { TRACE "Under oem-factory-reset:generate_OEM_gpg_keys" #This function simply generates subkeys in smartcard following smarcard config from gpg_key_factory_reset - echo "Generating GPG keys in USB Security Dongle' smartcard..." + echo "Generating GPG keys in USB Security Dongle's smartcard..." { echo admin # admin menu echo generate # generate keys @@ -873,21 +873,21 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then ; then GPG_GEN_KEY_IN_MEMORY=1 echo " ++++ Master key and subkeys will be generated in memory, backed up to dedicated LUKS container +++" - echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security Dongle' smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: " + echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security Dongle's smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: " read -n 1 prompt_output echo if [ "$prompt_output" == "n" \ -o "$prompt_output" == "N" ]; then - warn "Subkeys will NOT be copied to USB Security Dongle' smartcard." + warn "Subkeys will NOT be copied to USB Security Dongle's smartcard." warn "Your GPG key material backup thumb drive should be cloned to a second thumb drive for redundancy for production environements" GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=0 else - echo "++++ Subkeys will be copied to USB Security Dongle' smartcard ++++" + echo "++++ Subkeys will be copied to USB Security Dongle's smartcard ++++" warn "Please keep your GPG key material backup thumb drive safe" GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=1 fi else - warn "GPG key material will be generated on USB Security Dongle' smartcard without backup" + warn "GPG key material will be generated on USB Security Dongle's smartcard without backup" GPG_GEN_KEY_IN_MEMORY=0 fi diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 99becfbb..4d247360 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -123,7 +123,7 @@ confirm_gpg_card() { fi fi - # setup the USB so we can reach the USB Security Dongle' smartcard + # setup the USB so we can reach the USB Security Dongle's smartcard enable_usb echo -e "\nVerifying presence of GPG card...\n" From 644a59ab602e65b75a226167eab6b289246cee1a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 2 Nov 2023 12:49:13 -0400 Subject: [PATCH 42/69] oem-factory-reset: simplify first question for users to have a GPG key material backup and enable GPG Authentication Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 486e5577..44642b2d 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -865,7 +865,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then fi #Prompt to ask if user wants to generate GPG key material in memory or on smartcard - echo -e -n "Would you like to format an encrypted USB Thumb drive to store GPG key material generated in memory?\n (Required to enable GPG authentication) [y/N]: " + echo -e -n "Would you like to format an encrypted USB Thumb drive to store GPG key material?\n (Required to enable GPG authentication) [y/N]: " read -n 1 prompt_output echo if [ "$prompt_output" == "y" \ From 19c5d16e4038fb8b5687d00d7a179ac712aa7728 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 2 Nov 2023 12:58:19 -0400 Subject: [PATCH 43/69] functions: guide user torward resetting TPM more directly if counter_increment fails. Signed-off-by: Thierry Laurion --- initrd/etc/functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index 2b5ebb0b..9ff2b14f 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -272,7 +272,7 @@ increment_tpm_counter() { TRACE "Under /etc/functions:increment_tpm_counter" tpmr counter_increment -ix "$1" -pwdc '' | tee /tmp/counter-$1 || - die "TPM counter increment failed for rollback prevention. Please reflash firmware and choose TPM Reset reset option" + die "TPM counter increment failed for rollback prevention. Please reset the TPM" } check_config() { From 6d7f9be41439097aad14d1adbd146ef888f23962 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 2 Nov 2023 14:17:38 -0400 Subject: [PATCH 44/69] TPM2: add DEBUG and fix path for TPM2 primary key handle hash. Signed-off-by: Thierry Laurion --- initrd/bin/kexec-save-default | 3 +- initrd/bin/kexec-select-boot | 198 +++++++++++++++++----------------- 2 files changed, 101 insertions(+), 100 deletions(-) diff --git a/initrd/bin/kexec-save-default b/initrd/bin/kexec-save-default index d4f26c85..e21dd13e 100755 --- a/initrd/bin/kexec-save-default +++ b/initrd/bin/kexec-save-default @@ -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 diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 6f4cdfc7..5fc5119f 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -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 @@ -50,30 +57,28 @@ bootdir="${bootdir%%/}" paramsdev="${paramsdev%%/}" 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" + 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 -#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"; -# } -# else -# warn "Hash of TPM2 primary key handle does not exist" -# warn "Please rebuild the boot hash tree" -# default_failed="y" -# fi -#fi -#TODO: Readd when this can work successfully by simply resealing TOTP/HOTP without having to reset TPM2, this is a major pain point for users -#And acutally don't work as intended, even more with TPM DUK - -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' @@ -85,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 @@ -132,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 \ @@ -149,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]: " \ @@ -166,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 } @@ -175,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" @@ -193,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() { @@ -205,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 @@ -227,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" @@ -245,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' \ @@ -264,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 @@ -285,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 @@ -308,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 @@ -322,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 @@ -333,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" @@ -366,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 @@ -381,8 +381,8 @@ 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" + tpmr extend -ix 4 -ic generic || + die "Failed to extend PCR 4" fi fi @@ -415,7 +415,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 From 9523b4fee22f936f940198fee25ab67af401e180 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 3 Nov 2023 09:31:44 -0400 Subject: [PATCH 45/69] unseal-totp: fix indentation Signed-off-by: Thierry Laurion --- initrd/bin/unseal-totp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/unseal-totp b/initrd/bin/unseal-totp index ed8f18af..7a8dfaf3 100755 --- a/initrd/bin/unseal-totp +++ b/initrd/bin/unseal-totp @@ -10,7 +10,7 @@ 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" - fi +fi if ! totp -q <"$TOTP_SECRET"; then shred -n 10 -z -u "$TOTP_SECRET" 2>/dev/null From 51caab8ea4d766955f29e4b6069e0c97d3f13b47 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 3 Nov 2023 10:10:05 -0400 Subject: [PATCH 46/69] functions: check_tpm_counter; add shred call to wipe tpm_owner_password if creating counter fails with cached tpm owner password so prompt_tpm_owner_password asks for it again on next run Signed-off-by: Thierry Laurion --- initrd/etc/functions | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index 9ff2b14f..5cdc504c 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -194,7 +194,7 @@ list_usb_storage() { # 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 [ -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) @@ -253,7 +253,15 @@ check_tpm_counter() { -pwdc '' \ -la $LABEL | tee /tmp/counter || - die "Unable to create TPM counter" + { + DEBUG "Failed to create TPM counter. Shredding TPM owner password" + #TODO: refactor tpmr to wipe tpm_owner_password when invalid + # As of today, the callers are responsible to wipe it + # prompt_tpm_owner_password caches the password until externally invalidated + shred -n 10 -z -u /tmp/secret/tpm_owner_password + : + die "Unable to create TPM counter" 2>/dev/null + } TPM_COUNTER=$(cut -d: -f1 Date: Fri, 3 Nov 2023 10:15:37 -0400 Subject: [PATCH 47/69] seal-totp/tpmr: differenciate die messages to show which between tpm1_seal/tpm2_seal or check_tpm_counter fails to seal as first step to possible refactor Signed-off-by: Thierry Laurion --- initrd/bin/seal-totp | 2 +- initrd/bin/tpmr | 349 ++++++++++++++++++++++++------------------- 2 files changed, 195 insertions(+), 156 deletions(-) diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index 9df8e85a..69ee70d0 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -52,7 +52,7 @@ tpmr seal "$TOTP_SECRET" "$TPM_NVRAM_SPACE" 0,1,2,3,4,7 "$pcrf" 312 "" "$TPM_PAS { shred -n 10 -z -u /tmp/secret/tpm_owner_password 2>/dev/null : - die "Unable to write sealed secret to NVRAM" + 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 diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 52b183f0..425e08be 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -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: @@ -232,17 +232,21 @@ 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,67 @@ 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" 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;; + -pwdo) + pwdo="$2" + shift 2 + ;; + -pwdof) + pwdo="file:$2" + shift 2 + ;; + -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`" + 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 "$pwdo")" "0x$rand_index" >/dev/console echo "$rand_index: (valid after an increment)" } @@ -311,16 +325,16 @@ 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" + --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" @@ -354,27 +368,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" } # 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" } # tpm2_seal: Seal a file against PCR values and, optionally, a password. @@ -388,13 +402,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 + 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)" @@ -448,7 +462,8 @@ tpm2_seal() { -c "$handle" 2>/dev/null || true DO_WITH_DEBUG --mask-position 6 \ tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_owner_password")" \ - -c "$SECRET_DIR/$bname.seal.ctx" "$handle" + -c "$SECRET_DIR/$bname.seal.ctx" "$handle" || + die "Unable to write sealed secret to NVRAM from tpm2_seal" } tpm1_seal() { TRACE "Under /bin/tpmr:tpm1_seal" @@ -457,8 +472,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 +492,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 \ @@ -494,18 +509,17 @@ tpm1_seal() { # # 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_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 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" || + die "Unable to write sealed secret to NVRAM from tpm1_seal" fi } @@ -555,7 +569,7 @@ tpm2_unseal() { fi tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \ - -S "$ENC_SESSION_FILE" > "$file" + -S "$ENC_SESSION_FILE" >"$file" } tpm1_unseal() { TRACE "Under /bin/tpmr:tpm1_unseal" @@ -577,8 +591,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 @@ -598,7 +612,7 @@ tpm2_reset() { 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" + 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 "$tpm_owner_password")" tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")" @@ -647,7 +661,7 @@ tpm1_reset() { 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" + echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password" # Make sure the TPM is ready to be reset tpm physicalpresence -s tpm physicalenable @@ -667,20 +681,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() { @@ -700,72 +714,97 @@ 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" "$@" + ;; + 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_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 + ;; esac From 84374dfbcdfbbef3f5038a5b2b1bcd134effcaa5 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 3 Nov 2023 10:54:16 -0400 Subject: [PATCH 48/69] kexec-seal-key/seal-totp/tpmr/functions: move wiping of tpm_owner_password to tpmr calls directly Signed-off-by: Thierry Laurion --- initrd/bin/kexec-seal-key | 10 +++++----- initrd/bin/seal-totp | 6 +----- initrd/bin/tpmr | 22 +++++++++++++++++++--- initrd/etc/functions | 13 +++---------- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index bff788d9..958e836e 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -137,11 +137,11 @@ 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" || { - shred -n 10 -z -u /tmp/secret/tpm_owner_password 2>/dev/null - : - die "Unable to write TPM Disk Unlock Key to NVRAM" -} + "$TPM_SIZE" "$key_password" || / + { + DEBUG "Sealing of TPM Disk Unlock Key failed with current TPM owner 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 || diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index 69ee70d0..ef418e33 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -49,11 +49,7 @@ DEBUG "Sealing TOTP without PCR6 involvement (LUKS header consistency is not fir tpmr pcrread -a 7 "$pcrf" #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" || - { - shred -n 10 -z -u /tmp/secret/tpm_owner_password 2>/dev/null - : - die "Unable to write sealed secret to NVRAM from seal-totp" - } + 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 diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 425e08be..d0b0eea6 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -317,7 +317,13 @@ tpm2_counter_cre() { done 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 "$pwdo")" "0x$rand_index" >/dev/console || + { + DEBUG "Failed to create counter from tpm2_counter_cre with current tpm owner password. Wiping tpm_owner_password" + shred -n 10 -z -u /tmp/secret/tpm_owner_password + : + die "Unable to create counter from tpm2_counter_cre" + } echo "$rand_index: (valid after an increment)" } @@ -463,7 +469,12 @@ tpm2_seal() { DO_WITH_DEBUG --mask-position 6 \ tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_owner_password")" \ -c "$SECRET_DIR/$bname.seal.ctx" "$handle" || - die "Unable to write sealed secret to NVRAM from tpm2_seal" + { + DEBUG "Failed to write sealed secret to NVRAM from tpm2_seal with current tpm owner password. Wiping tpm_owner_password" + shred -n 10 -z -u /tmp/secret/tpm_owner_password + : + die "Unable to write sealed secret to NVRAM from tpm2_seal" + } } tpm1_seal() { TRACE "Under /bin/tpmr:tpm1_seal" @@ -519,7 +530,12 @@ tpm1_seal() { warn "Unable to define NVRAM space; trying anyway" tpm nv_writevalue -in "$index" -if "$sealed_file" || - die "Unable to write sealed secret to NVRAM from tpm1_seal" + { + DEBUG "Failed to write sealed secret to NVRAM from tpm1_seal with current tpm owner password. Wiping tpm_owner_password" + shred -n 10 -z -u /tmp/secret/tpm_owner_password + : + die "Unable to write sealed secret to NVRAM from tpm1_seal" + } fi } diff --git a/initrd/etc/functions b/initrd/etc/functions index 5cdc504c..4fd256fe 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -239,6 +239,7 @@ prompt_new_owner_password() { 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 @@ -252,16 +253,8 @@ check_tpm_counter() { -pwdo "$tpm_password" \ -pwdc '' \ -la $LABEL | - tee /tmp/counter || - { - DEBUG "Failed to create TPM counter. Shredding TPM owner password" - #TODO: refactor tpmr to wipe tpm_owner_password when invalid - # As of today, the callers are responsible to wipe it - # prompt_tpm_owner_password caches the password until externally invalidated - shred -n 10 -z -u /tmp/secret/tpm_owner_password - : - die "Unable to create TPM counter" 2>/dev/null - } + tee /tmp/counter || die "Unable to create TPM counter under check_tpm_counter" + TPM_COUNTER=$(cut -d: -f1 Date: Fri, 3 Nov 2023 11:07:36 -0400 Subject: [PATCH 49/69] tpmr: give users better error/DEBUG messages in regard of TPM errors Signed-off-by: Thierry Laurion --- initrd/bin/tpmr | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index d0b0eea6..a4b7cab3 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -319,7 +319,7 @@ tpm2_counter_cre() { tpm2 nvdefine -C o -s 8 -a "ownerread|authread|authwrite|nt=1" \ -P "$(tpm2_password_hex "$pwdo")" "0x$rand_index" >/dev/console || { - DEBUG "Failed to create counter from tpm2_counter_cre with current tpm owner password. Wiping tpm_owner_password" + DEBUG "Failed to create counter from tpm2_counter_cre. Wiping /tmp/secret/tpm_owner_password" shred -n 10 -z -u /tmp/secret/tpm_owner_password : die "Unable to create counter from tpm2_counter_cre" @@ -382,7 +382,7 @@ tpm2_destroy() { # remove possible data occupying this handle tpm2 evictcontrol -Q -C p -c "$handle" 2>/dev/null || - die "Unable to evict secret" + die "Unable to evict secret from TPM NVRAM" } # tpm1_destroy: Destroy a sealed file in the TPM. The mechanism differs by @@ -394,7 +394,7 @@ tpm1_destroy() { 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" + die "Unable to wipe sealed secret from TPM NVRAM" } # tpm2_seal: Seal a file against PCR values and, optionally, a password. @@ -470,10 +470,10 @@ tpm2_seal() { 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 with current tpm owner password. Wiping tpm_owner_password" + 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 NVRAM from tpm2_seal" + die "Unable to write sealed secret to TPM NVRAM" } } tpm1_seal() { @@ -531,10 +531,10 @@ tpm1_seal() { tpm nv_writevalue -in "$index" -if "$sealed_file" || { - DEBUG "Failed to write sealed secret to NVRAM from tpm1_seal with current tpm owner password. Wiping tpm_owner_password" + 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 NVRAM from tpm1_seal" + die "Unable to write sealed secret to TPM NVRAM" } fi } @@ -563,7 +563,7 @@ tpm2_unseal() { # can't do anything without a primary handle. 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" + warn "No TPM primary handle. You must reset TPM to seal secret to TPM NVRAM" exit 1 fi From cd3ce6999c07ad1c32e20c9c9bcd16da3ed0b0cc Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 3 Nov 2023 13:53:47 -0400 Subject: [PATCH 50/69] tpmr/kexec-seal-key/functions: end refactoring of tpmr being in carge of wiping /tmp/secret/tpm_owner_password if invalid Signed-off-by: Thierry Laurion --- initrd/bin/kexec-seal-key | 15 +++++++-------- initrd/bin/tpmr | 9 +++------ initrd/etc/functions | 20 +++++++++++++------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index 958e836e..9c377fd6 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -137,11 +137,10 @@ 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" || / - { - DEBUG "Sealing of TPM Disk Unlock Key failed with current TPM owner password." - die "Unable to write TPM Disk Unlock Key to NVRAM" - } + "$TPM_SIZE" "$key_password" || { + shred -n 10 -z -u /tmp/secret/tpm_owner_password 2>/dev/null + 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 || @@ -149,7 +148,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" diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index a4b7cab3..933bd103 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -321,7 +321,6 @@ tpm2_counter_cre() { { DEBUG "Failed to create counter from tpm2_counter_cre. Wiping /tmp/secret/tpm_owner_password" shred -n 10 -z -u /tmp/secret/tpm_owner_password - : die "Unable to create counter from tpm2_counter_cre" } echo "$rand_index: (valid after an increment)" @@ -472,7 +471,6 @@ tpm2_seal() { { 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" } } @@ -513,7 +511,7 @@ 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 # and the TPM physical presence must be asserted. @@ -527,13 +525,12 @@ tpm1_seal() { tpm nv_definespace -in "$index" -sz "$sealed_size" \ -pwdo "$tpm_password" -per 0 || - warn "Unable to define NVRAM space; trying anyway" + warn "Unable to define TPM NVRAM space; trying anyway" 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 @@ -644,7 +641,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 diff --git a/initrd/etc/functions b/initrd/etc/functions index 4fd256fe..fa142c66 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -189,9 +189,10 @@ list_usb_storage() { done } -# 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 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" @@ -210,8 +211,9 @@ prompt_tpm_owner_password() { 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() { TRACE "Under /etc/functions:prompt_new_owner_password" @@ -253,8 +255,12 @@ check_tpm_counter() { -pwdo "$tpm_password" \ -pwdc '' \ -la $LABEL | - tee /tmp/counter || die "Unable to create TPM counter under check_tpm_counter" - + tee /tmp/counter || + { + DEBUG "Failed to create TPM counter. Shredding TPM Owner Password" + shred -n 10 -z -u /tmp/secret/tpm_owner_password + die "Unable to create TPM counter" + } TPM_COUNTER=$(cut -d: -f1 Date: Fri, 3 Nov 2023 14:34:40 -0400 Subject: [PATCH 51/69] oem-factory-reset/ash_functions/luks-functions: replace provisioning with configuring keywords. Tweak oem-factory-reset flow and questionnaire. Now first prompt is to ask if user wants to go advanced or use defaults. Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 35 +++++++++++++++++++++-------------- initrd/etc/ash_functions | 2 +- initrd/etc/luks-functions | 6 +++--- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 44642b2d..a12eec73 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -831,21 +831,27 @@ report_integrity_measurements # Determine gpg algorithm to be used, based on available usb-token usb_security_token_capabilities_check -use_defaults=n -if [ "$CONFIG_OEMRESET_OFFER_DEFAULTS" = y ]; then +# Clear the screen +clear + +use_defaults=y +if [ "$CONFIG_OEMRESET_OFFER_DEFAULTS" = y -o "$use_defaults" = y ]; then echo -e -n "Would you like to use default configuration options?\nIf N, you will be prompted for each option [Y/n]: " read -n 1 use_defaults fi if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then #Give general guidance to user on how to answer prompts - echo -e "\n **** Factory Reset / Re-Ownership Questionnaire ****\n\n" - echo -e "The following questionnaire will help you configure the security components of your system.\n" - echo -e "Each prompt requires a single letter answer: eg. (Y/n).\n" + echo + echo "****************************************************" + echo "**** Factory Reset / Re-Ownership Questionnaire ****" + echo "****************************************************" + echo "The following questionnaire will help you configure the security components of your system." + echo "Each prompt requires a single letter answer: eg. (Y/n)." echo -e "If you don't know what to answer, pressing Enter will select the default answer for that prompt: eg. Y, above.\n" # Re-ownership of encrypted disk key, content and passphrase - echo -e -n "\n\nWould you like to change the current LUKS Disk Recovery Key passphrase?\n (Highly recommended if you didn't install the Operating System yourself, so that past provisioned passphrase would not permit to access content.\n Note that without re-encrypting disk, a backed up header could be restored to access encrypted content with old passphrase) [y/N]: " + echo -e -n "\n\nWould you like to change the current LUKS Disk Recovery Key passphrase?\n (Highly recommended if you didn't install the Operating System yourself, so that past configured passphrase would not permit to access content.\n Note that without re-encrypting disk, a backed up header could be restored to access encrypted content with old passphrase) [y/N]: " read -n 1 prompt_output echo if [ "$prompt_output" == "y" \ @@ -878,7 +884,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then echo if [ "$prompt_output" == "n" \ -o "$prompt_output" == "N" ]; then - warn "Subkeys will NOT be copied to USB Security Dongle's smartcard." + warn "Subkeys will NOT be copied to USB Security Dongle's smartcard" warn "Your GPG key material backup thumb drive should be cloned to a second thumb drive for redundancy for production environements" GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=0 else @@ -913,11 +919,12 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then # Inform user of security components affected for the following prompts - echo -e "The following security components will be provisioned with defaults or chosen PINs/passwords: + echo + echo -e "The following Security Components will be configured with defaults or further chosen PINs/passwords: $CUSTOM_PASS_AFFECTED_COMPONENTS\n" # Prompt to change default passwords - echo -e -n "Would you like to set a single custom password that will be provisioned to previously stated security components? [y/N]: " + echo -e -n "Would you like to set a single custom password to all previously stated security components? [y/N]: " read -n 1 prompt_output echo if [ "$prompt_output" == "y" \ @@ -938,7 +945,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then luks_new_Disk_Recovery_Key_passphrase=${CUSTOM_SINGLE_PASS} fi else - echo -e -n "Would you like to set distinct PINs/passwords to be provisioned to previously stated security components? [y/N]: " + echo -e -n "Would you like to set distinct PINs/passwords to configure previously stated security components? [y/N]: " read -n 1 prompt_output echo if [ "$prompt_output" == "y" \ @@ -1195,7 +1202,7 @@ fi if [[ "$CONFIG_BOARD_NAME" == qemu-* ]]; then warn "Skipping flash of GPG key to ROM because we are running in QEMU without internal flashing support." warn "Please review boards/qemu*/qemu*.md documentation to extract public key from raw disk and inject at build time" - warn "Also review boards/qemu*/qemu*.config to tweak CONFIG_* options you might want to turn on/off manually at build time" + warn "Also review boards/qemu*/qemu*.config to tweak CONFIG_* options you might need to turn on/off manually at build time" else #We are not running in QEMU, so flash the key to ROM @@ -1247,7 +1254,7 @@ fi # passphrases set to be empty first passphrases="\n" -# Prepare whiptail output of provisioned secrets +# Prepare whiptail output of configured secrets if [ -n "$luks_new_Disk_Recovery_Key_passphrase" -o -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then passphrases+="LUKS Disk Recovery Key passphrase: ${luks_new_Disk_Recovery_Key_passphrase}\n" fi @@ -1268,10 +1275,10 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n" fi -## Show to user current provisioned secrets prior of rebooting +## Show to user current configured secrets prior of rebooting whiptail --msgbox " $passphrases" \ - $HEIGHT $WIDTH --title "Provisioned secrets" + $HEIGHT $WIDTH --title "Configured secrets" ## all done -- reboot whiptail --msgbox " diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 4d247360..836e75ce 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -94,7 +94,7 @@ confirm_gpg_card() { #Wipe any previous CR_NONCE and CR_SIG shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true - #Prompt user for provisioned GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys + #Prompt user for configured GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys echo #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 diff --git a/initrd/etc/luks-functions b/initrd/etc/luks-functions index 9f2943a4..ca75a36b 100644 --- a/initrd/etc/luks-functions +++ b/initrd/etc/luks-functions @@ -253,7 +253,7 @@ test_luks_current_disk_recovery_key_passphrase() 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 warn "Test opening "$LUKS" LUKS encrypted drive content with current Recovery Disk Key passphrase..." @@ -296,7 +296,7 @@ luks_reencrypt() { #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):" + 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..." @@ -345,7 +345,7 @@ luks_change_passphrase() };done fi if [ -z "$luks_current_Disk_Recovery_Key_passphrase" ]; then - echo -e "\nEnter current Disk Recovery Key passphrase (Provisioned at OS installation or by OEM):" + 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 From c064b78ef658418d190e041bac33a6f90da84f43 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 3 Nov 2023 16:36:19 -0400 Subject: [PATCH 52/69] gui-init: fix TRACE: clean_check_boot stating mount_boot instead of clean_boot_check Signed-off-by: Thierry Laurion --- initrd/bin/gui-init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 1434f570..ac75de7b 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -313,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 From eee913d8d2957c6c51eeeab160f0a52653c14367 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 3 Nov 2023 16:38:41 -0400 Subject: [PATCH 53/69] oem-factory-reset: add rudimentary mount_boot function so that oem-factory-reset can be called early at boot without /boot previously mounted. Also fix logic so that GPG User PIN is showed as configured when keytocard or smartcard only is configured. Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index a12eec73..297fbae6 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -71,6 +71,18 @@ whiptail_error_die() { die } +mount_boot() { + TRACE "Under oem-factory-reset:mount_boot" + # Mount local disk if it is not already mounted. + # Added so that 'o' can be typed early at boot to enter directly into OEM Factory Reset + if ! grep -q /boot /proc/mounts; then + # try to mount if CONFIG_BOOT_DEV exists + if [ -e "$CONFIG_BOOT_DEV" ]; then + mount -o ro $CONFIG_BOOT_DEV /boot || die "Failed to mount $CONFIG_BOOT_DEV. Please change boot device under Configuration > Boot Device" + fi + fi +} + #Generate a gpg master key: no expiration date, RSA 4096 bits #This key will be used to sign 3 subkeys: encryption, authentication and signing #The master key and subkeys will be copied to backup, and the subkeys moved from memory keyring to the smartcard @@ -825,6 +837,8 @@ $TPM_STR exit 1 fi +#Make sure /boot is mounted if board config defines default +mount_boot # We show current integrity measurements status and time report_integrity_measurements @@ -897,7 +911,6 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then GPG_GEN_KEY_IN_MEMORY=0 fi - # Dynamic messages to be given to user in terms of security components that will be applied # based on previous answers CUSTOM_PASS_AFFECTED_COMPONENTS="\n" @@ -912,12 +925,11 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup passphrase (Same a GPG Admin PIN)\n" fi CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Admin PIN\n" - # Only show GPG User PIN as affected component if GPG_GEN_KEY_IN_MEMORY=0 or GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=1 - if [ "$GPG_GEN_KEY_IN_MEMORY" = "0" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then + # Only show GPG User PIN as affected component if GPG_GEN_KEY_IN_MEMORY variable is empty/not existing or GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is set to 1 + if [ -z "$GPG_GEN_KEY_IN_MEMORY" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG User PIN\n" fi - # Inform user of security components affected for the following prompts echo echo -e "The following Security Components will be configured with defaults or further chosen PINs/passwords: @@ -964,7 +976,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then read ADMIN_PIN done #USER PIN not required in case of GPG_GEN_KEY_IN_MEMORY=1 while GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=0 - # That is, if keys were NOT generated in memory (on smartcard only) or + # That is, if keys were NOT generated in memory (on smartcard only) or # if keys were generated in memory but are to be moved from local keyring to smartcard if [ "$GPG_GEN_KEY_IN_MEMORY" = "0" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then while [[ ${#USER_PIN} -lt 8 ]] || [[ ${#USER_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do @@ -1265,8 +1277,8 @@ fi #GPG PINs output passphrases+="GPG Admin PIN: ${ADMIN_PIN}\n" -#USER PIN not required in case of GPG_GEN_KEY_IN_MEMORY=1 while GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=0 -if [ "$GPG_GEN_KEY_IN_MEMORY" = "0" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then +#USER PIN was configured if GPG_GEN_KEY_IN_MEMORY is not defined or GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=1 +if [ -z "$GPG_GEN_KEY_IN_MEMORY" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then passphrases+="GPG User PIN: ${USER_PIN}\n" fi From 504f0336ac46e0a6d20440d5805d07604d22f7aa Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 3 Nov 2023 16:40:06 -0400 Subject: [PATCH 54/69] init: add early boot 'o' option to jump directly to oem-factory-reset for OEM provisioning of secret prior of shipping products, once OS is installed and after MRC training happened on first boot. Signed-off-by: Thierry Laurion --- initrd/init | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/initrd/init b/initrd/init index a9297c23..f604dc03 100755 --- a/initrd/init +++ b/initrd/init @@ -168,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 From bfc877c49c2a2521aff1d1c507f11350805159e0 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 6 Nov 2023 10:03:14 -0500 Subject: [PATCH 55/69] kexec-select-boot/kexec-insert-key: add info message explaining why PCR 4 is extended Signed-off-by: Thierry Laurion --- initrd/bin/kexec-insert-key | 1 + initrd/bin/kexec-select-boot | 1 + 2 files changed, 2 insertions(+) diff --git a/initrd/bin/kexec-insert-key b/initrd/bin/kexec-insert-key index ad0fbe12..91a1c7c8 100755 --- a/initrd/bin/kexec-insert-key +++ b/initrd/bin/kexec-insert-key @@ -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 +echo " !!!!! Extending TPM PCR 4 to prevent further secret unsealing !!!!!" tpmr extend -ix 4 -ic generic || die 'Unable to scramble PCR' diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 5fc5119f..f676128f 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -381,6 +381,7 @@ while true; do if [ "$CONFIG_TPM" = "y" ]; then if [ ! -r "$TMP_KEY_DEVICES" ]; then # Extend PCR4 as soon as possible + echo " !!!!! Extending TPM PCR 4 to prevent further secret unsealing !!!!!" tpmr extend -ix 4 -ic generic || die "Failed to extend PCR 4" fi From 8d7efa021d9c1796c0ee697763138fc77a379b01 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 6 Nov 2023 10:04:51 -0500 Subject: [PATCH 56/69] media-scan: die if gpg_auth fails (should loop and never exit anyway) Signed-off-by: Thierry Laurion --- initrd/bin/media-scan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/media-scan b/initrd/bin/media-scan index bc416c21..e22cddec 100755 --- a/initrd/bin/media-scan +++ b/initrd/bin/media-scan @@ -8,7 +8,7 @@ set -e -o pipefail TRACE "Under /bin/media-scan" #Booting from external media should be authenticated if supported -gpg_auth +gpg_auth || die "GPG authentication failed" # Unmount any previous boot device if grep -q /boot /proc/mounts ; then From 923b4e1fe9e6754e40be35274f79d88d9aac3e2a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 6 Nov 2023 10:06:19 -0500 Subject: [PATCH 57/69] ash_functions:confirm_gpg_card: loop gpg_admin_pin prompt until non-empty Signed-off-by: Thierry Laurion --- initrd/etc/ash_functions | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 836e75ce..f330e273 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -96,9 +96,12 @@ confirm_gpg_card() { #Prompt user for configured GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys echo - #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 + 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" @@ -154,7 +157,7 @@ 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 card/backup media to prove you are the owner of this machine !!!!!" + 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 From 00421638617a75b8f45d15296a14ca1db9275de1 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 6 Nov 2023 10:07:50 -0500 Subject: [PATCH 58/69] kexec-seal-key: remove non-needed shred of file cached /tmp/secret/tpm_owner_password (done when sealing fails under tpmr) - document why shred is still called under functions:check_tpm_counter for safety and add TODO there Signed-off-by: Thierry Laurion --- initrd/bin/kexec-seal-key | 5 +---- initrd/etc/functions | 5 +++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index 9c377fd6..03b64ab8 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -137,10 +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" || { - shred -n 10 -z -u /tmp/secret/tpm_owner_password 2>/dev/null - die "Unable to write TPM Disk Unlock Key to NVRAM" -} + "$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 || diff --git a/initrd/etc/functions b/initrd/etc/functions index fa142c66..0a3ffd1a 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -258,6 +258,11 @@ check_tpm_counter() { tee /tmp/counter || { DEBUG "Failed to create TPM counter. Shredding TPM Owner Password" + #tpm2 counter_cre wipes the cached tpm owner password if invalid. + #tpm1 calls counter_create directly and does not wipe the cached password. + # This is a workaround to make the two calls behave the same in case we need to create a new counter. + # I am not able to get here in my tests: the cached password should be able to create a counter at this point. + #TODO: unify the two calls further and delete the next shred call. shred -n 10 -z -u /tmp/secret/tpm_owner_password die "Unable to create TPM counter" } From 9e0491e9dbd68ffdd6d15aa398addd16738fcfd9 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 6 Nov 2023 10:34:28 -0500 Subject: [PATCH 59/69] oem-factory-reset/librem boards: remove CONFIG_OEMRESET_OFFER_DEFAULTS=y and checks for it; the default of oem-factory-reset is now to propose user to use defaults first for simplicity of most common use case without allianating advanced users which can simply not accept the default and answer questionnaire Signed-off-by: Thierry Laurion --- boards/librem_13v2/librem_13v2.config | 1 - boards/librem_13v4/librem_13v4.config | 1 - boards/librem_14/librem_14.config | 1 - boards/librem_15v3/librem_15v3.config | 1 - boards/librem_15v4/librem_15v4.config | 1 - boards/librem_l1um/librem_l1um.config | 1 - boards/librem_l1um_v2/librem_l1um_v2.config | 1 - boards/librem_mini/librem_mini.config | 1 - boards/librem_mini_v2/librem_mini_v2.config | 1 - initrd/bin/oem-factory-reset | 8 +++----- 10 files changed, 3 insertions(+), 14 deletions(-) diff --git a/boards/librem_13v2/librem_13v2.config b/boards/librem_13v2/librem_13v2.config index 9dd46728..34d6afff 100644 --- a/boards/librem_13v2/librem_13v2.config +++ b/boards/librem_13v2/librem_13v2.config @@ -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 diff --git a/boards/librem_13v4/librem_13v4.config b/boards/librem_13v4/librem_13v4.config index e1776290..34da99e0 100644 --- a/boards/librem_13v4/librem_13v4.config +++ b/boards/librem_13v4/librem_13v4.config @@ -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 diff --git a/boards/librem_14/librem_14.config b/boards/librem_14/librem_14.config index f00c277d..bfb6795d 100644 --- a/boards/librem_14/librem_14.config +++ b/boards/librem_14/librem_14.config @@ -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 diff --git a/boards/librem_15v3/librem_15v3.config b/boards/librem_15v3/librem_15v3.config index 5f6db0a6..6b57db22 100644 --- a/boards/librem_15v3/librem_15v3.config +++ b/boards/librem_15v3/librem_15v3.config @@ -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 diff --git a/boards/librem_15v4/librem_15v4.config b/boards/librem_15v4/librem_15v4.config index a70ce845..a33482b2 100644 --- a/boards/librem_15v4/librem_15v4.config +++ b/boards/librem_15v4/librem_15v4.config @@ -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 diff --git a/boards/librem_l1um/librem_l1um.config b/boards/librem_l1um/librem_l1um.config index 69052e1e..4d182cbc 100644 --- a/boards/librem_l1um/librem_l1um.config +++ b/boards/librem_l1um/librem_l1um.config @@ -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 diff --git a/boards/librem_l1um_v2/librem_l1um_v2.config b/boards/librem_l1um_v2/librem_l1um_v2.config index dcb302e2..0de610ef 100644 --- a/boards/librem_l1um_v2/librem_l1um_v2.config +++ b/boards/librem_l1um_v2/librem_l1um_v2.config @@ -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 diff --git a/boards/librem_mini/librem_mini.config b/boards/librem_mini/librem_mini.config index b8b130a3..3759bca4 100644 --- a/boards/librem_mini/librem_mini.config +++ b/boards/librem_mini/librem_mini.config @@ -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 diff --git a/boards/librem_mini_v2/librem_mini_v2.config b/boards/librem_mini_v2/librem_mini_v2.config index ab007a0c..c32f30ff 100644 --- a/boards/librem_mini_v2/librem_mini_v2.config +++ b/boards/librem_mini_v2/librem_mini_v2.config @@ -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 diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 297fbae6..a2db035a 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -848,11 +848,9 @@ usb_security_token_capabilities_check # Clear the screen clear -use_defaults=y -if [ "$CONFIG_OEMRESET_OFFER_DEFAULTS" = y -o "$use_defaults" = y ]; then - echo -e -n "Would you like to use default configuration options?\nIf N, you will be prompted for each option [Y/n]: " - read -n 1 use_defaults -fi +#Prompt user for use of default configuration options +echo -e -n "Would you like to use default configuration options?\nIf N, you will be prompted for each option [Y/n]: " +read -n 1 use_defaults if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then #Give general guidance to user on how to answer prompts From fd6a947cb35ff970b6d04230e31e4e597add289f Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Mon, 6 Nov 2023 10:31:50 -0500 Subject: [PATCH 60/69] tpmr: Move last TPM owner password prompt/shred into tpmr Prompt for TPM owner password internally within tpm2_counter_create. Add tpm1_counter_create to prompt for password internally. Wipe the cache in either if the operation fails, in case the password was incorrect. Signed-off-by: Jonathon Hall --- initrd/bin/oem-factory-reset | 1 - initrd/bin/tpmr | 38 +++++++++++++++++++++++------------- initrd/etc/functions | 11 ----------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index a2db035a..fe0936d8 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -603,7 +603,6 @@ generate_checksums() { if [ "$CONFIG_TPM" = "y" ]; then if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then tpmr counter_create \ - -pwdo "$TPM_PASS" \ -pwdc '' \ -la -3135106223 | tee /tmp/counter || diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 933bd103..c530deb7 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -290,18 +290,23 @@ tpm2_counter_inc() { 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 @@ -315,13 +320,14 @@ tpm2_counter_cre() { ;; esac done + 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_cre. Wiping /tmp/secret/tpm_owner_password" + 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_cre" + die "Unable to create counter from tpm2_counter_create" } echo "$rand_index: (valid after an increment)" } @@ -742,6 +748,10 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then shift replay_pcr "sha1" "$@" ;; + counter_create) + shift + tpm1_counter_create "$@" + ;; destroy) shift tpm1_destroy "$@" @@ -793,7 +803,7 @@ counter_increment) tpm2_counter_inc "$@" ;; counter_create) - tpm2_counter_cre "$@" + tpm2_counter_create "$@" ;; destroy) tpm2_destroy "$@" diff --git a/initrd/etc/functions b/initrd/etc/functions index 0a3ffd1a..7e6a6351 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -250,22 +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_owner_password tpmr counter_create \ - -pwdo "$tpm_password" \ -pwdc '' \ -la $LABEL | tee /tmp/counter || - { - DEBUG "Failed to create TPM counter. Shredding TPM Owner Password" - #tpm2 counter_cre wipes the cached tpm owner password if invalid. - #tpm1 calls counter_create directly and does not wipe the cached password. - # This is a workaround to make the two calls behave the same in case we need to create a new counter. - # I am not able to get here in my tests: the cached password should be able to create a counter at this point. - #TODO: unify the two calls further and delete the next shred call. - shred -n 10 -z -u /tmp/secret/tpm_owner_password die "Unable to create TPM counter" - } TPM_COUNTER=$(cut -d: -f1 Date: Mon, 6 Nov 2023 15:53:17 -0500 Subject: [PATCH 61/69] All TPM Extend additional context passed from console echo output to DEBUG. Put back console output as of master. TODO: decide what we do with tpmr extend output for the future. Hint: forward sealing of next flashed firmware measurements. Signed-off-by: Thierry Laurion --- initrd/bin/cbfs-init | 2 +- initrd/bin/kexec-insert-key | 2 +- initrd/bin/kexec-select-boot | 2 +- initrd/bin/qubes-measure-luks | 2 +- initrd/etc/ash_functions | 2 +- initrd/sbin/insmod | 8 +++----- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index 81948ef8..06d78f00 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -24,7 +24,7 @@ for cbfsname in `echo $cbfsfiles`; do TMPFILE=/tmp/cbfs.$$ echo "$filename" > $TMPFILE cat $filename >> $TMPFILE - echo " !!!!! Extending TPM PCR $CONFIG_PCR with $filename !!!!!" + DEBUG "Extending TPM PCR $CONFIG_PCR with $filename" tpmr extend -ix "$CONFIG_PCR" -if $TMPFILE \ || die "$filename: tpm extend failed" fi diff --git a/initrd/bin/kexec-insert-key b/initrd/bin/kexec-insert-key index 91a1c7c8..1b8632c0 100755 --- a/initrd/bin/kexec-insert-key +++ b/initrd/bin/kexec-insert-key @@ -49,7 +49,7 @@ if ! kexec-unseal-key "$INITRD_DIR/secret.key"; then fi # Override PCR 4 so that user can't read the key -echo " !!!!! Extending TPM PCR 4 to prevent further secret unsealing !!!!!" +DEBUG "Extending TPM PCR 4 to prevent further secret unsealing" tpmr extend -ix 4 -ic generic || die 'Unable to scramble PCR' diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index f676128f..edf3abba 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -381,7 +381,7 @@ while true; do if [ "$CONFIG_TPM" = "y" ]; then if [ ! -r "$TMP_KEY_DEVICES" ]; then # Extend PCR4 as soon as possible - echo " !!!!! Extending TPM PCR 4 to prevent further secret unsealing !!!!!" + DEBUG "Extending TPM PCR 4 to prevent further secret unsealing" tpmr extend -ix 4 -ic generic || die "Failed to extend PCR 4" fi diff --git a/initrd/bin/qubes-measure-luks b/initrd/bin/qubes-measure-luks index 12248160..0e3c7801 100755 --- a/initrd/bin/qubes-measure-luks +++ b/initrd/bin/qubes-measure-luks @@ -19,6 +19,6 @@ sha256sum /tmp/lukshdr-* >/tmp/luksDump.txt || die "Unable to hash LUKS headers" DEBUG "Removing /tmp/lukshdr-*" rm /tmp/lukshdr-* -echo " !!!! Extending PCR 6 with hash of LUKS headers from /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" diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index f330e273..4b761c02 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -227,7 +227,7 @@ recovery() { . /tmp/config if [ "$CONFIG_TPM" = "y" ]; then - echo " !!!!! Extending TPM PCR 4 for recovery shell access !!!!!" + DEBUG "Extending TPM PCR 4 for recovery shell access" tpmr extend -ix 4 -ic recovery fi diff --git a/initrd/sbin/insmod b/initrd/sbin/insmod index 34138ee5..3f04edc8 100755 --- a/initrd/sbin/insmod +++ b/initrd/sbin/insmod @@ -30,18 +30,16 @@ if [ ! -r /sys/class/tpm/tpm0/pcrs -o ! -x /bin/tpm ]; then fi if [ -z "$tpm_missing" ]; then - echo - echo " !!!!! Extending TPM PCR $MODULE_PCR with $MODULE prior of usage !!!!!" + 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 - echo - echo " !!!!! Extending TPM PCR $MODULE_PCR with $MODULE prior of usage !!!!!" + 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 From 659de631804794476962d627da3039bfdf854b0a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 6 Nov 2023 16:02:19 -0500 Subject: [PATCH 62/69] oem-factory-reset: fix typo : Same a GPG Admin PIN Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index fe0936d8..902debf6 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -919,7 +919,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS+="TPM Owner Password\n" fi if [ "$GPG_GEN_KEY_IN_MEMORY" = "1" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup passphrase (Same a GPG Admin PIN)\n" + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup passphrase (Same as GPG Admin PIN)\n" fi CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Admin PIN\n" # Only show GPG User PIN as affected component if GPG_GEN_KEY_IN_MEMORY variable is empty/not existing or GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is set to 1 From 160367d065167ed2c296fde54f7201fa7356c951 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 6 Nov 2023 16:05:08 -0500 Subject: [PATCH 63/69] oem-factory-reset: normal output to inform user of consequences of generating keys on smartcard without backup, not a wanring anymore Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 902debf6..685d3b88 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -904,7 +904,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=1 fi else - warn "GPG key material will be generated on USB Security Dongle's smartcard without backup" + echo "GPG key material will be generated on USB Security Dongle's smartcard without backup" GPG_GEN_KEY_IN_MEMORY=0 fi From 37872937f022a4c17d4865f087e23426d7bbf9e4 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 7 Nov 2023 13:20:31 -0500 Subject: [PATCH 64/69] oem-factory-reset: unify booleen y/n variable usage and double check logic. Also move USB Security dongle capability detection under code already checking for USB Security Dongle's smartcard presence. Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 53 +++++++++++++++++++----------------- initrd/etc/ash_functions | 2 +- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 685d3b88..ebc9895d 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -28,6 +28,8 @@ TPM_PASS_DEF=12345678 USER_PIN="" ADMIN_PIN="" TPM_PASS="" +GPG_GEN_KEY_IN_MEMORY="n" +GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" #Circumvent Librem Key/Nitrokey HOTP firmware bug https://github.com/osresearch/heads/issues/1167 MAX_HOTP_GPG_PIN_LENGTH=25 @@ -641,14 +643,14 @@ generate_checksums() { [ -z "$param_files" ] && whiptail_error_die "No kexec parameter files to sign" - if [ "$GPG_GEN_KEY_IN_MEMORY" = "1" -a "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "0" ]; then - #The local keyring is still valid since no key has been moved to smartcard - #Local keyring passwd is ADMIN_PIN. We need to set USER_PIN to ADMIN_PIN + if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" -a "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "n" ]; then + #The local keyring used to generate in memory subkeys is still valid since no key has been moved to smartcard + #Local keyring passwd is ADMIN_PIN. We need to set USER_PIN to ADMIN_PIN to be able to sign next in this boot session DEBUG "Setting GPG User PIN to GPG Admin PIN so local keyring can be used to detach-sign kexec files next" USER_PIN=$ADMIN_PIN fi - DEBUG "Detach-signing boot files under kexec.sig: $param_files" + DEBUG "Detach-signing boot files under kexec.sig: ${param_files}" if sha256sum $param_files 2>/dev/null | gpg \ --pinentry-mode loopback \ --passphrase "${USER_PIN}" \ @@ -841,9 +843,6 @@ mount_boot # We show current integrity measurements status and time report_integrity_measurements -# Determine gpg algorithm to be used, based on available usb-token -usb_security_token_capabilities_check - # Clear the screen clear @@ -888,7 +887,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then if [ "$prompt_output" == "y" \ -o "$prompt_output" == "Y" ] \ ; then - GPG_GEN_KEY_IN_MEMORY=1 + GPG_GEN_KEY_IN_MEMORY="y" echo " ++++ Master key and subkeys will be generated in memory, backed up to dedicated LUKS container +++" echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security Dongle's smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: " read -n 1 prompt_output @@ -897,15 +896,16 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then -o "$prompt_output" == "N" ]; then warn "Subkeys will NOT be copied to USB Security Dongle's smartcard" warn "Your GPG key material backup thumb drive should be cloned to a second thumb drive for redundancy for production environements" - GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=0 + GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" else echo "++++ Subkeys will be copied to USB Security Dongle's smartcard ++++" warn "Please keep your GPG key material backup thumb drive safe" - GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=1 + GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="y" fi else echo "GPG key material will be generated on USB Security Dongle's smartcard without backup" - GPG_GEN_KEY_IN_MEMORY=0 + GPG_GEN_KEY_IN_MEMORY="n" + GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" fi # Dynamic messages to be given to user in terms of security components that will be applied @@ -918,12 +918,12 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then if [ "$CONFIG_TPM" = "y" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS+="TPM Owner Password\n" fi - if [ "$GPG_GEN_KEY_IN_MEMORY" = "1" ]; then + if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup passphrase (Same as GPG Admin PIN)\n" fi CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Admin PIN\n" - # Only show GPG User PIN as affected component if GPG_GEN_KEY_IN_MEMORY variable is empty/not existing or GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is set to 1 - if [ -z "$GPG_GEN_KEY_IN_MEMORY" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then + # Only show GPG User PIN as affected component if GPG_GEN_KEY_IN_MEMORY not requested or GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is + if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG User PIN\n" fi @@ -972,10 +972,10 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then echo -e -n "Enter desired GPG Admin PIN: " read ADMIN_PIN done - #USER PIN not required in case of GPG_GEN_KEY_IN_MEMORY=1 while GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=0 + #USER PIN not required in case of GPG_GEN_KEY_IN_MEMORY not requested of if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is # That is, if keys were NOT generated in memory (on smartcard only) or # if keys were generated in memory but are to be moved from local keyring to smartcard - if [ "$GPG_GEN_KEY_IN_MEMORY" = "0" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then + if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then while [[ ${#USER_PIN} -lt 8 ]] || [[ ${#USER_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do echo -e -n "\nThis PIN should be between 8 to $MAX_HOTP_GPG_PIN_LENGTH characters in length.\n" echo -e -n "Enter desired GPG User PIN: " @@ -1040,7 +1040,7 @@ if [ "$ADMIN_PIN" == "" ]; then ADMIN_PIN=${ADMIN_PIN_DEF}; fi ## sanity check the USB, GPG key, and boot device before proceeding further -if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then +if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" ]; then # Prompt to insert USB drive if desired echo -e -n "\nWould you like to export your public key to an USB drive? [y/N]: " read -n 1 prompt_output @@ -1070,8 +1070,8 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then fi fi -# ensure USB Security Dongle connected if GPG_GEN_KEY_IN_MEMORY=0 -if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then +# ensure USB Security Dongle connected if GPG_GEN_KEY_IN_MEMORY=n or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=y +if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then echo -e "\nChecking for USB Security Dongle...\n" enable_usb if ! gpg --card-status >/dev/null 2>&1; then @@ -1081,6 +1081,9 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then whiptail_error_die "Unable to detect USB Security Dongle:\n\n${ERROR}" fi fi + + #Now that USB Security Dongle is detected, we can check its capabilities and limitations + usb_security_token_capabilities_check fi assert_signable @@ -1135,7 +1138,7 @@ rm /.gnupg/*.kbx 2>/dev/null gpg --list-keys >/dev/null 2>&1 #Generate keys in memory and copy to smartcard -if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then +if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then if [ "$GPG_ALGO" == "RSA" ]; then # Generate GPG master key generate_inmemory_RSA_master_and_subkeys @@ -1146,7 +1149,7 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then fi wipe_thumb_drive_and_copy_gpg_key_material set_user_config "CONFIG_HAVE_GPG_KEY_BACKUP" "y" - if [ "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" == "1" ]; then + if [ "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then keytocard_subkeys_to_smartcard fi else @@ -1168,7 +1171,7 @@ if ! gpg --export --armor "$GPG_GEN_KEY" >"${PUBKEY}" 2>/tmp/error; then fi #Applying custom GPG PINs to the smartcard if they were provided -if [ -z "GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then +if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then #Only apply smartcard PIN change if smartcard only or if keytocard op is expected next if [ "${USER_PIN}" != "" -o "${ADMIN_PIN}" != "" ]; then echo -e "\nChanging default GPG Admin PIN\n" @@ -1274,13 +1277,13 @@ fi #GPG PINs output passphrases+="GPG Admin PIN: ${ADMIN_PIN}\n" -#USER PIN was configured if GPG_GEN_KEY_IN_MEMORY is not defined or GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=1 -if [ -z "$GPG_GEN_KEY_IN_MEMORY" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "1" ]; then +#USER PIN was configured if GPG_GEN_KEY_IN_MEMORY is not active or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is active +if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then passphrases+="GPG User PIN: ${USER_PIN}\n" fi #If user decided to generate keys in memory, we add the thumb drive passphrase -if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then +if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n" fi diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 4b761c02..078c3bdd 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -115,7 +115,7 @@ confirm_gpg_card() { 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 ++++" || \ + 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 From 23c967f26d6ff7e3d850458b0fa7305e06970780 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 9 Nov 2023 13:57:07 -0500 Subject: [PATCH 65/69] nv41/ns50/librem linux: Add EXFAT fs support (mandatory). config/linux-librem_common-6.1.8.config: passed to oldconfig format through 'make BOARD=librem_14 linux.modify_and_save_oldconfig_in_place' Signed-off-by: Thierry Laurion --- config/linux-librem_common-6.1.8.config | 2940 +++++++++++++++++++++++ config/linux-nitropad-x.config | 5 +- 2 files changed, 2943 insertions(+), 2 deletions(-) diff --git a/config/linux-librem_common-6.1.8.config b/config/linux-librem_common-6.1.8.config index 0dc89610..1e482862 100644 --- a/config/linux-librem_common-6.1.8.config +++ b/config/linux-librem_common-6.1.8.config @@ -1,123 +1,1394 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/x86 6.1.8 Kernel Configuration +# +CONFIG_CC_VERSION_TEXT="x86_64-linux-musl-gcc (GCC) 8.3.0" +CONFIG_CC_IS_GCC=y +CONFIG_GCC_VERSION=80300 +CONFIG_CLANG_VERSION=0 +CONFIG_AS_IS_GNU=y +CONFIG_AS_VERSION=23200 +CONFIG_LD_IS_BFD=y +CONFIG_LD_VERSION=23200 +CONFIG_LLD_VERSION=0 +CONFIG_CC_CAN_LINK=y +CONFIG_CC_CAN_LINK_STATIC=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_PAHOLE_VERSION=0 +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_TABLE_SORT=y +CONFIG_THREAD_INFO_IN_TASK=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_COMPILE_TEST is not set +# CONFIG_WERROR is not set CONFIG_LOCALVERSION="-@BRAND_NAME@" # CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="" +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_HAVE_KERNEL_ZSTD=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_KERNEL_XZ=y +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +# CONFIG_KERNEL_ZSTD is not set +CONFIG_DEFAULT_INIT="" +CONFIG_DEFAULT_HOSTNAME="(none)" +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_WATCH_QUEUE is not set # CONFIG_CROSS_MEMORY_ATTACH is not set +# CONFIG_USELIB is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y +CONFIG_GENERIC_IRQ_RESERVATION_MODE=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +# end of IRQ subsystem + +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_ARCH_CLOCKSOURCE_INIT=y +CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100 +# end of Timers subsystem + +CONFIG_BPF=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y + +# +# BPF subsystem +# +# CONFIG_BPF_SYSCALL is not set +# CONFIG_BPF_JIT is not set +# end of BPF subsystem + +CONFIG_PREEMPT_BUILD=y +# CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_COUNT=y +CONFIG_PREEMPTION=y +CONFIG_PREEMPT_DYNAMIC=y +# CONFIG_SCHED_CORE is not set + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_PSI is not set +# end of CPU/Task time and stats accounting + +CONFIG_CPU_ISOLATION=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +CONFIG_PREEMPT_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_SRCU=y +CONFIG_TREE_SRCU=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y +# end of RCU Subsystem + +# CONFIG_IKCONFIG is not set +# CONFIG_IKHEADERS is not set CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 +# CONFIG_PRINTK_INDEX is not set +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y + +# +# Scheduler features +# +# CONFIG_UCLAMP_TASK is not set +# end of Scheduler features + +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y +CONFIG_CC_HAS_INT128=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_GCC11_NO_ARRAY_BOUNDS=y +CONFIG_GCC12_NO_ARRAY_BOUNDS=y +CONFIG_ARCH_SUPPORTS_INT128=y +# CONFIG_CGROUPS is not set +# CONFIG_NAMESPACES is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="@BLOB_DIR@/dev.cpio" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 # CONFIG_RD_GZIP is not set # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +CONFIG_RD_XZ=y # CONFIG_RD_LZO is not set # CONFIG_RD_LZ4 is not set +CONFIG_RD_ZSTD=y +CONFIG_INITRAMFS_COMPRESSION_XZ=y +# CONFIG_INITRAMFS_COMPRESSION_ZSTD is not set +# CONFIG_INITRAMFS_COMPRESSION_NONE is not set +# CONFIG_BOOT_CONFIG is not set +CONFIG_INITRAMFS_PRESERVE_MTIME=y +# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_LD_ORPHAN_WARN=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_HAVE_PCSPKR_PLATFORM=y +CONFIG_EXPERT=y +CONFIG_MULTIUSER=y # CONFIG_SGETMASK_SYSCALL is not set # CONFIG_SYSFS_SYSCALL is not set # CONFIG_FHANDLE is not set +CONFIG_POSIX_TIMERS=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_PCSPKR_PLATFORM=y # CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +CONFIG_EPOLL=y # CONFIG_SIGNALFD is not set # CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set +CONFIG_SHMEM=y # CONFIG_AIO is not set +CONFIG_IO_URING=y # CONFIG_ADVISE_SYSCALLS is not set +CONFIG_MEMBARRIER=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y +CONFIG_KALLSYMS_BASE_RELATIVE=y +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +# CONFIG_KCMP is not set +CONFIG_RSEQ=y +# CONFIG_DEBUG_RSEQ is not set CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +# CONFIG_PC104 is not set + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# end of Kernel Performance Events And Counters + +# CONFIG_PROFILING is not set +# end of General setup + +CONFIG_64BIT=y +CONFIG_X86_64=y +CONFIG_X86=y +CONFIG_INSTRUCTION_DECODER=y +CONFIG_OUTPUT_FORMAT="elf64-x86-64" +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_MMU=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=28 +CONFIG_ARCH_MMAP_RND_BITS_MAX=32 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_NR_GPIO=1024 +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_AUDIT_ARCH=y +CONFIG_HAVE_INTEL_TXT=y +CONFIG_X86_64_SMP=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=5 +CONFIG_CC_HAS_SANE_STACKPROTECTOR=y + +# +# Processor type and features +# CONFIG_SMP=y +CONFIG_X86_FEATURE_NAMES=y +CONFIG_X86_MPPARSE=y +# CONFIG_GOLDFISH is not set +# CONFIG_X86_CPU_RESCTRL is not set # CONFIG_X86_EXTENDED_PLATFORM is not set +# CONFIG_X86_INTEL_LPSS is not set +# CONFIG_X86_AMD_PLATFORM_DEVICE is not set +# CONFIG_IOSF_MBI is not set +CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +# CONFIG_HYPERVISOR_GUEST is not set +# CONFIG_MK8 is not set +# CONFIG_MPSC is not set +# CONFIG_MCORE2 is not set +# CONFIG_MATOM is not set +CONFIG_GENERIC_CPU=y +CONFIG_X86_INTERNODE_CACHE_SHIFT=6 +CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_TSC=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_IA32_FEAT_CTL=y +CONFIG_X86_VMX_FEATURE_NAMES=y CONFIG_PROCESSOR_SELECT=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_HYGON=y # CONFIG_CPU_SUP_CENTAUR is not set +CONFIG_CPU_SUP_ZHAOXIN=y +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_DMI=y +# CONFIG_GART_IOMMU is not set +CONFIG_BOOT_VESA_SUPPORT=y +# CONFIG_MAXSMP is not set +CONFIG_NR_CPUS_RANGE_BEGIN=2 +CONFIG_NR_CPUS_RANGE_END=512 +CONFIG_NR_CPUS_DEFAULT=64 +CONFIG_NR_CPUS=64 +CONFIG_SCHED_CLUSTER=y +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_MC_PRIO=y +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y +CONFIG_X86_MCE=y +# CONFIG_X86_MCELOG_LEGACY is not set +CONFIG_X86_MCE_INTEL=y # CONFIG_X86_MCE_AMD is not set +CONFIG_X86_MCE_THRESHOLD=y +# CONFIG_X86_MCE_INJECT is not set + +# +# Performance monitoring +# +CONFIG_PERF_EVENTS_INTEL_UNCORE=y # CONFIG_PERF_EVENTS_INTEL_RAPL is not set +CONFIG_PERF_EVENTS_INTEL_CSTATE=y +# CONFIG_PERF_EVENTS_AMD_POWER is not set +CONFIG_PERF_EVENTS_AMD_UNCORE=y +# CONFIG_PERF_EVENTS_AMD_BRS is not set +# end of Performance monitoring + +CONFIG_X86_VSYSCALL_EMULATION=y +CONFIG_X86_IOPL_IOPERM=y # CONFIG_MICROCODE is not set +# CONFIG_X86_MSR is not set +# CONFIG_X86_CPUID is not set +CONFIG_X86_5LEVEL=y +CONFIG_X86_DIRECT_GBPAGES=y +# CONFIG_X86_CPA_STATISTICS is not set +# CONFIG_AMD_MEM_ENCRYPT is not set +# CONFIG_NUMA is not set +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_X86_PMEM_LEGACY_DEVICE=y CONFIG_X86_PMEM_LEGACY=y +# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set # CONFIG_MTRR is not set +CONFIG_X86_UMIP=y +CONFIG_CC_HAS_IBT=y +# CONFIG_X86_KERNEL_IBT is not set # CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS is not set +CONFIG_X86_INTEL_TSX_MODE_OFF=y +# CONFIG_X86_INTEL_TSX_MODE_ON is not set +# CONFIG_X86_INTEL_TSX_MODE_AUTO is not set CONFIG_EFI=y +# CONFIG_EFI_STUB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_KEXEC=y CONFIG_KEXEC_FILE=y +CONFIG_ARCH_HAS_KEXEC_PURGATORY=y +# CONFIG_KEXEC_SIG is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_PHYSICAL_START=0x1000000 # CONFIG_RELOCATABLE is not set CONFIG_PHYSICAL_ALIGN=0x1000000 +CONFIG_DYNAMIC_MEMORY_LAYOUT=y +CONFIG_HOTPLUG_CPU=y +# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set +# CONFIG_DEBUG_HOTPLUG_CPU0 is not set +CONFIG_LEGACY_VSYSCALL_XONLY=y +# CONFIG_LEGACY_VSYSCALL_NONE is not set +# CONFIG_CMDLINE_BOOL is not set # CONFIG_MODIFY_LDT_SYSCALL is not set +# CONFIG_STRICT_SIGALTSTACK_SIZE is not set +CONFIG_HAVE_LIVEPATCH=y +# end of Processor type and features + +CONFIG_CC_HAS_RETURN_THUNK=y +CONFIG_SPECULATION_MITIGATIONS=y +CONFIG_PAGE_TABLE_ISOLATION=y # CONFIG_RETPOLINE is not set +CONFIG_CPU_IBPB_ENTRY=y +CONFIG_CPU_IBRS_ENTRY=y +CONFIG_ARCH_HAS_ADD_PAGES=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y + +# +# Power management and ACPI options +# # CONFIG_SUSPEND is not set +# CONFIG_PM is not set +# CONFIG_ENERGY_MODEL is not set +CONFIG_ARCH_SUPPORTS_ACPI=y +CONFIG_ACPI=y +CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y +CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y +CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y +# CONFIG_ACPI_DEBUGGER is not set +CONFIG_ACPI_SPCR_TABLE=y +# CONFIG_ACPI_FPDT is not set +CONFIG_ACPI_LPIT=y +CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y +# CONFIG_ACPI_EC_DEBUGFS is not set +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_FAN=y +# CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_CPU_FREQ_PSS=y +CONFIG_ACPI_PROCESSOR_CSTATE=y +CONFIG_ACPI_PROCESSOR_IDLE=y +CONFIG_ACPI_CPPC_LIB=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_HOTPLUG_CPU=y +# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_CUSTOM_DSDT_FILE="" +CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y +CONFIG_ACPI_TABLE_UPGRADE=y +# CONFIG_ACPI_DEBUG is not set +# CONFIG_ACPI_PCI_SLOT is not set +CONFIG_ACPI_CONTAINER=y +CONFIG_ACPI_HOTPLUG_IOAPIC=y +# CONFIG_ACPI_SBS is not set +# CONFIG_ACPI_HED is not set +# CONFIG_ACPI_CUSTOM_METHOD is not set +# CONFIG_ACPI_BGRT is not set +# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set +# CONFIG_ACPI_NFIT is not set +CONFIG_HAVE_ACPI_APEI=y +CONFIG_HAVE_ACPI_APEI_NMI=y +# CONFIG_ACPI_APEI is not set +# CONFIG_ACPI_DPTF is not set +# CONFIG_ACPI_CONFIGFS is not set +# CONFIG_ACPI_PFRUT is not set +CONFIG_ACPI_PCC=y +# CONFIG_PMIC_OPREGION is not set +CONFIG_ACPI_PRMT=y +CONFIG_X86_PM_TIMER=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +# CONFIG_CPU_FREQ_STAT is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y + +# +# CPU frequency scaling drivers +# +CONFIG_X86_INTEL_PSTATE=y +# CONFIG_X86_PCC_CPUFREQ is not set +# CONFIG_X86_AMD_PSTATE is not set +# CONFIG_X86_AMD_PSTATE_UT is not set +# CONFIG_X86_ACPI_CPUFREQ is not set +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +# CONFIG_X86_P4_CLOCKMOD is not set + +# +# shared options +# +# end of CPU Frequency scaling + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +# CONFIG_CPU_IDLE_GOV_LADDER is not set +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_CPU_IDLE_GOV_TEO is not set +# end of CPU Idle + +# CONFIG_INTEL_IDLE is not set +# end of Power management and ACPI options + +# +# Bus options (PCI etc.) +# +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_MMCONF_FAM10H=y +# CONFIG_PCI_CNB20LE_QUIRK is not set +# CONFIG_ISA_BUS is not set +CONFIG_ISA_DMA_API=y +CONFIG_AMD_NB=y +# end of Bus options (PCI etc.) + +# +# Binary Emulations +# +# CONFIG_IA32_EMULATION is not set +# CONFIG_X86_X32_ABI is not set +# end of Binary Emulations + +CONFIG_HAVE_KVM=y # CONFIG_VIRTUALIZATION is not set +CONFIG_AS_AVX512=y +CONFIG_AS_SHA1_NI=y +CONFIG_AS_SHA256_NI=y +CONFIG_AS_TPAUSE=y + +# +# General architecture-dependent options +# +CONFIG_CRASH_CORE=y +CONFIG_KEXEC_CORE=y +CONFIG_HOTPLUG_SMT=y +CONFIG_GENERIC_ENTRY=y +# CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set +# CONFIG_STATIC_CALL_SELFTEST is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_KPROBES_ON_FTRACE=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y +CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y +CONFIG_HAVE_NMI=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SET_DIRECT_MAP=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_HAVE_ASM_MODVERSIONS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_RUST=y +CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y +CONFIG_HAVE_USER_RETURN_NOTIFIER=y +CONFIG_HAVE_PERF_EVENTS_NMI=y +CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y +CONFIG_MMU_GATHER_MERGE_VMAS=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_HAVE_ARCH_SECCOMP=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y # CONFIG_SECCOMP is not set +CONFIG_HAVE_ARCH_STACKLEAK=y +CONFIG_HAVE_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y +CONFIG_LTO_NONE=y +CONFIG_ARCH_SUPPORTS_CFI_CLANG=y +CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y +CONFIG_HAVE_CONTEXT_TRACKING_USER=y +CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOVE_PUD=y +CONFIG_HAVE_MOVE_PMD=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y +CONFIG_HAVE_ARCH_HUGE_VMALLOC=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_HAVE_ARCH_SOFT_DIRTY=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_ARCH_MMAP_RND_BITS=28 +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_HAVE_OBJTOOL=y +CONFIG_HAVE_JUMP_LABEL_HACK=y +CONFIG_HAVE_NOINSTR_HACK=y +CONFIG_HAVE_NOINSTR_VALIDATION=y +CONFIG_HAVE_UACCESS_VALIDATION=y +CONFIG_HAVE_STACK_VALIDATION=y +CONFIG_HAVE_RELIABLE_STACKTRACE=y +# CONFIG_COMPAT_32BIT_TIME is not set +CONFIG_HAVE_ARCH_VMAP_STACK=y +CONFIG_VMAP_STACK=y +CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y +CONFIG_RANDOMIZE_KSTACK_OFFSET=y +# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y +CONFIG_ARCH_USE_MEMREMAP_PROT=y +# CONFIG_LOCK_EVENT_COUNTS is not set +CONFIG_ARCH_HAS_MEM_ENCRYPT=y +CONFIG_HAVE_STATIC_CALL=y +CONFIG_HAVE_STATIC_CALL_INLINE=y +CONFIG_HAVE_PREEMPT_DYNAMIC=y +CONFIG_HAVE_PREEMPT_DYNAMIC_CALL=y +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y +CONFIG_ARCH_HAS_ELFCORE_COMPAT=y +CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y +CONFIG_DYNAMIC_SIGFRAME=y +CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# end of GCOV-based kernel profiling + +CONFIG_HAVE_GCC_PLUGINS=y +CONFIG_GCC_PLUGINS=y +# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set +# end of General architecture-dependent options + +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=1 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +CONFIG_MODULE_COMPRESS_NONE=y +# CONFIG_MODULE_COMPRESS_GZIP is not set +# CONFIG_MODULE_COMPRESS_XZ is not set +# CONFIG_MODULE_COMPRESS_ZSTD is not set +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +CONFIG_MODPROBE_PATH="/sbin/modprobe" +# CONFIG_TRIM_UNUSED_KSYMS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_BLOCK_LEGACY_AUTOLOAD=y +CONFIG_BLK_DEV_BSG_COMMON=y +CONFIG_BLK_DEV_BSGLIB=y +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_ZONED is not set +# CONFIG_BLK_WBT is not set +CONFIG_BLK_DEBUG_FS=y +# CONFIG_BLK_SED_OPAL is not set +# CONFIG_BLK_INLINE_ENCRYPTION is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_EFI_PARTITION=y +# end of Partition Types + +CONFIG_BLK_MQ_PCI=y +CONFIG_BLOCK_HOLDER_DEPRECATED=y +CONFIG_BLK_MQ_STACKING=y + +# +# IO Schedulers +# +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +# CONFIG_IOSCHED_BFQ is not set +# end of IO Schedulers + +CONFIG_ASN1=m +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y +CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y +CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_ELFCORE=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_BINFMT_MISC is not set # CONFIG_COREDUMP is not set +# end of Executable file formats + +# +# Memory Management options +# # CONFIG_SWAP is not set + +# +# SLAB allocator options +# +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLAB_MERGE_DEFAULT=y +# CONFIG_SLAB_FREELIST_RANDOM is not set +# CONFIG_SLAB_FREELIST_HARDENED is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SLUB_CPU_PARTIAL=y +# end of SLAB allocator options + +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set # CONFIG_COMPAT_BRK is not set +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_FAST_GUP=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +# CONFIG_MEMORY_HOTPLUG is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y # CONFIG_COMPACTION is not set +# CONFIG_PAGE_REPORTING is not set +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_MMU_NOTIFIER=y +# CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +# CONFIG_MEMORY_FAILURE is not set +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANTS_THP_SWAP=y +# CONFIG_TRANSPARENT_HUGEPAGE is not set +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +# CONFIG_CMA is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y +CONFIG_ARCH_HAS_PTE_DEVMAP=y +CONFIG_ARCH_HAS_ZONE_DMA_SET=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA32=y # CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_PERCPU_STATS is not set +# CONFIG_GUP_TEST is not set +CONFIG_ARCH_HAS_PTE_SPECIAL=y +# CONFIG_USERFAULTFD is not set +# CONFIG_LRU_GEN is not set + +# +# Data Access Monitoring +# +# CONFIG_DAMON is not set +# end of Data Access Monitoring +# end of Memory Management options + CONFIG_NET=y + +# +# Networking options +# CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set CONFIG_UNIX=y +CONFIG_UNIX_SCM=y +CONFIG_AF_UNIX_OOB=y +# CONFIG_UNIX_DIAG is not set +# CONFIG_TLS is not set +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set CONFIG_SYN_COOKIES=y +# CONFIG_NET_IPVTI is not set +# CONFIG_NET_FOU is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_TABLE_PERTURB_ORDER=16 # CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set +# CONFIG_MPTCP is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_BPFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC2 is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_MPLS is not set +# CONFIG_NET_NSH is not set +# CONFIG_HSR is not set +# CONFIG_NET_SWITCHDEV is not set +# CONFIG_NET_L3_MASTER_DEV is not set +# CONFIG_QRTR is not set +# CONFIG_NET_NCSI is not set +CONFIG_PCPU_DEV_REFCNT=y +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_XPS=y +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# end of Network testing +# end of Networking options + +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_AF_KCM is not set +# CONFIG_MCTP is not set # CONFIG_WIRELESS is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +# CONFIG_PSAMPLE is not set +# CONFIG_NET_IFE is not set +# CONFIG_LWTUNNEL is not set +# CONFIG_FAILOVER is not set +CONFIG_ETHTOOL_NETLINK=y + +# +# Device Drivers +# +CONFIG_HAVE_EISA=y +# CONFIG_EISA is not set +CONFIG_HAVE_PCI=y CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_PCIEASPM=y +CONFIG_PCIEASPM_DEFAULT=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +# CONFIG_PCIEASPM_PERFORMANCE is not set +# CONFIG_PCIE_PTM is not set CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PCI_QUIRKS=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_PF_STUB is not set +CONFIG_PCI_ATS=y +CONFIG_PCI_LOCKLESS_CONFIG=y CONFIG_PCI_IOV=y +CONFIG_PCI_PRI=y +CONFIG_PCI_PASID=y +CONFIG_PCI_LABEL=y +# CONFIG_PCIE_BUS_TUNE_OFF is not set +CONFIG_PCIE_BUS_DEFAULT=y +# CONFIG_PCIE_BUS_SAFE is not set +# CONFIG_PCIE_BUS_PERFORMANCE is not set +# CONFIG_PCIE_BUS_PEER2PEER is not set +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +# CONFIG_HOTPLUG_PCI is not set + +# +# PCI controller drivers +# +# CONFIG_VMD is not set + +# +# DesignWare PCI Core Support +# +# CONFIG_PCIE_DW_PLAT_HOST is not set +# CONFIG_PCI_MESON is not set +# end of DesignWare PCI Core Support + +# +# Mobiveil PCIe Core Support +# +# end of Mobiveil PCIe Core Support + +# +# Cadence PCIe controllers support +# +# end of Cadence PCIe controllers support +# end of PCI controller drivers + +# +# PCI Endpoint +# +# CONFIG_PCI_ENDPOINT is not set +# end of PCI Endpoint + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set +# end of PCI switch controller drivers + +# CONFIG_CXL_BUS is not set +# CONFIG_PCCARD is not set +# CONFIG_RAPIDIO is not set + +# +# Generic Driver Options +# +# CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_DEVTMPFS_SAFE is not set # CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# Firmware loader +# +CONFIG_FW_LOADER=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER is not set +# CONFIG_FW_LOADER_COMPRESS is not set +# CONFIG_FW_UPLOAD is not set +# end of Firmware loader + # CONFIG_ALLOW_DEV_COREDUMP is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +# end of Generic Driver Options + +# +# Bus devices +# +# CONFIG_MHI_BUS is not set +# CONFIG_MHI_BUS_EP is not set +# end of Bus devices + +# CONFIG_CONNECTOR is not set + +# +# Firmware Drivers +# + +# +# ARM System Control and Management Interface Protocol +# +# end of ARM System Control and Management Interface Protocol + +# CONFIG_EDD is not set # CONFIG_FIRMWARE_MEMMAP is not set # CONFIG_DMIID is not set +# CONFIG_DMI_SYSFS is not set +CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y +# CONFIG_ISCSI_IBFT is not set +# CONFIG_FW_CFG_SYSFS is not set +CONFIG_SYSFB=y +# CONFIG_SYSFB_SIMPLEFB is not set +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_ESRT=y +CONFIG_EFI_RUNTIME_MAP=y +# CONFIG_EFI_FAKE_MEMMAP is not set +CONFIG_EFI_RUNTIME_WRAPPERS=y +# CONFIG_EFI_BOOTLOADER_CONTROL is not set +# CONFIG_EFI_CAPSULE_LOADER is not set +# CONFIG_EFI_TEST is not set +# CONFIG_EFI_RCI2_TABLE is not set +# CONFIG_EFI_DISABLE_PCI_DMA is not set +CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y +# CONFIG_EFI_DISABLE_RUNTIME is not set +# CONFIG_EFI_COCO_SECRET is not set +# end of EFI (Extensible Firmware Interface) Support + +# +# Tegra firmware driver +# +# end of Tegra firmware driver +# end of Firmware Drivers + +# CONFIG_GNSS is not set +# CONFIG_MTD is not set +# CONFIG_OF is not set +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_PARPORT is not set +CONFIG_PNP=y +CONFIG_PNP_DEBUG_MESSAGES=y + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +# CONFIG_BLK_DEV_FD is not set +CONFIG_CDROM=y +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +# CONFIG_ZRAM is not set CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_UBLK is not set + +# +# NVME Support +# +CONFIG_NVME_CORE=y CONFIG_BLK_DEV_NVME=y +# CONFIG_NVME_MULTIPATH is not set +# CONFIG_NVME_VERBOSE_ERRORS is not set +# CONFIG_NVME_FC is not set +# CONFIG_NVME_TCP is not set +# CONFIG_NVME_AUTH is not set +# end of NVME Support + +# +# Misc devices +# +# CONFIG_DUMMY_IRQ is not set +# CONFIG_IBM_ASM is not set +# CONFIG_PHANTOM is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_SRAM is not set +# CONFIG_DW_XDATA_PCIE is not set +# CONFIG_PCI_ENDPOINT_TEST is not set +# CONFIG_XILINX_SDFEC is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# CONFIG_EEPROM_93CX6=m +# end of EEPROM support + +# CONFIG_CB710_CORE is not set + +# +# Texas Instruments shared transport line discipline +# +# end of Texas Instruments shared transport line discipline + +# +# Altera FPGA firmware download module (requires I2C) +# +CONFIG_INTEL_MEI=m CONFIG_INTEL_MEI_ME=m CONFIG_INTEL_MEI_TXE=m +# CONFIG_VMWARE_VMCI is not set +# CONFIG_GENWQE is not set +# CONFIG_ECHO is not set +# CONFIG_BCM_VK is not set +# CONFIG_MISC_ALCOR_PCI is not set +# CONFIG_MISC_RTSX_PCI is not set +# CONFIG_MISC_RTSX_USB is not set +# CONFIG_HABANA_AI is not set +# CONFIG_UACCE is not set +# CONFIG_PVPANIC is not set +# end of Misc devices + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI_COMMON=y +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y # CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set CONFIG_BLK_DEV_SR=y CONFIG_CHR_DEV_SG=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=y +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# end of SCSI Transports + +CONFIG_SCSI_LOWLEVEL=y CONFIG_ISCSI_TCP=y +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_MVUMI is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_ESAS2R is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT3SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_MPI3MR is not set +# CONFIG_SCSI_SMARTPQI is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_MYRB is not set +# CONFIG_SCSI_MYRS is not set +# CONFIG_VMWARE_PVSCSI is not set +# CONFIG_SCSI_SNIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FDOMAIN_PCI is not set +# CONFIG_SCSI_ISCI is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_WD719X is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_DH is not set +# end of SCSI device support + CONFIG_ATA=y +CONFIG_SATA_HOST=y +CONFIG_PATA_TIMINGS=y +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATA_FORCE=y +CONFIG_ATA_ACPI=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# CONFIG_SATA_AHCI=y +CONFIG_SATA_MOBILE_LPM_POLICY=0 +# CONFIG_SATA_AHCI_PLATFORM is not set +# CONFIG_AHCI_DWC is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_ACARD_AHCI is not set +# CONFIG_SATA_SIL24 is not set # CONFIG_ATA_SFF is not set CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM_BUILTIN=y CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=y +# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set +# CONFIG_DM_UNSTRIPED is not set CONFIG_DM_CRYPT=y +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_THIN_PROVISIONING is not set +# CONFIG_DM_CACHE is not set +# CONFIG_DM_WRITECACHE is not set +# CONFIG_DM_EBS is not set +# CONFIG_DM_ERA is not set +# CONFIG_DM_CLONE is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_RAID is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_DUST is not set +# CONFIG_DM_INIT is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set CONFIG_DM_VERITY=y +# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set CONFIG_DM_VERITY_FEC=y +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_DM_INTEGRITY is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +# end of IEEE 1394 (FireWire) support + +# CONFIG_MACINTOSH_DRIVERS is not set CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_WIREGUARD is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_IPVLAN is not set +# CONFIG_VXLAN is not set +# CONFIG_GENEVE is not set +# CONFIG_BAREUDP is not set +# CONFIG_GTP is not set +# CONFIG_MACSEC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_TUN is not set +# CONFIG_TUN_VNET_CROSS_LE is not set +# CONFIG_VETH is not set +# CONFIG_NLMON is not set +# CONFIG_ARCNET is not set +CONFIG_ETHERNET=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_ADAPTEC is not set # CONFIG_NET_VENDOR_AGERE is not set +CONFIG_NET_VENDOR_ALACRITECH=y +# CONFIG_SLICOSS is not set # CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_ALTERA_TSE is not set # CONFIG_NET_VENDOR_AMAZON is not set # CONFIG_NET_VENDOR_AMD is not set +CONFIG_NET_VENDOR_AQUANTIA=y +# CONFIG_AQTION is not set # CONFIG_NET_VENDOR_ARC is not set +CONFIG_NET_VENDOR_ASIX=y # CONFIG_NET_VENDOR_ATHEROS is not set +# CONFIG_CX_ECAT is not set # CONFIG_NET_VENDOR_BROADCOM is not set +CONFIG_NET_VENDOR_CADENCE=y +# CONFIG_MACB is not set # CONFIG_NET_VENDOR_CAVIUM is not set # CONFIG_NET_VENDOR_CHELSIO is not set # CONFIG_NET_VENDOR_CISCO is not set +CONFIG_NET_VENDOR_CORTINA=y +CONFIG_NET_VENDOR_DAVICOM=y +# CONFIG_DNET is not set # CONFIG_NET_VENDOR_DEC is not set # CONFIG_NET_VENDOR_DLINK is not set # CONFIG_NET_VENDOR_EMULEX is not set +CONFIG_NET_VENDOR_ENGLEDER=y +# CONFIG_TSNEP is not set # CONFIG_NET_VENDOR_EZCHIP is not set +CONFIG_NET_VENDOR_FUNGIBLE=y +# CONFIG_FUN_ETH is not set +CONFIG_NET_VENDOR_GOOGLE=y +# CONFIG_GVE is not set +CONFIG_NET_VENDOR_HUAWEI=y +# CONFIG_HINIC is not set # CONFIG_NET_VENDOR_I825XX is not set +CONFIG_NET_VENDOR_INTEL=y +# CONFIG_E100 is not set CONFIG_E1000=m CONFIG_E1000E=m +CONFIG_E1000E_HWTS=y +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_IXGB is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +# CONFIG_I40E is not set +# CONFIG_I40EVF is not set +# CONFIG_ICE is not set +# CONFIG_FM10K is not set +# CONFIG_IGC is not set +CONFIG_NET_VENDOR_WANGXUN=y +# CONFIG_NGBE is not set +# CONFIG_TXGBE is not set +# CONFIG_JME is not set +CONFIG_NET_VENDOR_LITEX=y # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MELLANOX is not set # CONFIG_NET_VENDOR_MICREL is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_LAN743X is not set +CONFIG_NET_VENDOR_MICROSEMI=y +CONFIG_NET_VENDOR_MICROSOFT=y # CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_FEALNX is not set +CONFIG_NET_VENDOR_NI=y +# CONFIG_NI_XGE_MANAGEMENT_ENET is not set # CONFIG_NET_VENDOR_NATSEMI is not set +CONFIG_NET_VENDOR_NETERION=y +# CONFIG_S2IO is not set # CONFIG_NET_VENDOR_NETRONOME is not set # CONFIG_NET_VENDOR_NVIDIA is not set # CONFIG_NET_VENDOR_OKI is not set +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_PACKET_ENGINES=y +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_NET_VENDOR_PENSANDO=y +# CONFIG_IONIC is not set # CONFIG_NET_VENDOR_QLOGIC is not set # CONFIG_NET_VENDOR_BROCADE is not set # CONFIG_NET_VENDOR_QUALCOMM is not set @@ -129,156 +1400,1825 @@ CONFIG_E1000E=m # CONFIG_NET_VENDOR_SEEQ is not set # CONFIG_NET_VENDOR_SILAN is not set # CONFIG_NET_VENDOR_SIS is not set +CONFIG_NET_VENDOR_SOLARFLARE=y +# CONFIG_SFC is not set +# CONFIG_SFC_FALCON is not set +# CONFIG_SFC_SIENA is not set # CONFIG_NET_VENDOR_SMSC is not set +CONFIG_NET_VENDOR_SOCIONEXT=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_SUN is not set # CONFIG_NET_VENDOR_SYNOPSYS is not set # CONFIG_NET_VENDOR_TEHUTI is not set # CONFIG_NET_VENDOR_TI is not set +CONFIG_NET_VENDOR_VERTEXCOM=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NET_VENDOR_XILINX=y +# CONFIG_XILINX_EMACLITE is not set +# CONFIG_XILINX_AXI_EMAC is not set +# CONFIG_XILINX_LL_TEMAC is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_PHYLIB is not set +# CONFIG_PSE_CONTROLLER is not set +# CONFIG_MDIO_DEVICE is not set + +# +# PCS device drivers +# +# end of PCS device drivers + +# CONFIG_PPP is not set +# CONFIG_SLIP is not set # CONFIG_USB_NET_DRIVERS is not set # CONFIG_WLAN is not set +# CONFIG_WAN is not set + +# +# Wireless WAN +# +# CONFIG_WWAN is not set +# end of Wireless WAN + +# CONFIG_VMXNET3 is not set +# CONFIG_FUJITSU_ES is not set +# CONFIG_NETDEVSIM is not set +# CONFIG_NET_FAILOVER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_SPARSEKMAP is not set +# CONFIG_INPUT_MATRIXKMAP is not set +CONFIG_INPUT_VIVALDIFMAP=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set # CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set +# CONFIG_RMI4_CORE is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y +CONFIG_SERIO_I8042=y # CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_USERIO is not set +# CONFIG_GAMEPORT is not set +# end of Hardware I/O ports +# end of Input device support + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set +CONFIG_LDISC_AUTOLOAD=y + +# +# Serial drivers +# CONFIG_SERIAL_8250=y # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set # CONFIG_SERIAL_8250_PNP is not set +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set +# CONFIG_SERIAL_8250_FINTEK is not set +# CONFIG_SERIAL_8250_CONSOLE is not set # CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_DW is not set +# CONFIG_SERIAL_8250_RT288X is not set # CONFIG_SERIAL_8250_LPSS is not set # CONFIG_SERIAL_8250_MID is not set +CONFIG_SERIAL_8250_PERICOM=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_LANTIQ is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_RP2 is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_FSL_LINFLEXUART is not set +# CONFIG_SERIAL_SPRD is not set +# end of Serial drivers + +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_NOZOMI is not set +# CONFIG_NULL_TTY is not set +# CONFIG_SERIAL_DEV_BUS is not set CONFIG_TTY_PRINTK=y +CONFIG_TTY_PRINTK_LEVEL=6 +# CONFIG_VIRTIO_CONSOLE is not set +# CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_HW_RANDOM_INTEL=y CONFIG_HW_RANDOM_AMD=m +# CONFIG_HW_RANDOM_BA431 is not set CONFIG_HW_RANDOM_VIA=m +# CONFIG_HW_RANDOM_XIPHERA is not set +# CONFIG_APPLICOM is not set +# CONFIG_MWAVE is not set +CONFIG_DEVMEM=y +# CONFIG_NVRAM is not set +CONFIG_DEVPORT=y +# CONFIG_HPET is not set +# CONFIG_HANGCHECK_TIMER is not set CONFIG_TCG_TPM=y # CONFIG_HW_RANDOM_TPM is not set +CONFIG_TCG_TIS_CORE=y CONFIG_TCG_TIS=y +# CONFIG_TCG_NSC is not set +# CONFIG_TCG_ATMEL is not set +# CONFIG_TCG_INFINEON is not set +# CONFIG_TCG_CRB is not set +# CONFIG_TCG_VTPM_PROXY is not set +# CONFIG_TELCLOCK is not set +# CONFIG_XILLYBUS is not set +# CONFIG_XILLYUSB is not set +CONFIG_RANDOM_TRUST_CPU=y # CONFIG_RANDOM_TRUST_BOOTLOADER is not set +# end of Character devices + +# +# I2C support +# +# CONFIG_I2C is not set +# end of I2C support + +# CONFIG_I3C is not set +# CONFIG_SPI is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +# end of PTP clock support + +# CONFIG_PINCTRL is not set +# CONFIG_GPIOLIB is not set +# CONFIG_W1 is not set +# CONFIG_POWER_RESET is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_SAMSUNG_SDI is not set +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_BATTERY_GOLDFISH is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y +# CONFIG_THERMAL_NETLINK is not set +# CONFIG_THERMAL_STATISTICS is not set +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +# CONFIG_THERMAL_WRITABLE_TRIPS is not set +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_EMULATION is not set + +# +# Intel thermal drivers +# +# CONFIG_INTEL_POWERCLAMP is not set +CONFIG_X86_THERMAL_VECTOR=y # CONFIG_X86_PKG_TEMP_THERMAL is not set +# CONFIG_INTEL_SOC_DTS_THERMAL is not set + +# +# ACPI INT340X thermal drivers +# +# CONFIG_INT340X_THERMAL is not set +# end of ACPI INT340X thermal drivers + +# CONFIG_INTEL_PCH_THERMAL is not set +# CONFIG_INTEL_TCC_COOLING is not set +# CONFIG_INTEL_MENLOW is not set +# CONFIG_INTEL_HFI_THERMAL is not set +# end of Intel thermal drivers + +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_MADERA is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +# CONFIG_MFD_INTEL_LPSS_ACPI is not set +# CONFIG_MFD_INTEL_LPSS_PCI is not set +# CONFIG_MFD_INTEL_PMC_BXT is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_SM501 is not set CONFIG_MFD_SYSCON=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_TQMX86 is not set +# CONFIG_MFD_VX855 is not set +# end of Multifunction device drivers + +# CONFIG_REGULATOR is not set +# CONFIG_RC_CORE is not set + +# +# CEC support +# +# CONFIG_MEDIA_CEC_SUPPORT is not set +# end of CEC support + +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +CONFIG_APERTURE_HELPERS=y +# CONFIG_AGP is not set +# CONFIG_VGA_SWITCHEROO is not set +# CONFIG_DRM is not set +# CONFIG_DRM_DEBUG_MODESET_LOCK is not set + +# +# ARM devices +# +# end of ARM devices + +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y + +# +# Frame buffer Devices +# +CONFIG_FB_CMDLINE=y +CONFIG_FB_NOTIFY=y CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_VGA16 is not set CONFIG_FB_VESA=y CONFIG_FB_EFI=y +# CONFIG_FB_N411 is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SM712 is not set +# end of Frame buffer Devices + +# +# Backlight & LCD device support +# +# CONFIG_LCD_CLASS_DEVICE is not set +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set +# end of Backlight & LCD device support + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# end of Console display driver support + +# CONFIG_LOGO is not set +# end of Graphics support + +# CONFIG_SOUND is not set + +# +# HID support +# +CONFIG_HID=y +# CONFIG_HID_BATTERY_STRENGTH is not set +# CONFIG_HIDRAW is not set +# CONFIG_UHID is not set +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACCUTOUCH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_BETOP_FF is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_COUGAR is not set +# CONFIG_HID_MACALLY is not set +# CONFIG_HID_CMEDIA is not set +# CONFIG_HID_CREATIVE_SB0540 is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_GEMBIRD is not set +# CONFIG_HID_GFRM is not set +# CONFIG_HID_GLORIOUS is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_VIVALDI is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_VIEWSONIC is not set +# CONFIG_HID_VRC2 is not set +# CONFIG_HID_XIAOMI is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_ITE is not set +# CONFIG_HID_JABRA is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LENOVO is not set +# CONFIG_HID_LETSKETCH is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MALTRON is not set +# CONFIG_HID_MAYFLASH is not set +# CONFIG_HID_MEGAWORLD_FF is not set +# CONFIG_HID_REDRAGON is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NTI is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PENMOUNT is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PXRC is not set +# CONFIG_HID_RAZER is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_RETRODE is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SEMITEK is not set +# CONFIG_HID_SIGMAMICRO is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEAM is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_RMI is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_TOPRE is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_UDRAW_PS3 is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_XINMO is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_ALPS is not set +# end of Special HID drivers + +# +# USB HID support +# CONFIG_USB_HID=m +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# end of USB HID Boot Protocol drivers +# end of USB HID support + +# +# Intel ISH HID support +# +# CONFIG_INTEL_ISH_HID is not set +# end of Intel ISH HID support + +# +# AMD SFH HID Support +# +# CONFIG_AMD_SFH_HID is not set +# end of AMD SFH HID Support +# end of HID support + +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +# CONFIG_USB_ULPI_BUS is not set +CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB=y +CONFIG_USB_PCI=y +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_PRODUCTLIST is not set +# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set +CONFIG_USB_AUTOSUSPEND_DELAY=2 +# CONFIG_USB_MON is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set CONFIG_USB_XHCI_HCD=m +# CONFIG_USB_XHCI_DBGCAP is not set +CONFIG_USB_XHCI_PCI=m +# CONFIG_USB_XHCI_PCI_RENESAS is not set CONFIG_USB_XHCI_PLATFORM=m CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=m +# CONFIG_USB_EHCI_FSL is not set CONFIG_USB_EHCI_HCD_PLATFORM=m +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_USB_CDNS_SUPPORT is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_DWC2 is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_APPLE_MFI_FASTCHARGE is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_EZUSB_FX2 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +# CONFIG_NOP_USB_XCEIV is not set +# end of USB Physical Layer drivers + +# CONFIG_USB_GADGET is not set +# CONFIG_TYPEC is not set +# CONFIG_USB_ROLE_SWITCH is not set +# CONFIG_MMC is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_RTC_LIB=y +CONFIG_RTC_MC146818_LIB=y CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# + +# +# SPI RTC drivers +# + +# +# SPI and I2C RTC drivers +# + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_FTRTC010 is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_GOLDFISH is not set +# CONFIG_DMADEVICES is not set + +# +# DMABUF options +# +# CONFIG_SYNC_FILE is not set +# CONFIG_DMABUF_HEAPS is not set +# end of DMABUF options + +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VFIO is not set +# CONFIG_VIRT_DRIVERS is not set +CONFIG_VIRTIO_MENU=y +# CONFIG_VIRTIO_PCI is not set +# CONFIG_VIRTIO_MMIO is not set +# CONFIG_VDPA is not set +CONFIG_VHOST_MENU=y +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set + +# +# Microsoft Hyper-V guest support +# +# end of Microsoft Hyper-V guest support + +# CONFIG_GREYBUS is not set +# CONFIG_COMEDI is not set +# CONFIG_STAGING is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_MELLANOX_PLATFORM is not set +CONFIG_SURFACE_PLATFORMS=y +# CONFIG_SURFACE_GPE is not set +# CONFIG_SURFACE_PRO3_BUTTON is not set +CONFIG_X86_PLATFORM_DEVICES=y +# CONFIG_ACPI_WMI is not set +# CONFIG_ACERHDF is not set +# CONFIG_ACER_WIRELESS is not set +# CONFIG_AMD_PMF is not set +# CONFIG_AMD_PMC is not set +# CONFIG_AMD_HSMP is not set +# CONFIG_ADV_SWBUTTON is not set +# CONFIG_ASUS_WIRELESS is not set +# CONFIG_X86_PLATFORM_DRIVERS_DELL is not set +# CONFIG_FUJITSU_TABLET is not set +# CONFIG_GPD_POCKET_FAN is not set +# CONFIG_HP_ACCEL is not set +# CONFIG_WIRELESS_HOTKEY is not set +# CONFIG_IBM_RTL is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_INTEL_SAR_INT1092 is not set +# CONFIG_INTEL_PMC_CORE is not set + +# +# Intel Speed Select Technology interface support +# +# CONFIG_INTEL_SPEED_SELECT_INTERFACE is not set +# end of Intel Speed Select Technology interface support + +# +# Intel Uncore Frequency Control +# +# CONFIG_INTEL_UNCORE_FREQ_CONTROL is not set +# end of Intel Uncore Frequency Control + +# CONFIG_INTEL_PUNIT_IPC is not set +# CONFIG_INTEL_RST is not set +# CONFIG_INTEL_SMARTCONNECT is not set +# CONFIG_INTEL_TURBO_MAX_3 is not set +# CONFIG_INTEL_VSEC is not set +# CONFIG_SAMSUNG_Q10 is not set +# CONFIG_TOSHIBA_BT_RFKILL is not set +# CONFIG_TOSHIBA_HAPS is not set +# CONFIG_ACPI_CMPC is not set +# CONFIG_TOPSTAR_LAPTOP is not set +# CONFIG_INTEL_IPS is not set +# CONFIG_INTEL_SCU_PCI is not set +# CONFIG_INTEL_SCU_PLATFORM is not set +# CONFIG_SIEMENS_SIMATIC_IPC is not set +# CONFIG_WINMATE_FM07_KEYS is not set +# CONFIG_P2SB is not set +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y +# CONFIG_XILINX_VCU is not set +# CONFIG_HWSPINLOCK is not set + +# +# Clock Source drivers +# +CONFIG_CLKEVT_I8253=y +CONFIG_I8253_LOCK=y +CONFIG_CLKBLD_I8253=y +# end of Clock Source drivers + +CONFIG_MAILBOX=y +CONFIG_PCC=y +# CONFIG_ALTERA_MBOX is not set +CONFIG_IOMMU_IOVA=y +CONFIG_IOASID=y +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +# end of Generic IOMMU Pagetable Support + +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set +CONFIG_IOMMU_DEFAULT_DMA_LAZY=y +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_IOMMU_DMA=y +CONFIG_IOMMU_SVA=y +# CONFIG_AMD_IOMMU is not set +CONFIG_DMAR_TABLE=y CONFIG_INTEL_IOMMU=y CONFIG_INTEL_IOMMU_SVM=y +CONFIG_INTEL_IOMMU_DEFAULT_ON=y +CONFIG_INTEL_IOMMU_FLOPPY_WA=y # CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON is not set +# CONFIG_IRQ_REMAP is not set + +# +# Remoteproc drivers +# +# CONFIG_REMOTEPROC is not set +# end of Remoteproc drivers + +# +# Rpmsg drivers +# +# CONFIG_RPMSG_QCOM_GLINK_RPM is not set +# CONFIG_RPMSG_VIRTIO is not set +# end of Rpmsg drivers + +# CONFIG_SOUNDWIRE is not set + +# +# SOC (System On Chip) specific Drivers +# + +# +# Amlogic SoC drivers +# +# end of Amlogic SoC drivers + +# +# Broadcom SoC drivers +# +# end of Broadcom SoC drivers + +# +# NXP/Freescale QorIQ SoC drivers +# +# end of NXP/Freescale QorIQ SoC drivers + +# +# fujitsu SoC drivers +# +# end of fujitsu SoC drivers + +# +# i.MX SoC drivers +# +# end of i.MX SoC drivers + +# +# Enable LiteX SoC Builder specific drivers +# +# end of Enable LiteX SoC Builder specific drivers + +# +# Qualcomm SoC drivers +# +# end of Qualcomm SoC drivers + +# CONFIG_SOC_TI is not set + +# +# Xilinx SoC drivers +# +# end of Xilinx SoC drivers +# end of SOC (System On Chip) specific Drivers + +# CONFIG_PM_DEVFREQ is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_NTB is not set +# CONFIG_PWM is not set + +# +# IRQ chip support +# +# end of IRQ chip support + +# CONFIG_IPACK_BUS is not set +# CONFIG_RESET_CONTROLLER is not set + +# +# PHY Subsystem +# CONFIG_GENERIC_PHY=y +# CONFIG_USB_LGM_PHY is not set +# CONFIG_PHY_CAN_TRANSCEIVER is not set + +# +# PHY drivers for Broadcom platforms +# +# CONFIG_BCM_KONA_USB2_PHY is not set +# end of PHY drivers for Broadcom platforms + +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_PHY_INTEL_LGM_EMMC is not set +# end of PHY Subsystem + +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +# end of Performance monitor support + +# CONFIG_RAS is not set +# CONFIG_USB4 is not set + +# +# Android +# +# CONFIG_ANDROID_BINDER_IPC is not set +# end of Android + +CONFIG_LIBNVDIMM=y # CONFIG_BLK_DEV_PMEM is not set # CONFIG_BTT is not set +# CONFIG_DAX is not set +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y +# CONFIG_NVMEM_RMEM is not set + +# +# HW tracing support +# +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set +# end of HW tracing support + +# CONFIG_FPGA is not set +# CONFIG_TEE is not set +# CONFIG_SIOX is not set +# CONFIG_SLIMBUS is not set +# CONFIG_INTERCONNECT is not set +# CONFIG_COUNTER is not set +# CONFIG_PECI is not set +# CONFIG_HTE is not set +# end of Device Drivers + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_VALIDATE_FS_PARSER is not set +CONFIG_FS_IOMAP=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_F2FS_FS is not set +# CONFIG_EXPORTFS_BLOCK_OPS is not set +CONFIG_FILE_LOCKING=y +# CONFIG_FS_ENCRYPTION is not set +# CONFIG_FS_VERITY is not set # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_FUSE_FS is not set +# CONFIG_OVERLAY_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set +# end of Caches + +# +# CD-ROM/DVD Filesystems +# CONFIG_ISO9660_FS=y CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set +# end of CD-ROM/DVD Filesystems + +# +# DOS/FAT/EXFAT/NT Filesystems +# +CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y 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=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 + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set # CONFIG_PROC_SYSCTL is not set # CONFIG_PROC_PAGE_MONITOR is not set +# CONFIG_PROC_CHILDREN is not set +CONFIG_PROC_PID_ARCH_STATUS=y +CONFIG_KERNFS=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +CONFIG_ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y +CONFIG_ARCH_HAS_GIGANTIC_PAGE=y +# CONFIG_CONFIGFS_FS is not set +CONFIG_EFIVAR_FS=m +# end of Pseudo filesystems + # CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NFS_FS is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_SMB_SERVER is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set CONFIG_NLS_UTF8=y +# CONFIG_UNICODE is not set +CONFIG_IO_WQ=y +# end of File systems + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +CONFIG_SECURITYFS=y +# CONFIG_INTEL_TXT is not set +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y CONFIG_HARDENED_USERCOPY=y +# CONFIG_FORTIFY_SOURCE is not set +# CONFIG_STATIC_USERMODEHELPER is not set +# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set +CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity,bpf" + +# +# Kernel hardening options +# + +# +# Memory initialization +# +CONFIG_INIT_STACK_NONE=y +# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set +# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set +# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL is not set +# CONFIG_GCC_PLUGIN_STACKLEAK is not set +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +# end of Memory initialization + +CONFIG_RANDSTRUCT_NONE=y +# CONFIG_RANDSTRUCT_FULL is not set +# CONFIG_RANDSTRUCT_PERFORMANCE is not set +# end of Kernel hardening options +# end of Security options + +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_SKCIPHER=y +CONFIG_CRYPTO_SKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=m +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_SIMD=y +# end of Crypto core or helper + +# +# Public-key cryptography +# CONFIG_CRYPTO_RSA=m +# CONFIG_CRYPTO_DH is not set +# CONFIG_CRYPTO_ECDH is not set +# CONFIG_CRYPTO_ECDSA is not set +# CONFIG_CRYPTO_ECRDSA is not set +# CONFIG_CRYPTO_SM2 is not set +# CONFIG_CRYPTO_CURVE25519 is not set +# end of Public-key cryptography + +# +# Block ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_AES_TI is not set CONFIG_CRYPTO_ANUBIS=m +# CONFIG_CRYPTO_ARIA is not set CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_BLOWFISH_COMMON=m CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST_COMMON=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +# CONFIG_CRYPTO_DES is not set CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +# CONFIG_CRYPTO_SM4_GENERIC is not set CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +# end of Block ciphers + +# +# Length-preserving ciphers and modes +# +# CONFIG_CRYPTO_ADIANTUM is not set CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_CHACHA20=m +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CFB is not set +CONFIG_CRYPTO_CTR=m CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_HCTR2 is not set CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_LRW=y +# CONFIG_CRYPTO_OFB is not set CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=y +# end of Length-preserving ciphers and modes + +# +# AEAD (authenticated encryption with associated data) ciphers +# +# CONFIG_CRYPTO_AEGIS128 is not set CONFIG_CRYPTO_CHACHA20POLY1305=m CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_GCM=m +# CONFIG_CRYPTO_SEQIV is not set +# CONFIG_CRYPTO_ECHAINIV is not set +CONFIG_CRYPTO_ESSIV=y +# end of AEAD (authenticated encryption with associated data) ciphers + +# +# Hashes, digests, and MACs +# +# CONFIG_CRYPTO_BLAKE2B is not set CONFIG_CRYPTO_CMAC=m +CONFIG_CRYPTO_GHASH=m CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_POLY1305=m CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_SHA3 is not set +# CONFIG_CRYPTO_SM3_GENERIC is not set +# CONFIG_CRYPTO_STREEBOG is not set CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_XCBC=m +# CONFIG_CRYPTO_XXHASH is not set +# end of Hashes, digests, and MACs + +# +# CRCs (cyclic redundancy checks) +# +CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_CRCT10DIF=y +# end of CRCs (cyclic redundancy checks) + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_LZO=y CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m CONFIG_CRYPTO_LZ4HC=m +# CONFIG_CRYPTO_ZSTD is not set +# end of Compression + +# +# Random number generation +# CONFIG_CRYPTO_ANSI_CPRNG=m +# CONFIG_CRYPTO_DRBG_MENU is not set +# CONFIG_CRYPTO_JITTERENTROPY is not set +# end of Random number generation + +# +# Userspace interface +# +CONFIG_CRYPTO_USER_API=y CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_USER_API_SKCIPHER=y CONFIG_CRYPTO_USER_API_RNG=y CONFIG_CRYPTO_USER_API_AEAD=y +CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y +# CONFIG_CRYPTO_STATS is not set +# end of Userspace interface + +CONFIG_CRYPTO_HASH_INFO=y + +# +# Accelerated Cryptographic Algorithms for CPU (x86) +# +# CONFIG_CRYPTO_CURVE25519_X86 is not set CONFIG_CRYPTO_AES_NI_INTEL=y CONFIG_CRYPTO_BLOWFISH_X86_64=m +CONFIG_CRYPTO_CAMELLIA_X86_64=m +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=m CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=m CONFIG_CRYPTO_CAST5_AVX_X86_64=m CONFIG_CRYPTO_CAST6_AVX_X86_64=m CONFIG_CRYPTO_DES3_EDE_X86_64=m CONFIG_CRYPTO_SERPENT_SSE2_X86_64=m +CONFIG_CRYPTO_SERPENT_AVX_X86_64=m CONFIG_CRYPTO_SERPENT_AVX2_X86_64=m +# CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64 is not set +# CONFIG_CRYPTO_SM4_AESNI_AVX2_X86_64 is not set +CONFIG_CRYPTO_TWOFISH_X86_64=m +CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m +# CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64 is not set CONFIG_CRYPTO_CHACHA20_X86_64=m +# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set +# CONFIG_CRYPTO_NHPOLY1305_SSE2 is not set +# CONFIG_CRYPTO_NHPOLY1305_AVX2 is not set +# CONFIG_CRYPTO_BLAKE2S_X86 is not set +# CONFIG_CRYPTO_POLYVAL_CLMUL_NI is not set CONFIG_CRYPTO_POLY1305_X86_64=m CONFIG_CRYPTO_SHA1_SSSE3=y CONFIG_CRYPTO_SHA256_SSSE3=y CONFIG_CRYPTO_SHA512_SSSE3=y +# CONFIG_CRYPTO_SM3_AVX_X86_64 is not set CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m CONFIG_CRYPTO_CRC32C_INTEL=y CONFIG_CRYPTO_CRC32_PCLMUL=m CONFIG_CRYPTO_CRCT10DIF_PCLMUL=m +# end of Accelerated Cryptographic Algorithms for CPU (x86) + # CONFIG_CRYPTO_HW is not set + +# +# Certificates for signature checking +# +# end of Certificates for signature checking + +# +# Library routines +# +# CONFIG_PACKING is not set +CONFIG_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y CONFIG_CORDIC=m +# CONFIG_PRIME_NUMBERS is not set +CONFIG_RATIONAL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IOMAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_HAS_FAST_MULTIPLIER=y +CONFIG_ARCH_USE_SYM_ANNOTATIONS=y + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m +# CONFIG_CRYPTO_LIB_CHACHA is not set +# CONFIG_CRYPTO_LIB_CURVE25519 is not set +CONFIG_CRYPTO_LIB_DES=m +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11 +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m +# CONFIG_CRYPTO_LIB_POLY1305 is not set +# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +# end of Crypto library routines + CONFIG_CRC_CCITT=m +CONFIG_CRC16=y CONFIG_CRC_T10DIF=y +# CONFIG_CRC64_ROCKSOFT is not set CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC64 is not set +# CONFIG_CRC4 is not set CONFIG_CRC7=m CONFIG_LIBCRC32C=m CONFIG_CRC8=m +CONFIG_XXHASH=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_842_COMPRESS=m +CONFIG_842_DECOMPRESS=m +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4HC_COMPRESS=m +CONFIG_LZ4_DECOMPRESS=m +CONFIG_ZSTD_COMMON=y +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +# CONFIG_XZ_DEC_MICROLZMA is not set +CONFIG_XZ_DEC_BCJ=y CONFIG_XZ_DEC_TEST=m +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_ZSTD=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_INTERVAL_TREE=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_DMA_OPS=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_SWIOTLB=y +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_DMA_MAP_BENCHMARK is not set +CONFIG_SGL_ALLOC=y +# CONFIG_FORCE_NR_CPUS is not set +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set +CONFIG_NLATTR=y +CONFIG_CLZ_TAB=y CONFIG_IRQ_POLL=y +CONFIG_MPILIB=m +CONFIG_UCS2_STRING=y +CONFIG_HAVE_GENERIC_VDSO=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_VDSO_TIME_NS=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_SG_POOL=y +CONFIG_ARCH_HAS_PMEM_API=y +CONFIG_MEMREGION=y +CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y +CONFIG_ARCH_HAS_COPY_MC=y +CONFIG_ARCH_STACKWALK=y +CONFIG_SBITMAP=y +# end of Library routines + +# +# Kernel hacking +# + +# +# printk and dmesg options +# CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_CALLER is not set +# CONFIG_STACKTRACE_BUILD_ID is not set +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 +CONFIG_CONSOLE_LOGLEVEL_QUIET=4 +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 CONFIG_BOOT_PRINTK_DELAY=y CONFIG_DYNAMIC_DEBUG=y +CONFIG_DYNAMIC_DEBUG_CORE=y +CONFIG_SYMBOLIC_ERRNAME=y # CONFIG_DEBUG_BUGVERBOSE is not set +# end of printk and dmesg options + +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MISC=y + +# +# Compile-time checks and compiler options +# +CONFIG_DEBUG_INFO=y +CONFIG_AS_HAS_NON_CONST_LEB128=y +# CONFIG_DEBUG_INFO_NONE is not set +# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set CONFIG_DEBUG_INFO_DWARF4=y +# CONFIG_DEBUG_INFO_DWARF5 is not set +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_INFO_COMPRESSED is not set +# CONFIG_DEBUG_INFO_SPLIT is not set CONFIG_GDB_SCRIPTS=y CONFIG_FRAME_WARN=1024 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_HEADERS_INSTALL is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set +CONFIG_OBJTOOL=y +# CONFIG_VMLINUX_MAP is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# end of Compile-time checks and compiler options + +# +# Generic Kernel Debugging Instruments +# CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" CONFIG_DEBUG_FS=y +CONFIG_DEBUG_FS_ALLOW_ALL=y +# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set +# CONFIG_DEBUG_FS_ALLOW_NONE is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y +# CONFIG_UBSAN is not set +CONFIG_HAVE_ARCH_KCSAN=y +# end of Generic Kernel Debugging Instruments + +# +# Networking Debugging +# +# CONFIG_NET_DEV_REFCNT_TRACKER is not set +# CONFIG_NET_NS_REFCNT_TRACKER is not set +# CONFIG_DEBUG_NET is not set +# end of Networking Debugging + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_SLUB_DEBUG is not set +# CONFIG_PAGE_OWNER is not set +# CONFIG_PAGE_TABLE_CHECK is not set +# CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_RODATA_TEST is not set +CONFIG_ARCH_HAS_DEBUG_WX=y +# CONFIG_DEBUG_WX is not set +CONFIG_GENERIC_PTDUMP=y +# CONFIG_PTDUMP_DEBUGFS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SHRINKER_DEBUG is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_SCHED_STACK_END_CHECK is not set +CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VM_PGTABLE is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP=y +# CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP is not set +CONFIG_HAVE_ARCH_KASAN=y +CONFIG_HAVE_ARCH_KASAN_VMALLOC=y +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y +# CONFIG_KASAN is not set +CONFIG_HAVE_ARCH_KFENCE=y +# CONFIG_KFENCE is not set +CONFIG_HAVE_ARCH_KMSAN=y +# end of Memory Debugging + +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Oops, Lockups and Hangs +# +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_HARDLOCKUP_DETECTOR_PERF=y +CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set CONFIG_WQ_WATCHDOG=y +# CONFIG_TEST_LOCKUP is not set +# end of Debug Oops, Lockups and Hangs + +# +# Scheduler Debugging +# # CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# end of Scheduler Debugging + +# CONFIG_DEBUG_TIMEKEEPING is not set +CONFIG_DEBUG_PREEMPT=y + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +CONFIG_LOCK_DEBUGGING_SUPPORT=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set +# CONFIG_CSD_LOCK_WAIT_DEBUG is not set +# end of Lock Debugging (spinlocks, mutexes, etc...) + +# CONFIG_DEBUG_IRQFLAGS is not set CONFIG_STACKTRACE=y +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set + +# +# Debug kernel data structures +# +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PLIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# CONFIG_DEBUG_MAPLE_TREE is not set +# end of Debug kernel data structures + +# CONFIG_DEBUG_CREDENTIALS is not set + +# +# RCU Debugging +# +# CONFIG_RCU_SCALE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_REF_SCALE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 # CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# end of RCU Debugging + +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_LATENCYTOP is not set +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_HAVE_RETHOOK=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_FENTRY=y +CONFIG_HAVE_OBJTOOL_MCOUNT=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y +CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y # CONFIG_STRICT_DEVMEM is not set + +# +# x86 Debugging +# # CONFIG_X86_VERBOSE_BOOTUP is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +# CONFIG_EARLY_PRINTK_USB_XDBC is not set +# CONFIG_EFI_PGT_DUMP is not set +# CONFIG_DEBUG_TLBFLUSH is not set +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +# CONFIG_X86_DECODER_SELFTEST is not set +# CONFIG_IO_DELAY_0X80 is not set CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +# CONFIG_DEBUG_BOOT_PARAMS is not set +# CONFIG_CPA_DEBUG is not set +# CONFIG_DEBUG_ENTRY is not set +# CONFIG_DEBUG_NMI_SELFTEST is not set # CONFIG_X86_DEBUG_FPU is not set +# CONFIG_PUNIT_ATOM_DEBUG is not set +CONFIG_UNWINDER_ORC=y +# CONFIG_UNWINDER_FRAME_POINTER is not set +# CONFIG_UNWINDER_GUESS is not set +# end of x86 Debugging + +# +# Kernel Testing and Coverage +# +# CONFIG_KUNIT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set +CONFIG_RUNTIME_TESTING_MENU=y +# CONFIG_LKDTM is not set +# CONFIG_TEST_MIN_HEAP is not set +# CONFIG_TEST_DIV64 is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_TEST_REF_TRACKER is not set +# CONFIG_RBTREE_TEST is not set +# CONFIG_REED_SOLOMON_TEST is not set +# CONFIG_INTERVAL_TREE_TEST is not set +# CONFIG_PERCPU_TEST is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_TEST_HEXDUMP is not set +# CONFIG_STRING_SELFTEST is not set +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_STRSCPY is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_TEST_PRINTF is not set +# CONFIG_TEST_SCANF is not set +# CONFIG_TEST_BITMAP is not set +# CONFIG_TEST_UUID is not set +# CONFIG_TEST_XARRAY is not set +# CONFIG_TEST_MAPLE_TREE is not set +# CONFIG_TEST_RHASHTABLE is not set +# CONFIG_TEST_SIPHASH is not set +# CONFIG_TEST_IDA is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_BITOPS is not set +# CONFIG_TEST_VMALLOC is not set +# CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_BPF is not set +# CONFIG_TEST_BLACKHOLE_DEV is not set +# CONFIG_FIND_BIT_BENCHMARK is not set +# CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_UDELAY is not set +# CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_TEST_DYNAMIC_DEBUG is not set +# CONFIG_TEST_KMOD is not set +# CONFIG_TEST_MEMCAT_P is not set +# CONFIG_TEST_MEMINIT is not set +# CONFIG_TEST_FREE_PAGES is not set +# CONFIG_TEST_FPU is not set +# CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set +CONFIG_ARCH_USE_MEMTEST=y +# CONFIG_MEMTEST is not set +# end of Kernel Testing and Coverage + +# +# Rust hacking +# +# end of Rust hacking +# end of Kernel hacking diff --git a/config/linux-nitropad-x.config b/config/linux-nitropad-x.config index a82c42a2..638605fa 100644 --- a/config/linux-nitropad-x.config +++ b/config/linux-nitropad-x.config @@ -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 From e924a8afcac004d5e9f4dc882ace7093c2b75b2e Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 9 Nov 2023 17:01:35 -0500 Subject: [PATCH 66/69] oem-factory-reset : Prompt user for any connected block device, give storage size and loop until none is connected to exit loop. Warn user if connected usb block device is less then 128mb, since creating LUKS container of less then 8mb might cause issues. Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 63 ++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index ebc9895d..2960d7ee 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -326,12 +326,6 @@ prompt_insert_to_be_wiped_thumb_drive() { die "Error displaying warning about having only desired to be wiped thumb drive inserted" } -#list blkid devices (removing partition numbers) -list_blkid_devices() { - TRACE "Under oem-factory-reset:list_blkid_devices" - blkid | cut -d: -f1 | sed 's/[0-9]$//' -} - #export master key and subkeys to thumbdrive's private LUKS contained partition export_master_key_subkeys_and_revocation_key_to_private_LUKS_container() { TRACE "Under oem-factory-reset:export_master_key_subkeys_and_revocation_key_to_private_LUKS_container" @@ -422,16 +416,59 @@ export_public_key_to_thumbdrive_public_partition() { wipe_thumb_drive_and_copy_gpg_key_material() { TRACE "Under oem-factory-reset:wipe_thumb_drive_and_copy_gpg_key_material" prompt_disconnect_external_USB_storage_device - actual_devices=$(list_blkid_devices) #enable usb storage enable_usb enable_usb_storage - prompt_insert_to_be_wiped_thumb_drive - new_devices=$(list_blkid_devices) - thumb_drive=$(echo "$new_devices" | grep -v "$actual_devices" | uniq) - if [ -z "$thumb_drive" ]; then - whiptail_error_die "No new thumb drive detected! Aborting." - fi + + #loop until user chooses a disk + thumb_drive="" + while [ -z "$thumb_drive" ]; do + prompt_insert_to_be_wiped_thumb_drive + #list usb storage devices + list_usb_storage disks >/tmp/usb_disk_list + if [ $(cat /tmp/usb_disk_list | wc -l) -gt 0 ]; then + file_selector "/tmp/usb_disk_list" "Select USB device to partition" + if [ "$FILE" == "" ]; then + #No USB storage device selected + warn "No USB storage device selected!" + else + # Obtain size of thumb drive to be wiped with fdisk + disk_size_bytes="$(blockdev --getsize64 "$FILE")" + #Convert disk size to GB + thumb_drive_size_mb=$((disk_size_bytes / 1024 / 1024)) + thumb_drive_size_gb=$((thumb_drive_size_mb / 1024 )) + + #if thumb_drive_size_gb is 0, then disk size is less than 1GB + thumb_drive_size_message="" + if [ "$thumb_drive_size_gb" -eq 0 ]; then + thumb_drive_size_message="$thumb_drive_size_mb MB" + if [ "$thumb_drive_size_mb" -lt 128 ]; then + warn "Thumb drive size is less than 128MB!" + warn "LUKS container needs to be at least 8mb!" + warn "If the next operation fails, try with a bigger thumb drive" + fi + else + thumb_drive_size_message="$thumb_drive_size_gb GB" + fi + + # confirm with user size of thumb drive to be wiped + whiptail --title "Confirm thumb drive to be wiped" --yesno "Are you sure you want to wipe the following thumb drive?\n\n$FILE\n\nSize: $thumb_drive_size_message" 0 0 + if [ $? -ne 0 ]; then + warn "Thumb drive wipe aborted by user!" + continue + fi + + #User chose and confirmed a thumb drive and its size to be wiped + thumb_drive=$FILE + fi + else + #No USB storage device detected + warn "No USB storage device detected! Aborting OEM Factory Reset / Re-Ownership" + sleep 3 + die "No USB storage device detected! User decided to not wipe any thumb drive" + fi + done + select_luks_container_size_percent #Wipe thumb drive with a LUKS container of size $(cat /tmp/luks_container_size_percent) prepare_thumb_drive --device "$thumb_drive" --percentage "$(cat /tmp/luks_container_size_percent)" --pass "${ADMIN_PIN}" From a925219efb526188780ecba8d3fc8c8961405816 Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Mon, 13 Nov 2023 13:54:37 -0500 Subject: [PATCH 67/69] oem-factory-reset: Improve prompt flow formatting flash drive Combine prompt to disconnect other devices with prompt to connect the desired device. Show block device sizes in MB/GB when selecting device so it is easier to select. file_selector now supports --show-size to include block device sizes in menu. Rework file_selector so menu options can contain spaces (use bash array) and to simplify logic. Prompt to select flash drive and LUKS percentage in OEM reset before actually taking any actions, so aborting doesn't half-reset the system. Abort OEM reset if user aborts the flash drive selection instead of looping forever. (Canceling the confirmation still loops to retry but it is possible to exit by aborting the repeated menu.) Signed-off-by: Jonathon Hall --- initrd/bin/oem-factory-reset | 101 +++++++++++++-------------- initrd/etc/gui_functions | 128 ++++++++++++++++++++++++----------- 2 files changed, 138 insertions(+), 91 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 2960d7ee..9cd2c257 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -307,22 +307,12 @@ keytocard_subkeys_to_smartcard() { TRACE "oem-factory-reset:keytocard_subkeys_to_smartcard done" } -#Whiptail prompt to disconnect any external USB storage device -prompt_disconnect_external_USB_storage_device() { - TRACE "Under oem-factory-reset:disconnect_external_USB_storage_device" - #Whiptail $BG_COLOR_WARNING warning about removing any external USB storage device currently connected - whiptail $BG_COLOR_WARNING --title 'WARNING: Please disconnect any external USB storage device' \ - --msgbox "An external USB storage device will be WIPED next.\n\nPlease disconnect all external USB storage devices." 0 80 || - die "Error displaying warning about removing any external USB storage device currently connected" - -} - #Whiptail prompt to insert to be wiped thumb drive prompt_insert_to_be_wiped_thumb_drive() { TRACE "Under oem-factory-reset:prompt_insert_to_be_wiped_thumb_drive" #Whiptail warning about having only desired to be wiped thumb drive inserted whiptail $BG_COLOR_WARNING --title 'WARNING: Please insert the thumb drive to be wiped' \ - --msgbox "The thumb drive will be WIPED next.\n\nPlease have connected only the thumb drive to be wiped." 0 80 || + --msgbox "The thumb drive will be WIPED next.\n\nPlease connect only the thumb drive to be wiped and disconnect others." 0 80 || die "Error displaying warning about having only desired to be wiped thumb drive inserted" } @@ -412,10 +402,13 @@ export_public_key_to_thumbdrive_public_partition() { TRACE "oem-factory-reset:export_public_key_to_thumbdrive_public_partition done" } -#Wipe a thumb drive and export master key and subkeys to it -wipe_thumb_drive_and_copy_gpg_key_material() { +# Select thumb drive and LUKS container size for GPG key export +# Sets variables containing selections: +# - thumb_drive +# - thumb_drive_luks_percent +select_thumb_drive_for_key_material() { TRACE "Under oem-factory-reset:wipe_thumb_drive_and_copy_gpg_key_material" - prompt_disconnect_external_USB_storage_device + #enable usb storage enable_usb enable_usb_storage @@ -426,41 +419,32 @@ wipe_thumb_drive_and_copy_gpg_key_material() { prompt_insert_to_be_wiped_thumb_drive #list usb storage devices list_usb_storage disks >/tmp/usb_disk_list - if [ $(cat /tmp/usb_disk_list | wc -l) -gt 0 ]; then - file_selector "/tmp/usb_disk_list" "Select USB device to partition" - if [ "$FILE" == "" ]; then - #No USB storage device selected - warn "No USB storage device selected!" - else - # Obtain size of thumb drive to be wiped with fdisk - disk_size_bytes="$(blockdev --getsize64 "$FILE")" - #Convert disk size to GB - thumb_drive_size_mb=$((disk_size_bytes / 1024 / 1024)) - thumb_drive_size_gb=$((thumb_drive_size_mb / 1024 )) - - #if thumb_drive_size_gb is 0, then disk size is less than 1GB - thumb_drive_size_message="" - if [ "$thumb_drive_size_gb" -eq 0 ]; then - thumb_drive_size_message="$thumb_drive_size_mb MB" - if [ "$thumb_drive_size_mb" -lt 128 ]; then - warn "Thumb drive size is less than 128MB!" - warn "LUKS container needs to be at least 8mb!" - warn "If the next operation fails, try with a bigger thumb drive" - fi - else - thumb_drive_size_message="$thumb_drive_size_gb GB" - fi - - # confirm with user size of thumb drive to be wiped - whiptail --title "Confirm thumb drive to be wiped" --yesno "Are you sure you want to wipe the following thumb drive?\n\n$FILE\n\nSize: $thumb_drive_size_message" 0 0 - if [ $? -ne 0 ]; then - warn "Thumb drive wipe aborted by user!" - continue - fi - - #User chose and confirmed a thumb drive and its size to be wiped - thumb_drive=$FILE + # Abort if: + # - no disks found (prevent file_selector's nonsense prompt) + # - file_selector fails for any reason + # - user aborts (file_selector succeeds but FILE is empty) + if [ $(cat /tmp/usb_disk_list | wc -l) -gt 0 ] && + file_selector --show-size "/tmp/usb_disk_list" "Select USB device to partition" && + [ -n "$FILE" ]; then + # Obtain size of thumb drive to be wiped with fdisk + disk_size_bytes="$(blockdev --getsize64 "$FILE")" + if [ "$disk_size_bytes" -lt "$((128*1024*1024))" ]; then + warn "Thumb drive size is less than 128MB!" + warn "LUKS container needs to be at least 8MB!" + warn "If the next operation fails, try with a bigger thumb drive" fi + + thumb_drive_size_message="$(display_size "$disk_size_bytes")" + # confirm with user size of thumb drive to be wiped + whiptail --title "Confirm thumb drive to be wiped" --yesno \ + "Are you sure you want to wipe the following thumb drive?\n\n$FILE\n\nSize: $thumb_drive_size_message" 0 0 + if [ $? -ne 0 ]; then + warn "Thumb drive wipe aborted by user!" + continue + fi + + #User chose and confirmed a thumb drive and its size to be wiped + thumb_drive=$FILE else #No USB storage device detected warn "No USB storage device detected! Aborting OEM Factory Reset / Re-Ownership" @@ -470,8 +454,21 @@ wipe_thumb_drive_and_copy_gpg_key_material() { done select_luks_container_size_percent + thumb_drive_luks_percent="$(cat /tmp/luks_container_size_percent)" +} + +#Wipe a thumb drive and export master key and subkeys to it +# $1 - thumb drive block device +# $2 - LUKS container percentage [1-99] +wipe_thumb_drive_and_copy_gpg_key_material() { + TRACE "Under oem-factory-reset:wipe_thumb_drive_and_copy_gpg_key_material" + + local thumb_drive thumb_drive_luks_percent + thumb_drive="$1" + thumb_drive_luks_percent="$2" + #Wipe thumb drive with a LUKS container of size $(cat /tmp/luks_container_size_percent) - prepare_thumb_drive --device "$thumb_drive" --percentage "$(cat /tmp/luks_container_size_percent)" --pass "${ADMIN_PIN}" + prepare_thumb_drive --device "$thumb_drive" --percentage "$thumb_drive_luks_percent" --pass "${ADMIN_PIN}" #Export master key and subkeys to thumb drive first partition export_master_key_subkeys_and_revocation_key_to_private_LUKS_container --mode rw --device "$thumb_drive"1 --mountpoint /media --pass "${ADMIN_PIN}" #Export public key to thumb drive's public partition @@ -1068,6 +1065,10 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then } done fi + + if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then + select_thumb_drive_for_key_material + fi fi # If nothing is stored in custom variables, we set them to their defaults @@ -1184,7 +1185,7 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then else die "Unsupported GPG_ALGO: $GPG_ALGO" fi - wipe_thumb_drive_and_copy_gpg_key_material + wipe_thumb_drive_and_copy_gpg_key_material "$thumb_drive" "$thumb_drive_luks_percent" set_user_config "CONFIG_HAVE_GPG_KEY_BACKUP" "y" if [ "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then keytocard_subkeys_to_smartcard diff --git a/initrd/etc/gui_functions b/initrd/etc/gui_functions index ac9fbcfb..86e09916 100755 --- a/initrd/etc/gui_functions +++ b/initrd/etc/gui_functions @@ -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() From d39fc26dd95ae4b7a82376ede49e9a2612cafa36 Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Mon, 13 Nov 2023 14:37:19 -0500 Subject: [PATCH 68/69] oem-factory-reset: Move format confirmation before resetting anything Move confirmation of formatting flash drive with LUKS percentage selection before any reset actions have been taken, so aborting does not result in a half-reset system. Combine with the more basic "confirm" prompt that existed after selecting the device (but did not include the LUKS size information). Split up prepare_flash_drive into interactive_prepare_flash_drive (both prompts and formats as before), confirm_thumb_drive_format (just confirms the selections), and prepare_thumb_drive (now noninteractive). Signed-off-by: Jonathon Hall --- initrd/bin/oem-factory-reset | 13 +++--- initrd/etc/luks-functions | 77 +++++++++++++++++++++++++++++------- 2 files changed, 67 insertions(+), 23 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 9cd2c257..4a970c6d 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -434,11 +434,10 @@ select_thumb_drive_for_key_material() { warn "If the next operation fails, try with a bigger thumb drive" fi - thumb_drive_size_message="$(display_size "$disk_size_bytes")" - # confirm with user size of thumb drive to be wiped - whiptail --title "Confirm thumb drive to be wiped" --yesno \ - "Are you sure you want to wipe the following thumb drive?\n\n$FILE\n\nSize: $thumb_drive_size_message" 0 0 - if [ $? -ne 0 ]; then + select_luks_container_size_percent + thumb_drive_luks_percent="$(cat /tmp/luks_container_size_percent)" + + if ! confirm_thumb_drive_format "$FILE" "$thumb_drive_luks_percent"; then warn "Thumb drive wipe aborted by user!" continue fi @@ -452,8 +451,6 @@ select_thumb_drive_for_key_material() { die "No USB storage device detected! User decided to not wipe any thumb drive" fi done - - select_luks_container_size_percent thumb_drive_luks_percent="$(cat /tmp/luks_container_size_percent)" } @@ -468,7 +465,7 @@ wipe_thumb_drive_and_copy_gpg_key_material() { thumb_drive_luks_percent="$2" #Wipe thumb drive with a LUKS container of size $(cat /tmp/luks_container_size_percent) - prepare_thumb_drive --device "$thumb_drive" --percentage "$thumb_drive_luks_percent" --pass "${ADMIN_PIN}" + prepare_thumb_drive "$thumb_drive" "$thumb_drive_luks_percent" "${ADMIN_PIN}" #Export master key and subkeys to thumb drive first partition export_master_key_subkeys_and_revocation_key_to_private_LUKS_container --mode rw --device "$thumb_drive"1 --mountpoint /media --pass "${ADMIN_PIN}" #Export public key to thumb drive's public partition diff --git a/initrd/etc/luks-functions b/initrd/etc/luks-functions index ca75a36b..0b7d8a1c 100644 --- a/initrd/etc/luks-functions +++ b/initrd/etc/luks-functions @@ -51,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,6 +85,7 @@ prepare_thumb_drive() ;; *) echo "usage: prepare_thumb_drive [--device device] [--percentage percentage] [--pass passphrase]" + return 1 ;; esac done @@ -171,31 +173,76 @@ 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))" + #Calculate percentage of device in MB + LUKS_SIZE_MB="$((DISK_SIZE_BYTES*LUKS_PERCENTAGE/100/1024/1024))" - #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 + 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\n assigned to private LUKS contained private ext4 partition,\n 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 while rest of device will be assigned to extfat public partition...\n" +# 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" From 97d903f22a7ab1b4abb3eca09dbf7db165cb065b Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Mon, 13 Nov 2023 14:52:09 -0500 Subject: [PATCH 69/69] oem-factory-reset: Don't repeat "insert flash drive" message Don't repeat this message if the user says "no" to the confirmation prompt. Go directly to the menu. Signed-off-by: Jonathon Hall --- initrd/bin/oem-factory-reset | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 4a970c6d..b64d469f 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -413,10 +413,11 @@ select_thumb_drive_for_key_material() { enable_usb enable_usb_storage + prompt_insert_to_be_wiped_thumb_drive + #loop until user chooses a disk thumb_drive="" while [ -z "$thumb_drive" ]; do - prompt_insert_to_be_wiped_thumb_drive #list usb storage devices list_usb_storage disks >/tmp/usb_disk_list # Abort if: