Merge remote-tracking branch 'github-heads/master' into pureboot-27-heads-upstream

This commit is contained in:
Jonathon Hall 2023-07-12 14:14:17 -04:00
commit 47e9e4cf45
No known key found for this signature in database
GPG Key ID: 1E9C3CA91AE25114
8 changed files with 3350 additions and 53 deletions

File diff suppressed because it is too large Load Diff

View File

@ -182,10 +182,22 @@ update_totp()
TRACE "Under /bin/gui-init:update_totp" TRACE "Under /bin/gui-init:update_totp"
# update the TOTP code # update the TOTP code
date=`date "+%Y-%m-%d %H:%M:%S %Z"` date=`date "+%Y-%m-%d %H:%M:%S %Z"`
tries=0
if [ "$CONFIG_TPM" != "y" ]; then if [ "$CONFIG_TPM" != "y" ]; then
TOTP="NO TPM" TOTP="NO TPM"
else else
TOTP=`unseal-totp` 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 if [ $? -ne 0 ]; then
BG_COLOR_MAIN_MENU=$BG_COLOR_ERROR BG_COLOR_MAIN_MENU=$BG_COLOR_ERROR
if [ "$skip_to_menu" = "true" ]; then if [ "$skip_to_menu" = "true" ]; then

View File

@ -93,8 +93,8 @@ tpmr pcrread 0 "$pcrf"
tpmr pcrread -a 1 "$pcrf" tpmr pcrread -a 1 "$pcrf"
tpmr pcrread -a 2 "$pcrf" tpmr pcrread -a 2 "$pcrf"
tpmr pcrread -a 3 "$pcrf" tpmr pcrread -a 3 "$pcrf"
# Note that PCR 4 needs to be set with the "normal-boot" path value, which is 0. # Note that PCR 4 needs to be set with the "normal-boot" path value, read it from event log.
dd if=/dev/zero bs="$(tpmr pcrsize)" count=1 status=none >> "$pcrf" tpmr calcfuturepcr 4 >> "$pcrf"
if [ "$CONFIG_USB_KEYBOARD" = "y" -o -r /lib/modules/libata.ko -o -x /bin/hotp_verification ]; then 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)..." 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 # 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 else
DEBUG "Sealing TPM disk unlock key with PCR5=0 (NO additional kernel modules are loaded per board config)..." 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 #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 fi
# Precompute the value for pcr 6 # Precompute the value for pcr 6
DEBUG "Precomputing TPM future value for PCR6 sealing/unsealing of TPM disk unlock key..." 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 # We take into consideration user files in cbfs
tpmr pcrread -a 7 "$pcrf" tpmr pcrread -a 7 "$pcrf"

View File

@ -30,17 +30,17 @@ dd \
secret="`base32 < $TOTP_SECRET`" secret="`base32 < $TOTP_SECRET`"
pcrf="/tmp/secret/pcrf.bin" 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 0 "$pcrf"
tpmr pcrread -a 1 "$pcrf" tpmr pcrread -a 1 "$pcrf"
tpmr pcrread -a 2 "$pcrf" tpmr pcrread -a 2 "$pcrf"
tpmr pcrread -a 3 "$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: # pcr 4 is expected to either:
# zero on bare coreboot+linuxboot on x86 (boot mode: init) # zero on bare coreboot+linuxboot on x86 (boot mode: init)
# already extended on ppc64 per BOOTKERNEL (skiboot) which boots heads. # already extended on ppc64 per BOOTKERNEL (skiboot) which boots heads.
#We expect the PCR4 to be in the right state at unattended unseal operation # Read from event log to catch both cases, even when called from recovery shell.
tpmr pcrread -a 4 "$pcrf" tpmr calcfuturepcr 4 >> "$pcrf"
# pcr 5 (kernel modules loaded) is not measured at sealing/unsealing of totp # 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)" 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

View File

@ -12,9 +12,5 @@ devmem 0x80060300D0010082 8 254
# PRCs every time. # PRCs every time.
nvram -p ibm,skiboot --update-config fast-reset=0 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 # Proceed with standard init path
exec /bin/gui-init exec /bin/gui-init

View File

@ -86,45 +86,146 @@ tpm1_pcrread() {
DO_WITH_DEBUG tpm pcrread -ix "$index" | hex2bin >>"$file" DO_WITH_DEBUG tpm pcrread -ix "$index" | hex2bin >>"$file"
} }
# usage: tpmr calcfuturepcr [-a] <input_file> <output_file> # is_hash - Check if a value is a valid hash of a given type
# Uses the scratch PCR to calculate a future PCR value (TPM2 23, TPM1 16). The # usage: is_hash <alg> <value>
# data in input file are hashed into a PCR, and the PCR value is placed in is_hash() {
# output_file. # Must only contain 0-9a-fA-F
# -a: Append to output_file. Default is to overwrite if [ "$(echo -n "$2" | tr -d '0-9a-fA-F' | wc -c)" -ne 0 ]; then return 1; fi
tpm2_calcfuturepcr() { # SHA-1 hashes are 40 chars
TRACE "Under /bin/tpmr:tpm2_calcfuturepcr" if [ "$1" = "sha1" ] && [ "${#2}" -eq 40 ]; then return 0; fi
if [ "$1" = "-a" ]; then # SHA-256 hashes are 64 chars
APPEND=y if [ "$1" = "sha256" ] && [ "${#2}" -eq 64 ]; then return 0; fi
shift return 1
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
} }
tpm1_calcfuturepcr() {
TRACE "Under /bin/tpmr:tpm1_calcfuturepcr" # extend_pcr_state - extend a PCR state value with more hashes or raw data (which is hashed)
if [ "$1" = "-a" ]; then # usage:
APPEND=y # 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 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 fi
if [ "$2" -ge 8 ] ; then
input_file="$1" >&2 echo "Illegal PCR number ($2)"
output_file="$2" return
if [ -z "$APPEND" ]; then
true >"$output_file"
fi fi
local log=`cbmem -L`
DO_WITH_DEBUG tpm calcfuturepcr -ix 16 -if "$input_file" | hex2bin >>"$output_file" 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() { tpm2_extend() {
@ -601,7 +702,7 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then
pcrsize) pcrsize)
echo "$PCR_SIZE";; echo "$PCR_SIZE";;
calcfuturepcr) calcfuturepcr)
shift; tpm1_calcfuturepcr "$@";; shift; replay_pcr "sha1" "$@";;
destroy) destroy)
shift; tpm1_destroy "$@";; shift; tpm1_destroy "$@";;
seal) seal)
@ -634,7 +735,7 @@ case "$subcmd" in
pcrsize) pcrsize)
echo "$PCR_SIZE";; echo "$PCR_SIZE";;
calcfuturepcr) calcfuturepcr)
tpm2_calcfuturepcr "$@";; replay_pcr "sha256" "$@";;
extend) extend)
tpm2_extend "$@";; tpm2_extend "$@";;
counter_read) counter_read)

View File

@ -44,7 +44,7 @@ else ifeq "$(CONFIG_COREBOOT_VERSION)" "4.19"
else ifeq "$(CONFIG_COREBOOT_VERSION)" "talos_2" else ifeq "$(CONFIG_COREBOOT_VERSION)" "talos_2"
coreboot_version = git coreboot_version = git
coreboot_patch_version = talos_2 coreboot_patch_version = talos_2
coreboot_commit_hash = 068ad520e4ae898d356add72ea7d2a13913b76ab coreboot_commit_hash = c8aed443c631042ad2b0326c35cd0b774752b924
coreboot_repo := https://github.com/Dasharo/coreboot coreboot_repo := https://github.com/Dasharo/coreboot
else ifeq "$(CONFIG_COREBOOT_VERSION)" "purism" else ifeq "$(CONFIG_COREBOOT_VERSION)" "purism"

View File

@ -14,7 +14,7 @@
BINUTILS_ARCHIVE="https://ftpmirror.gnu.org/binutils/binutils-${BINUTILS_VERSION}.tar.xz" BINUTILS_ARCHIVE="https://ftpmirror.gnu.org/binutils/binutils-${BINUTILS_VERSION}.tar.xz"
GDB_ARCHIVE="https://ftpmirror.gnu.org/gdb/gdb-${GDB_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-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" 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" EXPAT_ARCHIVE="https://downloads.sourceforge.net/sourceforge/expat/expat-${EXPAT_VERSION}.tar.bz2"
# CLANG toolchain archive locations # CLANG toolchain archive locations