linuxboot / heads

A minimal Linux that runs as a coreboot or LinuxBoot ROM payload to provide a secure, flexible boot environment for laptops, workstations and servers.
https://osresearch.net/
GNU General Public License v2.0
1.42k stars 186 forks source link

Heads cannot share HOTP dongle between multiple computers? Heads shouldn't accept having multiple user public keys injected in ROM. #1156

Closed ghost closed 2 years ago

ghost commented 2 years ago

v0.2.0-1192-g3201cd4 boards for w530-dgpu-k2000m-hotp-maximized and t430-dgpu-hotp-maximized (configs and vbios scripts merged from @eganonoa's https://github.com/eganonoa/heads/tree/t430-dgpu) seem to have common issues with gpg operations.

OEM Factory Reset works to completion on both boards, but the following operations fail to update checksums & sign kexec files in /boot:

after selecting the gpg key on my usb (same one exported after a factory reset) and flashing, it then prompts me to update checksums. after i verify presence of gpg card, this error appears for a split second-- i had to take a slo-mo video to catch it: gpg: no default secret key: No public key gpg: signing failed: No public key gpg: no default secret key: No public key gpg: signing failed: No public key gpg: no default secret key: No public key gpg: signing failed: No public key /boot: Unable to sign kexec hashes it then reports "Failed to update checksums / sign default config" then "Checksums have been updated and /boot files signed. Press Enter to reboot"

the only way that i am ever able to get /boot files properly signed is by doing an OEM Factory Reset. none of the other options ever end up working. this has been a common issue since the first dgpu build i did.

tlaurion commented 2 years ago

It seems that your public key was not merged into the firmware?

A generated public key, exported to USB dongle can only work if matching the private key on the smartcard.

If the factory reset scripts generates a key that is then fused into firmware and is recognised as working, it works.

Factory resetting the USB security dongle wipes previous private subkeys.

Injecting a public key that is not matching the signing private key in the USB security dongle would explain the behavior you are having.

Otherwise I have no explanation @walliams .

ghost commented 2 years ago

thing is, i am able to get it to the point where it passes the hotp verification but still won't sign the checksums... so i am merging the right key into the firmware, creating a new secret successfully, but it refuses to update checksums. is it possible it is a privileges thing? is it safe to manually wipe kexec files from /boot with rm -rf kexec* and then try updating checksums again? i considered doing this, but didn't want to fiddle with my /boot. i also tried to do a backup of the kexec files before wiping, but i was unable to mount a usb drive. mkdir /tmp/usb then mount /dev/sdb1 /tmp/usb fails. which is also confusing, because that worked for me on a previous heads build...

tlaurion commented 2 years ago

@walliams: Two concepts seem to be mixed here.

HOTP sealing can be done to any compatible HOTP USB Security dongle as long as its GPG Admin PIN is known.

GPG function requires having a public key matching thr actual private key on the USB Security dongle. That keypair is valid until another OEM Factory reset round.

Doing a factory reset will resrt USB security dongle and regenerate keypairs for which the public key is then fused in the firmware, and exported to USB thumb drive if requested.

That public key is valid only until the next OEM factory reset, which will invalidate previous private keys on the USB Security dongle.

Each time you run the OEM factory reset, you invalidate past private keys on the USB Security dongle, and render invalid the past public key as well.

My hypothesis here is that the public key you try to inject in ROM doesn't match any private key anymore in your USB Security dongle, which seems to match your success story with OEM factory resetting your USB Security dongle.

Makes sense? If yes please rename issue title and close.

Unfortunately, there is no way to restore private keys under Heads, they are generated in the USB security smartcard and the private signingbkey never leaves it. When you factory reset, you invalidate past keypairs. I think this is where there is a misunderstanding.

ghost commented 2 years ago

thankyou for clarification of what's going on with gpg keys, but i still think your hypothesis is incorrect. let me back up a bit. so my goal is to do this:

1) OEM Factory Reset one laptop 2) Export the new key to USB 3) Merge this key to the firmware of another laptop, sign /boot files, generate a new secret

is this process possible-- to have 2 laptops verified from the same HOTP Security Dongle? or am i still misunderstanding? i am certain i have been trying to merge the most recently generated key with the firmware on the second laptop, but it is never able to update checksums.

also if i'm misunderstanding, then what is the purpose of the "Add/Replace GPG key..." options if not to be able to link any heads board with the same GPG & Dongle?

tlaurion commented 2 years ago

You can't use the same USB Security dongle to use HOTP for remote attestation.

This is a one laptop/HOTP sealing.

For the GPG signing, the signing is made on the USB dongle, and then verified with the public key fused in ROM.

The reason why I still believe in my hypothesis (private and public key not matching) comes from the error you posted initially.

You can verify current public key by showing it under options->gpg options-> show public key

ghost commented 2 years ago

ok my apologies. i guess i have been attempting to do something that is impossible. i misunderstood the purpose of the GPG options available.

@tlaurion if you could would you please elaborate on what purpose these operations serve? is it, for example, if you flashed a new rom with no GPG and then want to add the original key back in?

thankyou for being patient, clear, and helpful with me through my learning process :)

tlaurion commented 2 years ago

HOTP/TOTP are firmware attestation features. TOTP is not requiring USB Security dongle, while HOTP binds one to Heads (HOTP variants of boards). This permits visual remote attestation of firmware measurements, including the measurement of the public key fused into the firmware.

A GPG Security dongle is required under Heads. A valid keypair is required, the public key matching the private key needs to be injected in the ROM and reflashed.

GPG is used to detach sign the checksum file of /boot content. Then the detach signature is used to verify that user authenticated the last changes that happened under /boot.

Other questions on documents station, needed clarifications should happen under heads-wiki for what is unclear on https://osresearch.net

ghost commented 2 years ago

@tlaurion thanks for the breakdown.

a little followup for clarity:

i just built t430-dgpu-maximized (w/o hotp) and then using the gpg key generated from my w530-dgpu-K2000m-hotp-maximized board in the latest OEM Factory Reset, i was able to merge the gpg key into the t430 board (w/o hotp) and successfully updated checksums.

so it seems that my previous issue was that the checksum updates were blocked by a mismatched hotp secret on the key... that seems to be the only difference here.

anyway, i am satisfied with this result and thanks again for the guiding hand.

now that i have successfully built and flashed the t430-dgpu board i will follow the guide in the wiki to fork the git and PR a merge to bring those configs upstream to master.

tlaurion commented 2 years ago

gpg: no default secret key: No public key gpg: signing failed: No public key gpg: no default secret key: No public key gpg: signing failed: No public key gpg: no default secret key: No public key gpg: signing failed: No public key /boot: Unable to sign kexec hashes

Then there is another possibility.

You may have added a second public key un ROM ans flashed it? The error that mattered in that block was that there was no default secret key.

So here, that may have meant that multiple public keys were fused into the ROM, where Heads expects to have only one user public key?

Would be nice if having two public keys was retested to confirm the behavior, in which case the title of this issue being renamed ans thé issue reopened to be fixed by code.

The error is not linked to a specific board, may be linked to an unsupported use case, that is correct. In which case, code could be changed to warn that having two user keys would cause error and refuse to flash, or promp the user to replace current public keys in ROM (not add).

In short: you might have found a bug, Heads permitting to add a public key where one was already present, where it should replace, not add @walliams?

tlaurion commented 2 years ago

@walliams adding the same key two times would not cause a bad behavior. Basically, Heads injects the keychain in ROM and GPG would neglect adding the same key.

I will try to test my hypothesis when back in front of computer in the next days.

tlaurion commented 2 years ago

gpg --list-keys from recovery shell would show what is happening. cbfs-init script being responsible to export the files from ROM after having measured them, the files are then available in ramfs as part of / filesystem exposed to Heads.

usb-init from recovery shell, followed by gpg --card-status and gpg --list-keys will tell what happens.

flash-gui.sh contains the logic of backup of firmware, key injection and flashing back to SPI.

ghost commented 2 years ago

@walliams adding the same key two times would not cause a bad behavior. Basically, Heads injects the keychain in ROM and GPG would neglect adding the same key.

I will try to test my hypothesis when back in front of computer in the next days.

yes, sorry i made a fatal mistake in my testing, did it again more intentionally after i made that hypothesis and proved myself wrong so i deleted that whole comment lol. i think you are on the right track.

jtmoree-github-com commented 2 years ago

is this process possible-- to have 2 laptops verified from the same HOTP Security Dongle? or am i still misunderstanding? i am certain i have been trying to merge the most recently generated key with the firmware on the second laptop, but it is never able to update checksums.

@walliams fyi. I use the same usb security dongle with two laptops but only 1 has coreboot. The process should be repeatable on multiple coreboot setups. I created the public/private keys on a separate system and transferred to the security dongle before loading the public key into coreboot. (of course I deleted the private key from the first system).

tlaurion commented 2 years ago

@jtmoree-github-com where the same USB security dongle can be used to sign/verify /boot content across multiple devices, HOTP function of the USB security dongle is bound to a single Heads computer.

You can generate keypair externally and copy to card your subkeys to multiple USB security dongles, and use each privisioned USB dongles on unique Heads computer, that is true (each remote attesting with HOTP which is bound to individual computers).

USB security dongles supported by Heads only have one HOTP slot used for remote attestation, which bound the USB security dongle to that computer for hotp board variants.

This is a recurring question @jans23 @kylerankins : can that limitation be leveraged at the firmware level of those USB security dongles in the future, so that a single USB security dongle could be used to attest integrity of multiple Heads computers?