Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce optional quiet mode (move technical output from console to /tmp/debug.log) #1863

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Configuration for building a coreboot ROM that works in
# the qemu emulator in graphical mode thanks to FBWhiptail
# This version requires a supported HOTP Security dongle (Nitrokey Pro/Storage or Librem Key)
#
# TPM can be used with a qemu software TPM (TIS, 2.0).
export CONFIG_COREBOOT=y
export CONFIG_COREBOOT_VERSION=24.02.01
export CONFIG_LINUX_VERSION=6.1.8

CONFIG_COREBOOT_CONFIG=config/coreboot-qemu-tpm2-prod.config
CONFIG_LINUX_CONFIG=config/linux-qemu.config

#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
#Enable TPM2 pcap output under /tmp
#export CONFIG_TPM2_CAPTURE_PCAP=y

#Enable quiet mode: technical information logged under /tmp/debug.log
export CONFIG_QUIET_MODE=y

#On-demand hardware support (modules.cpio)
CONFIG_LINUX_USB=y
CONFIG_LINUX_E1000=y
#CONFIG_MOBILE_TETHERING=y
#Runtime on-demand additional hardware support (modules.cpio)
export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y



#Modules packed into tools.cpio
ifeq "$(CONFIG_UROOT)" "y"
CONFIG_BUSYBOX=n
else
#Modules packed into tools.cpio
CONFIG_CRYPTSETUP2=y
CONFIG_FLASHPROG=y
CONFIG_FLASHTOOLS=y
CONFIG_GPG2=y
CONFIG_KEXEC=y
CONFIG_UTIL_LINUX=y
CONFIG_LVM2=y
CONFIG_MBEDTLS=y
CONFIG_PCIUTILS=y
#Runtime tools to write to MSR
CONFIG_MSRTOOLS=y
#Remote attestation support
# TPM2 requirements
CONFIG_TPM2_TSS=y
CONFIG_OPENSSL=y
#Remote Attestation common tools
CONFIG_POPT=y
CONFIG_QRENCODE=y
CONFIG_TPMTOTP=y
#HOTP based remote attestation for supported USB Security dongle
#With/Without TPM support
CONFIG_HOTPKEY=y
#Nitrokey Storage admin tool (deprecated)
#CONFIG_NKSTORECLI=n
#GUI Support
#Console based Whiptail support(Console based, no FB):
#CONFIG_SLANG=y
#CONFIG_NEWT=y
#FBWhiptail based (Graphical):
CONFIG_CAIRO=y
CONFIG_FBWHIPTAIL=y
#Additional tools (tools.cpio):
#SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E)
CONFIG_DROPBEAR=y
endif

#Runtime configuration
#Automatically boot if HOTP is valid
export CONFIG_AUTO_BOOT_TIMEOUT=5
#TPM2 requirements
export CONFIG_TPM2_TOOLS=y
export CONFIG_PRIMARY_KEY_TYPE=ecc
#TPM1 requirements
#export CONFIG_TPM=y
export CONFIG_BOOTSCRIPT=/bin/gui-init
#text-based original init:
#export CONFIG_BOOTSCRIPT=/bin/generic-init
export CONFIG_BOOT_REQ_HASH=n
export CONFIG_BOOT_REQ_ROLLBACK=n
export CONFIG_BOOT_RECOVERY_SERIAL="/dev/ttyS0"
export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0"
export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash"
export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm2-hotp"
#export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal"
export CONFIG_AUTO_BOOT_TIMEOUT=5

BOARD_TARGETS := qemu
6 changes: 2 additions & 4 deletions initrd/bin/cbfs-init
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ for cbfsname in `echo $cbfsfiles`; do
if [ ! -z "$filename" ]; then
mkdir -p `dirname $filename` \
|| die "$filename: mkdir failed"
echo "Extracting CBFS file $cbfsname into $filename"
LOG "Extracting CBFS file $cbfsname into $filename"
cbfs -t 50 $CBFS_ARG -r $cbfsname > "$filename" \
|| die "$filename: cbfs file read failed"
if [ "$CONFIG_TPM" = "y" ]; then
TRACE_FUNC
echo "TPM: Extending PCR[$CONFIG_PCR] with $filename"
LOG "TPM: Extending PCR[$CONFIG_PCR] with filename $filename and then its content"
# Measure both the filename and its content. This
# ensures that renaming files or pivoting file content
# will still affect the resulting PCR measurement.
Expand All @@ -32,5 +32,3 @@ for cbfsname in `echo $cbfsfiles`; do
fi
fi
done

# TODO: copy CBFS file named "heads/initrd.tgz" to /tmp, measure and extract
2 changes: 1 addition & 1 deletion initrd/bin/inject_firmware.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ chmod a+x "$INITRD_ROOT/init"
# Linux ignores zeros between archive segments, so any extra padding is not
# harmful.
FW_INITRD="/tmp/inject_firmware_initrd.cpio.gz"
dd if="$ORIG_INITRD" of="$FW_INITRD" bs=512 conv=sync status=none
dd if="$ORIG_INITRD" of="$FW_INITRD" bs=512 conv=sync status=none > /dev/null 2>&1
# Pack up the new contents and append to the initrd. Don't spend time
# compressing this.
(cd "$INITRD_ROOT"; find . | cpio -o -H newc) >>"$FW_INITRD"
Expand Down
4 changes: 2 additions & 2 deletions initrd/bin/kexec-insert-key
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fi

# Override PCR 4 so that user can't read the key
TRACE_FUNC
echo "TPM: Extending PCR[4] to prevent any future secret unsealing"
LOG "TPM: Extending PCR[4] to prevent any future secret unsealing"
tpmr extend -ix 4 -ic generic ||
die 'Unable to scramble PCR'

Expand All @@ -92,7 +92,7 @@ echo '+++ Building initrd'
# pad the initramfs (dracut doesn't pad the last gz blob)
# without this the kernel init/initramfs.c fails to read
# the subsequent uncompressed/compressed cpio
dd if="$INITRD" of="$SECRET_CPIO" bs=512 conv=sync ||
dd if="$INITRD" of="$SECRET_CPIO" bs=512 conv=sync > /dev/null 2>&1 ||
die "Failed to copy initrd to /tmp"

if [ "$unseal_failed" = "n" ]; then
Expand Down
2 changes: 1 addition & 1 deletion initrd/bin/kexec-select-boot
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ while true; do
if [ ! -r "$TMP_KEY_DEVICES" ]; then
# Extend PCR4 as soon as possible
TRACE_FUNC
DEBUG "TPM: Extending PCR[4] to prevent further secret unsealing"
LOG "TPM: Extending PCR[4] to prevent further secret unsealing"
tpmr extend -ix 4 -ic generic ||
die "Failed to extend TPM PCR[4]"
fi
Expand Down
10 changes: 10 additions & 0 deletions initrd/bin/kexec-sign-config
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ assert_signable

confirm_gpg_card

# remount /boot as rw
mount -o remount,rw /boot

# update hashes in /boot before signing
if [ "$update" = "y" ]; then
(
Expand Down Expand Up @@ -81,8 +84,15 @@ for tries in 1 2 3; do
; then
# successful - update the validated params
check_config $paramsdir

# remount /boot as ro
mount -o remount,ro /boot

exit 0
fi
done

# remount /boot as ro
mount -o remount,ro /boot

die "$paramsdir: Unable to sign kexec hashes"
9 changes: 7 additions & 2 deletions initrd/bin/oem-factory-reset
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,11 @@ generate_OEM_gpg_keys() {
echo ${USER_PIN_DEF} # Default user PIN since we just factory reset
} | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \
>/tmp/gpg_card_edit_output 2>&1
#This outputs to console \
# "gpg: checking the trustdb"
# "gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model"
# "gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u"
#TODO: Suppress this output to console (stdout shown in DEBUG mode)?
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR"
Expand Down Expand Up @@ -636,7 +641,7 @@ generate_checksums() {
tpmr counter_create \
-pwdc '' \
-la -3135106223 |
tee /tmp/counter ||
tee /tmp/counter >/dev/null 2>&1 ||
whiptail_error_die "Unable to create TPM counter"
TPM_COUNTER=$(cut -d: -f1 </tmp/counter)

Expand Down Expand Up @@ -682,7 +687,7 @@ generate_checksums() {
DEBUG "Detach-signing boot files under kexec.sig: ${param_files}"
if sha256sum $param_files 2>/dev/null | DO_WITH_DEBUG --mask-position 4 gpg \
--pinentry-mode loopback \
--passphrase "${USER_PIN}" \
--passphrase-file <(echo -n "$USER_PIN") \
--digest-algo SHA256 \
--detach-sign \
-a \
Expand Down
2 changes: 1 addition & 1 deletion initrd/bin/qubes-measure-luks
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ DEBUG "Removing /tmp/lukshdr-*"
rm /tmp/lukshdr-*

TRACE_FUNC
echo "TPM: Extending PCR[6] with hash of LUKS headers from /tmp/luksDump.txt"
LOG "TPM: 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"
1 change: 1 addition & 0 deletions initrd/bin/seal-hotpkey
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ awk_get_admin_counter="$awk_admin_counter_regex"' { print gensub('"$awk_admin_co
admin_pin_retries="$(echo "$hotp_token_info" | awk "$awk_get_admin_counter")"
admin_pin_retries="${admin_pin_retries:-0}"
DEBUG "Admin PIN retry counter is $admin_pin_retries"
#TODO: as per hotp_verification 1.6: this is 8 for nk3 and wrong. FIX

# Try using factory default admin PIN for 1 month following OEM reset to ease
# initial setup. But don't do it forever to encourage changing the PIN and
Expand Down
52 changes: 26 additions & 26 deletions initrd/bin/tpmr
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ tpm2_extend() {
esac
done
tpm2 pcrextend "$index:sha256=$hash"
tpm2 pcrread "sha256:$index"
LOG $(tpm2 pcrread "sha256:$index" 2>&1)

TRACE_FUNC
DEBUG "TPM: Extended PCR[$index] with hash $hash"
Expand Down Expand Up @@ -307,7 +307,7 @@ tpm1_counter_create() {
# 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
if ! tpm counter_create -pwdo "$(cat "/tmp/secret/tpm_owner_password")" "$@" >/dev/null 2>&1; 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"
Expand All @@ -332,9 +332,9 @@ tpm2_counter_create() {
esac
done
prompt_tpm_owner_password
rand_index="1$(dd if=/dev/urandom bs=1 count=3 | xxd -pc3)"
rand_index="1$(dd if=/dev/urandom bs=1 count=3 2>/dev/null | xxd -pc3)"
tpm2 nvdefine -C o -s 8 -a "ownerread|authread|authwrite|nt=1" \
-P "$(tpm2_password_hex "$(cat "/tmp/secret/tpm_owner_password")")" "0x$rand_index" >/dev/console ||
-P "$(tpm2_password_hex "$(cat "/tmp/secret/tpm_owner_password")")" "0x$rand_index" >/dev/null 2>&1 ||
{
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
Expand Down Expand Up @@ -412,7 +412,7 @@ tpm1_destroy() {
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
dd if=/dev/zero bs="$size" count=1 of=/tmp/wipe-totp-zero > /dev/null 2>&1
tpm nv_writevalue -in "$index" -if /tmp/wipe-totp-zero ||
die "Unable to wipe sealed secret from TPM NVRAM"
}
Expand Down Expand Up @@ -650,15 +650,15 @@ tpm2_reset() {
# output TPM Owner Password to a file to be reused in this boot session until recovery shell/reboot
DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password"
echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password"
tpm2 clear -c platform || warn "Unable to clear TPM on platform hierarchy"
tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")"
tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")"
tpm2 clear -c platform > /dev/null 2>&1 || LOG "Unable to clear TPM on platform hierarchy"
tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to change owner password"
tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to change endorsement password"
tpm2 createprimary -C owner -g sha256 -G "${CONFIG_PRIMARY_KEY_TYPE:-rsa}" \
-c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")"
-c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to create primary key"
tpm2 evictcontrol -C owner -c "$SECRET_DIR/primary.ctx" "$PRIMARY_HANDLE" \
-P "$(tpm2_password_hex "$tpm_owner_password")"
shred -u "$SECRET_DIR/primary.ctx"
tpm2_startsession
-P "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to evict primary key"
shred -u "$SECRET_DIR/primary.ctx" > /dev/null 2>&1
tpm2_startsession > /dev/null 2>&1 || LOG "Unable to start session"

# Set the dictionary attack parameters. TPM2 defaults vary widely, we
# want consistent behavior on any TPM.
Expand All @@ -681,7 +681,7 @@ tpm2_reset() {
--max-tries=10 \
--recovery-time=3600 \
--lockout-recovery-time=0 \
--auth="session:$ENC_SESSION_FILE"
--auth="session:$ENC_SESSION_FILE" > /dev/null 2>&1 || LOG "Unable to set dictionary lockout parameters"

# 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
Expand All @@ -690,7 +690,7 @@ tpm2_reset() {
# The default lockout password is empty, so we must set this, and we
# don't need to provide any auth (use the default empty password).
tpm2 changeauth -Q -c lockout \
"hex:$(dd if=/dev/urandom bs=32 count=1 status=none | xxd -p | tr -d ' \n')"
"hex:$(dd if=/dev/urandom bs=32 count=1 status=none 2>/dev/null | xxd -p | tr -d ' \n')" > /dev/null 2>&1 || LOG "Unable to set lockout password"
}
tpm1_reset() {
TRACE_FUNC
Expand All @@ -700,17 +700,17 @@ tpm1_reset() {
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 "$tpm_owner_password"
tpm physicalpresence -s > /dev/null 2>&1 || LOG "Unable to assert physical presence"
tpm physicalenable > /dev/null 2>&1 || >LOG "Unable to enable TPM"
tpm physicalsetdeactivated -c > /dev/null 2>&1 || LOG "Unable to deactivate TPM"
tpm forceclear -pwdo "$tpm_owner_password" > /dev/null 2>&1 || LOG "Unable to clear TPM"
tpm physicalenable > /dev/null 2>&1 || LOG "Unable to enable TPM"
tpm takeown -pwdo "$tpm_owner_password" > /dev/null 2>&1 || LOG "Unable to take ownership of TPM"

# And now turn it all back on
tpm physicalpresence -s
tpm physicalenable
tpm physicalsetdeactivated -c
tpm physicalpresence -s > /dev/null 2>&1 || LOG "Unable to assert physical presence"
tpm physicalenable > /dev/null 2>&1 || LOG "Unable to enable TPM"
tpm physicalsetdeactivated -c > /dev/null 2>&1 || LOG "Unable to deactivate TPM"
}

# Perform final cleanup before boot and lock the platform heirarchy.
Expand All @@ -729,7 +729,7 @@ tpm2_kexec_finalize() {
# 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)
randpass=$(dd if=/dev/urandom bs=4 count=1 status=none 2>/dev/null | xxd -p)
tpm2 changeauth -c platform "$randpass" ||
warn "Failed to lock platform hierarchy of TPM2"
}
Expand Down Expand Up @@ -786,7 +786,7 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then
fi

TRACE_FUNC
DEBUG "TPM: Extending PCR[$3] with hash $hash"
LOG "TPM: Extending PCR[$3] with hash $hash"
DO_WITH_DEBUG exec tpm "$@"
;;
seal)
Expand Down Expand Up @@ -828,7 +828,7 @@ calcfuturepcr)
;;
extend)
TRACE_FUNC
DEBUG "TPM: Extending PCR[$2] with $4"
LOG "TPM: Extending PCR[$2] with $4"
tpm2_extend "$@"
;;
counter_read)
Expand Down
2 changes: 1 addition & 1 deletion initrd/bin/unpack_initramfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ unpack_first_segment() {
mkdir -p "$dest_dir"

# peek the beginning of the file to determine what type of content is next
magic="$(dd if="$unpack_archive" bs=6 count=1 status=none | xxd -p)"
magic="$(dd if="$unpack_archive" bs=6 count=1 status=none 2>/dev/null | xxd -p)"

# read this segment of the archive, then write the rest to the next file
(
Expand Down
Loading