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

Use the Librem Key as a TPM work-alike in the absence of a TPM #493

Closed
wants to merge 5 commits into from
Closed
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
15 changes: 14 additions & 1 deletion initrd/bin/flash.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ flash_rom() {
else
die "$ROM: Read inconsistent"
fi
elif [ "$SHA" -eq 1 ]; then
flashrom $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
Expand All @@ -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] <path_to_image.rom>"
die "Usage: $0 [-c|-r|-s] <path_to_image.rom>"
fi

flash_rom $ROM
Expand Down
33 changes: 20 additions & 13 deletions initrd/bin/seal-libremkey
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,26 @@ mount_boot()
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"

rm -f "$HOTP_SEALED"
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"

rm -f "$HOTP_SEALED"
else
# without a TPM, use the first 20 characters of the ROM SHA256sum
echo "TPM not configured, measuring ROM directly"
flash.sh -s /tmp/coreboot.rom | cut -c 1-20 | tr -d '\n' > $HOTP_SECRET
fi

secret="`cat $HOTP_SECRET`"
rm -f "$HOTP_SECRET"

Expand Down
94 changes: 51 additions & 43 deletions initrd/bin/seal-totp
Original file line number Diff line number Diff line change
Expand Up @@ -17,69 +17,77 @@ 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"
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`"
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
rm -f "$TOTP_SECRET"
die "Unable to seal secret"
fi
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
rm -f "$TOTP_SECRET"
die "Unable to seal secret"
fi


# 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"
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
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_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
tpm nv_writevalue \
-in $TPM_NVRAM_SPACE \
-if "$TOTP_SEALED" \
|| die "Unable to write sealed secret to NVRAM"
fi

rm -f "$TOTP_SEALED"
rm -f "$TOTP_SEALED"
else
# without a TPM, use the first 20 characters of the ROM SHA256sum
echo "TPM not configured, measuring ROM directly"
flash.sh -s /tmp/coreboot.rom | cut -c 1-20 | tr -d '\n' > $TOTP_SECRET
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why truncate the hash prematurely? Could you not get the full 120 bits of the HOTP with something like

Suggested change
flash.sh -s /tmp/coreboot.rom | cut -c 1-20 | tr -d '\n' > $TOTP_SECRET
secret="`flash.sh -s /tmp/coreboot.rom | xxd -r -p | base32 | cut -c 1-24 | tr -d '\n'`"

(i.e., decode the base16 string then re-encode as base32)?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kylerankin thoughts?

secret="`base32 < $TOTP_SECRET`"
rm -f $TOTP_SECRET
fi

url="otpauth://totp/$HOST?secret=$secret"
secret=""
Expand Down
38 changes: 25 additions & 13 deletions initrd/bin/unseal-hotp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
HOTP_SEALED="/tmp/secret/hotp.sealed"
HOTP_SECRET="/tmp/secret/hotp.key"
HOTP_COUNTER="/boot/kexec_hotp_counter"
ROM_IMAGE="/tmp/coreboot-notpm.rom"

mount_boot()
{
Expand All @@ -16,19 +17,30 @@ mount_boot()
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"

rm -f "$HOTP_SEALED"
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"

rm -f "$HOTP_SEALED"
else
# without a TPM, use the first 20 characters of the ROM SHA256sum
echo "TPM not configured, measuring ROM directly" 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' > $HOTP_SECRET
else
flash.sh -s ${ROM_IMAGE} | cut -c 1-20 | tr -d '\n' > $HOTP_SECRET
fi
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
Expand Down