diff --git a/initrd/bin/flash.sh b/initrd/bin/flash.sh index d82d43b71..7bf3f4d35 100755 --- a/initrd/bin/flash.sh +++ b/initrd/bin/flash.sh @@ -8,7 +8,7 @@ set -e -o pipefail case "$CONFIG_FLASHROM_OPTIONS" in -* ) - echo "Board $CONFIG_BOARD detected, continuing..." + [ "$1" != "-s" ] && echo "Board $CONFIG_BOARD detected, continuing..." ;; * ) die "ERROR: No board has been configured!\n\nEach board requires specific flashrom options and it's unsafe to flash without them.\n\nAborting." @@ -30,6 +30,10 @@ flash_rom() { else die "$ROM: Read inconsistent" fi + elif [ "$SHA" -eq 1 ]; then + flashrom $CONFIG_FLASHROM_OPTIONS -r "${ROM}" 1&>2 >/dev/null \ + || die "$ROM: Read failed" + sha256sum ${ROM} | cut -f1 -d ' ' else cp "$ROM" /tmp/${CONFIG_BOARD}.rom sha256sum /tmp/${CONFIG_BOARD}.rom @@ -52,20 +56,29 @@ flash_rom() { if [ "$1" == "-c" ]; then CLEAN=1 READ=0 + SHA=0 ROM="$2" elif [ "$1" == "-r" ]; then CLEAN=0 READ=1 + SHA=0 + ROM="$2" + touch $ROM +elif [ "$1" == "-s" ]; then + CLEAN=0 + READ=0 + SHA=1 ROM="$2" touch $ROM else CLEAN=0 READ=0 + SHA=0 ROM="$1" fi if [ ! -e "$ROM" ]; then - die "Usage: $0 [-c|-r] " + die "Usage: $0 [-c|-r|-s] " fi flash_rom $ROM diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 70b0e933f..83b8236ae 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -24,19 +24,24 @@ else HOTPKEY_BRANDING="HOTP USB Security Dongle" fi -tpm nv_readvalue \ - -in 4d47 \ - -sz 312 \ - -of "$HOTP_SEALED" \ -|| die "Unable to retrieve sealed file from TPM NV" - -tpm unsealfile \ - -hk 40000000 \ - -if "$HOTP_SEALED" \ - -of "$HOTP_SECRET" \ -|| die "Unable to unseal HOTP secret" - -shred -n 10 -z -u "$HOTP_SEALED" 2> /dev/null +if [ "$CONFIG_TPM" = "y" ]; then + tpm nv_readvalue \ + -in 4d47 \ + -sz 312 \ + -of "$HOTP_SEALED" \ + || die "Unable to retrieve sealed file from TPM NV" + + tpm unsealfile \ + -hk 40000000 \ + -if "$HOTP_SEALED" \ + -of "$HOTP_SECRET" \ + || die "Unable to unseal HOTP secret" + + shred -n 10 -z -u "$HOTP_SEALED" 2> /dev/null +else + # without a TPM, use the first 20 characters of the ROM SHA256sum + secret_from_rom_hash > $HOTP_SECRET +fi # Store counter in file instead of TPM for now, as it conflicts with Heads # config TPM counter as TPM 1.2 can only increment one counter between reboots diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index f33449e58..7c98480ef 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -17,72 +17,79 @@ fi TOTP_SECRET="/tmp/secret/totp.key" TOTP_SEALED="/tmp/secret/totp.sealed" -dd \ - if=/dev/urandom \ - of="$TOTP_SECRET" \ - count=1 \ - bs=20 \ - 2>/dev/null \ -|| die "Unable to generate 20 random bytes" - -secret="`base32 < $TOTP_SECRET`" - -# Use the current values of the PCRs, which will be read -# from the TPM as part of the sealing ("X"). -# PCR4 == 0 means that we are still in the boot process and -# not a recovery shell. -# should this read the storage root key? -if ! tpm sealfile2 \ - -if "$TOTP_SECRET" \ - -of "$TOTP_SEALED" \ - -hk 40000000 \ - -ix 0 X \ - -ix 1 X \ - -ix 2 X \ - -ix 3 X \ - -ix 4 0000000000000000000000000000000000000000 \ - -ix 7 X \ -; then +if [ "$CONFIG_TPM" = "y" ]; then + dd \ + if=/dev/urandom \ + of="$TOTP_SECRET" \ + count=1 \ + bs=20 \ + 2>/dev/null \ + || die "Unable to generate 20 random bytes" + + secret="`base32 < $TOTP_SECRET`" + + # Use the current values of the PCRs, which will be read + # from the TPM as part of the sealing ("X"). + # PCR4 == 0 means that we are still in the boot process and + # not a recovery shell. + # should this read the storage root key? + if ! tpm sealfile2 \ + -if "$TOTP_SECRET" \ + -of "$TOTP_SEALED" \ + -hk 40000000 \ + -ix 0 X \ + -ix 1 X \ + -ix 2 X \ + -ix 3 X \ + -ix 4 0000000000000000000000000000000000000000 \ + -ix 7 X \ + ; then + shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null + die "Unable to seal secret" + fi + shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null - die "Unable to seal secret" -fi -shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null + # to create an nvram space we need the TPM owner password + # and the TPM physical presence must be asserted. + # + # The permissions are 0 since there is nothing special + # about the sealed file + tpm physicalpresence -s \ + || warn "Warning: Unable to assert physical presence" -# to create an nvram space we need the TPM owner password -# and the TPM physical presence must be asserted. -# -# The permissions are 0 since there is nothing special -# about the sealed file -tpm physicalpresence -s \ -|| warn "Warning: Unable to assert physical presence" - -# Try to write it without the password first, and then create -# the NVRAM space using the owner password if it fails for some reason. -if ! tpm nv_writevalue \ - -in $TPM_NVRAM_SPACE \ - -if "$TOTP_SEALED" \ -; then - warn 'NVRAM space does not exist? Owner password is required' - read -s -p "TPM Owner password: " tpm_password - echo - - tpm nv_definespace \ - -in $TPM_NVRAM_SPACE \ - -sz 312 \ - -pwdo "$tpm_password" \ - -per 0 \ - || die "Unable to define NVRAM space" - - tpm nv_writevalue \ + # Try to write it without the password first, and then create + # the NVRAM space using the owner password if it fails for some reason. + if ! tpm nv_writevalue \ -in $TPM_NVRAM_SPACE \ -if "$TOTP_SEALED" \ - || die "Unable to write sealed secret to NVRAM" + ; then + warn 'NVRAM space does not exist? Owner password is required' + read -s -p "TPM Owner password: " tpm_password + echo + + tpm nv_definespace \ + -in $TPM_NVRAM_SPACE \ + -sz 312 \ + -pwdo "$tpm_password" \ + -per 0 \ + || die "Unable to define NVRAM space" + + tpm nv_writevalue \ + -in $TPM_NVRAM_SPACE \ + -if "$TOTP_SEALED" \ + || die "Unable to write sealed secret to NVRAM" + fi + + shred -n 10 -z -u "$TOTP_SEALED" 2> /dev/null +else + # without a TPM, use the first 20 characters of the ROM SHA256sum + secret_from_rom_hash > $TOTP_SECRET + secret="`base32 < $TOTP_SECRET`" + shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null fi -shred -n 10 -z -u "$TOTP_SEALED" 2> /dev/null - url="otpauth://totp/$HOST?secret=$secret" secret="" diff --git a/initrd/bin/unseal-hotp b/initrd/bin/unseal-hotp index 0fc3fb28e..d3a4621d3 100755 --- a/initrd/bin/unseal-hotp +++ b/initrd/bin/unseal-hotp @@ -36,19 +36,24 @@ fi #counter_value=$(printf "%d" 0x${counter_value}) -tpm nv_readvalue \ - -in 4d47 \ - -sz 312 \ - -of "$HOTP_SEALED" \ -|| die "Unable to retrieve sealed file from TPM NV" - -tpm unsealfile \ - -hk 40000000 \ - -if "$HOTP_SEALED" \ - -of "$HOTP_SECRET" \ -|| die "Unable to unseal HOTP secret" - -shred -n 10 -z -u "$HOTP_SEALED" 2> /dev/null +if [ "$CONFIG_TPM" = "y" ]; then + tpm nv_readvalue \ + -in 4d47 \ + -sz 312 \ + -of "$HOTP_SEALED" \ + || die "Unable to retrieve sealed file from TPM NV" + + tpm unsealfile \ + -hk 40000000 \ + -if "$HOTP_SEALED" \ + -of "$HOTP_SECRET" \ + || die "Unable to unseal HOTP secret" + + shred -n 10 -z -u "$HOTP_SEALED" 2> /dev/null +else + # without a TPM, use the first 20 characters of the ROM SHA256sum + secret_from_rom_hash > $HOTP_SECRET +fi if ! hotp $counter_value < "$HOTP_SECRET"; then shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null diff --git a/initrd/etc/functions b/initrd/etc/functions index a5935f61c..8f55a1087 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -261,6 +261,19 @@ combine_configs() { cat /etc/config* > /tmp/config } +# Generate secret value using first 20 chars of ROM SHA256 hash +secret_from_rom_hash() { + local ROM_IMAGE="/tmp/coreboot-notpm.rom" + + echo -e "\nTPM not detected; measuring ROM directly\n" 1>&2 + # use a previously-copied image if it exists + if [ -f ${ROM_IMAGE} ]; then + sha256sum ${ROM_IMAGE} | cut -f1 -d ' ' | cut -c 1-20 | tr -d '\n' + else + flash.sh -s ${ROM_IMAGE} | cut -c 1-20 | tr -d '\n' + fi +} + update_checksums() { # clear screen