linuxboot/heads-wiki

Better explain Heads functionnings and limitation

tlaurion opened this issue · 9 comments

Edit: best unbiased, user written doc at https://tech.michaelaltfield.net/2023/02/16/evil-maid-heads-pureboot/


The following should go into a wiki page.

Actual Heads security mechanisms are:

  1. Measured /boot, requiring a USB Security dongle to offload GPG operations (signing with private key in smartcard). The verification of detached signed /boot digest is automatic on each boot, verified against public key injected in firmware (and measured by TPM).

  2. Firmware remote attestation (TOTP, HOTP) of measured firmware components, including GPG public key into PCR7, used to provide validation of detached signed digest of precedent step.

  3. Disk Unlock Key, using NV TPM reserved space to release Disk Unlock Key when (1) (2) and LUKS header + Disk Unlock Key passphrase are valid, while rate limiting passphrase attempts by the TPM. (Note that if going into recovery shell, measurements are invalidated and this won't be successful)

Let's focus on (1) here.

  1. On each boot, Heads verifies that the detached signed digest (/boot/kexec.sig) matches the digest(/boot/kexec_hashes.txt). (Verified authenticity and integrity with public key matching private key in USB Security dongle's smartcard).
  2. Heads generates a new sha256sum digest of /boot found files (sha256sum of /boot files) and compares its result against signed one (/boot/kexec_hashes.txt)
  3. If there is a mismatch of integrity of past signed digest, the difference of integrity are showed. If there are new files not in digest, those are shown as errors. Both are different. For example, grub.cfg having changed (grub.cfg) and a new file (xen or kernel) gives hints of what changed in case the user forgot to reboot his computer directly after a core upgrade to sign related changes and keep his workflow worry free.
  • The public key needs to be injected in rom to have detached signature validation under Heads.
  • The private key should not be exposed to the operating system. Having access to a copy of private key and knowing its PIN would permit all content having been crypted to be decrypted (no forward secrecy with GPG). Having access to that private key would also permit an attacker to sign changes as if he was the user.
  • A USB Security dongle normally implements rate limiting on password prompts. More radically, USB Security dongles are actually locking the user out of their User role if 3 bad attempts were made, actually protecting the private key of abuse. In such case, the Admin role of the USB Security dongle is required to unlock the User role so the key can be used again. Having a private key exposed offers unlimited attempts.

For more information, please read: https://www.linuxjournal.com/content/why-smart-cards-are-smart

Should be considered in limitations when implementing linuxboot/heads#921

Another note of interest here is that Heads does not implement dmverity checks as of now (was in before, never really documented, could have worked with patches to QubesOS 3.2 but never happened for QubesOS, where I cannot find link to past discussions as of right now.)

For QubesOS to support such setup (as safeboot goal) QubesOS disk layout and keeping QubesOS from constantly writing into the rootfs layer (which should not change outside of updates) needs to be implemented.

The best Heads implements, as of right now, in my opinion, is:

  1. /boot detached signed digest from USB Security dongle's private key (Yubikey, Nitrokey Pro/Nitrokey Storage, Librem Key, other GPG tokens). Verified on each boot against public key counterpart, injected in ROM and measured by....
  2. TPM-based measured boot, verifying ROM components, including User's customizations (read here /etc/config.user which is customizations of board deployed config exports under /etc/config, and GPG public key as part of PCR7). Sealed under...
  3. Remote attestation over Qr Code to be scanned by OTP application over smartphone, for which OTP code can be verified manually at each boot (OTP) and/or through HOTP compliant USB Security dongle (currently supported: Nitrokey Pro/Nitrokey Storage/Librem Key)
  4. Disk Unlock Key released by the TPM only if /boot detached signed digest is valid, if provided with proper Disk Unlock Key passphrase (passphrase attempts rate limited by TPM) which would release Disk Unlock Key only if TPM measurements are valid (including public key, user config, that Heads did not come back from recovery shell, that LUKS header is valid)

Any other implementation proposed previously would lower the security offered.

The above implementation comes with limits as well. In theory, it would be totally possible to:

  • get the sealed secret value (totp secret in Heads jargon) by opening the hardware and listening TPM IO, and craft a firmware that would simply hardcode tat value to generate remote attestation challenge, which would be used against HOTP/TOTP. That, here again thanks to the TPM, required physical access, where a simple tamper seal with glitter would probably get prying eyes away.
  • The USB Security firmware could theoritically be tampered with. (Nitrokey Pro needs physical access and complicated process, for which tampering should invalidate the secrets, require factory reset and resealing.)
  • Another option that was theorized is to have a rubber ducky replacement USB Security dongle, simply flashing green. I think this is way too complicated while possible. The result of the hanshake through HOTP returns also the result on screen (HOTP:Sucess) while the TOTP code on smartphone should be invalid, or not even returned (considering TPM counter value). I would love to see this in action.

On TPM-less USB Security dongle-only enforced remote attestation (firmware integrity remote attestation on USB Security dongle through HOTP):

  • Changing the ROM to produce statically obtained hash of past ROM is enough to break actual security measure of the current proposition. If you want Heads, you want a TPM and a USB Security dongle. At least in my opinion. Wanting to use a non-tpm board, with a LUKS encrypted card to replace the USB Security dongle and hope to have the same security..... is delusional. I would question why you wanted Heads at the first place.
  • Another approach, since there is no TPM involved, would be to create a USB rubber ducky, simulating keyboard input to go into recovery shell, sed the shell scripts to always return the good OTP value based on backuped ROM content, and return to GUI. The user would not notice the screen flicker, the HOTP:Success and green led flashing would be shown, the user would think its ok. Well, until he tries to sign/encrypt content with that rubber ducky and realize it was swapped with the original. Above point is more attractive approach to compromise heads functions; changing the whole Heads scripts to save in /boot or anywhere else the USB Security dongle's PINs and Disk Recovery Key passphrases. Why not put the logic further, and have Heads code wait for a USB disk UUID to mount it in a flash, exfiltrate secrets. Or simply wait a day or two so that the user uses his computer, and simply steal it at this point, knowing that you have all that is desired inside of /boot, just needing to reset passphrases from OS from an external boot media.

On LUKS encrypted backup of key generation:

  • The goal here would be to have 4096 RSA keys generated/backup/copy-to-card(restored) from Heads, permitting to mitigate current outcome of loosing USB Securty dongle and having to regenerate a new keypair, losing access to past encrypted mails/content, by offering the possibility to the user of generating such keys from the computer, in a safe environment. How to verify that we are in such good environment on older hardware? Well, this is where xx30-maximized and xx20 boards are changing the rules a bit here. You can now reflash the whole ROM. Reflashing, from Heads, gives the possibility to keep user's files (public key and config is exported, added into new rom, and flashed back).

On LUKS encrypted partition replacing USB Security dongle:

  • This is, without doubt, a lower secure version of the USB Security dongle. No rate limiting nor locking out the user from bad PIN. Unlimited attempts permitted to unlock the container. Disk can be cloned in no time and bruteforced at leisure by Evil Maid. This is why I am putting ideas out there, doing devil's advocate, because people ask for those features not wanting to buy a USB Security dongle.

For documentation purposes, a long discussion happened on slack from here to here

@tlaurion More detail and better explanations are needed in the wiki but how would this be organized? This, when all together, seems like it lead to more questions from new users.

Diagrams laying out where everything is stored and a glossary may be useful but seem like they are outside of the scope of this ticket. I'll open new ones.

Sandy and Ivy bridge (xx20/xx30) get platform locking (no SPI write outside of Heads) through linuxboot/heads#326

Take into consideration #116 when updating docs to differenciate measuring and sealing operations.

Detailed again what kexec*.txt files are for, as detached signed under kexec.sig under linuxboot/heads#1620 (comment)

Time to work on docs!

  1. Firmware remote attestation (TOTP, HOTP) of measured firmware components, including GPG public key into PCR7, used to provide validation of detached signed digest of precedent step.

Discussion on bootguard vs bootblock RoT at https://matrix.to/#/!GzefHyBKGoKjOgarWV:matrix.org/$Fa2nJy6D0W0mNELnNzUJVYAXhZoVGn1Dw4Mqtmax9qg?via=dreamless.one&via=matrix.org&via=tchncs.de