osresearch / safeboot

Scripts to slightly improve the security of the Linux boot process with UEFI Secure Boot and TPM support
https://safeboot.dev/
GNU General Public License v2.0
268 stars 28 forks source link

Proof of possession protocol (PoP) is needed #141

Open nicowilliams opened 2 years ago

nicowilliams commented 2 years ago

We're almost certainly going to end up needing a proof of possession protocol.

Currently we rely on the correctness of legitimate TPMs and the SafeBoot attestation protocol, but we may want to make network access control decisions based on evidence of successful completion of attestation.

@geoffthorpe's idea is to use the same attestation protocol again and repeat something from the previous one. We can then take advantage of our current ability to use PCR #11 to sequence enrolled secret recovery at a configured Nth attestation for each secret type.

Perhaps we could have a secret included in the attestation reply that we can use for PoP. Perhaps we can even extend PCR #11 with that secret, not just an agreed constant.

A sketch of one possible PoP:

So then after each attestation the client would extend PCR #11 with an agreed-upon constant, then again with the pop-secret, then in the next attestation request the client would include last-pcr11.dat and last-pcr11.dat.sig so the server can validate that the current value of PCR #11 is extended from that as it should have been.

nicowilliams commented 2 years ago

See PR #140.

nicowilliams commented 2 years ago

Observations:

Being able to attest repeatedly, chaining all the attestations, and using that to deny network access to devices that fail to attest frequently enough, seems like a desirable feature, at the cost of keeping more state for longer periods of time.

Designs:

a) stateless (push state-keeping to client), b) statefull on the server side.

Trade-offs:

For the client-side state design we can always detect replays by scanning logs -- logs can be the server-side state, checked lazily.

The state that needs to be kept boils down to {client_device_id, client_device_tpm_resetCount, n}, where n is the number of the last attestation (0 for the first one at boot time, 1 for the next, and so on).

nicowilliams commented 2 years ago

I'm inclined to be lazy about replays, so I'm inclined to go with a stateless solution (keep the state on the client).

Synchronizing cryptographic keys for PoP token integrity protection doesn't seem like a big deal. We do this all the time for other systems.

We can minimize the state that the client needs to keep down to just the previous PoP token, and possibly we could keep it in a TPM NV index. We could minimize this further, but at the cost of having to do O(N) work on the server-side to reconstruct past PoP tokens, so maybe not.