mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-18 20:47:55 +00:00
Merge remote-tracking branch 'github-heads/master' into pureboot-27-heads-upstream
This commit is contained in:
commit
47e9e4cf45
File diff suppressed because it is too large
Load Diff
@ -182,10 +182,22 @@ update_totp()
|
||||
TRACE "Under /bin/gui-init:update_totp"
|
||||
# update the TOTP code
|
||||
date=`date "+%Y-%m-%d %H:%M:%S %Z"`
|
||||
tries=0
|
||||
if [ "$CONFIG_TPM" != "y" ]; then
|
||||
TOTP="NO TPM"
|
||||
else
|
||||
TOTP=`unseal-totp`
|
||||
# On platforms using CONFIG_BOOT_EXTRA_TTYS multiple processes may try to
|
||||
# access TPM at the same time, failing with EBUSY. The order of execution
|
||||
# is unpredictable, so the error may appear on main console, secondary one,
|
||||
# or neither of them if the calls are sufficiently staggered. Try up to
|
||||
# three times (including previous one) with small delays in case of error,
|
||||
# instead of immediately scaring users with "you've been pwned" message.
|
||||
while [ $? -ne 0 ] && [ $tries -lt 2 ]; do
|
||||
sleep 0.5
|
||||
((tries++))
|
||||
TOTP=`unseal-totp`
|
||||
done
|
||||
if [ $? -ne 0 ]; then
|
||||
BG_COLOR_MAIN_MENU=$BG_COLOR_ERROR
|
||||
if [ "$skip_to_menu" = "true" ]; then
|
||||
|
@ -93,8 +93,8 @@ tpmr pcrread 0 "$pcrf"
|
||||
tpmr pcrread -a 1 "$pcrf"
|
||||
tpmr pcrread -a 2 "$pcrf"
|
||||
tpmr pcrread -a 3 "$pcrf"
|
||||
# Note that PCR 4 needs to be set with the "normal-boot" path value, which is 0.
|
||||
dd if=/dev/zero bs="$(tpmr pcrsize)" count=1 status=none >> "$pcrf"
|
||||
# Note that PCR 4 needs to be set with the "normal-boot" path value, read it from event log.
|
||||
tpmr calcfuturepcr 4 >> "$pcrf"
|
||||
if [ "$CONFIG_USB_KEYBOARD" = "y" -o -r /lib/modules/libata.ko -o -x /bin/hotp_verification ]; then
|
||||
DEBUG "Sealing TPM disk unlock key with PCR5 involvement (additional kernel modules are loaded per board config)..."
|
||||
# Here, we take pcr 5 into consideration if modules are expected to be measured+loaded
|
||||
@ -102,11 +102,11 @@ if [ "$CONFIG_USB_KEYBOARD" = "y" -o -r /lib/modules/libata.ko -o -x /bin/hotp_v
|
||||
else
|
||||
DEBUG "Sealing TPM disk unlock key with PCR5=0 (NO additional kernel modules are loaded per board config)..."
|
||||
#no kernel modules are expected to be measured+loaded
|
||||
dd if=/dev/zero bs="$(tpmr pcrsize)" count=1 status=none >> "$pcrf"
|
||||
tpmr calcfuturepcr 5 >> "$pcrf"
|
||||
fi
|
||||
# Precompute the value for pcr 6
|
||||
DEBUG "Precomputing TPM future value for PCR6 sealing/unsealing of TPM disk unlock key..."
|
||||
tpmr calcfuturepcr -a "/tmp/luksDump.txt" "$pcrf"
|
||||
tpmr calcfuturepcr 6 "/tmp/luksDump.txt" >> "$pcrf"
|
||||
# We take into consideration user files in cbfs
|
||||
tpmr pcrread -a 7 "$pcrf"
|
||||
|
||||
|
@ -30,17 +30,17 @@ dd \
|
||||
|
||||
secret="`base32 < $TOTP_SECRET`"
|
||||
pcrf="/tmp/secret/pcrf.bin"
|
||||
DEBUG "Sealing TOTP with actual state of PCR0-4)"
|
||||
DEBUG "Sealing TOTP with actual state of PCR0-3"
|
||||
tpmr pcrread 0 "$pcrf"
|
||||
tpmr pcrread -a 1 "$pcrf"
|
||||
tpmr pcrread -a 2 "$pcrf"
|
||||
tpmr pcrread -a 3 "$pcrf"
|
||||
DEBUG "Sealing TOTP with actual state of PCR4 (Going to recovery shell extends PCR4)"
|
||||
DEBUG "Sealing TOTP with boot state of PCR4 (Going to recovery shell extends PCR4)"
|
||||
# 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.
|
||||
#We expect the PCR4 to be in the right state at unattended unseal operation
|
||||
tpmr pcrread -a 4 "$pcrf"
|
||||
# Read from event log to catch both cases, even when called from recovery shell.
|
||||
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
|
||||
|
@ -12,9 +12,5 @@ devmem 0x80060300D0010082 8 254
|
||||
# PRCs every time.
|
||||
nvram -p ibm,skiboot --update-config fast-reset=0
|
||||
|
||||
# Alias for cbmem to remove need for '-f' option in every call
|
||||
echo "alias cbmem='cbmem -f /sys/firmware/cbmem'" >> $HOME/.profile
|
||||
export ENV=$HOME/.profile
|
||||
|
||||
# Proceed with standard init path
|
||||
exec /bin/gui-init
|
||||
|
175
initrd/bin/tpmr
175
initrd/bin/tpmr
@ -86,45 +86,146 @@ tpm1_pcrread() {
|
||||
DO_WITH_DEBUG tpm pcrread -ix "$index" | hex2bin >>"$file"
|
||||
}
|
||||
|
||||
# usage: tpmr calcfuturepcr [-a] <input_file> <output_file>
|
||||
# Uses the scratch PCR to calculate a future PCR value (TPM2 23, TPM1 16). The
|
||||
# data in input file are hashed into a PCR, and the PCR value is placed in
|
||||
# output_file.
|
||||
# -a: Append to output_file. Default is to overwrite
|
||||
tpm2_calcfuturepcr() {
|
||||
TRACE "Under /bin/tpmr:tpm2_calcfuturepcr"
|
||||
if [ "$1" = "-a" ]; then
|
||||
APPEND=y
|
||||
shift
|
||||
fi
|
||||
|
||||
input_file="$1"
|
||||
output_file="$2"
|
||||
|
||||
if [ -z "$APPEND" ]; then
|
||||
true >"$output_file"
|
||||
fi
|
||||
|
||||
tpm2 pcrreset -Q 23
|
||||
DO_WITH_DEBUG tpmr extend -ix 23 -if "$input_file"
|
||||
DO_WITH_DEBUG tpm2 pcrread -Q -o >(cat >>"$output_file") sha256:23
|
||||
tpm2 pcrreset -Q 23
|
||||
# is_hash - Check if a value is a valid hash of a given type
|
||||
# usage: is_hash <alg> <value>
|
||||
is_hash() {
|
||||
# Must only contain 0-9a-fA-F
|
||||
if [ "$(echo -n "$2" | tr -d '0-9a-fA-F' | wc -c)" -ne 0 ]; then return 1; fi
|
||||
# SHA-1 hashes are 40 chars
|
||||
if [ "$1" = "sha1" ] && [ "${#2}" -eq 40 ]; then return 0; fi
|
||||
# SHA-256 hashes are 64 chars
|
||||
if [ "$1" = "sha256" ] && [ "${#2}" -eq 64 ]; then return 0; fi
|
||||
return 1
|
||||
}
|
||||
tpm1_calcfuturepcr() {
|
||||
TRACE "Under /bin/tpmr:tpm1_calcfuturepcr"
|
||||
if [ "$1" = "-a" ]; then
|
||||
APPEND=y
|
||||
|
||||
# extend_pcr_state - extend a PCR state value with more hashes or raw data (which is hashed)
|
||||
# usage:
|
||||
# extend_pcr_state <alg> <initial_state> <files/hashes...>
|
||||
# alg - either 'sha1' or 'sha256' to specify algorithm
|
||||
# initial_state - a hash value setting the initial state
|
||||
# files/hashes... - any number of files or hashes, state is extended once for each item
|
||||
extend_pcr_state() {
|
||||
local alg="$1"
|
||||
local state="$2"
|
||||
local next extend
|
||||
shift 2
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
next="$1"
|
||||
shift
|
||||
if is_hash "$alg" "$next"; then
|
||||
extend="$next"
|
||||
else
|
||||
extend="$("${alg}sum" <"$next" | cut -d' ' -f1)"
|
||||
fi
|
||||
state="$(echo "$state$extend" | hex2bin | "${alg}sum" | cut -d' ' -f1)"
|
||||
done
|
||||
echo "$state"
|
||||
}
|
||||
|
||||
# There are 3 (and a half) possible formats of event log, each of them requires
|
||||
# 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'
|
||||
TPM2 log:
|
||||
Specification: 2.00
|
||||
Platform class: PC Client
|
||||
TPM2 log entry 1:
|
||||
PCR: 2
|
||||
Event type: Action
|
||||
Digests:
|
||||
SHA256: de73053377e1ae5ba5d2b637a4f5bfaeb410137722f11ef135e7a1be524e3092
|
||||
SHA1: 27c4f1fa214480c8626397a15981ef3a9323717f
|
||||
Event data: FMAP: FMAP
|
||||
EOF
|
||||
# 2) TPM1.2 log (aka TCPA), digest is always SHA1:
|
||||
: << 'EOF'
|
||||
TCPA log:
|
||||
Specification: 1.21
|
||||
Platform class: PC Client
|
||||
TCPA log entry 1:
|
||||
PCR: 2
|
||||
Event type: Action
|
||||
Digest: 27c4f1fa214480c8626397a15981ef3a9323717f
|
||||
Event data: FMAP: FMAP
|
||||
EOF
|
||||
# 3) coreboot-specific format:
|
||||
# 3.5) older versions printed 'coreboot TCPA log', even though it isn't TCPA
|
||||
: << 'EOF'
|
||||
coreboot TPM log:
|
||||
|
||||
PCR-2 27c4f1fa214480c8626397a15981ef3a9323717f SHA1 [FMAP: FMAP]
|
||||
EOF
|
||||
|
||||
# awk script to handle all of the above. Note this gets squashed to one line so
|
||||
# semicolons are required.
|
||||
AWK_PROG='
|
||||
BEGIN {
|
||||
getline;
|
||||
hash_regex="([a-fA-F0-9]{40,})";
|
||||
if ($0 == "TPM2 log:") {
|
||||
RS="\n[^[:space:]]";
|
||||
pcr="PCR: " pcr;
|
||||
alg=toupper(alg) ": " hash_regex;
|
||||
} else if ($0 == "TCPA log:") {
|
||||
RS="\n[^[:space:]]";
|
||||
pcr="PCR: " pcr;
|
||||
alg="Digest: " hash_regex;
|
||||
} else if ($0 ~ /^coreboot (TCPA|TPM) log:$/) {
|
||||
pcr="PCR-" pcr;
|
||||
alg=hash_regex " " toupper(alg) " ";
|
||||
} else {
|
||||
print "Unknown TPM event log format:", $0 > "/dev/stderr";
|
||||
exit -1;
|
||||
}
|
||||
}
|
||||
$0 ~ pcr {
|
||||
match($0, alg);
|
||||
print gensub(alg, "\\1", "g", substr($0, RSTART, RLENGTH));
|
||||
}
|
||||
'
|
||||
|
||||
# usage: replay_pcr <alg> <pcr_num> [ <input_file>|<input_hash> ... ]
|
||||
# Replays PCR value from CBMEM event log. Note that this contains only the
|
||||
# measurements performed by firmware, without those performed by Heads (USB
|
||||
# modules, LUKS header etc). First argument is PCR number, followed by optional
|
||||
# hashes and/or files extended to given PCR after firmware. Resulting PCR value
|
||||
# is returned in binary form.
|
||||
replay_pcr() {
|
||||
TRACE "Under /bin/tpmr:replay_pcr"
|
||||
if [ -z "$2" ] ; then
|
||||
>&2 echo "No PCR number passed"
|
||||
return
|
||||
fi
|
||||
|
||||
input_file="$1"
|
||||
output_file="$2"
|
||||
|
||||
if [ -z "$APPEND" ]; then
|
||||
true >"$output_file"
|
||||
if [ "$2" -ge 8 ] ; then
|
||||
>&2 echo "Illegal PCR number ($2)"
|
||||
return
|
||||
fi
|
||||
|
||||
DO_WITH_DEBUG tpm calcfuturepcr -ix 16 -if "$input_file" | hex2bin >>"$output_file"
|
||||
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
|
||||
# SHA-256 hashes are 64 chars
|
||||
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 $replayed_pcr | hex2bin
|
||||
DEBUG "Replayed cbmem -L clean boot state of PCR=$pcr ALG=$alg : $replayed_pcr"
|
||||
# To manually introspect current PCR values:
|
||||
# PCR-2:
|
||||
# tpmr calcfuturepcr 2 | xxd -p
|
||||
# PCR-4, in case of recovery shell (bash used for process substitution):
|
||||
# bash -c "tpmr calcfuturepcr 4 <(echo -n recovery)" | xxd -p
|
||||
# PCR-4, in case of normal boot passing through kexec-select-boot:
|
||||
# bash -c "tpmr calcfuturepcr 4 <(echo -n generic)" | xxd -p
|
||||
# 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)
|
||||
}
|
||||
|
||||
tpm2_extend() {
|
||||
@ -601,7 +702,7 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then
|
||||
pcrsize)
|
||||
echo "$PCR_SIZE";;
|
||||
calcfuturepcr)
|
||||
shift; tpm1_calcfuturepcr "$@";;
|
||||
shift; replay_pcr "sha1" "$@";;
|
||||
destroy)
|
||||
shift; tpm1_destroy "$@";;
|
||||
seal)
|
||||
@ -634,7 +735,7 @@ case "$subcmd" in
|
||||
pcrsize)
|
||||
echo "$PCR_SIZE";;
|
||||
calcfuturepcr)
|
||||
tpm2_calcfuturepcr "$@";;
|
||||
replay_pcr "sha256" "$@";;
|
||||
extend)
|
||||
tpm2_extend "$@";;
|
||||
counter_read)
|
||||
|
@ -44,7 +44,7 @@ else ifeq "$(CONFIG_COREBOOT_VERSION)" "4.19"
|
||||
else ifeq "$(CONFIG_COREBOOT_VERSION)" "talos_2"
|
||||
coreboot_version = git
|
||||
coreboot_patch_version = talos_2
|
||||
coreboot_commit_hash = 068ad520e4ae898d356add72ea7d2a13913b76ab
|
||||
coreboot_commit_hash = c8aed443c631042ad2b0326c35cd0b774752b924
|
||||
coreboot_repo := https://github.com/Dasharo/coreboot
|
||||
|
||||
else ifeq "$(CONFIG_COREBOOT_VERSION)" "purism"
|
||||
|
@ -14,7 +14,7 @@
|
||||
BINUTILS_ARCHIVE="https://ftpmirror.gnu.org/binutils/binutils-${BINUTILS_VERSION}.tar.xz"
|
||||
GDB_ARCHIVE="https://ftpmirror.gnu.org/gdb/gdb-${GDB_VERSION}.tar.xz"
|
||||
-IASL_ARCHIVE="https://acpica.org/sites/acpica/files/acpica-unix2-${IASL_VERSION}.tar.gz"
|
||||
+IASL_ARCHIVE="https://acpica.org/sites/acpica/files/acpica-unix-${IASL_VERSION}.tar.gz"
|
||||
+IASL_ARCHIVE="https://distfiles.macports.org/acpica/acpica-unix-${IASL_VERSION}.tar.gz"
|
||||
PYTHON_ARCHIVE="https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz"
|
||||
EXPAT_ARCHIVE="https://downloads.sourceforge.net/sourceforge/expat/expat-${EXPAT_VERSION}.tar.bz2"
|
||||
# CLANG toolchain archive locations
|
||||
|
Loading…
Reference in New Issue
Block a user