Skip to content

Commit

Permalink
WiP tpmr: add calc_pcr to simulate PCR content from reset state, meas…
Browse files Browse the repository at this point in the history
…uring files/strings to arrive to same cbmem -L (TCPA/Event log content from real measured stuff)

Traces:

When looking at TCPA log/TPM Event log:

~ # cbmem -L
coreboot TPM log:

 PCR-2 5622416ea417186aa1ac32b32c527ac09009fb5e SHA1 [FMAP: FMAP]
 PCR-2 8bbaeca78eb7e169df69d3687258318b58c8671e SHA1 [CBFS: bootblock]
 PCR-2 73ccefadc0a1be8184be89800e69186a260ebe40 SHA1 [CBFS: fallback/romstage]
 PCR-2 d697f8c98ef6f1b4aca397821e176bb48a227212 SHA1 [CBFS: fallback/postcar]
 PCR-2 b88302e3a46fb7fb11b92730d05c41b5f1f11bcf SHA1 [CBFS: fallback/ramstage]
 PCR-2 b688d567b0dfe1e1c6e4584289619a525b85cbd6 SHA1 [CBFS: bootsplash.jpg]
 PCR-2 9130eeb4cfe031edeabc56e6b84812d49a5a6bda SHA1 [CBFS: fallback/payload]

We see that PCR2 is extended from reset state (40*0) with:
FMAP (only one not under cbfs), bootblock, fallback/romstage, fallback/postcar, fallback/ramstage, bootsplash.jpg, fallback/payload

cbmem permits to extract FMAP from cbmem:
~ # cbmem --rawdump $(cbmem -l | grep FMAP | awk -F " " {'print $3'}) | xxd
00000000: 5f5f 464d 4150 5f5f 0101 0000 60ff 0000  __FMAP__....`...
00000010: 0000 0000 a000 464c 4153 4800 0000 0000  ......FLASH.....
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0300 0000 0800 0000 9800  ................
00000040: 4249 4f53 0000 0000 0000 0000 0000 0000  BIOS............
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0800 0002 0000 464d 4150 0000  ..........FMAP..
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0000 0000 0000 0000 0000 0000 0002 0800  ................
00000090: 00fe 9700 434f 5245 424f 4f54 0000 0000  ....COREBOOT....
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000                           ......

~ # xxd -r cbmem.txt  | sha1sum
6ecd73787c001bbc1215bd8787361e1a63b580cb  -

This sha1sum doesn't match reported TCPA/Event log for FMAP entry:
6ecd73787c001bbc1215bd8787361e1a63b580cb != 5622416ea417186aa1ac32b32c527ac09009fb5e

FMAP extracted from cbfsutil externally from ROM image is padded with ff up to 512 bytes (this is dynamic and cannot be hardcoded magic):

user@heads-tests-deb12:~/heads$ sudo cbfstool ~/heads/build/x86/qemu-coreboot-whiptail-tpm1/heads-qemu-coreboot-whiptail-tpm1-v0.2.0-1955-gfff99df-dirty.rom read -r FMAP -f xxx.bin
user@heads-tests-deb12:~/heads$ xxd xxx.bin > hex.txt
user@heads-tests-deb12:~/heads$ cat hex.txt
00000000: 5f5f 464d 4150 5f5f 0101 0000 60ff 0000  __FMAP__....`...
00000010: 0000 0000 a000 464c 4153 4800 0000 0000  ......FLASH.....
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0300 0000 0800 0000 9800  ................
00000040: 4249 4f53 0000 0000 0000 0000 0000 0000  BIOS............
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0800 0002 0000 464d 4150 0000  ..........FMAP..
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0000 0000 0000 0000 0000 0000 0002 0800  ................
00000090: 00fe 9700 434f 5245 424f 4f54 0000 0000  ....COREBOOT....
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000 ffff ffff ffff ffff ffff  ................
000000c0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000d0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000e0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000f0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000100: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000110: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000120: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000130: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000140: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000150: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000160: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000170: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000180: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000190: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000001a0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000001b0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000001c0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000001d0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000001e0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000001f0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
user@heads-tests-deb12:~/heads$ xxd -r hex.txt | sha1sum
5622416ea417186aa1ac32b32c527ac09009fb5e  -

This matches FMAP region measured in TCPA/TPM event log for FMAP trace above:
6ecd73787c001bbc1215bd8787361e1a63b580cb = 6ecd73787c001bbc1215bd8787361e1a63b580cb

It seems that coreboot measured boot code does the same as cbfstool (padding prior of measuring) instead of taking only the raw output we could replicate with cbfs....

Signed-off-by: Thierry Laurion <[email protected]>
  • Loading branch information
tlaurion committed Dec 31, 2023
1 parent de389ac commit 8701d14
Showing 1 changed file with 51 additions and 1 deletion.
52 changes: 51 additions & 1 deletion initrd/bin/tpmr
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,49 @@ replay_pcr() {
# (6: LUKS header, 7: user related cbfs files loaded from cbfs-init)
}

# usage: calc_pcr <alg> <pcr_num> [ <input_file>|<input_hash> ... ]
# Calculate PCR value to compare with CBMEM event log.
# First argument is PCR number, followed by optional
# hashes and/or files.
# Resulting PCR value is returned in binary form.
calc_pcr() {
TRACE "Under /bin/tpmr:calc_pcr"
if [ -z "$2" ]; then
echo >&2 "No PCR number passed"
return
fi
if [ "$2" -ge 8 ]; then
echo >&2 "Illegal PCR number ($2)"
return
fi
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 $replayed_pcr | hex2bin
DEBUG "Replayed cbmem -L clean boot state of PCR=$pcr ALG=$alg : $replayed_pcr"
# To manually introspect calculated to PCR values:
# TODO: fix the following examples with WORKING examples
# PCR-2:
# bash tpmr calc_pcr 2 <(cbmem -r 464d4150) <(cbfs --read bootblock) \
# <(cbfs --read fallback/romstage) <(cbfs --read fallback/postcar) \
# <(cbfs --read fallback/ramstage) <(cbfs --read bootsplash.jpg) \
# <(cbfs --read fallback/payload) | xxd -p
# PCR-4, in case of recovery shell (bash used for process substitution):
# bash -c "tpmr calc_pcr 4 <(echo -n recovery)" | xxd -p
# PCR-4, in case of normal boot passing through kexec-select-boot:
# bash -c "tpmr calc_pcr 4 <(echo -n generic)" | xxd -p
# PCR-5, depending on which modules are loaded for given board:
# tpmr calc_pcr 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() {
TRACE "Under /bin/tpmr:tpm2_extend"
while true; do
Expand Down Expand Up @@ -519,7 +562,7 @@ tpm1_seal() {
-of "$sealed_file" \
-hk 40000000 \
"${POLICY_ARGS[@]}"

# try it without the TPM Owner Password first
if ! tpm nv_writevalue -in "$index" -if "$sealed_file"; then
# to create an nvram space we need the TPM Owner Password
Expand Down Expand Up @@ -751,6 +794,10 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then
shift
replay_pcr "sha1" "$@"
;;
calc_pcr)
shift
calc_pcr "sha1" "$@"
;;
counter_create)
shift
tpm1_counter_create "$@"
Expand Down Expand Up @@ -796,6 +843,9 @@ pcrsize)
calcfuturepcr)
replay_pcr "sha256" "$@"
;;
calc_pcr)
calc_pcr "sha256" "$@"
;;
extend)
tpm2_extend "$@"
;;
Expand Down

0 comments on commit 8701d14

Please sign in to comment.