Skip to content

Commit 223b545

Browse files
committed
bin/tpmr:recalculate_firmware_pcr_from_cbfs Add basic TPM2 suppport
Signed-off-by: Thierry Laurion <insurgo@riseup.net>
1 parent 2e29463 commit 223b545

File tree

1 file changed

+47
-19
lines changed

1 file changed

+47
-19
lines changed

initrd/bin/tpmr

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ extend_pcr_state() {
114114
local argument=1
115115

116116
while [ "$#" -gt 0 ]; do
117-
DEBUG "Extending PCR state with argument #$argument: $1"
118117
next="$1"
119118
shift
120119
if is_hash "$alg" "$next"; then
@@ -239,29 +238,46 @@ replay_pcr() {
239238
}
240239

241240

242-
# Read the FMAP from cbmem and pad it to the next multiple of 512 bytes to match cbfsutil/measured boot FMAP
241+
# Function: read_and_pad_FMAP_from_cbmem
242+
# Description: This function reads the FMAP (Firmware Map) from the cbmem (coreboot memory) and pads it to the next multiple of 512 bytes.
243+
# It then calculates the checksum of the padded FMAP using the specified checksum algorithm (sha1 or sha256) and returns the checksum value.
244+
# Parameters:
245+
# - $1: The checksum algorithm to use (sha1 or sha256)
246+
# Returns:
247+
# - The checksum value of the padded FMAP
248+
# - Returns 1 if an unknown checksum algorithm is provided
243249
read_and_pad_FMAP_from_cbmem() {
250+
TRACE "Under /bin/tpmr:read_and_pad_FMAP_from_cbmem"
251+
# Check if the checksum algorithm is supported and set the appropriate program
252+
if [ "$1" == "sha1" ]; then
253+
checksum_prog="sha1sum"
254+
elif [ "$1" == "sha256" ]; then
255+
checksum_prog="sha256sum"
256+
else
257+
echo >&2 "Unknown checksum algorithm: $1"
258+
return 1
259+
fi
260+
244261
# Create the directory for temporary files
245262
mkdir -p /tmp/secret/
246263
# Fetch the address of the FMAP in memory and write the raw FMAP data to a file
247-
cbmem --rawdump $(cbmem -l | grep FMAP | awk -F " " {'print $3'}) >/tmp/secret/fmap.raw
264+
cbmem --rawdump "$(cbmem -l | grep FMAP | awk -F " " '{print $3}')" >/tmp/secret/fmap.raw
248265
# Fetch the size of the FMAP from the raw data (4 bytes at offset 8) and store it as a hexadecimal string
249266
fmap_size_hex=$(hexdump -v -e '/1 "%02x"' -s 8 -n 4 /tmp/secret/fmap.raw)
250267
# Rearrange the bytes in the size to little-endian format
251-
fmap_size_le=${fmap_size_hex:6:2}${fmap_size_hex:4:2}${fmap_size_hex:2:2}${fmap_size_hex:0:2}
268+
fmap_size_le="${fmap_size_hex:6:2}${fmap_size_hex:4:2}${fmap_size_hex:2:2}${fmap_size_hex:0:2}"
252269
# Convert the size from hexadecimal to decimal
253-
fmap_size=$((16#$fmap_size_le))
270+
fmap_size=$((16#"$fmap_size_le"))
254271
# Calculate the next multiple of 512 that is greater than or equal to the size of the FMAP
255-
next_multiple=$((($fmap_size + 511) / 512 * 512))
272+
next_multiple=$(( (fmap_size + 511) / 512 * 512 ))
256273
# Calculate the number of bytes needed to fill the fmap.raw file to the next multiple of 512
257-
#fill_size=$(( $next_multiple - $fmap_size ))
258-
fill_size=$(($next_multiple - $(stat -c%s /tmp/secret/fmap.raw)))
274+
fill_size=$(( next_multiple - $(stat -c%s /tmp/secret/fmap.raw) ))
259275
# Create a file named fill.ff filled with 'ff' of the required size
260-
dd if=/dev/zero bs=1 count=$fill_size 2>/dev/null | tr '\0' '\377' >/tmp/secret/fill.ff
276+
dd if=/dev/zero bs=1 count="$fill_size" 2>/dev/null | tr '\0' '\377' >/tmp/secret/fill.ff
261277
# Append the fill.ff file to the fmap.raw file, resulting in a file named fmap_filled.raw
262278
cat /tmp/secret/fmap.raw /tmp/secret/fill.ff >/tmp/secret/fmap_filled.raw
263279
# Caller is expected to use hash format that matches the algorithm used for the PCR
264-
sha1sum /tmp/secret/fmap_filled.raw | awk -F " " {'print $1'}
280+
"$checksum_prog" /tmp/secret/fmap_filled.raw | awk -F " " '{print $1}'
265281
# Removal of the tempory files in tmpfs is left to when going to recovery shell or rebooting
266282
}
267283

@@ -326,16 +342,28 @@ recalculate_firmware_pcr_from_cbfs()
326342
TRACE "Under /bin/tpmr:recalculate_firmware_pcr_from_cbfs"
327343
# We pass hashes of the files that are measured by coreboot, simulating the measurement process
328344
# As of now, Heads uses coreboot custom TPM Event log format, which measures everything in PCR-2
345+
346+
if [ "$1" == "sha1" ]; then
347+
checksum_prog="sha1sum"
348+
PCR_STRING="PCR-2"
349+
elif [ "$1" == "sha256" ]; then
350+
checksum_prog="sha256sum"
351+
PCR_STRING="2 :"
352+
else
353+
echo >&2 "Unknown checksum algorithm: $1"
354+
return 1
355+
fi
356+
329357
DO_WITH_DEBUG calc_pcr "$1" 2 \
330-
$(read_and_pad_FMAP_from_cbmem) \
331-
$(cbfs --read bootblock | sha1sum | awk -F " " {'print $1'}) \
332-
$(cbfs --read fallback/romstage | sha1sum | awk -F " " {'print $1'}) \
333-
$(cbfs --read fallback/postcar | sha1sum | awk -F " " {'print $1'}) \
334-
$(cbfs --read fallback/ramstage | sha1sum | awk -F " " {'print $1'}) \
335-
$(cbfs --read bootsplash.jpg | sha1sum | awk -F " " {'print $1'}) \
336-
$(cbfs --read fallback/payload | sha1sum | awk -F " " {'print $1'})
337-
338-
DEBUG "Actual TPM $(pcrs | grep PCR-02)"
358+
"$(read_and_pad_FMAP_from_cbmem "$1")" \
359+
"$(cbfs --read bootblock | $checksum_prog | awk -F ' ' '{print $1}')" \
360+
"$(cbfs --read fallback/romstage | $checksum_prog | awk -F ' ' '{print $1}')" \
361+
"$(cbfs --read fallback/postcar | $checksum_prog | awk -F ' ' '{print $1}')" \
362+
"$(cbfs --read fallback/ramstage | $checksum_prog | awk -F ' ' '{print $1}')" \
363+
"$(cbfs --read bootsplash.jpg | $checksum_prog | awk -F ' ' '{print $1}')" \
364+
"$(cbfs --read fallback/payload | $checksum_prog | awk -F ' ' '{print $1}')"
365+
366+
DEBUG "Actual TPM $(pcrs | grep "$PCR_STRING")"
339367
DEBUG "TPM event log reported by cbmem -L: $(cbmem -L)"
340368
}
341369

0 commit comments

Comments
 (0)