Foxboron / sbctl

:computer: :lock: :key: Secure Boot key manager
MIT License
1.44k stars 81 forks source link

Add password to PK private key #165

Open oXis opened 2 years ago

oXis commented 2 years ago

Secure boot provides a chain of trust for the boot environment. The current implementation protects against Evil Maid attacks, granted that your root is encrypted and you have an unified image.

Secure Boot is also designed to protect against rootkits, but the current implementation doesn't do the job. The Microsoft bootloader is signed by MSFT and the private key is not available to anyone, whereas sbctl stores the PK private key in clear inside /usr/share/secureboot/. A proposed improvement would be to store the private PK key encrypted on disk, so when sbctl loads the key, the user is prompted for a unlock password. This would prevent malicious root users (malware) from installing a signed rootkit/bootkit.

If you think that this is an interesting idea, I could try and work on the new feature, I just need to find some time :(

Edit: I realised that TPM support in the roadmap probably means that secrets will be sealed inside the TPM. Password protected keys are still interesting though.

Foxboron commented 2 years ago

Edit: I realised that TPM support in the roadmap probably means that secrets will be sealed inside the TPM. Password protected keys are still interesting though.

I was about to comment on this :)

I'd prefer TPM, but we can probably do passwords as well. Keep in mind that PK isnt the key that we sign stuff with, it's just the root of trust we assigned. So password protecting PK itself doesn't do a whole lot as we can still sign with db. However password protecting db is going to be a bit annoying to deal with when we automate the signing.

Some UX stuff needs to be fixed and I need to implement the configuration support I have been thinking about for a while now.

oXis commented 2 years ago

Hey! Thanks for the answer.

I didn't edit the comment, but I later realised/remembered that db is signed with the KEK. You could replicate a "chain of trust" where the private part of the PK is password protected and is used to encrypt the private part of the KEK.

I was thinking about the TPM implementation and yesterday I read A Practical Guide to TPM 2.0 just to get an idea about how the TMP works, what can be sealed, how, etc...

Automatic signing is interesting, you could seal the private key inside the TPM, or use the TPM to generate a key pair and sign KEK with it (though I don't know how to use tpm2_sign to sign a KEK). The TMP PK could even be linked to a PCR policy, so signing happens only if the boot process was not tempered with.

But is doesn't change the fact that root can still sign your kernel/bootloader, hence you're not protected against rootkits/bootkits. So sealing the private key inside the TMP with for example a PCR policy is not enough. root should not be able to access the signing keys without another layer of authentication. Removing the private keys and signing "offline" is a solution (it's actually the only real solution haha), but I still think that password protection would be nice to have.

Now that I'm thinking about offline signing, I think that offline signing could also be implemented. sbctl could generate the keys, and put all the signed efivars blobs on disk. Then you could import those blobs on another computer. So the private keys never touch the target computer.

(I need to find the time, but I'll be happy to do it myself)

Foxboron commented 2 years ago

I wrote a very bare bones TPM UEFI signing thing last year as a quick demonstration. https://github.com/Foxboron/go-uefi/blob/morten/tpm/cmd/gotpm/main.go

The main issue on my end is to get the time to implement this in sbctl and also have PCR sealing work correctly. I have some POC code but I really need to spend more time to grok the API from go-tpm :)

root should not be able to access the signing keys without another layer of authentication.

I would ignore this threat scenario. Root access on a booted machine is not what Secure Boot is designed for, thus out of scope for sbctl as well. We are here to protect the boot chain, not to protect the machine from root :)

Now that I'm thinking about offline signing, I think that offline signing could also be implemented. sbctl could generate the keys, and put all the signed efivars blobs on disk. Then you could import those blobs on another computer. So the private keys never touch the target computer.

You could do this as a form of "seeding" the machine with some configuration setup where you just have everything pre-signed and then enroll at early boot stage (look at the enrollment support in systemd-boot).

oXis commented 2 years ago

I wrote a very bare bones TPM UEFI signing thing last year as a quick demonstration. https://github.com/Foxboron/go-uefi/blob/morten/tpm/cmd/gotpm/main.go

Ha thanks! Might be useful.

I would ignore this threat scenario. Root access on a booted machine is not what Secure Boot is designed for, thus out of scope for sbctl as well. We are here to protect the boot chain, not to protect the machine from root :)

I understand perfectly. Secure boot protects against unsigned kernel drivers, but protecting the bootloader after boot is probably not part of the threat model.

You could do this as a form of "seeding" the machine with some configuration setup where you just have everything pre-signed and then enroll at early boot stage (look at the enrollment support in systemd-boot).

I don't understand :( do you have link?

Foxboron commented 2 years ago

I understand perfectly. Secure boot protects against unsigned kernel drivers, but protecting the bootloader after boot is probably not part of the threat model.

This is partially a misconception, actually. There isn't really any conncetion between Secure Boot and kernel module signatures. Downstream distros patch the kernel to enable lockdown mode when Secure Boot is enabled. But this isn't an automatic thing.

For kernel module signatures to work, you would still need a Machine Owner Key and utilize the shim to have the kernel accept secure boot keys.

See this general issue; https://github.com/Foxboron/sbctl/issues/52

IPlayZed commented 1 year ago

It should be noted that Arch doesn't enable lockdown by default. Out of tree drivers need to be signed with the same keys used during kernel compilation.