Re: [RFC PATCH 0/2] TPM derived keys

Ignat Korchagin
2024-05-14T14:54:13Z

On Tue, May 14, 2024 at 3:11 PM James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>
> On Tue, 2024-05-14 at 10:50 +0100, Ignat Korchagin wrote:
> > On Mon, May 13, 2024 at 11:33 PM James Bottomley
> > <James.Bottomley@hansenpartnership.com> wrote:
> > >
> > > On Mon, 2024-05-13 at 18:09 +0100, Ignat Korchagin wrote:
> > > [...]
> > > > TPM derived keys attempt to address the above use cases by
> > > > allowing applications to deterministically derive unique
> > > > cryptographic keys for their own purposes directly from the TPM
> > > > seed in the owner hierarchy. The idea is that when an application
> > > > requests a new key, instead of generating a random key and
> > > > wrapping it with the TPM, the implementation generates a key via
> > > > KDF(hierarchy seed, application specific info). Therefore, the
> > > > resulting keys will always be cryptographically bound to the
> > > > application itself and the device they were generated on.
> > >
> > > So I think what confuses me is what the expected cryptographic
> > > secrecy properties of the derived keys are. I get they're a KDF of
> > > seed and deterministic properties, but if those mixing values are
> > > well known (as the path or binary checksum cases) then anyone with
> > > access to the TPM can derive the key from user space because they
> > > can easily obtain the mixing parameters and there's no protection
> > > to the TPM keyed hash operation.
> > >
> > > Consider the use case where two users are using derived keys on the
> > > same system (so same TPM). Assuming they use them to protect
> > > sensitive information, what prevents user1 from simply deriving
> > > user2's key and getting the information, or am I missing the point
> > > of this?
> >
> > You are correct: it is possible, but in practice it would be limited
> > only to privileged users/applications. I remember there was a push to
> > set a 666 mask for the TPM device file, but it is not how it is done
> > today by default.
>
> No, it's 660, but in consequence of that every user of the TPM is a
> member of the tpm group which, since TPM use from userspace is growing,
> is everyone, so it might as well have been 666. In other words relying
> on access restrictions to the TPM itself is largely useless.
>
> > Also I think the same applies to trusted keys as well, at least
> > without any additional authorizations or PCR restrictions on the blob
> > (I remember I could manually unwrap a trusted key blob in userspace
> > as root).
>
> Well, that's correct, but a TPM key file without policy still has two
> protections: the file itself (so the key owner can choose what
> permissions and where it is) and the key authority (or password)
> although for the mechanical (unsupervised insertion) use case keys tend
> not to have an authority.
>
> > It would be fixed if we could limit access to some TPM ops only from
> > the kernel, but I remember from one of your presentations that it is
> > generally a hard problem and that some solution was in the works (was
> > it based on limiting access to a resettable PCR?). I'm happy to
> > consider adopting it here as well somehow.
>
> Well, that was based on constructing a policy that meant only the
> kernel could access the data (so it requires PCR policy).
>
> In addition to the expected secrecy property question which I don't
> think is fully answered I did think of another issue: what if the
> application needs to rotate keys because of a suspected compromise?
> For sealed keys, we just generate a new one an use that in place of the
> old, but for your derived keys we'd have to change one of the mixing
> values, which all look to be based on fairly permanent properties of
> the system.

For our current (non-TPM based) derived key hierarchy we do allow
applications to specify a "freeform" mixing value, which in practice
may contain a key version, like "v1"/"v2" etc. This also allows
applications to derive multiple different keys for different purposes.
Perhaps, we can do the same here, for example keyctl add derived test
"<key len> (path|csum) <the rest is used as is as another mixin>". We
can also "just ship" a new version of the code (for the csum case),
which would rotate the key. Another option could be using some
optional xattr as a mixin, which can specify the version of the key or
just be a freeform input.

> James
>