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 a USB security key as a TPM work-alike in the absence of a physical TPM #836

Closed

Conversation

MrChromebox
Copy link
Contributor

On machines without a TPM, we'd still like some way for the BIOS to
attest that it has not been modified. With a USB security 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 USB security 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.

This supersedes #493

Signed-off-by: Matt DeVillier matt.devillier@puri.sm

@tlaurion
Copy link
Collaborator

tlaurion commented Sep 17, 2020

@MrChromebox
20 chars limitation was fixed a long time ago in firmware, exposed here: #493 (comment) so no need to truncate prematurely sha256sum to 20 characters (can be 40 characters) in newer upstreamed firmware ( #493 (comment) ) and consequently produced Librem Keys/Nitrokey Pro versions manufactured since 2019.

Questions of how to deal with old keys is here: #493 (comment) with returns if users really want this from both Purism (@kylerankin ) /Nitrokey? (@jans23) ?

Else a big fat warning could be given to users if using a USB Security dongle's firmware (detectable) requiring to truncate secret in insecure ways, giving users a risk choice they should be clear about prior of using such technology for tamper evidence.

@tlaurion
Copy link
Collaborator

tlaurion commented Sep 17, 2020

@MrChromebox : i'm so confused by the build failing. Logs (now capture) saying that the compiler was killed. Too memory hungry?!

From :https://circleci.com/api/v1.1/project/github/MrChromebox/heads/11/output/127/0?file=true&allocation-id=5f628bc03ecc101f341bc0a2-0-build%2FCDC2F19

/bin/bash ../../gcc-8.3.0/gcc/../move-if-change tmp-automata.c insn-automata.c
g++ -fno-PIE -c   -O2  -fomit-frame-pointer -m64  -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE   -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings   -DHAVE_CONFIG_H -I. -I. -I../../gcc-8.3.0/gcc -I../../gcc-8.3.0/gcc/. -I../../gcc-8.3.0/gcc/../include -I../../gcc-8.3.0/gcc/../libcpp/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include  -I../../gcc-8.3.0/gcc/../libdecnumber -I../../gcc-8.3.0/gcc/../libdecnumber/dpd -I../libdecnumber -I../../gcc-8.3.0/gcc/../libbacktrace   -o ipa-hsa.o -MT ipa-hsa.o -MMD -MP -MF ./.deps/ipa-hsa.TPo ../../gcc-8.3.0/gcc/ipa-hsa.c
echo timestamp > s-automata
g++ -fno-PIE -c   -O2  -fomit-frame-pointer -m64  -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE   -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings   -DHAVE_CONFIG_H -I. -I. -I../../gcc-8.3.0/gcc -I../../gcc-8.3.0/gcc/. -I../../gcc-8.3.0/gcc/../include -I../../gcc-8.3.0/gcc/../libcpp/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include  -I../../gcc-8.3.0/gcc/../libdecnumber -I../../gcc-8.3.0/gcc/../libdecnumber/dpd -I../libdecnumber -I../../gcc-8.3.0/gcc/../libbacktrace   -o ipa-ref.o -MT ipa-ref.o -MMD -MP -MF ./.deps/ipa-ref.TPo ../../gcc-8.3.0/gcc/ipa-ref.c
g++ -fno-PIE -c   -O2  -fomit-frame-pointer -m64  -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE   -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings   -DHAVE_CONFIG_H -I. -I. -I../../gcc-8.3.0/gcc -I../../gcc-8.3.0/gcc/. -I../../gcc-8.3.0/gcc/../include -I../../gcc-8.3.0/gcc/../libcpp/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include  -I../../gcc-8.3.0/gcc/../libdecnumber -I../../gcc-8.3.0/gcc/../libdecnumber/dpd -I../libdecnumber -I../../gcc-8.3.0/gcc/../libbacktrace   -o ipa-utils.o -MT ipa-utils.o -MMD -MP -MF ./.deps/ipa-utils.TPo ../../gcc-8.3.0/gcc/ipa-utils.c
g++ -fno-PIE -c   -O2  -fomit-frame-pointer -m64  -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE   -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings   -DHAVE_CONFIG_H -I. -I. -I../../gcc-8.3.0/gcc -I../../gcc-8.3.0/gcc/. -I../../gcc-8.3.0/gcc/../include -I../../gcc-8.3.0/gcc/../libcpp/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include  -I../../gcc-8.3.0/gcc/../libdecnumber -I../../gcc-8.3.0/gcc/../libdecnumber/dpd -I../libdecnumber -I../../gcc-8.3.0/gcc/../libbacktrace   -o ipa.o -MT ipa.o -MMD -MP -MF ./.deps/ipa.TPo ../../gcc-8.3.0/gcc/ipa.c
g++ -fno-PIE -c   -O2  -fomit-frame-pointer -m64  -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE   -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings   -DHAVE_CONFIG_H -I. -I. -I../../gcc-8.3.0/gcc -I../../gcc-8.3.0/gcc/. -I../../gcc-8.3.0/gcc/../include -I../../gcc-8.3.0/gcc/../libcpp/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include -I/root/project/build/coreboot-4.12/util/crossgcc/xgcc/include  -I../../gcc-8.3.0/gcc/../libdecnumber -I../../gcc-8.3.0/gcc/../libdecnumber/dpd -I../libdecnumber -I../../gcc-8.3.0/gcc/../libbacktrace   -o ira.o -MT ira.o -MMD -MP -MF ./.deps/ira.TPo ../../gcc-8.3.0/gcc/ira.c
g++: fatal error: Killed signal terminated program cc1plus
compilation terminated.
make[1]: *** [Makefile:1110: insn-emit.o] Error 1
make[1]: *** Waiting for unfinished jobs....
/bin/bash ../../gcc-8.3.0/gcc/../move-if-change tmp-attrtab.c    insn-attrtab.c
/bin/bash ../../gcc-8.3.0/gcc/../move-if-change tmp-dfatab.c     insn-dfatab.c
/bin/bash ../../gcc-8.3.0/gcc/../move-if-change tmp-latencytab.c insn-latencytab.c
echo timestamp > s-attrtab
rm gcc.pod
make[1]: Leaving directory '/root/project/build/coreboot-4.12/util/crossgcc/build-i386-elf-GCC/gcc'
make: *** [Makefile:4244: all-gcc] Error 2

@tlaurion
Copy link
Collaborator

Not a cryptographer here, but my intuition is that it might be better to use sha1sum vs sha256sum (tpm 1.1 measurements are sha1 anyway, so would be equivalent) resulting in hash that would fit under those 40 chars buffer that we have available.

Better to truncate a 64 char into 40 (or worse, twenty...) or use lower checksuming techniques to fill buffer available?

elif [ "$SHA" -eq 1 ]; then
flashrom $CONFIG_FLASHROM_OPTIONS -r "${ROM}" 1&>2 >/dev/null \
|| die "$ROM: Read failed"
sha256sum ${ROM} | cut -f1 -d ' '
Copy link
Collaborator

@tlaurion tlaurion Sep 17, 2020

Choose a reason for hiding this comment

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

sha1sum fitting in available 40 chars as per TPM 1.1 equivalent?

echo -e "\nTPM not detected; measuring ROM directly\n" 1>&2
# use a previously-copied image if it exists
if [ -f ${ROM_IMAGE} ]; then
sha256sum ${ROM_IMAGE} | cut -f1 -d ' ' | cut -c 1-20 | tr -d '\n'
Copy link
Collaborator

Choose a reason for hiding this comment

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

sha1sum fitting in 40 char?

if [ -f ${ROM_IMAGE} ]; then
sha256sum ${ROM_IMAGE} | cut -f1 -d ' ' | cut -c 1-20 | tr -d '\n'
else
flash.sh -s ${ROM_IMAGE} | cut -c 1-20 | tr -d '\n'
Copy link
Collaborator

Choose a reason for hiding this comment

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

No need to cut if sha1sum instead of sha256sum and firmware 0.8+?

@@ -44,6 +44,13 @@ hwclock -l -s
. /etc/functions
. /etc/config

# set CONFIG_TPM dynamically before init
if [ -e /dev/tpm0 ]; then
Copy link
Collaborator

Choose a reason for hiding this comment

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

What if TPM lines are cut? What is the behavior and conditional codepath effects here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd assume that a TPM with cut lines would behave exactly like a device without a TPM, since there would be no communication and /dev/tpm0 would not exist

Copy link
Collaborator

Choose a reason for hiding this comment

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

@MrChromebox my point here is that since the codepath is dynamic and not set inside of ROM inside of /etc/config anymore, cutting the lines of TPM would simply result in a different codepath without the user knowing the his TPM lines were cut, and from the LIBREM KEY/ Nitrokey Pro Nitrokey Storage being used for validation. I'm not sure this is desirable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the user would absolutely be notified, since there would be text indicating no TPM on the main menu, and LK/NK verification would fail as the secret would have changed from the TPM-backed one to the hash-based one.

if [ -e /dev/tpm0 ]; then
echo "CONFIG_TPM=y" >> /etc/config.user
else
echo "CONFIG_TPM=n" >> /etc/config.user
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not measured. No change detected.

else
echo "CONFIG_TPM=n" >> /etc/config.user
fi

combine_configs
Copy link
Collaborator

Choose a reason for hiding this comment

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

Combined in ram, no change detected.

Copy link
Collaborator

@tlaurion tlaurion Aug 18, 2022

Choose a reason for hiding this comment

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

Point here is what is in cbfs is measured, but not the result of combine_configs, where the result is taken as the new applied config ( next line importing the actual config . /tmp/config)

@jans23
Copy link

jans23 commented Sep 17, 2020

Questions of how to deal with old keys is here: #493 (comment) with returns if users really want this from both Purism (@kylerankin ) /Nitrokey? (@jans23) ?

Loosing backward compatibility to old Nitrokeys is ok for me.

@kylerankin
Copy link
Collaborator

kylerankin commented Sep 18, 2020 via email

@MrChromebox
Copy link
Contributor Author

@tlaurion @jans23: Kyle and I tested here, and all our of LKs are using firmware >= 0.8, so they all support 40-byte keys. So we're fine dropping support for/breaking older NK/LK firmwares.

I'll update the PR to use 40-byte truncation; Kyle and I agree that SHA256 truncated is still better than SHA1 not.

@tlaurion
Copy link
Collaborator

tlaurion commented Oct 2, 2020

@MrChromebox could you rebase on master to trigger a build please?

Dynamically set CONFIG_TPM at boot based on the presence of /dev/tpm0.
This allows the same board/device with and without a TPM to be handled
by a single board definition and single firmware image. It also eliminates
the need to explictly define CONFIG_TPM in board config files.

Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
On machines without a TPM, we'd still like some way for the BIOS to
attest that it has not been modified. With a USB security 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 USB security key.

This approach provides one big drawback in that we have to truncate the
SHA256sum to 40 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.

Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
@tlaurion
Copy link
Collaborator

@MrChromebox Is the librem_mini taking a change in its board config, or should you provide an additional board config added in CircleCI to be able to test this platform and being pushed at the same time to give example for future platform integrations?

@tlaurion
Copy link
Collaborator

tlaurion commented Oct 16, 2020

@jans23 @MrChromebox @alex-nitrokey @kylerankin:

Shouldn't this feature be activated per additional boards, by explicitely specifying its configuration flags, for all platforms not having a TPM where TPM-like remote attestation can be approximated with HOTPKEY module supported USB Security dongle? If this is the case, then code logic should check for:
export CONFIG_TPM=n && export CONFIG_HOTPKEY=y
before applying different codepaths.

@MrChromebox I reviewed https://github.com/osresearch/heads/blob/master/boards/librem_mini/librem_mini.config#L25-L29 and it is there, but :

  • code is not validating that both export CONFIG_TPM=n && export CONFIG_HOTPKEY=y board configuration parameters are explicited.
  • I would also want to see in board config header differenciations for that board config for future port of other platforms, so that future developers can see in board config that this board has no TPM and requires HOTPKEY module supported USB Security dongle realize its function (Opening port for X200 and other vTPM deactivated boards by Intel ME deactivation)

@MrChromebox
Copy link
Contributor Author

@MrChromebox Is the librem_mini taking a change in its board config, or should you provide an additional board config added in CircleCI to be able to test this platform and being pushed at the same time to give example for future platform integrations?

I'm not understanding this question at all. There is a single librem_mini board config. It does not have a TPM. It will always use a HOTP key.

@MrChromebox
Copy link
Contributor Author

part of the issue here is that there is no handling for boards without a TPM (or with a deactivated vTPM) -- they just fail miserably because /dev/tpm0 doesn't exist. I'm happy to split this into two PRs -- handing of boards without a TPM, and handling of boards without a TPM and with a HOTP key, but we need to define what the former looks like first

@tlaurion
Copy link
Collaborator

@MrChromebox Is the librem_mini taking a change in its board config, or should you provide an additional board config added in CircleCI to be able to test this platform and being pushed at the same time to give example for future platform integrations?

I'm not understanding this question at all. There is a single librem_mini board config. It does not have a TPM. It will always use a HOTP key.

Sorry for the confusion @MrChromebox, I wrote this prior of reviewing board.

After reviewing board config, my point here is to clearly state what makes it different as a board in terms of configuration: without a TPM while requiring HOTPKEY supported USB Security dongle.

@tlaurion
Copy link
Collaborator

part of the issue here is that there is no handling for boards without a TPM (or with a deactivated vTPM) -- they just fail miserably because /dev/tpm0 doesn't exist. I'm happy to split this into two PRs -- handing of boards without a TPM, and handling of boards without a TPM and with a HOTP key, but we need to define what the former looks like first

@MrChromebox Agreed that there are some codepaths not dealing properly with boards without a TPM. My tests back in 2018 with the KGPE-D16 and x200 were with generic-init, so I have not thoroughly tested newer gui-init post #477

@tlaurion
Copy link
Collaborator

We will have to reflect on a way to disable hid functions of USB Security dongles inside of heads guys!
@MrChromebox @jans23 @szszszsz @alex-nitrokey @daringer @kylerankin

@szszszsz
Copy link
Contributor

Hi @tlaurion ! Could you elaborate on disabling the HID interface mentioned in #836 (comment)? I do not see such need coming from this ticket context, unless I am missing something.

@tlaurion
Copy link
Collaborator

tlaurion commented Oct 19, 2020

Hi @tlaurion ! Could you elaborate on disabling the HID interface mentioned in #836 (comment)? I do not see such need coming from this ticket context, unless I am missing something.

@MrChromebox @jans23 @szszszsz @alex-nitrokey @daringer @kylerankin: it's not specific to this PR, but HID without TPM released Disk Unlock Key opens the door to rubber ducky attacks where Heads could be instructed to go into recovery (early 'r' keypress, for example), sed files and reenter GUI by calling gui-init, showing measurements as being good and where Heads scripts are not validated for integrity at this point, being trusted solely per ROM measurements through flashrom backup when TPM is disabled (insufficient).

The only protection Heads offers on this codepath is that entering recovery changes PCR4, invalidating TPM released content, or through TPM based HOTP/TOTP remote attestation.

When TPM + TPM released Disk Unlock Key codepath is active, the user, even if receiving HOTP:Success, would still have to enter TPM nvram passphrase (valid only if attestation is good) to be able to boot system's default boot option. In this Disk Unlock Key released by TPM scenario, the HID based rubber ducky attacks would fail with the Disk Unlock Key passphrase typed correctly (which will only release secret if LUKS header+ TPM extended measurements is good and if Disk Unlock Key passphrase to unlock nvram is valid) being the last guard against booting that insecure environment.

In the current PR, if someone manages to create a rubber ducky with HID programmed to enter key presses, the screen would flicker, and shell scripts could be modified without the user being aware of it. Actual codepaths would validate the firmware parts through flashrom, not actual ramfs modified scripts, and boot into default boot option without TPM measurements being invalidated.

My point here is if there is no TPM released Disk Unlock key + this actual PR + USB Security dongle based firmware integrity validation, hid functions could invalidate Heads security without the user knowing, even more for platform activating USB early in init to support USB keyboards.

Do we have a way to not have HID feature (keyboard like permitted inputs) outside of deactivating USB support altogether (And USB Security dongle, HOTP if Disk Unlock Key is not supported when early USB Keyboard support is enabled while TPM is disabled and HOTP support is enabled ) ?

@alex-nitrokey
Copy link
Contributor

I do not know enough about it yet, to have a solution at hand, but honestly I am thinking about looking at this topic for some time. I was thinking about looking at how usbguard is working and if we can include something like this. On a clean boot there should be no new device plugged into the heads machine other than those present during initialization as we do not want any fiddling by an malicious device anyway. To conclude imho a blocking of unknown devices is a good idea anyway.

@szszszsz
Copy link
Contributor

  1. To add to Use a USB security key as a TPM work-alike in the absence of a physical TPM #836 (comment), perhaps we could add device authentication via OpenPGP to avoid vid:pid:sn triple spoofing, then accept its input.
  2. Another idea is to tunnel the HOTP requests to the USB Security dongle over CCID instead of HID.

@tlaurion
Copy link
Collaborator

My point here is that a rubber ducky specially crafted to fit Librem Key/Nitrokey Pro 3D printed shells to have green led flashing to simulate functionning could break the protection offered by this PR if hid is not blocked. Otherwise, vid:pid:sn triple spoofing can make KO this security mechanism.

1. To add to [#836 (comment)](https://github.com/osresearch/heads/pull/836#issuecomment-712713397), perhaps we could add device authentication via OpenPGP to avoid vid:pid:sn triple spoofing, then accept its input.

Authentication is a good idea only if #771 is implemented and user has a backup of his private key he can reinject at will in a USB Securty dongle replacement if prior is lost, else he locks himself out of Heads. Not desirable.

2. Another idea is to tunnel the HOTP requests to the USB Security dongle over CCID instead of HID.

I think this one is the better approach. While HID still needs to be somehow disabled inside of Heads (no input accepted from USB Security dongle) else sed is going to win.

  1. Another approach here would be to implement not only /boot measurements, but all shell scripts measurements prior of permitting boot. WIP: Shellcheck script files in initrd #862 is going that path setting the basis. We could definitely have an extended validation inside of Heads; reusing the concept of hashes, produced by the build system as of now as an example, and be able, at the moment of booting system default, to revalidate that ramfs scripts are still valid.

Thoughts? @MrChromebox @jans23 @szszszsz @alex-nitrokey @daringer @kylerankin:

@MrChromebox
Copy link
Contributor Author

I think this one is the better approach. While HID still needs to be somehow disabled inside of Heads (no input accepted from USB Security dongle) else sed is going to win.

agreed. Problem is, how do we do that effectively? Using a blocklist for HID would mean newer security dongles would require a Heads update to be fully secure

@tlaurion
Copy link
Collaborator

tlaurion commented Oct 25, 2020

I think this one is the better approach. While HID still needs to be somehow disabled inside of Heads (no input accepted from USB Security dongle) else sed is going to win.

agreed. Problem is, how do we do that effectively? Using a blocklist for HID would mean newer security dongles would require a Heads update to be fully secure

Well... FWUPD firmware upgrades are around the corner, in all cases. :) And newer produced USB Security dongles should be provided after newer Heads firmwares being deployed in all case. HID ID can be faked, btw. I have no solution for that problem, unfortunately, as of now. Disk Unlock Key released by the TPM is the true last line of protection here, not being released if recovery shell was accessed.

I have no idea how to replicate such solution in a TPM-less platform, since USB device cannot be considered truly in the root of trust, being accessible too late to accomplish the same result from tools that could be already compromised. The issue here is HID keyboard being permitted inside of Heads prior of HOTP challenge being made.

tlaurion added a commit to tlaurion/heads that referenced this pull request Oct 29, 2020
Based on past work https://github.com/tlaurion/heads/tree/x200_readd

TODO:
- upgrade coreboot to 4.12
- upgrade kernel to 5.x
- Test and merge linuxboot#836

Addresses linuxboot#878
tlaurion added a commit to tlaurion/heads that referenced this pull request Oct 29, 2020
Based on past work https://github.com/tlaurion/heads/tree/x200_readd

TODO:
- upgrade coreboot to 4.12
- upgrade kernel to 5.x
- Test and merge linuxboot#836

Addresses linuxboot#878
tlaurion added a commit to tlaurion/heads that referenced this pull request Oct 30, 2020
Based on past work https://github.com/tlaurion/heads/tree/x200_readd

- musl-cross-make updated to latest
  - -Wno-address-of-packed-member added to coreboot config

TODO:
- upgrade coreboot to 4.12
- upgrade kernel to 5.x
- Test and merge linuxboot#836

Addresses linuxboot#878
@daringer
Copy link
Collaborator

daringer commented Jan 17, 2021

The flaws, both theoretical(HID keyboard Rubber Ducky going in recovery, sedding bash scripts in a blink of an eye and going back to gui) and now the practically proven flaws we now all know would be easy to deploy, is all known prior of merging.

No discussion from my side, strong and true arguments. On the other hand, as you also said, this decision is not exclusively a technical decision. So, not to drag this out too much, I will vote yes and hereby briefly outline why:

  • TPM2 (or in general future hardware) will introduce other drawbacks (e.g., ME cannot be disabled, or is even needed...) so Heads has sooner or later to cope with different levels of security
  • Added security is imho better than no-added security (as long as the level of security is transparent)
  • Keeping development resources and knowledge together inside Heads, i.e., non-tpm improvements will increase security for both: tpm-driven and non-tpm Heads installations (as otherwise likely (worst-case even closed) forks will partly split resources)

Therefore my likely not too heavy vote is 👍

@lrvick
Copy link

lrvick commented Jan 17, 2021

Having read the entire thread and caught up, my (potentially wrong) TLDR of both sides is:

  1. A TPM-Free solution lacks any defense against evil maid attacks all historically supported devices which include a TPM cover which theatens to make users mistake equivilant UX of different devices for equivilant security, which is bad and must be avoided.
  2. If a TPM-free solution can offer damage control to someone rooted by a remote adversary that stock firmware can not offer, then it has merit.

On point 1:

I think boot integrity solutions need to support more than binary pass/fail states to a user if not all potential configurations are equally secure.

Android for example solves the UX issues of different levels of boot trust with strict color codes:

  • YELLOW: Warning screen for LOCKED devices with custom root of trust set
  • ORANGE: Warning screen for UNLOCKED devices
  • RED (eio): Warning screen for dm-verity corruption

A user used to seeing green that now sees any other color would hopefully pause to read.

I will also note that older Android devices with weaker verified boot inforcements still get GREEN if all checks possible on the given hardware are satisfied. This is reasonable as the boot level responsible is read only and not user/attacker updatable and if -anything- in the boot path is updated, an OS wipe is forced as the TEE will no longer cooperate with the FDE handshake.

If heads could similarly inform a user accurately with clear UX of various security modes, alternate modes are OK IMO.

E.g.
"Your boot stack is reasonably well defended against tampering by remote or local adversaries" in TPM operation.
"Your boot stack is reasonably well defended against tampering by remote adversaries" in TPM-free operation.

Heads in TPM-free mode however can't really promise even the latter statement though.

As I undersand current implementations, the following two attacks are potentially viable when there is no TPM in play:

  1. A remote adversary could flash malicious Heads firmware that always shows verified boot was successful. Worse, it could DFU the nitrokey on next enumeration and flash a small/fast firmware that does nothing but blink green.
  2. A remote adversary could flash a firmware that blinks green -and- behaves as a usb rubber ducky on next enumeration with no hardware modifications.

Unless there are strong defenses to both of theses attacks in tpm-less operations I feel Heads offers little to no value there.

Honestly these attacks could be bad even when a TPM -is- in play if the firmware does not have a physical write protect and should be addressed either way, perhaps elsewhere. ( I have some ideas).

I am in favor of Heads supporting tpm-less devices only if paired with strong and immutable UX showing what classes of attack they are defended against beyond what stock BIOs would, but It it is not clear to me if this is really the case ATM.

Someone steer me straight if I am way off base here!

@jans23
Copy link

jans23 commented Feb 1, 2021

To me it's important that users are informed well. Such information during configuration of Heads would be good. Informing users who buy a system would be seller's responsibility.

I vote for "yes".

In order to understand the whole system's security: This article (in German) states that Librem Mini's flash chip could only be written at the very first boot after flashing. Is this true and is it a property of the chip itself or is another aspect of the system guaranteeing it?

@MrChromebox
Copy link
Contributor Author

This article (in German) states that Librem Mini's flash chip could only be written at the very first boot after flashing. Is this true and is it a property of the chip itself or is another aspect of the system guaranteeing it?

no idea where they got that idea from, but it would make updates nearly impossible (obviously) and I can't think of how someone would even implement such a restriction

@tlaurion
Copy link
Collaborator

tlaurion commented Feb 4, 2021

@kylerankin

I was pointed out to Purism's article by a technical journalist who was inquiring about the validity of the claim:

[...]you can now use a Librem Key in place of your TPM chip and get similar protection against tampering!

I pointed him here.

Will that blob post have an erratum?

Comment on lines +271 to +281
secret_from_rom_hash() {
local ROM_IMAGE="/tmp/coreboot-notpm.rom"

echo -e "\nTPM not detected; measuring ROM directly\n" 1>&2
# use a previously-copied image if it exists
if [ -f ${ROM_IMAGE} ]; then
sha256sum ${ROM_IMAGE} | cut -f1 -d ' ' | cut -c 1-40 | tr -d '\n'
else
flash.sh -s ${ROM_IMAGE} | cut -c 1-40 | tr -d '\n'
fi
}
Copy link
Collaborator

@tlaurion tlaurion Feb 5, 2021

Choose a reason for hiding this comment

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

@MrChromebox @daringer @jans23 @kylerankin @szszszsz @osresearch @fhvyhjriur @Tonux599 @Thrilleratplay @irelativism @blobless @lrvick

Current security of TPM-less hardware, secured solely by USB Security dongle if we merge this :

  1. Boot hardware secured by Librem Key/Nitrokey Pro/Nitrokey Storage on TPM-less supported devices. User owning those devices trusted marketing speech and left said hardware unattended because remotely attested with the USB Security dongle they keep diligently in their pockets. Press 'r' frenetically until reaching recovery shell. Plug formatted usb thumbdrive. Keep calm. If you are cought, you just wanted to see the security of the system, right? Play dumb. Be cute. Be prepared, plan accordingly. You're there for a maximum of 2 ~minutes with largest SPI flash hardware out there, the backup is actually taking 3 backups of the SPI with flashrom internally.
  2. Run the following from shell prompt/a script: mount-usb rw && flash.sh -r /media/backuped.rom && umount /media && poweroff. Wonder around, get back your USB dongle when screen goes off. Leave the scene with USB thumbdrive.
  3. Craft your own evil maid aimed rom at leasure. Tamper also with /boot content! If there is enough space in SPI flash of the hardware in question, add as much stuff as you need! Make scripts to copy them from decompressed initrd under /boot if not existing, modify Heads scripts to your liking so that signed digest verification lies to the user... If you want, you can craft an evil xen, kernel, initrd and grub config if you'd like, script enough so that next updates are still triggering a resign request. Or if the user is so blindly trusting the system, he might never notice that there is no /boot resign warnings after having updated /boot content... Know your target, plan accordingly.
  4. Obtain secret from backuped rom at leasure. That "secret" is used as remote attestation secret in the HOTP challenge with user's Nitrokey Pro/Nitrokey Storage/Librem Key, by running the following on obtained backuped.rom: sha256sum backuped.rom | cut -f1 -d ' ' | cut -c 1-40 | tr -d '\n'
  5. Replace the content of secret_from_rom_hash function commented here with the value obtained from precedent step, simply replacing secret in between the following quotes: echo "secret"
  6. Build your crafted rom. Put it back on usb thumbdrive as file new.rom
  7. Redo step 1 on unattended hardware because trusted by user that the rom is protected with his USB Security dongle kept securely with him.
  8. Run the following from shell/script: mount-usb rw && flash.sh /media/new.rom && umount /media && poweroff. This will take more time then step 2, since writing takes more time. Keep looking discretely at the screen for it to go dark. Get back your thumbdrive and leave for good.
  9. Be confident that on every next boot, HOTP challenge will succeed over Nitrokey Pro/Nitrokey Storage/Librem Key... until the user decides to upgrade firmware on said trusted hardware. Repeat at will on that hardware. Code was merged upstream under Heads. Keep in mind that all TPM-less hardware out there now supported by Heads can be hacked easily the same way by users bragging about their security dongles and the hardware you know doesn't have a TPM. Keep track of supported devices upstream (devices with boards configs having CONFIG_TPM=n and CONFIG_HOTPKEY=y), own them and test locally for guaranteed success!

Notes:

  • Part of Pureboot actual codebase since a year)
  • Advertised in April 2019 by Purism : "This means that if you have a Librem 13 version 2 or Librem 15 version 3 without a TPM, you can now use a Librem Key in place of your TPM chip and get similar protection against tampering!" (and a librem_mini, and people wants this for GM45 based boards...)

@osresearch : We merge? Please press the button if you will.
I can't merge without #361 + flash functions restrictions nor without #836 (comment) being implemented so that the user is well aware of the risks of this approach while leaving hardware unattended (blind trust)...

Without a TPM, I would reflash my x230-hotp-maximized rom on my laptop prior of each use when left unattended....

Copy link
Collaborator

Choose a reason for hiding this comment

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

hilarious (although realistic) story @tlaurion , my favorite:

Play dumb. Be cute. Be prepared, plan accordingly

but seriously: seeing which misconceptions this (not even upstream) patch has already produced,
I think I also re-cast my vote to "no". I still see a gap between Heads and coreboot+seabios in terms of security (no password, no hotp, not even the chance to check the firmware, no /boot signing), but have to admit that the whole: Heads-implies-another-level-of-security argument, is stronger than I expected.

@jans23
Copy link

jans23 commented Feb 5, 2021

Until recently I assumed the stated flash chip protection would be in place. Now I doubt this is true. In the case there is no flash chip protection I vote with "no".

@rugk
Copy link

rugk commented Mar 22, 2021

Backlink German article on the security of TPM-less Heads and Purism's Librem Mini including this discussion:
https://www.golem.de/news/purism-sicherheit-zweiter-klasse-im-librem-mini-2103-155007.html

Edit: And the Purism forum.

@tlaurion
Copy link
Collaborator

Any followup on recommendations #836 (comment) so that changes applied from Purism fork can be merged upstream here?

I think we all agree that TPM + HOTP is better then TPM-less (with simple oneliner hack). The question now is how to make the user aware in total transparency of the differences of the approaches and where.

@tlaurion
Copy link
Collaborator

tlaurion commented Oct 8, 2021

@kylerankin @MrChromebox update on last comment?

@MrChromebox
Copy link
Contributor Author

@tlaurion see my comments in #326. SMM locking via the payload isn't viable in Skylake and newer platforms

@tlaurion
Copy link
Collaborator

tlaurion commented Dec 7, 2021

@kylerankin @MrChromebox coule you write something on the difference between tpm enforced attestation vs USB security dongle without TPM support on heads-wiki so we can finally merge this in?

@kylerankin
Copy link
Collaborator

kylerankin commented Dec 7, 2021 via email

@tlaurion
Copy link
Collaborator

@kylerankin threat modeling section would be great?

@tlaurion
Copy link
Collaborator

tlaurion commented Apr 1, 2022

  1. To add to Use a USB security key as a TPM work-alike in the absence of a physical TPM #836 (comment), perhaps we could add device authentication via OpenPGP to avoid vid:pid:sn triple spoofing, then accept its input.

    1. Another idea is to tunnel the HOTP requests to the USB Security dongle over CCID instead of HID.

@szszszsz : #1145 removes USB_HID from kernel (putting it as module for Heads boards needing USB Keyboard support only), and it doesn't impact HOTP/GPG functions under Heads/Pureboot.

Am I missing something?

@tlaurion
Copy link
Collaborator

tlaurion commented Apr 5, 2022

@MrChromebox (@jans23 NitroKey rebrand? not sure) While not relevant to this ticket but still important since it was talked here in the past:

@tlaurion see my comments in #326. SMM locking via the payload isn't viable in Skylake and newer platforms

This X11 platform is actually enforcing platform locking even if Intel FSP initialized through patches (VaultBoot forks of Heads)

@irelativism
Copy link

you should look into something called TBM (TBM!=TPM), trusted boot module a project by whithebox systems and also supported by nlnet

@irelativism
Copy link

@tlaurion
Copy link
Collaborator

tlaurion commented Aug 18, 2022

@irelativism Thanks for the pointer. The challenge here, as with any additional external components doing measurements, is to have that device connected at a low level enough so that, in Heads case, coreboot can initialize such device soon enough (boot block preferred, write protected) to be able to have such component measure itself and next stages of the firmware.

On current existing devices, such components require simple communication protocols (LPC/I2C) to be able to talk with components existing on such buses. I checked the links you pointed out. This is linked to another discussion that I reveisited in the past months by mikebdp2 under #717 which back in time, missed his point and edited original reply under #717 (comment). It is true that a serial connection under early USB init could be accomplished under coreboot, and such USB device could be used to act as a USB alternative to TPM.

I welcome further discussions on the matter to happen under #717, not here.

@tlaurion
Copy link
Collaborator

@JonathonHall-Purism : I think this is time to revisit this PR.

A lot of things changed since this PR was first opened under #493

  • USB HID was a blocker. It is not exposed anymore from Nitrokey/Librem Key firmware somewhere after v.0.10?
  • Heads now requires the board configurations to specify if a usb keyboard is desired/required, and adds USB HID support only if requested per board config (to mitigate rubber ducky attacks)
  • HOTP secret size was increased in both firmware and in software

@kylerankin I requested in past comments a threat modeling note under heads wiki from Purism here


The reason I'm poking again here is that

As opposed to laptops that simply come/doesn't come with a TPM, those motherboards (as for Purism's and Nitrokey's mini (running on UEFI and tianocore as of now @jans23) would still require something along the lines of dynamic codepaths for TPM/no-tpm, as currently implemented in this PR at https://github.com/osresearch/heads/pull/836/files#diff-63d474ce25ab525343c0d061b286b1cd45199cd14fdf9ea535f396fd8be5de45R47. Using Heads (today) without a TPM is not so relevant, while having HOTP is better then nothing, even though nothing can prove thatthe firmwre wasn't tampered with to produce and feed the right measurement to HOTP alone without a TPM. But we would still need to be able to have boards that support TPM to be able to dynamically set CONFIG_TPM=n if no TPM is detected, instead of supporting multiple unique board configurations named -tpm/-no-tpm.

@jans23 @SergiiDmytruk @MrChromebox @JonathonHall-Purism @szszszsz : https://github.com/osresearch/heads/pull/836/files#diff-63d474ce25ab525343c0d061b286b1cd45199cd14fdf9ea535f396fd8be5de45R47 could be reused seperately, of course, but since the current states of Nitrokey Pro/Nitrokey Storage/Librem Key firmware and Heads have evolved to mitigate criticisms of this PR over time (some risks still existing for boards having CONFIG_HOTPKEY=y and export CONFIG_USB_KEYBOARD without a TPM detecting recovery shell access) I think it is time to rediscuss this PR in the goal of merging it, with proper thread modeling notes in board configurations themselves and in the threat model section of the wiki.

@SergiiDmytruk : Meanwhile, maybe a seperate PR might be needed to simply have TPM detected and having CONFIG_TPM deactivated at runtime as implemented under https://github.com/osresearch/heads/pull/836/files#diff-63d474ce25ab525343c0d061b286b1cd45199cd14fdf9ea535f396fd8be5de45R47 so that Talos II can have a single workstation board config and server board config, the same applying to kgpe-d16 boards reupstreaming efforts. Note that kgpe-d16 is having ps2 for keyboard/mouse, while Talos II is requiring USB for input in workstation mode, so that risks exposed above would also apply if another workstation board configuration is brought online to support add support to CONFIG_HOTP, since export CONFIG_USB_KEYBOARD is required. But again, the Talos II with/without TPM (and without CONFIG_HOTP) is a different story here: the point of mitigating rubber ducky attacks while still using USB Security dongle to validate firmware integrity being at stake here. And having a TPM+HOTP not being the same as having HOTP alone without a TPM (which we all agreed in previous discussions here that those were not equivalent outside of marketing speech).

@tlaurion
Copy link
Collaborator

Merged as part of #1419.

Requires to not have a TPM and HOTP.
Interesting for #453 and #925 #925 #934

@tlaurion tlaurion closed this Jul 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.