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

GPG key and config should live in separate cbfs file #182

Closed
osresearch opened this Issue Apr 12, 2017 · 11 comments

Comments

Projects
None yet
3 participants
@osresearch
Owner

osresearch commented Apr 12, 2017

Right now the user's GPG key has to be baked into the initrd.cpio file along with all of the system utilities. It would be easier to update if it could live in a separate CBFS file in the ROM so that users do not need to rebuild all of Heads.

@osresearch

This comment has been minimized.

Show comment
Hide comment
@osresearch

osresearch Apr 14, 2017

Owner

Post to coreboot mailing list: https://mail.coreboot.org/pipermail/coreboot/2017-April/083963.html
Response is that there is no defined way to do this, so dd or flashrom might be the best choice: https://mail.coreboot.org/pipermail/coreboot/2017-April/083967.html

Owner

osresearch commented Apr 14, 2017

Post to coreboot mailing list: https://mail.coreboot.org/pipermail/coreboot/2017-April/083963.html
Response is that there is no defined way to do this, so dd or flashrom might be the best choice: https://mail.coreboot.org/pipermail/coreboot/2017-April/083967.html

@flammit

This comment has been minimized.

Show comment
Hide comment
@flammit

flammit Jul 16, 2017

Contributor

I was thinking about taking a shot at closing this issue. Any preference on the approaches below?

  1. A patch to coreboot so that on boot it can extend the initrd/ramdisk area and append the contents of an appropriately-named CBFS cpio file right before running the linux payload (inserted with the standard cbfstool prior to flashing).
  2. A patch to cbfstool so that the linux payload can be extracted from a pre-built Heads ROM and the initrd extended with the user-specific files before flashing.
  3. Using cbfstool to extract files from ROM after Heads payload has started (seems like it would take up quite a lot of valuable space).
Contributor

flammit commented Jul 16, 2017

I was thinking about taking a shot at closing this issue. Any preference on the approaches below?

  1. A patch to coreboot so that on boot it can extend the initrd/ramdisk area and append the contents of an appropriately-named CBFS cpio file right before running the linux payload (inserted with the standard cbfstool prior to flashing).
  2. A patch to cbfstool so that the linux payload can be extracted from a pre-built Heads ROM and the initrd extended with the user-specific files before flashing.
  3. Using cbfstool to extract files from ROM after Heads payload has started (seems like it would take up quite a lot of valuable space).
@flammit

This comment has been minimized.

Show comment
Hide comment
@flammit

flammit Jul 17, 2017

Contributor

If we went with option 2, it would be possible to have cross-platform binaries (maybe in Go) to customize the Heads ROM (adjust config / add keys / verify initial ROM validity) without needing the end user to compile anything prior to flashing. Maybe it's not worth the effort to replicate the CBFS parsing though.

Contributor

flammit commented Jul 17, 2017

If we went with option 2, it would be possible to have cross-platform binaries (maybe in Go) to customize the Heads ROM (adjust config / add keys / verify initial ROM validity) without needing the end user to compile anything prior to flashing. Maybe it's not worth the effort to replicate the CBFS parsing though.

@tlaurion

This comment has been minimized.

Show comment
Hide comment
@tlaurion

tlaurion Nov 24, 2017

Contributor

I'm questioning the need to integrate GPG keys inside of the rom. What if we externalized that dependency into /boot? The actual problem is that this is a chicken egg problem, since we want to flash a rom from an external programmer to safe boot a machine. We ask that user to generate his keys from someone else's machine? That should be done on oneself's machine from reproducible build rom.

This is what I thought and would like your comments.

First boot. Call of seal-tpm.

  • Key is found /.gnupg which would be osresearch's, expended from initrd.
  • Mount /boot. Check if user gpg key is found under /boot/.gnupg
  • gpg user key not found. Ask user if he wants to generate his own key from his own GPG key under /boot
  • Generate new keys under /boot/.gnupg
  • Seal those keys with TPM and store the result in proper PCR
  • generate totp

Other boots

  • on-fly boot config doesn't match stored one
  • Ask user to select boot option (equivalent of 'm' being pressed)
  • Setting new defaults and signing chain depends of /boot/.gnupg and connected GPG usb key.

What do you think?

Contributor

tlaurion commented Nov 24, 2017

I'm questioning the need to integrate GPG keys inside of the rom. What if we externalized that dependency into /boot? The actual problem is that this is a chicken egg problem, since we want to flash a rom from an external programmer to safe boot a machine. We ask that user to generate his keys from someone else's machine? That should be done on oneself's machine from reproducible build rom.

This is what I thought and would like your comments.

First boot. Call of seal-tpm.

  • Key is found /.gnupg which would be osresearch's, expended from initrd.
  • Mount /boot. Check if user gpg key is found under /boot/.gnupg
  • gpg user key not found. Ask user if he wants to generate his own key from his own GPG key under /boot
  • Generate new keys under /boot/.gnupg
  • Seal those keys with TPM and store the result in proper PCR
  • generate totp

Other boots

  • on-fly boot config doesn't match stored one
  • Ask user to select boot option (equivalent of 'm' being pressed)
  • Setting new defaults and signing chain depends of /boot/.gnupg and connected GPG usb key.

What do you think?

@tlaurion

This comment has been minimized.

Show comment
Hide comment
Contributor

tlaurion commented Nov 26, 2017

@osresearch

This comment has been minimized.

Show comment
Hide comment
@osresearch

osresearch Nov 26, 2017

Owner

Ideally the user's public key would live somewhere in the ROM protected by the WP# and BP bits so that there are hopefully no software attacks to modify it. As you point out, this does require a hardware programmer step to install it.

I'm not sure that I understand the concern with generating the key off-machine. The key that is stored in the ROM is only the public key and for users with hardware tokens like yubikeys, the key can be generated in hardware and never live on any machine. In some extreme threat case, it is potentially unsafe for a user to store their key on the same machine that is validating the signatures.

If you're using dm-verity (which we need to document!), then you need GPG to verify the signature on / or /boot. If the key lives on /boot, then an attacker could swap the key and re-sign the merkle root hash. The totp check could potentially reveal this attack. (A separate issue is that I've had problems with clock sync under qubes4 and my x230's hwclock drifts, so the totp is often stale)

Owner

osresearch commented Nov 26, 2017

Ideally the user's public key would live somewhere in the ROM protected by the WP# and BP bits so that there are hopefully no software attacks to modify it. As you point out, this does require a hardware programmer step to install it.

I'm not sure that I understand the concern with generating the key off-machine. The key that is stored in the ROM is only the public key and for users with hardware tokens like yubikeys, the key can be generated in hardware and never live on any machine. In some extreme threat case, it is potentially unsafe for a user to store their key on the same machine that is validating the signatures.

If you're using dm-verity (which we need to document!), then you need GPG to verify the signature on / or /boot. If the key lives on /boot, then an attacker could swap the key and re-sign the merkle root hash. The totp check could potentially reveal this attack. (A separate issue is that I've had problems with clock sync under qubes4 and my x230's hwclock drifts, so the totp is often stale)

@flammit

This comment has been minimized.

Show comment
Hide comment
@flammit

flammit Nov 26, 2017

Contributor

re: time drift - There was a qubes4 bug in the qubes-core-agent-linux where chronyd wasn't starting due to a missing service setting. It's been fixed and is in current-testing right now, but the short term workaround is: qvm-service -e sys-net ntpd, restart sys-net, then qvm-sync-clock in dom0 to immediately fix the drift instead of waiting for cron.

As for the keys, I was also thinking that you'd likely be using a hardware-isolated key to start (such as a yubikey 4). If you flash the unmodified version of Heads (w/ the known good reproducible hash), you can use the Heads recovery shell to generate the key on device and retrieve your public key safely. I also find it useful that the key scheme works now without any local persistent storage (i.e. for external verified USB boot only).

That being said, I agree the current UX is a pain and it'd be nice to be able to "add" your public key to the base Heads rom and reflash - all from the recovery shell.

I'm happy to take a shot at this but would like some feedback on which of the approaches above to take - thoughts @osresearch ?

Contributor

flammit commented Nov 26, 2017

re: time drift - There was a qubes4 bug in the qubes-core-agent-linux where chronyd wasn't starting due to a missing service setting. It's been fixed and is in current-testing right now, but the short term workaround is: qvm-service -e sys-net ntpd, restart sys-net, then qvm-sync-clock in dom0 to immediately fix the drift instead of waiting for cron.

As for the keys, I was also thinking that you'd likely be using a hardware-isolated key to start (such as a yubikey 4). If you flash the unmodified version of Heads (w/ the known good reproducible hash), you can use the Heads recovery shell to generate the key on device and retrieve your public key safely. I also find it useful that the key scheme works now without any local persistent storage (i.e. for external verified USB boot only).

That being said, I agree the current UX is a pain and it'd be nice to be able to "add" your public key to the base Heads rom and reflash - all from the recovery shell.

I'm happy to take a shot at this but would like some feedback on which of the approaches above to take - thoughts @osresearch ?

@tlaurion

This comment has been minimized.

Show comment
Hide comment
@tlaurion

tlaurion Nov 27, 2017

Contributor

@osresearch The problem comes when trying to train multiple persons at the same time/more massive deployments. The trainee needs to use trainer's laptop to generate his own rom to have his key included in it or have a copy of his key, which comes with some productivity/trust/privacy issues (typing his yubikey password / need to have another computer with old version of GPG to generate the keys / have them copied to the builder's machine who has to build multiple roms...).

It would be ideal that the trainee/user could validate himself that the rom provided on a usb key is a reproducible rom, and that he could add himself his keys from within heads prior to flashing it, on his computer, not the trainer's, prior to installing Qubes.

The workaround I currently use is to have on trainee's computer reproducible rom flashed, make them install Qubes, restore a backup (debian-9-build template and build-x230 vm) and make them build the reproducible rom themselves and check validity, then make them generate the keys under initrd from Nitrokey/Yubikey, put resulting rom on usb key, and make them flash it themselves on their computer.This is time consuming, and error prone. But with that, they can regenerate rom for updates with their own key in the future from provided build-x230 vm.

@osresearch @flammit : Ideally, those keys should be in a different CBFS partition, and that partition known from flashrom's flash map (option from flashrom-x230.sh for initial flash vs updates) and not overwritten from Heads upgrades. That way, the user could boot from heads with osresearch's key present, generate his own key from yubikey/nitrokey from there and add them to the generic rom previously verified and then flash it.

Heads upgrades could then be available online as reproducible binaries (and/or third parties/organizations), and the user could flash it while keeping his keys untouched.

Contributor

tlaurion commented Nov 27, 2017

@osresearch The problem comes when trying to train multiple persons at the same time/more massive deployments. The trainee needs to use trainer's laptop to generate his own rom to have his key included in it or have a copy of his key, which comes with some productivity/trust/privacy issues (typing his yubikey password / need to have another computer with old version of GPG to generate the keys / have them copied to the builder's machine who has to build multiple roms...).

It would be ideal that the trainee/user could validate himself that the rom provided on a usb key is a reproducible rom, and that he could add himself his keys from within heads prior to flashing it, on his computer, not the trainer's, prior to installing Qubes.

The workaround I currently use is to have on trainee's computer reproducible rom flashed, make them install Qubes, restore a backup (debian-9-build template and build-x230 vm) and make them build the reproducible rom themselves and check validity, then make them generate the keys under initrd from Nitrokey/Yubikey, put resulting rom on usb key, and make them flash it themselves on their computer.This is time consuming, and error prone. But with that, they can regenerate rom for updates with their own key in the future from provided build-x230 vm.

@osresearch @flammit : Ideally, those keys should be in a different CBFS partition, and that partition known from flashrom's flash map (option from flashrom-x230.sh for initial flash vs updates) and not overwritten from Heads upgrades. That way, the user could boot from heads with osresearch's key present, generate his own key from yubikey/nitrokey from there and add them to the generic rom previously verified and then flash it.

Heads upgrades could then be available online as reproducible binaries (and/or third parties/organizations), and the user could flash it while keeping his keys untouched.

@tlaurion

This comment has been minimized.

Show comment
Hide comment
@tlaurion

tlaurion Nov 27, 2017

Contributor

@osresearch what is the use case scenario with Librem 13 having Heads preinstalled?

Contributor

tlaurion commented Nov 27, 2017

@osresearch what is the use case scenario with Librem 13 having Heads preinstalled?

@tlaurion

This comment has been minimized.

Show comment
Hide comment
@tlaurion

tlaurion Nov 30, 2017

Contributor

@flammit: I would go with option 1, since the CBFS partition could be kept intact after inserting the keys once. That would permit to flash reproducible rom upgrades without needing to reflash that partition.

Contributor

tlaurion commented Nov 30, 2017

@flammit: I would go with option 1, since the CBFS partition could be kept intact after inserting the keys once. That would permit to flash reproducible rom upgrades without needing to reflash that partition.

@tlaurion

This comment has been minimized.

Show comment
Hide comment
@tlaurion

tlaurion Feb 23, 2018

Contributor

@flammit @osresearch : which direction have you chose? Have you debated?

Contributor

tlaurion commented Feb 23, 2018

@flammit @osresearch : which direction have you chose? Have you debated?

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