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

Use the Librem Key as a TPM work-alike in the absence of a TPM #493

Closed
wants to merge 5 commits into from

Conversation

kylerankin
Copy link
Collaborator

On machines without a TPM, we'd still like some way for the BIOS to attest that it has not been modified. With a Librem Key, we can have the BIOS use its own ROM measurement converted to a SHA256sum and truncated so it fits within an HOTP secret. Like with a TPM, a malicious BIOS with access to the correct measurements can send pre-known good measurements to the Librem Key.

This approach provides one big drawback in that we have to truncate the SHA256sum to 20 characters so that it fits within the limitations of HOTP secrets. This means the possibility of collisions is much higher but again, an attacker could also capture and spoof an existing ROM's measurements if they have prior access to it, either with this approach or with a TPM.

On machines without a TPM, we'd still like some way for the BIOS to
attest that it has not been modified. With a Librem Key, we can have the
BIOS use its own ROM measurement converted to a SHA256sum and truncated
so it fits within an HOTP secret. Like with a TPM, a malicious BIOS with
access to the correct measurements can send pre-known good measurements
to the Librem Key.

This approach provides one big drawback in that we have to truncate the
SHA256sum to 19 characters so that it fits within the limitations of
HOTP secrets. This means the possibility of collisions is much higher
but again, an attacker could also capture and spoof an existing ROM's
measurements if they have prior access to it, either with this approach
or with a TPM.
The flash script had a minor bug that stopped SHA mode from working and
also needed the flashrom output suppressed. The seal and unseal modes
for the Librem Key needed 20 characters from the SHA instead of 19.
For users who want to use a TOTP QR code as a backup to a Librem Key,
this will add similar support to that mode
@tlaurion
Copy link
Collaborator

tlaurion commented Dec 9, 2018

Tested this on KGPE-D16 with unreliable results, since for some reason, the kgpe-d16 coreboot configuration with CONFIG_RELOCATABLE_RAMSTAGE breaks boot. Also note that CBMEM console output would need to be disabled in all coreboot configs.

My insight on this is that extracting all rom for integrity attestation may not be the right solution. For example, on the kgpe-d16, we have 16MB of rom, which takes around 60 seconds to extract. I haven't tested this on the x200 yet, but will at the end of this week.

What I would propose would be:

  • export in board config a list of blacklisted modules to skip measurements for (eg: kgpe-d16: s3nv since it changes at each boot)
  • list rom files with cbfs --list
  • loop in module list, extract unblacklisted modules files and sha256sum them on the fly, keeping new_value = Hash(old_value || new_measurement))
  • truncate final hash and store it in HOTP.

@kylerankin @flammit : any thoughts?

@tlaurion
Copy link
Collaborator

On KGPE-D16 s3nv, from Timothy Pearson on coreboot ML

The memory is not (and cannot be) retrained, the
previous settings are loaded from the s3nv region of Flash (this is also
why the settings change on each boot -- the last known good training
data is loaded into Flash to support resume from suspend).

My understanding is that because the current coreboot native AMD
codebase doesn't support relocatable ramstage (yet?) we're hitting a
slow path somewhere in resume.  I think there was some work being put
into adding the relocateable ramstage support but I don't know current
status.

@tlaurion
Copy link
Collaborator

tlaurion commented Dec 26, 2018

@kylerankin:

I'm playing around and exploring options. Testing the following gives faster reads and consistent results, while not perfect yet.

You can cherry-pick this and adapt.

@tlaurion
Copy link
Collaborator

@kylerankin :

I updated my small PoC to extend measured modules

Here is the modules present in x200 coreboot 4.9:

FMAP REGION: COREBOOT
Name                           Offset     Type           Size   Comp
cbfs master header             0x0        cbfs header        32 none
fallback/romstage              0x80       stage           53836 none
cpu_microcode_blob.bin         0xd340     microcode       49152 none
fallback/ramstage              0x193c0    stage           88270 none
cmos_layout.bin                0x2ed00    cmos_layout      1664 none
fallback/postcar               0x2f3c0    stage           14920 none
fallback/dsdt.aml              0x32e40    raw             14207 none
data_ccfl.vbt                  0x36640    raw              1501 LZMA (3854 decompressed)
data_led.vbt                   0x36c80    raw              1439 LZMA (3863 decompressed)
fallback/payload               0x37280    simple elf    6483537 none
(empty)                        0x666140   null           628824 none
bootblock                      0x6ff9c0   bootblock         976 none

Built lenovo/x200 (ThinkPad X200)

	** WARNING **
coreboot has been built without an Intel Firmware Descriptor.
Never write a complete coreboot.rom without an IFD to your
board's flash chip! You can use flashrom's IFD or layout
parameters to flash only to the BIOS region.

Here are the modules present in kgpe-d16 coreboot 4.9:

FMAP REGION: COREBOOT
Name                           Offset     Type           Size   Comp
cbfs master header             0x0        cbfs header        32 none
fallback/romstage              0x80       stage          173132 none
config                         0x2a540    raw               613 none
revision                       0x2a800    raw               561 none
cmos.default                   0x2aa80    cmos_default      256 none
cmos_layout.bin                0x2abc0    cmos_layout      3524 none
fallback/dsdt.aml              0x2b9c0    raw              9895 none
(empty)                        0x2e0c0    null             7384 none
s3nv                           0x2fdc0    raw             65536 none
fallback/ramstage              0x3fe00    stage           88189 none
fallback/payload               0x556c0    simple elf    6310996 none
microcode_amd.bin              0x65a380   microcode       12684 none
microcode_amd_fam15h.bin       0x65d580   microcode        7876 none
(empty)                        0x65f4c0   null         10092568 none
bootblock                      0xfff500   bootblock        2232 none

else
# without a TPM, use the first 20 characters of the ROM SHA256sum
echo "TPM not configured, measuring ROM directly"
flash.sh -s /tmp/coreboot.rom | cut -c 1-20 | tr -d '\n' > $TOTP_SECRET
Copy link

Choose a reason for hiding this comment

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

Why truncate the hash prematurely? Could you not get the full 120 bits of the HOTP with something like

Suggested change
flash.sh -s /tmp/coreboot.rom | cut -c 1-20 | tr -d '\n' > $TOTP_SECRET
secret="`flash.sh -s /tmp/coreboot.rom | xxd -r -p | base32 | cut -c 1-24 | tr -d '\n'`"

(i.e., decode the base16 string then re-encode as base32)?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@kylerankin thoughts?

@tlaurion
Copy link
Collaborator

@kylerankin: did I dream or did the HOTP code got upgraded to permit bigger HOTP size?

@tlaurion
Copy link
Collaborator

tlaurion commented Apr 27, 2019

@kylerankin

Confirmed for Nitrokey storage: Nitrokey/nitrokey-storage-firmware#85
Commit: Nitrokey/nitrokey-storage-firmware@ec5c0c1

Opened ticket for Nitrokey Pro: Nitrokey/nitrokey-pro-firmware#59

Sent from my Galaxy S3 using FastHub-Libre

@tlaurion
Copy link
Collaborator

tlaurion commented Apr 28, 2019

@kylerankin : Confirmed 40 bytes (320 bits) for NitroKey Pro 0.8+ here and coming to NitroKey Storage next week.

So what do we do from here?

@tlaurion
Copy link
Collaborator

tlaurion commented May 25, 2019

@kylerankin, @jtracey:

Nitrokey permits firmware upgrade free of charge by sending units back to them. I guess Purism does the same?

Considering this.
If a user chooses to keep using his older version then 0.8, or wants to keep his actual GPG card for signing and email encryption with that key and buy a new one for integrity measurements...

I think we should in any case modify the actual code to take advantage of the upgraded HOTP size to 40 bytes by default, at least in this codepath, instead of trimming measurements down to 20 bytes.

Or even better, check firmware version and warn accordingly of truncation to 20 bytes if <0.8.

Let me know what you think.

Sent from my Galaxy S3 using FastHub-Libre

@tlaurion
Copy link
Collaborator

tlaurion commented Sep 15, 2020

@MrChromebox :
#493 (comment)
#493 (comment)

Firmware version difference to keep in consideration #493 (comment)

@MrChromebox
Copy link
Contributor

@tlaurion think it will be easier if I just push a new PR for this rather than trying to take over Kyle's. This one can be closed once I do

@kylerankin
Copy link
Collaborator Author

Closing this PR as we have a newer one that solves the same issue.

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.

5 participants