Skip to content

Commit 47e9e4c

Browse files
Merge remote-tracking branch 'github-heads/master' into pureboot-27-heads-upstream
2 parents 440dc5b + 3c492f9 commit 47e9e4c

8 files changed

Lines changed: 3349 additions & 52 deletions

File tree

config/linux-talos-2.config

Lines changed: 3190 additions & 2 deletions
Large diffs are not rendered by default.

initrd/bin/gui-init

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,22 @@ update_totp()
182182
TRACE "Under /bin/gui-init:update_totp"
183183
# update the TOTP code
184184
date=`date "+%Y-%m-%d %H:%M:%S %Z"`
185+
tries=0
185186
if [ "$CONFIG_TPM" != "y" ]; then
186187
TOTP="NO TPM"
187188
else
188189
TOTP=`unseal-totp`
190+
# On platforms using CONFIG_BOOT_EXTRA_TTYS multiple processes may try to
191+
# access TPM at the same time, failing with EBUSY. The order of execution
192+
# is unpredictable, so the error may appear on main console, secondary one,
193+
# or neither of them if the calls are sufficiently staggered. Try up to
194+
# three times (including previous one) with small delays in case of error,
195+
# instead of immediately scaring users with "you've been pwned" message.
196+
while [ $? -ne 0 ] && [ $tries -lt 2 ]; do
197+
sleep 0.5
198+
((tries++))
199+
TOTP=`unseal-totp`
200+
done
189201
if [ $? -ne 0 ]; then
190202
BG_COLOR_MAIN_MENU=$BG_COLOR_ERROR
191203
if [ "$skip_to_menu" = "true" ]; then

initrd/bin/kexec-seal-key

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,20 +93,20 @@ tpmr pcrread 0 "$pcrf"
9393
tpmr pcrread -a 1 "$pcrf"
9494
tpmr pcrread -a 2 "$pcrf"
9595
tpmr pcrread -a 3 "$pcrf"
96-
# Note that PCR 4 needs to be set with the "normal-boot" path value, which is 0.
97-
dd if=/dev/zero bs="$(tpmr pcrsize)" count=1 status=none >> "$pcrf"
96+
# Note that PCR 4 needs to be set with the "normal-boot" path value, read it from event log.
97+
tpmr calcfuturepcr 4 >> "$pcrf"
9898
if [ "$CONFIG_USB_KEYBOARD" = "y" -o -r /lib/modules/libata.ko -o -x /bin/hotp_verification ]; then
9999
DEBUG "Sealing TPM disk unlock key with PCR5 involvement (additional kernel modules are loaded per board config)..."
100100
# Here, we take pcr 5 into consideration if modules are expected to be measured+loaded
101101
tpmr pcrread -a 5 "$pcrf"
102102
else
103103
DEBUG "Sealing TPM disk unlock key with PCR5=0 (NO additional kernel modules are loaded per board config)..."
104104
#no kernel modules are expected to be measured+loaded
105-
dd if=/dev/zero bs="$(tpmr pcrsize)" count=1 status=none >> "$pcrf"
105+
tpmr calcfuturepcr 5 >> "$pcrf"
106106
fi
107107
# Precompute the value for pcr 6
108108
DEBUG "Precomputing TPM future value for PCR6 sealing/unsealing of TPM disk unlock key..."
109-
tpmr calcfuturepcr -a "/tmp/luksDump.txt" "$pcrf"
109+
tpmr calcfuturepcr 6 "/tmp/luksDump.txt" >> "$pcrf"
110110
# We take into consideration user files in cbfs
111111
tpmr pcrread -a 7 "$pcrf"
112112

initrd/bin/seal-totp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ dd \
3030

3131
secret="`base32 < $TOTP_SECRET`"
3232
pcrf="/tmp/secret/pcrf.bin"
33-
DEBUG "Sealing TOTP with actual state of PCR0-4)"
33+
DEBUG "Sealing TOTP with actual state of PCR0-3"
3434
tpmr pcrread 0 "$pcrf"
3535
tpmr pcrread -a 1 "$pcrf"
3636
tpmr pcrread -a 2 "$pcrf"
3737
tpmr pcrread -a 3 "$pcrf"
38-
DEBUG "Sealing TOTP with actual state of PCR4 (Going to recovery shell extends PCR4)"
38+
DEBUG "Sealing TOTP with boot state of PCR4 (Going to recovery shell extends PCR4)"
3939
# pcr 4 is expected to either:
4040
# zero on bare coreboot+linuxboot on x86 (boot mode: init)
4141
# already extended on ppc64 per BOOTKERNEL (skiboot) which boots heads.
42-
#We expect the PCR4 to be in the right state at unattended unseal operation
43-
tpmr pcrread -a 4 "$pcrf"
42+
# Read from event log to catch both cases, even when called from recovery shell.
43+
tpmr calcfuturepcr 4 >> "$pcrf"
4444
# pcr 5 (kernel modules loaded) is not measured at sealing/unsealing of totp
4545
DEBUG "Sealing TOTP neglecting PCR5 involvement (Dynamically loaded kernel modules are not firmware integrity attestation related)"
4646
# pcr 6 (drive luks header) is not measured at sealing/unsealing of totp

initrd/bin/talos-init

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,5 @@ devmem 0x80060300D0010082 8 254
1212
# PRCs every time.
1313
nvram -p ibm,skiboot --update-config fast-reset=0
1414

15-
# Alias for cbmem to remove need for '-f' option in every call
16-
echo "alias cbmem='cbmem -f /sys/firmware/cbmem'" >> $HOME/.profile
17-
export ENV=$HOME/.profile
18-
1915
# Proceed with standard init path
2016
exec /bin/gui-init

initrd/bin/tpmr

Lines changed: 137 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -86,45 +86,146 @@ tpm1_pcrread() {
8686
DO_WITH_DEBUG tpm pcrread -ix "$index" | hex2bin >>"$file"
8787
}
8888

89-
# usage: tpmr calcfuturepcr [-a] <input_file> <output_file>
90-
# Uses the scratch PCR to calculate a future PCR value (TPM2 23, TPM1 16). The
91-
# data in input file are hashed into a PCR, and the PCR value is placed in
92-
# output_file.
93-
# -a: Append to output_file. Default is to overwrite
94-
tpm2_calcfuturepcr() {
95-
TRACE "Under /bin/tpmr:tpm2_calcfuturepcr"
96-
if [ "$1" = "-a" ]; then
97-
APPEND=y
98-
shift
99-
fi
100-
101-
input_file="$1"
102-
output_file="$2"
89+
# is_hash - Check if a value is a valid hash of a given type
90+
# usage: is_hash <alg> <value>
91+
is_hash() {
92+
# Must only contain 0-9a-fA-F
93+
if [ "$(echo -n "$2" | tr -d '0-9a-fA-F' | wc -c)" -ne 0 ]; then return 1; fi
94+
# SHA-1 hashes are 40 chars
95+
if [ "$1" = "sha1" ] && [ "${#2}" -eq 40 ]; then return 0; fi
96+
# SHA-256 hashes are 64 chars
97+
if [ "$1" = "sha256" ] && [ "${#2}" -eq 64 ]; then return 0; fi
98+
return 1
99+
}
103100

104-
if [ -z "$APPEND" ]; then
105-
true >"$output_file"
106-
fi
101+
# extend_pcr_state - extend a PCR state value with more hashes or raw data (which is hashed)
102+
# usage:
103+
# extend_pcr_state <alg> <initial_state> <files/hashes...>
104+
# alg - either 'sha1' or 'sha256' to specify algorithm
105+
# initial_state - a hash value setting the initial state
106+
# files/hashes... - any number of files or hashes, state is extended once for each item
107+
extend_pcr_state() {
108+
local alg="$1"
109+
local state="$2"
110+
local next extend
111+
shift 2
112+
113+
while [ "$#" -gt 0 ]; do
114+
next="$1"
115+
shift
116+
if is_hash "$alg" "$next"; then
117+
extend="$next"
118+
else
119+
extend="$("${alg}sum" <"$next" | cut -d' ' -f1)"
120+
fi
121+
state="$(echo "$state$extend" | hex2bin | "${alg}sum" | cut -d' ' -f1)"
122+
done
123+
echo "$state"
124+
}
107125

108-
tpm2 pcrreset -Q 23
109-
DO_WITH_DEBUG tpmr extend -ix 23 -if "$input_file"
110-
DO_WITH_DEBUG tpm2 pcrread -Q -o >(cat >>"$output_file") sha256:23
111-
tpm2 pcrreset -Q 23
126+
# There are 3 (and a half) possible formats of event log, each of them requires
127+
# different arguments for grep. Those formats are shown below as heredocs to
128+
# keep all the data, including whitespaces:
129+
# 1) TPM2 log, which can hold multiple hash algorithms at once:
130+
: << 'EOF'
131+
TPM2 log:
132+
Specification: 2.00
133+
Platform class: PC Client
134+
TPM2 log entry 1:
135+
PCR: 2
136+
Event type: Action
137+
Digests:
138+
SHA256: de73053377e1ae5ba5d2b637a4f5bfaeb410137722f11ef135e7a1be524e3092
139+
SHA1: 27c4f1fa214480c8626397a15981ef3a9323717f
140+
Event data: FMAP: FMAP
141+
EOF
142+
# 2) TPM1.2 log (aka TCPA), digest is always SHA1:
143+
: << 'EOF'
144+
TCPA log:
145+
Specification: 1.21
146+
Platform class: PC Client
147+
TCPA log entry 1:
148+
PCR: 2
149+
Event type: Action
150+
Digest: 27c4f1fa214480c8626397a15981ef3a9323717f
151+
Event data: FMAP: FMAP
152+
EOF
153+
# 3) coreboot-specific format:
154+
# 3.5) older versions printed 'coreboot TCPA log', even though it isn't TCPA
155+
: << 'EOF'
156+
coreboot TPM log:
157+
158+
PCR-2 27c4f1fa214480c8626397a15981ef3a9323717f SHA1 [FMAP: FMAP]
159+
EOF
160+
161+
# awk script to handle all of the above. Note this gets squashed to one line so
162+
# semicolons are required.
163+
AWK_PROG='
164+
BEGIN {
165+
getline;
166+
hash_regex="([a-fA-F0-9]{40,})";
167+
if ($0 == "TPM2 log:") {
168+
RS="\n[^[:space:]]";
169+
pcr="PCR: " pcr;
170+
alg=toupper(alg) ": " hash_regex;
171+
} else if ($0 == "TCPA log:") {
172+
RS="\n[^[:space:]]";
173+
pcr="PCR: " pcr;
174+
alg="Digest: " hash_regex;
175+
} else if ($0 ~ /^coreboot (TCPA|TPM) log:$/) {
176+
pcr="PCR-" pcr;
177+
alg=hash_regex " " toupper(alg) " ";
178+
} else {
179+
print "Unknown TPM event log format:", $0 > "/dev/stderr";
180+
exit -1;
181+
}
112182
}
113-
tpm1_calcfuturepcr() {
114-
TRACE "Under /bin/tpmr:tpm1_calcfuturepcr"
115-
if [ "$1" = "-a" ]; then
116-
APPEND=y
117-
shift
183+
$0 ~ pcr {
184+
match($0, alg);
185+
print gensub(alg, "\\1", "g", substr($0, RSTART, RLENGTH));
186+
}
187+
'
188+
189+
# usage: replay_pcr <alg> <pcr_num> [ <input_file>|<input_hash> ... ]
190+
# Replays PCR value from CBMEM event log. Note that this contains only the
191+
# measurements performed by firmware, without those performed by Heads (USB
192+
# modules, LUKS header etc). First argument is PCR number, followed by optional
193+
# hashes and/or files extended to given PCR after firmware. Resulting PCR value
194+
# is returned in binary form.
195+
replay_pcr() {
196+
TRACE "Under /bin/tpmr:replay_pcr"
197+
if [ -z "$2" ] ; then
198+
>&2 echo "No PCR number passed"
199+
return
118200
fi
119-
120-
input_file="$1"
121-
output_file="$2"
122-
123-
if [ -z "$APPEND" ]; then
124-
true >"$output_file"
201+
if [ "$2" -ge 8 ] ; then
202+
>&2 echo "Illegal PCR number ($2)"
203+
return
125204
fi
126-
127-
DO_WITH_DEBUG tpm calcfuturepcr -ix 16 -if "$input_file" | hex2bin >>"$output_file"
205+
local log=`cbmem -L`
206+
local alg="$1"
207+
local pcr="$2"
208+
local alg_digits=0
209+
# SHA-1 hashes are 40 chars
210+
if [ "$alg" = "sha1" ] ; then alg_digits=40; fi
211+
# SHA-256 hashes are 64 chars
212+
if [ "$alg" = "sha256" ] ; then alg_digits=64; fi
213+
shift 2
214+
replayed_pcr=$(extend_pcr_state $alg $(printf "%.${alg_digits}d" 0) \
215+
$(echo "$log" | awk -v alg=$alg -v pcr=$pcr -f <(echo $AWK_PROG)) $@)
216+
echo $replayed_pcr | hex2bin
217+
DEBUG "Replayed cbmem -L clean boot state of PCR=$pcr ALG=$alg : $replayed_pcr"
218+
# To manually introspect current PCR values:
219+
# PCR-2:
220+
# tpmr calcfuturepcr 2 | xxd -p
221+
# PCR-4, in case of recovery shell (bash used for process substitution):
222+
# bash -c "tpmr calcfuturepcr 4 <(echo -n recovery)" | xxd -p
223+
# PCR-4, in case of normal boot passing through kexec-select-boot:
224+
# bash -c "tpmr calcfuturepcr 4 <(echo -n generic)" | xxd -p
225+
# PCR-5, depending on which modules are loaded for given board:
226+
# tpmr calcfuturepcr 5 module0.ko module1.ko module2.ko | xxd -p
227+
# PCR-6 and PCR-7: similar to 5, but with different files passed
228+
# (6: luks header, 7: user related cbfs files loaded from cbfs-init)
128229
}
129230

130231
tpm2_extend() {
@@ -601,7 +702,7 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then
601702
pcrsize)
602703
echo "$PCR_SIZE";;
603704
calcfuturepcr)
604-
shift; tpm1_calcfuturepcr "$@";;
705+
shift; replay_pcr "sha1" "$@";;
605706
destroy)
606707
shift; tpm1_destroy "$@";;
607708
seal)
@@ -634,7 +735,7 @@ case "$subcmd" in
634735
pcrsize)
635736
echo "$PCR_SIZE";;
636737
calcfuturepcr)
637-
tpm2_calcfuturepcr "$@";;
738+
replay_pcr "sha256" "$@";;
638739
extend)
639740
tpm2_extend "$@";;
640741
counter_read)

modules/coreboot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ else ifeq "$(CONFIG_COREBOOT_VERSION)" "4.19"
4444
else ifeq "$(CONFIG_COREBOOT_VERSION)" "talos_2"
4545
coreboot_version = git
4646
coreboot_patch_version = talos_2
47-
coreboot_commit_hash = 068ad520e4ae898d356add72ea7d2a13913b76ab
47+
coreboot_commit_hash = c8aed443c631042ad2b0326c35cd0b774752b924
4848
coreboot_repo := https://github.com/Dasharo/coreboot
4949

5050
else ifeq "$(CONFIG_COREBOOT_VERSION)" "purism"

patches/coreboot-4.11/0070-crossgcc-iasl-2021-instead-of-2018_fix-old_coreboot-build-on-newer-platforms.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
BINUTILS_ARCHIVE="https://ftpmirror.gnu.org/binutils/binutils-${BINUTILS_VERSION}.tar.xz"
1515
GDB_ARCHIVE="https://ftpmirror.gnu.org/gdb/gdb-${GDB_VERSION}.tar.xz"
1616
-IASL_ARCHIVE="https://acpica.org/sites/acpica/files/acpica-unix2-${IASL_VERSION}.tar.gz"
17-
+IASL_ARCHIVE="https://acpica.org/sites/acpica/files/acpica-unix-${IASL_VERSION}.tar.gz"
17+
+IASL_ARCHIVE="https://distfiles.macports.org/acpica/acpica-unix-${IASL_VERSION}.tar.gz"
1818
PYTHON_ARCHIVE="https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz"
1919
EXPAT_ARCHIVE="https://downloads.sourceforge.net/sourceforge/expat/expat-${EXPAT_VERSION}.tar.bz2"
2020
# CLANG toolchain archive locations

0 commit comments

Comments
 (0)