Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WiP: introspection - replicate TPM PCRs measurements directly from measured content (TCPA/TPM Event log) #1568

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

tlaurion
Copy link
Collaborator

@tlaurion tlaurion commented Dec 31, 2023

Documented in commits as of now, particularly 8701d14. Will progress after reviewing coreboot codebase and maybe even open issues since there is already discrepencies for FMAP extraction/measurements as of now. See commit for details.

This is to give practical context (vs theoritical content as comment+ linuxboot/heads-wiki#107 (comment)) on what is attempted to be done to address current RFC comments:


At term

  • tpmr helper script will have functional tpmr calc_pcr, useable externall through introspect functions to be able to replicate measured content outside of coreboot measured boot code:
    • Take cbmem accessible memory to extract FMAP and properly measure it the same way coreboot measures it in measured boot code
    • Use cbfs to access mapped CBFS filesystem to validate (instrospect) sealed TOTP/HOTP/TPM DUK parts, by being able to validate files integrity
  • Finaly attain Implement forward sealing of firmware upgrades #523. If we can validate current state, we will be able to eventually seal content of future calculated PCRs content from those introspection helpers, applied to ROM to be flashed instead of validating runtime accessible content.

Let's go back to the basics.

Coreboot measured boot does its thing, leading to TPM PCRs being extended by:

~ # 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]

Current code is coreboot+heads extend operations of PCRs, leading to sealing/unsealing of secrets.

NOTE: THIS IS NON-HOTP UNDER QEMU (qemu-coreboot-whiptail-tpm1 board) which has DEBUG/TRACE activated in board config by default

On boot in debug mode, one can see:

[    6.367615] DEBUG: Debug output enabled from board CONFIG_DEBUG_OUTPUT=y option (/etc/config)
[    6.397918] TRACE: Under init
[    6.568554] TRACE: Under /bin/tpmr
[    6.713454] TRACE: Under /bin/cbfs-init
[    6.871008] DEBUG: Extending TPM PCR 7 with /.gnupg/pubring.kbx
[    6.993091] TRACE: Under /bin/tpmr
[    7.068339] DEBUG: Direct translation from tpmr to tpm1 call
[    7.117974] DEBUG: exec tpm extend -ix 7 -if /tmp/cbfs.106
[    7.308879] DEBUG: Extending TPM PCR 7 with /.gnupg/trustdb.gpg
[    7.425651] TRACE: Under /bin/tpmr
[    7.508279] DEBUG: Direct translation from tpmr to tpm1 call
[    7.557995] DEBUG: exec tpm extend -ix 7 -if /tmp/cbfs.106

when sealing/resealing TOTP/HOTP:

[   20.436488]  !!! ERROR: Unable to unseal TOTP secret !!!
[   22.492932] DEBUG: CONFIG_TPM: y
[   22.543257] DEBUG: CONFIG_TPM2_TOOLS:
[   22.608812] DEBUG: Show PCRs
[   22.803776] DEBUG: PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   22.840741] PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   22.881815] PCR-02: 29 5B FA C8 71 8E DC 56 38 FF 41 AC 24 42 1B 05 71 15 E9 9A
[   22.918112] PCR-03: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   22.954170] PCR-04: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   22.992496] PCR-05: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   23.026032] PCR-06: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   23.059503] PCR-07: B8 85 CF DE 4E B8 CA 55 B4 05 2D 02 C2 F4 74 D4 21 00 3C 4C
[   36.867188] TRACE: Under /bin/gui-init:generate_totp_hotp
[   36.967579] TRACE: Under /bin/seal-totp
[   37.052311] DEBUG: Sealing TOTP with actual state of PCR0-3
[   37.171910] TRACE: Under /bin/tpmr
[   37.253669] TRACE: Under /bin/tpmr:tpm1_pcrread
[   37.305168] DEBUG: tpm pcrread -ix 0
[   37.443424] TRACE: Under /bin/tpmr
[   37.517793] TRACE: Under /bin/tpmr:tpm1_pcrread
[   37.566605] DEBUG: tpm pcrread -ix 1
[   37.693229] TRACE: Under /bin/tpmr
[   37.753872] TRACE: Under /bin/tpmr:tpm1_pcrread
[   37.810666] DEBUG: tpm pcrread -ix 2
[   37.952421] TRACE: Under /bin/tpmr
[   38.028588] TRACE: Under /bin/tpmr:tpm1_pcrread
[   38.077889] DEBUG: tpm pcrread -ix 3
[   38.168742] DEBUG: Sealing TOTP with boot state of PCR4 (Going to recovery shell extends PCR4)
[   38.269630] TRACE: Under /bin/tpmr
[   38.351576] TRACE: Under /bin/tpmr:replay_pcr
[   38.504755] DEBUG: Replayed cbmem -L clean boot state of PCR=4 ALG=sha1 : 0000000000000000000000000000000000000000
[   38.570688] DEBUG: Sealing TOTP neglecting PCR5 involvement (Dynamically loaded kernel modules are not firmware integrity attestation related)
[   38.618129] DEBUG: Sealing TOTP without PCR6 involvement (LUKS header consistency is not firmware integrity attestation related)
[   38.752815] TRACE: Under /bin/tpmr
[   38.829422] TRACE: Under /bin/tpmr:tpm1_pcrread
[   38.880416] DEBUG: tpm pcrread -ix 7
[   39.025969] TRACE: Under /bin/tpmr
[   39.091944] TRACE: Under /bin/tpmr:tpm1_seal
[   39.171009] DEBUG: tpm1_seal arguments: file=/tmp/secret/totp.key index=4d47 pcrl=0,1,2,3,4,7 pcrf=/tmp/secret/pcrf.bin sealed_size=312 pass=<empty> tpm_password=<empty>
[   39.467437] DEBUG: Running at_exit handlers
[   39.518427] TRACE: Under /bin/tpmr:cleanup_shred
[   40.948091] TRACE: Under /bin/gui-init:update_totp
[   41.071700] TRACE: Under /bin/unseal-totp
[   41.160445] TRACE: Under /bin/tpmr
[   41.233640] TRACE: Under /bin/tpmr:tpm1_unseal
[   41.339872] DEBUG: Running at_exit handlers
[   41.366528] TRACE: Under /bin/tpmr:cleanup_shred

When sealing/resealing TPM DUK:

[   41.445377] TRACE: Under /etc/functions:reseal_tpm_disk_decryption_key
[   41.475321] DEBUG: TPM Disk Unlock Key is allowed in board configs. Continuing
[   41.540213]  *** WARNING: TPM sealed Disk Unlock Key secret needs to be resealed alongside TOTP/HOTP secret ***
[   42.688732] TRACE: Under kexec-seal-key
[   42.759000] DEBUG: Devices defined for disk encryption: /dev/vda4
[   42.805561] DEBUG: No LVM volume group defined for activation
[   42.985001] DEBUG: PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   43.008100] PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   43.036384] PCR-02: 29 5B FA C8 71 8E DC 56 38 FF 41 AC 24 42 1B 05 71 15 E9 9A
[   43.072981] PCR-03: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   43.100711] PCR-04: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   43.129680] PCR-05: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   43.158979] PCR-06: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   43.196712] PCR-07: B8 85 CF DE 4E B8 CA 55 B4 05 2D 02 C2 F4 74 D4 21 00 3C 4C
[  143.067899] DEBUG: Checking number of slots used on /dev/vda4 LUKS header
[  143.251583] DEBUG: Number of slots used on /dev/vda4 LUKS header: 2
[  143.288628] DEBUG: Slot 1 is not the only existing slot on /dev/vda4 LUKS header.
[  143.318917] DEBUG: /dev/vda4 LUKS header's slot 1 will store LUKS Disk Unlock Key that TPM will seal/unseal with TPM Disk Unlock Key passphrase
[  172.592929] TRACE: Under /bin/qubes-measure-luks
[  172.632252] DEBUG: Arguments passed to qubes-measure-luks: /dev/vda4
[  172.692086] DEBUG: Storing LUKS header for /dev/vda4 into /tmp/lukshdr-_dev_vda4
[  173.341529] DEBUG: Hashing LUKS headers into /tmp/luksDump.txt
[  174.149694] DEBUG: Removing /tmp/lukshdr-*
[  174.245129] DEBUG: Extending TPM PCR 6 with hash of LUKS headers from /tmp/luksDump.txt
[  174.353329] TRACE: Under /bin/tpmr
[  174.426883] DEBUG: Direct translation from tpmr to tpm1 call
[  174.473913] DEBUG: exec tpm extend -ix 6 -if /tmp/luksDump.txt
[  174.616760] TRACE: Under /bin/tpmr
[  174.678668] TRACE: Under /bin/tpmr:tpm1_pcrread
[  174.747086] DEBUG: tpm pcrread -ix 0
[  174.905885] TRACE: Under /bin/tpmr
[  174.967405] TRACE: Under /bin/tpmr:tpm1_pcrread
[  175.030457] DEBUG: tpm pcrread -ix 1
[  175.177769] TRACE: Under /bin/tpmr
[  175.259749] TRACE: Under /bin/tpmr:tpm1_pcrread
[  175.310981] DEBUG: tpm pcrread -ix 2
[  175.481466] TRACE: Under /bin/tpmr
[  175.561849] TRACE: Under /bin/tpmr:tpm1_pcrread
[  175.614064] DEBUG: tpm pcrread -ix 3
[  175.792765] TRACE: Under /bin/tpmr
[  175.882876] TRACE: Under /bin/tpmr:replay_pcr
[  176.040742] DEBUG: Replayed cbmem -L clean boot state of PCR=4 ALG=sha1 : 0000000000000000000000000000000000000000
[  176.103851] DEBUG: Sealing TPM Disk Unlock Key with PCR5=0 (NO additional kernel modules are loaded per board config)...
[  176.211233] TRACE: Under /bin/tpmr
[  176.292151] TRACE: Under /bin/tpmr:replay_pcr
[  176.440122] DEBUG: Replayed cbmem -L clean boot state of PCR=5 ALG=sha1 : 0000000000000000000000000000000000000000
[  176.523055] DEBUG: Precomputing TPM future value for PCR6 sealing/unsealing of TPM Disk Unlock Key...
[  176.659425] TRACE: Under /bin/tpmr
[  176.744122] TRACE: Under /bin/tpmr:replay_pcr
[  177.031080] DEBUG: Replayed cbmem -L clean boot state of PCR=6 ALG=sha1 : 01520898d3570c05f0d568c703ced659a86d07d0
[  177.154090] TRACE: Under /bin/tpmr
[  177.241526] TRACE: Under /bin/tpmr:tpm1_pcrread
[  177.299186] DEBUG: tpm pcrread -ix 7
[  177.413648] DEBUG: tpmr seal /tmp/secret/secret.key 3 0,1,2,3,4,5,6,7 /tmp/secret/pcrf.bin 312 <hidden>
[  177.556579] TRACE: Under /bin/tpmr
[  177.629027] TRACE: Under /bin/tpmr:tpm1_seal
[  177.708219] DEBUG: tpm1_seal arguments: file=/tmp/secret/secret.key index=3 pcrl=0,1,2,3,4,5,6,7 pcrf=/tmp/secret/pcrf.bin sealed_size=312 pass=<hidden> tpm_password=<empty>
[  178.059784] DEBUG: Running at_exit handlers
[  178.098162] TRACE: Under /bin/tpmr:cleanup_shred
[  178.205557] EXT4-fs (vda3): re-mounted. Opts: (null)
[  178.383950] EXT4-fs (vda3): re-mounted. Opts: (null)
[  178.457170]  *** WARNING: LUKS header hash changed under /boot/kexec_luks_hdr_hash.txt ***
[  179.534337] TRACE: Under /etc/functions:update_checksums
[  179.598859] EXT4-fs (vda3): re-mounted. Opts: (null)
[  179.697408] TRACE: Under /bin/kexec-sign-config
[  179.758587] TRACE: Under /etc/functions:assert_signable
[  179.945770] TRACE: Under /etc/ash_functions:confirm_gpg_card
[  190.293216] TRACE: Under /etc/ash_functions:enable_usb
[...]

On master, logic present trusts TCPA/TPM event log to be the "replay" base.

Current PR will try to add introspection required bases so that TCPA/TPM event log alone is not trusted, but validated. As explained in RFC under heeads-wiki, Heads packs other tools, including cbfs to read/write from/to cbfs (osresearch/flashtools built cbfs binary) and packs cbmem (coreboot) as of now which if used, would require more then FMAP+bootblock+++ compromise of coreboot base to be able to bypass Heads introspection.

I will point discussion to this so that we can now understand where we want to go instead of requestionning the base and goals of this attempt or focus more directly on what is missing, what we have and where we want to go for next steps.

@tlaurion tlaurion changed the title WiP: introspection - replicate pcr content from runtime WiP: introspection - replicate TPM PCRs measurements directly from measured content (TCPA/TPM Event log) Dec 31, 2023
@tlaurion
Copy link
Collaborator Author

TRACE "Under /bin/tpmr:calc_pcr"
if [ -z "$2" ]; then
echo >&2 "No PCR number passed"
return

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will return a successful status to the caller. Should this be return 1 or even exit 1?

fi
if [ "$2" -ge 8 ]; then
echo >&2 "Illegal PCR number ($2)"
return

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Comment on lines +249 to +300
# 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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# 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
case $alg in
(sha1)
# SHA-1 hashes are 40 chars
alg_digits=40;;
(sha256)
# SHA-256 hashes are 64 chars
alg_digits=64;;
(*)
# Invalid
printf 'Invalid hash algorithm %s\n' "$alg" >&2
exit 1;;
esac

initrd/bin/tpmr Outdated
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
echo $replayed_pcr | hex2bin
printf %s\\n "$replayed_pcr" | hex2bin

@tlaurion
Copy link
Collaborator Author

tlaurion commented Jan 3, 2024

Edit: finally working PoC:

Execution of PoC:

sha1sum of cbmem filled up to next 512 boundary with ff:
5622416ea417186aa1ac32b32c527ac09009fb5e
TPM Event log for FMAP:
5622416ea417186aa1ac32b32c527ac09009fb5e

Content of PoC

# Create the directory for temporary files
mkdir -p /tmp/secret/

# Fetch the address of the FMAP in memory and write the raw FMAP data to a file
cbmem --rawdump $(cbmem -l | grep FMAP | awk -F " " {'print $3'}) > /tmp/secret/fmap.raw

# Fetch the size of the FMAP from the raw data (4 bytes at offset 8) and store it as a hexadecimal string
fmap_size_hex=$(hexdump -v -e '/1 "%02x"' -s 8 -n 4 /tmp/secret/fmap.raw)

# Rearrange the bytes in the size to little-endian format
fmap_size_le=${fmap_size_hex:6:2}${fmap_size_hex:4:2}${fmap_size_hex:2:2}${fmap_size_hex:0:2}

# Convert the size from hexadecimal to decimal
fmap_size=$((16#$fmap_size_le))

# Calculate the next multiple of 512 that is greater than or equal to the size of the FMAP
next_multiple=$(( ($fmap_size + 511) / 512 * 512 ))

# Calculate the number of bytes needed to fill the fmap.raw file to the next multiple of 512
#fill_size=$(( $next_multiple - $fmap_size ))
fill_size=$(( $next_multiple - $(stat -c%s /tmp/secret/fmap.raw) ))

# Create a file named fill.ff filled with 'ff' of the required size
dd if=/dev/zero bs=1 count=$fill_size 2>/dev/null | tr '\0' '\377' > /tmp/secret/fill.ff

# Append the fill.ff file to the fmap.raw file, resulting in a file named fmap_filled.raw
cat /tmp/secret/fmap.raw /tmp/secret/fill.ff > /tmp/secret/fmap_filled.raw

# Calculate and print the sha1sum of the filled FMAP
echo "sha1sum of cbmem filled up to next 512 boundary with ff:"
sha1sum /tmp/secret/fmap_filled.raw | awk -F " " {'print $1'}

# Remove the /tmp/secret/ directory and all its contents
rm -rf /tmp/secret/

echo "TPM Event log for FMAP:"
cbmem -L | grep FMAP | awk -F " " {'print $2'}

@tlaurion tlaurion force-pushed the WiP_introspection-replicate_PCR_content_from_runtime branch from 8701d14 to 51231f3 Compare January 3, 2024 07:07
@tlaurion
Copy link
Collaborator Author

tlaurion commented Jan 3, 2024

With 5574fb4 we can use cbmem to extract FMAP and pad it up to next 512 byte boundary with ff, and then use cbfs to extract all measured boot coreboot stages.

PoC output looks like this from recovery shell on qemu-coreboot-whiptail-tpm1 (debug+trace activated):

~ # tpmr recalculate_firmware_pcr_from_cbfs #Replay coreboot TPM event log from 
CBFS
[   92.166420] TRACE: Under /bin/tpmr
[   92.231076] TRACE: Under /bin/tpmr:recalculate_firmware_pcr_from_cbfs
[   93.048080] DEBUG: calc_pcr sha1 2 5622416ea417186aa1ac32b32c527ac09009fb5e 4f2447281786fe209dbe350a07f31c579f7059c7 1f39b9bdf52c678785c885aaee2a9e6a6ee81381 5e70311bbbff493a813682a12174d3482acfb7ec f527597d31308054375f13329ee1f12d29a3f279 b688d567b0dfe1e1c6e4584289619a525b85cbd6 69d82307aafc1f9eefeac373aa21cdf2123d5c41
[   93.083696] TRACE: Under /bin/tpmr:calc_pcr
[   93.131434] TRACE: Under /bin/tpmr:extend_pcr_state
[   93.162074] DEBUG: Initial PCR state: 0000000000000000000000000000000000000000
[   93.197414] DEBUG: Extending PCR state with argument #1: 5622416ea417186aa1ac32b32c527ac09009fb5e
[   93.264496] DEBUG: Extending PCR state with passed argument #1 hash: 5622416ea417186aa1ac32b32c527ac09009fb5e
[   93.368362] DEBUG: Extending PCR state with argument #2: 4f2447281786fe209dbe350a07f31c579f7059c7
[   93.447132] DEBUG: Extending PCR state with passed argument #2 hash: 4f2447281786fe209dbe350a07f31c579f7059c7
[   93.537201] DEBUG: Extending PCR state with argument #3: 1f39b9bdf52c678785c885aaee2a9e6a6ee81381
[   93.604202] DEBUG: Extending PCR state with passed argument #3 hash: 1f39b9bdf52c678785c885aaee2a9e6a6ee81381
[   93.688703] DEBUG: Extending PCR state with argument #4: 5e70311bbbff493a813682a12174d3482acfb7ec
[   93.752334] DEBUG: Extending PCR state with passed argument #4 hash: 5e70311bbbff493a813682a12174d3482acfb7ec
[   93.846594] DEBUG: Extending PCR state with argument #5: f527597d31308054375f13329ee1f12d29a3f279
[   93.918457] DEBUG: Extending PCR state with passed argument #5 hash: f527597d31308054375f13329ee1f12d29a3f279
[   94.026392] DEBUG: Extending PCR state with argument #6: b688d567b0dfe1e1c6e4584289619a525b85cbd6
[   94.099127] DEBUG: Extending PCR state with passed argument #6 hash: b688d567b0dfe1e1c6e4584289619a525b85cbd6
[   94.204186] DEBUG: Extending PCR state with argument #7: 69d82307aafc1f9eefeac373aa21cdf2123d5c41
[   94.283342] DEBUG: Extending PCR state with passed argument #7 hash: 69d82307aafc1f9eefeac373aa21cdf2123d5c41
[   94.388297] DEBUG: Extended final PCR state: 9eab5af574049405f221292585b01c85cc53872a
[   94.443378] DEBUG: Replayed cbmem -L clean boot state of PCR=2 ALG=sha1 : 9eab5af574049405f221292585b01c85cc53872a
9eab5af574049405f221292585b01c85cc53872a
[   94.640554] DEBUG: Actual TPM PCR-02: 9E AB 5A F5 74 04 94 05 F2 21 29 25 85 B0 1C 85 CC 53 87 2A
[   94.708640] DEBUG: TPM event log reported by cbmem -L: coreboot TPM log:
[   94.748215] 
[   94.819908] PCR-2 5622416ea417186aa1ac32b32c527ac09009fb5e SHA1 [FMAP: FMAP]
[   94.861644] PCR-2 4f2447281786fe209dbe350a07f31c579f7059c7 SHA1 [CBFS: bootblock]
[   94.885169] PCR-2 1f39b9bdf52c678785c885aaee2a9e6a6ee81381 SHA1 [CBFS: fallback/romstage]
[   94.961600] PCR-2 5e70311bbbff493a813682a12174d3482acfb7ec SHA1 [CBFS: fallback/postcar]
[   94.994400] PCR-2 f527597d31308054375f13329ee1f12d29a3f279 SHA1 [CBFS: fallback/ramstage]
[   95.044307] PCR-2 b688d567b0dfe1e1c6e4584289619a525b85cbd6 SHA1 [CBFS: bootsplash.jpg]
[   95.082265] PCR-2 69d82307aafc1f9eefeac373aa21cdf2123d5c41 SHA1 [CBFS: fallback/payload]

It looks like we could add helpers in Makefile to manipulate, post rom assembly per coreboot, an additional forward sealing file containing the expected PCR value for PCR2 for next steps.

Here, the question is what we would want to do with that

  • Validate sealed PCR2 values of firmware prior of calling totp unseal?
  • Flash new firmware and then do the forward resealing of TPM DUK?

initrd/bin/tpmr Outdated
# Create the directory for temporary files
mkdir -p /tmp/secret/
# Fetch the address of the FMAP in memory and write the raw FMAP data to a file
cbmem --rawdump $(cbmem -l | grep FMAP | awk -F " " {'print $3'}) >/tmp/secret/fmap.raw

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cbmem --rawdump $(cbmem -l | grep FMAP | awk -F " " {'print $3'}) >/tmp/secret/fmap.raw
arg=$(cbmem -l | grep FMAP | awk -F " " {'print $3'})
cbmem --rawdump "$arg" >/tmp/secret/fmap.raw

Hopefully shellcheck catches this.

initrd/bin/tpmr Outdated
Comment on lines 330 to 336
$(read_and_pad_FMAP_from_cbmem) \
$(cbfs --read bootblock | sha1sum | awk -F " " {'print $1'}) \
$(cbfs --read fallback/romstage | sha1sum | awk -F " " {'print $1'}) \
$(cbfs --read fallback/postcar | sha1sum | awk -F " " {'print $1'}) \
$(cbfs --read fallback/ramstage | sha1sum | awk -F " " {'print $1'}) \
$(cbfs --read bootsplash.jpg | sha1sum | awk -F " " {'print $1'}) \
$(cbfs --read fallback/payload | sha1sum | awk -F " " {'print $1'})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Command substitutions should not be used in command arguments, as failure of the command is ignored. Instead, they should be assigned to a temporary variable.

@tlaurion
Copy link
Collaborator Author

tlaurion commented Jan 3, 2024

With 5bd19f4 on qemu-coreboot-whiptail-tpm2 (with DEBUG/TRACE activated per board config):

~ # tpmr recalculate_firmware_pcr_from_cbfs #Replay coreboot TPM event log from 
CBFS
[   30.736989] TRACE: Under /bin/tpmr
[   30.800904] TRACE: Under /bin/tpmr:recalculate_firmware_pcr_from_cbfs
[   31.497773] DEBUG: calc_pcr sha256 2 02778dad5303b911adc8828cf5101a251a9b2a5a2b711a44159fb89a5a0b5198 f42df98aeda999e2d9e5e5208668a78e1b7bdda5d02600cf4947591f35c67121 3e371b3ffe51f7ee1d483026ca004f0e0d4432de8103c4c1de31011a94fb1612 1b4f09549008ae961072514b397f2e391aa4d9e6c48a673e87c8a12c17be113a 284e7103b372e7ab1ccf3077ba49a754c06d976f33ad74da1bdb7467fa319c19 bc172d6c3551a44fbd6beef7ebbb2d4fa1452c46fcfdeebef1c519f13d668f1b 829573af425b78fa1bb7cb9cfcb61f520d5063f3c3ba2f93d806dedb3af79ac5
[   31.535528] TRACE: Under /bin/tpmr:calc_pcr
[   31.584183] TRACE: Under /bin/tpmr:extend_pcr_state
[   31.622667] DEBUG: Initial PCR state: 0000000000000000000000000000000000000000000000000000000000000000
[   31.693083] DEBUG: Extending PCR state with passed argument #1 hash: 02778dad5303b911adc8828cf5101a251a9b2a5a2b711a44159fb89a5a0b5198
[   31.806253] DEBUG: Extending PCR state with passed argument #2 hash: f42df98aeda999e2d9e5e5208668a78e1b7bdda5d02600cf4947591f35c67121
[   31.911070] DEBUG: Extending PCR state with passed argument #3 hash: 3e371b3ffe51f7ee1d483026ca004f0e0d4432de8103c4c1de31011a94fb1612
[   32.017774] DEBUG: Extending PCR state with passed argument #4 hash: 1b4f09549008ae961072514b397f2e391aa4d9e6c48a673e87c8a12c17be113a
[   32.151362] DEBUG: Extending PCR state with passed argument #5 hash: 284e7103b372e7ab1ccf3077ba49a754c06d976f33ad74da1bdb7467fa319c19
[   32.281688] DEBUG: Extending PCR state with passed argument #6 hash: bc172d6c3551a44fbd6beef7ebbb2d4fa1452c46fcfdeebef1c519f13d668f1b
[   32.416306] DEBUG: Extending PCR state with passed argument #7 hash: 829573af425b78fa1bb7cb9cfcb61f520d5063f3c3ba2f93d806dedb3af79ac5
[   32.522296] DEBUG: Extended final PCR state: ed1bbd19fceca6f7028e4eb97e6854e6ec24bc084e501b049cec0d19e0de82cd
[   32.580794] DEBUG: Replayed cbmem -L clean boot state of PCR=2 ALG=sha256 : ed1bbd19fceca6f7028e4eb97e6854e6ec24bc084e501b049cec0d19e0de82cd
ed1bbd19fceca6f7028e4eb97e6854e6ec24bc084e501b049cec0d19e0de82cd
[   32.754666] DEBUG: Actual TPM     2 : 0xED1BBD19FCECA6F7028E4EB97E6854E6EC24BC084E501B049CEC0D19E0DE82CD
[   32.846124] DEBUG: TPM event log reported by cbmem -L: coreboot TPM log:
[   32.902556] 
[   32.950721] PCR-2 02778dad5303b911adc8828cf5101a251a9b2a5a2b711a44159fb89a5a0b5198 SHA256 [FMAP: FMAP]
[   32.976485] PCR-2 f42df98aeda999e2d9e5e5208668a78e1b7bdda5d02600cf4947591f35c67121 SHA256 [CBFS: bootblock]
[   33.048439] PCR-2 3e371b3ffe51f7ee1d483026ca004f0e0d4432de8103c4c1de31011a94fb1612 SHA256 [CBFS: fallback/romstage]
[   33.093232] PCR-2 1b4f09549008ae961072514b397f2e391aa4d9e6c48a673e87c8a12c17be113a SHA256 [CBFS: fallback/postcar]
[   33.140986] PCR-2 284e7103b372e7ab1ccf3077ba49a754c06d976f33ad74da1bdb7467fa319c19 SHA256 [CBFS: fallback/ramstage]
[   33.178227] PCR-2 bc172d6c3551a44fbd6beef7ebbb2d4fa1452c46fcfdeebef1c519f13d668f1b SHA256 [CBFS: bootsplash.jpg]
[   33.240108] PCR-2 829573af425b78fa1bb7cb9cfcb61f520d5063f3c3ba2f93d806dedb3af79ac5 SHA256 [CBFS: fallback/payload]

@tlaurion tlaurion force-pushed the WiP_introspection-replicate_PCR_content_from_runtime branch from 5bd19f4 to ad79a93 Compare January 3, 2024 18:40
…nks @githubisnonfree!)

- Addition of ifdtool from coreboot project to extract gbe
  - As of now, its implemented in a hacky way:
    - ifdtool dir is copied over ifdtool_cross at coreboot's module configure step
    - then initrd packing step checks for CONFIG_NVMUTIL and builds and pack ifdtool_cross/ifdtool
    - As a result, what is build under build/coreboot/$BOARD is coreboot's real, where build/coreboot/ content follows Makefile rules
- CONFIG_NVMUTIL in board config adds both ifdtool_cross/ifdtool and nvmutil into initrd
- Added CONFIG_NVMUTIL to all hotp-maximized boards (to test for
 size changes)

Manually tested (working!):
- backup rom from: `flashrom -p internal -r /tmp/backup.rom`
- go to that dir: `cd /tmp`
- extract gbe from ifdtool on backup.rom: `ifdtool -x backup.rom`
- source shell functions: `. /etc/functions`
- show current PHY mac address: `nvm showmac flashregion_3_gbe.bin`
- generate mac address from sourced shell functions: `newmac=$(generate_random_mac_address)`
- show new mac: `echo $newmac`
- change mac from nvmtool on extracted gbe: `nvm flashregion_3_gbe.bin setmac $newmac`
- insert modified gbe into backup.rom.new with ifdtool: `ifdtool -i gbe:flashregion_3_gbe.bin backup.rom`
- flash back modified gbe only through flashrom: `flashrom -p internal --ifd -i gbe -w backup.rom.new`

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…fstool/ifdtool to get same cbmem -L/TPM eventlog/introspection of PRC content equivalence

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…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 <insurgo@riseup.net>
…fsutil/nvmutil for this task.

cbmem+cbfs is enough

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…ecalculate_firmware_pcr_from_cbfs

.ash_history: add tpmr recalculate_firmware_pcr_from_cbfs but remove unneeded deprecated ways of doing things

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…r comparison

Buggy as of now, will reverify next week

~ # tpmr verify_coreboot_measured_boot_tpm_event_log_vs_content_measured #Valida
te coreboot TPM event log against cbmem FMAP+cbfs content
[  293.267413] TRACE: Under /bin/tpmr
[  293.390454] TRACE: Under /bin/tpmr
[  293.441752] TRACE: Under /bin/tpmr:replay_pcr
[  293.551759] TRACE: Under /bin/tpmr:extend_pcr_state
[  293.574966] DEBUG: Initial PCR state: 0000000000000000000000000000000000000000000000000000000000000000
[  293.639890] DEBUG: Extending PCR state with passed argument #1 hash: 02778dad5303b911adc8828cf5101a251a9b2a5a2b711a44159fb89a5a0b5198
[  293.761500] DEBUG: Extending PCR state with passed argument #2 hash: 5444dba991b48df882ed1e2b85f0c90f947f6c7f8ed3dd6c91dc70dd661b66cb
[  293.899682] DEBUG: Extending PCR state with passed argument #3 hash: 13d3cacde02deff3d5e1ae2b52e5647c67046fb359b58d3899365a87a7161090
[  294.028814] DEBUG: Extending PCR state with passed argument #4 hash: cea785e25dfdc94b8296a0a2bcc75d2f44f93543d0eb4236a0efa5add87fc97a
[  294.137824] DEBUG: Extending PCR state with passed argument #5 hash: bb2ff5833f90c09916fb972f49963653cf207cc65033276d458e00ce31d4b3d7
[  294.259655] DEBUG: Extending PCR state with passed argument #6 hash: bc172d6c3551a44fbd6beef7ebbb2d4fa1452c46fcfdeebef1c519f13d668f1b
[  294.400277] DEBUG: Extending PCR state with passed argument linuxboot#7 hash: bf037ed20105da5af9affb40353a4bccc9c8e69f2b03b81260573821ccbfa6d8
[  294.514983] DEBUG: Extended final PCR state: ab50d5acd93870448844392a2582099650614e0c75f3b6c3f3a5f7a811ab3bca
[  294.561181] DEBUG: Replayed cbmem -L clean boot state of PCR=2 ALG=sha256 : ab50d5acd93870448844392a2582099650614e0c75f3b6c3f3a5f7a811ab3bca
[  294.699187] TRACE: Under /bin/tpmr
[  294.765450] TRACE: Under /bin/tpmr:recalculate_firmware_pcr_from_cbfs
[  294.812153] TRACE: Under /bin/tpmr:read_and_pad_FMAP_from_cbmem
[  295.853558] TRACE: Under /bin/tpmr:calc_pcr
[  295.909978] TRACE: Under /bin/tpmr:extend_pcr_state
[  295.955343] DEBUG: Initial PCR state: 0000000000000000000000000000000000000000000000000000000000000000
[  296.036572] DEBUG: Extending PCR state with passed argument #1 hash: 02778dad5303b911adc8828cf5101a251a9b2a5a2b711a44159fb89a5a0b5198
[  296.196037] DEBUG: Extending PCR state with passed argument #2 hash: 5444dba991b48df882ed1e2b85f0c90f947f6c7f8ed3dd6c91dc70dd661b66cb
[  296.364665] DEBUG: Extending PCR state with passed argument #3 hash: 13d3cacde02deff3d5e1ae2b52e5647c67046fb359b58d3899365a87a7161090
[  296.528953] DEBUG: Extending PCR state with passed argument #4 hash: cea785e25dfdc94b8296a0a2bcc75d2f44f93543d0eb4236a0efa5add87fc97a
[  296.683826] DEBUG: Extending PCR state with passed argument #5 hash: bb2ff5833f90c09916fb972f49963653cf207cc65033276d458e00ce31d4b3d7
[  296.843403] DEBUG: Extending PCR state with passed argument #6 hash: bc172d6c3551a44fbd6beef7ebbb2d4fa1452c46fcfdeebef1c519f13d668f1b
[  297.011405] DEBUG: Extending PCR state with passed argument linuxboot#7 hash: bf037ed20105da5af9affb40353a4bccc9c8e69f2b03b81260573821ccbfa6d8
[  297.142107] DEBUG: Extended final PCR state: ab50d5acd93870448844392a2582099650614e0c75f3b6c3f3a5f7a811ab3bca
[  297.200198] DEBUG: Replayed cbmem -L clean boot state of PCR=2 ALG=sha256 : ab50d5acd93870448844392a2582099650614e0c75f3b6c3f3a5f7a811ab3bca
[  297.375755] DEBUG: Original TPM PCR2 value:     2 : 0xAB50D5ACD93870448844392A2582099650614E0C75F3B6C3F3A5F7A811AB3BCA
[  297.438635] DEBUG: TPM event log reported by cbmem -L: coreboot TPM log:
[  297.472275]
[  297.514744] PCR-2 02778dad5303b911adc8828cf5101a251a9b2a5a2b711a44159fb89a5a0b5198 SHA256 [FMAP: FMAP]
[  297.559260] PCR-2 5444dba991b48df882ed1e2b85f0c90f947f6c7f8ed3dd6c91dc70dd661b66cb SHA256 [CBFS: bootblock]
[  297.594767] PCR-2 13d3cacde02deff3d5e1ae2b52e5647c67046fb359b58d3899365a87a7161090 SHA256 [CBFS: fallback/romstage]
[  297.632653] PCR-2 cea785e25dfdc94b8296a0a2bcc75d2f44f93543d0eb4236a0efa5add87fc97a SHA256 [CBFS: fallback/postcar]
[  297.688218] PCR-2 bb2ff5833f90c09916fb972f49963653cf207cc65033276d458e00ce31d4b3d7 SHA256 [CBFS: fallback/ramstage]
[  297.723743] PCR-2 bc172d6c3551a44fbd6beef7ebbb2d4fa1452c46fcfdeebef1c519f13d668f1b SHA256 [CBFS: bootsplash.jpg]
[  297.760327] PCR-2 bf037ed20105da5af9affb40353a4bccc9c8e69f2b03b81260573821ccbfa6d8 SHA256 [CBFS: fallback/payload]
[  297.823487] DEBUG: Calculated TPM PCR2 value from files: ab50d5acd93870448844392a2582099650614e0c75f3b6c3f3a5f7a811ab3bca
[  297.872171] DEBUG: Measured boot from TPM event log: ab50d5acd93870448844392a2582099650614e0c75f3b6c3f3a5f7a811ab
[  297.905953] 3bca
[  297.955757] DEBUG: Measured boot from content measured by coreboot: ab50d5acd93870448844392a2582099650614e0c75f3b6c3f3a5f7a811ab3bca
Failed: TPM event log does not match content measured by coreboot
[  298.008151]  !!! ERROR: TPM event log does not match content measured by coreboot !!!

the 3cba on second line is weird. Close but not good enough

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
@tlaurion tlaurion force-pushed the WiP_introspection-replicate_PCR_content_from_runtime branch from ad79a93 to bf7677c Compare January 5, 2024 17:50
@tlaurion tlaurion marked this pull request as draft January 25, 2024 20:07
@tlaurion
Copy link
Collaborator Author

Interesting helpers at TrenchBoot/qubes-antievilmaid#11

@tlaurion
Copy link
Collaborator Author

tlaurion commented Aug 12, 2024

@DemiMarie thanks for the early code review, but the reason I poked you here was to get your input on how trivial it is today to tamper bootblock and measured boot together, with end PCR bank values sealed/unsealed for secret release. How quotes would make it better, not really to get code review on PoC code material.

This PR lay down the technical details for anyone to tamper coreboot measured boot scheme (either tamper with coreboot bootblock + phases to report their prior known hardcoded hashes instead of passing content to be hashed that extend PCR today), alongside with also hacking Heads to hardcode LUKS header hash, CBFS generated+injected pubring + trustdb+config overrides (PCR7), kernel module hashes (PCR5) to permit, while passing real TPM DUK passphrase of the end user (rate limited), to unseal LUKS key to final OS through additional cpio passed to kexec call to final OS, so end users type Disk Encryption Key (TPM DUK) related secret in a known safe space.

In other words: how to attack this and pass from "bootblock based root of trust theoretically flawed and unfit" to a successful attack showing measured boot + Heads(sealing/unsealing both firmware remote attestation TPMTOTP and runtime attestation prior of TPM DUK unsealing with TPM DUK passphrase) not good enough AND leading to TPM DUK being released into cpio passed to kexec call with user provided TPM DUK nvram region, authenticated with both replayed (tampered) measurements and proper nvram passphrase, leading to save that passphrase somewhere or saving TPM released DUK key somewhere to capture, and how all of this would not leave an attacked to implant a keyboard sniffer instead and where any of what is discussed here would change anything anyway, and is the simplest attack an attacker would do to simply implant and come back next days to steal the computer altogether, not having to do any of the complex stuff we are talking about here.


For reference, see https://forum.qubes-os.org/t/discussion-on-purism/2627/158 which points back here.
I have left enough e-ink everywhere and nobody actually used this PR code to prove theoretical attack becoming practical, and where safeguarding bootblock behind WP/externally enforced tamper evidence would be a solution to all of this.


Also note and follow: https://forum.qubes-os.org/t/flashkeeper-the-solution-to-spi-flash-firmware-tampering/28028/5

“FlashKeeper: where SpiSpy meets Stateless Laptop jaded dreams: A retrofit plan first” will take place at 09-20, 15:10 in Social Hub Main Room.

Which will be presented/design decisions challenged at QubesOS mini-summit 2024 where I will present and have a chance to discuss all of this in details, maybe even around a beer later on at night. @DemiMarie : looking forward to this.
-> https://www.qubes-os.org/news/2024/08/11/qubes-os-summit-2024-tickets-now-available/


MEANWHILE TECHNICAL PEOPLE, I remind you that you can play with qemu-whiptail-tpm1/tpm2 board configs directly today: which enforces a sniffable (pcap) virtual TPM, a virtual OpenGPG card, everything needed basically test all of this without needing any physical hardware to render an evil maid PoC based on this PR PoC and follow the white rabiit in this hole, equipped only with docker ce alone to build reproducible Heads images right now and provide practical PoC of an evil maid attack.

Follow:

  • https://github.com/linuxboot/heads/blob/master/targets/qemu.md#swtpm-on-nix-docker-image
  • ie
    • docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) tlaurion/heads-dev-env:latest -- make BOARD=qemu-coreboot-whiptail-tpm2
    • docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) tlaurion/heads-dev-env:latest -- make BOARD=qemu-coreboot-whiptail-tpm2 run
    • Do OEM Factory Resetf wizard, follow notes in referred link above on how to extract public key from emulated SUB Thumb drive (losetup, mount, cp under heads dir), then point to it in next command
    • docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) tlaurion/heads-dev-env:latest -- make BOARD=qemu-coreboot-whiptail-tpm2 PUBKEY_ASC=<path_to_key.asc> inject_gpg
    • docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) tlaurion/heads-dev-env:latest -- make BOARD=qemu-coreboot-whiptail-tpm2 PUBKEY_ASC=<path_to_key.asc> run
    • You will of course need to follow ISO OS install notes in above referred docs (just point to iso in heads local dir) to fully test TPM DUK etc on a working simulated setup following https://osresearch.net/InstallingOS/#generic-os-installation
  • other usage notes in that direct link, above.
    This will provide OP similar TRACE+DEBUG output traces on dual consoles, permitting you to hack this efficiently. So please do it.

Bounty tag added (I won't pay, who would?)
IF you prove this flawed practically, the whole coreboot ecosystem, Heads and all coreboot enforced, reasonably secure platforms would benefit of that vuln, you would have a CVE in your name and shake the future of trustworthy computing forever for the better. So please do it if you think bootblock enforced RoT is not enough.

@tlaurion tlaurion added UX server linux Bounty Work could be funded labels Aug 12, 2024
@DemiMarie
Copy link

@tlaurion Bootblock-based root of trust is already known to be broken unless either Intel Boot Guard/AMD Platform Secure Boot is in use or the bootblock cannot be tampered with. Chromebooks ensure this by putting it in a SPI chip with the write protect pin always enabled in hardware.

@tlaurion
Copy link
Collaborator Author

tlaurion commented Nov 3, 2024

Prerequisite was merged #1824

@tlaurion
Copy link
Collaborator Author

tlaurion commented Nov 3, 2024

This is prerequisite for #1827 (comment)

Reasoning:
To be able to seal TOTP/HOTP/TPM DUK without using TPM measured boot logs or actual measurements, there needs to be mechanisms to extract info from firmware to simulate what would be in TPM PCR banks for forward sealing.

Practical needs here outside of a firmware upgrade:

  • OEM factory reset needs to be able to forward seal config.user + pub keyring + trustdb into TPMTOTP+HOTP + LUKS header + TPM DUK prior of reboot so that TPMTOTP+HOTP+TPM DUK are valid upon reboot without further action from OEM
  • User reownership needs the same as OEM

On firmware upgrade:

  • Heads needs to be able to forward seal TPM PCR2 measured boot event log expected measurements, alongside of above OEM/Re-ownership changes highlighted above.

In lack of doing so, Heads UX stays complicated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants