tpmkey: add support for keys sealed to a local TPM - #166
Conversation
|
I've tested this against the simulated TPM, but it's a bit late here and I haven't had the chance to test against a "real" (i.e. "Proxmox-provided") TPM yet. Will do that tomorrow. |
| return nil, fmt.Errorf("loading sealed key from %q into TPM: %w", path, err) | ||
| } | ||
| defer func() { | ||
| flushCmd := tpm2.FlushContext{FlushHandle: loadRsp.ObjectHandle} |
There was a problem hiding this comment.
A question for my understanding: I see that createSRK returns a callback to flush the transaction, as do we here, but the Unseal step below does not. Should that one also do this? (I don't know if the flush is per transaction or per session, or what)
| // Copyright (c) Tailscale Inc & contributors | ||
| // SPDX-License-Identifier: BSD-3-Clause | ||
|
|
||
| package tpmkey |
There was a problem hiding this comment.
If it is practical to do so, I'd prefer we put tests in a separate package (package tpmkey_test) rather than exercising via the unexported surfaces.
Here, I think it is only openOrCreate that we really need.
What do you think about making OpenOrCreate accept a device (a transport.TPM) rather than a path, and exporting OpenDevice (or maybe OpenDevicePath, since presumably we might get devices some other way on Windows or Darwin)? All we're really saving the caller is stitching those two together, and the fact that the tests immediately have to work around that makes me think it should be part of the API.
There was a problem hiding this comment.
SGTM; just made the change. I kept the openDevice / OpenDevicePath split so the godoc isn't duplicated in two locations
df16f88 to
6b34316
Compare
Add a new tpmkey package that seals the key-encryption key to a TPM 2.0 device, as an alternative to a cloud KMS. TPMs cannot perform AEAD operations directly, so instead a random 32-byte key is generated and sealed to the TPM, with the sealed blob stored in a file on disk. At startup the blob is unsealed through the TPM, and the key is used with a software AEAD. The sealed blob can only be used by the TPM that created it, so a copy of the database and key file together cannot be decrypted elsewhere. This also works with virtual TPMs such as those QEMU (and thus Proxmox) provide.
|
Just tested this on a Proxmox VM with a vTPM installed, and it works great 😁 |
| "tailscale.com/atomicfile" | ||
| ) | ||
|
|
||
| // A quick digression on how and why we "flush" something from the TPM: |
There was a problem hiding this comment.
Thanks, this is really helpful.
Add a new tpmkey package that seals the key-encryption key to a TPM 2.0 device, as an alternative to a cloud KMS.
TPMs cannot perform AEAD operations directly, so instead a random 32-byte key is generated and sealed to the TPM, with the sealed blob stored in a file on disk. At startup the blob is unsealed through the TPM, and the key is used with a software AEAD.
The sealed blob can only be used by the TPM that created it, so a copy of the database and key file together cannot be decrypted elsewhere. This also works with virtual TPMs such as those QEMU (and thus Proxmox) provide.