mbox series

[0/4] Trusted Key policy for TPM 2.0

Message ID 20210521004401.4167-1-James.Bottomley@HansenPartnership.com (mailing list archive)
Headers show
Series Trusted Key policy for TPM 2.0 | expand

Message

James Bottomley May 21, 2021, 12:43 a.m. UTC
Now that the ASN.1 representation of trusted keys is upstream we can
add policy to the keys as a sequence of policy statements meaning the
kernel can now construct and use the policy session rather than the
user having to do it and pass the session down to the kernel.  This
makes TPM 2.0 keys with policy much easier.

The format of the policy statements is compatible with the
openssl_tpm2_engine policy implementation:

https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/

And the seal_tpm2_data command in the above can be used to create
sealed keys (including with policy statements) for the kernel.

The current implementation only has a limited subset of the full TPM
2.0 policy commands, but it is enough to implement keys locked to PCR
values and expiring keys.  The main missing feature is support for the
TPM2_PolicyOR statement, which means all current policy has to be AND
chains (key doesn't unlock unless every policy statement succeeds).

I can't fix the checkpatch error in the first patch: the thing its
complaining about is a sha1 sum, just not a sha1 sum representing a
kernel commit.

James

---

James Bottomley (4):
  security: keys: trusted: add PCR policy to TPM2 keys
  security: keys: trusted: add ability to specify arbitrary policy
  security: keys: trusted: implement counter/timer policy
  security: keys: trusted: implement authorization policy

 .../security/keys/trusted-encrypted.rst       |  83 +++-
 include/keys/trusted-type.h                   |   5 +-
 include/linux/tpm.h                           |   6 +
 security/keys/Kconfig                         |   2 +
 security/keys/trusted-keys/Makefile           |   1 +
 security/keys/trusted-keys/tpm2-policy.c      | 466 ++++++++++++++++++
 security/keys/trusted-keys/tpm2-policy.h      |  31 ++
 security/keys/trusted-keys/tpm2key.asn1       |  13 +
 security/keys/trusted-keys/trusted_core.c     |   8 +-
 security/keys/trusted-keys/trusted_tpm1.c     |  15 +
 security/keys/trusted-keys/trusted_tpm2.c     | 124 ++++-
 11 files changed, 740 insertions(+), 14 deletions(-)
 create mode 100644 security/keys/trusted-keys/tpm2-policy.c
 create mode 100644 security/keys/trusted-keys/tpm2-policy.h

Comments

David Woodhouse May 21, 2021, 1:48 p.m. UTC | #1
On Thu, 2021-05-20 at 17:43 -0700, James Bottomley wrote:
> Now that the ASN.1 representation of trusted keys is upstream we can
> add policy to the keys as a sequence of policy statements meaning the
> kernel can now construct and use the policy session rather than the
> user having to do it and pass the session down to the kernel.  This
> makes TPM 2.0 keys with policy much easier.
> 
> The format of the policy statements is compatible with the
> openssl_tpm2_engine policy implementation:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/
> 
> And the seal_tpm2_data command in the above can be used to create
> sealed keys (including with policy statements) for the kernel.

I'd love to see that format properly defined and documented instead of
just a reference to another implementation.
James Bottomley May 21, 2021, 2:28 p.m. UTC | #2
On Fri, 2021-05-21 at 14:48 +0100, David Woodhouse wrote:
> On Thu, 2021-05-20 at 17:43 -0700, James Bottomley wrote:
> > Now that the ASN.1 representation of trusted keys is upstream we
> > can add policy to the keys as a sequence of policy statements
> > meaning the kernel can now construct and use the policy session
> > rather than the user having to do it and pass the session down to
> > the kernel.  This makes TPM 2.0 keys with policy much easier.
> > 
> > The format of the policy statements is compatible with the
> > openssl_tpm2_engine policy implementation:
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/
> > 
> > And the seal_tpm2_data command in the above can be used to create
> > sealed keys (including with policy statements) for the kernel.
> 
> I'd love to see that format properly defined and documented instead
> of just a reference to another implementation.

Well if you want to help me write an RFC, I can try to submit it.

James
David Woodhouse May 21, 2021, 3:22 p.m. UTC | #3
On Fri, 2021-05-21 at 07:28 -0700, James Bottomley wrote:
> On Fri, 2021-05-21 at 14:48 +0100, David Woodhouse wrote:
> > On Thu, 2021-05-20 at 17:43 -0700, James Bottomley wrote:
> > > Now that the ASN.1 representation of trusted keys is upstream we
> > > can add policy to the keys as a sequence of policy statements
> > > meaning the kernel can now construct and use the policy session
> > > rather than the user having to do it and pass the session down to
> > > the kernel.  This makes TPM 2.0 keys with policy much easier.
> > > 
> > > The format of the policy statements is compatible with the
> > > openssl_tpm2_engine policy implementation:
> > > 
> > > https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/
> > > 
> > > And the seal_tpm2_data command in the above can be used to create
> > > sealed keys (including with policy statements) for the kernel.
> > 
> > I'd love to see that format properly defined and documented instead
> > of just a reference to another implementation.
> 
> Well if you want to help me write an RFC, I can try to submit it.

The xml2rfc tool makes it fairly easy.

See https://github.com/dwmw2/ietf-cert-best-practice for a template; in
Appendix B there is an example of specifying an ASN.1 format.

We should probably define not just the ASN.1 format but also a URI
scheme for referencing objects in NVRAM. A TPMv2 version of 
https://datatracker.ietf.org/doc/html/draft-mavrogiannopoulos-tpmuri-01
might be a good idea.
James Bottomley May 21, 2021, 3:55 p.m. UTC | #4
On Fri, 2021-05-21 at 16:22 +0100, David Woodhouse wrote:
> On Fri, 2021-05-21 at 07:28 -0700, James Bottomley wrote:
> > On Fri, 2021-05-21 at 14:48 +0100, David Woodhouse wrote:
> > > On Thu, 2021-05-20 at 17:43 -0700, James Bottomley wrote:
> > > > Now that the ASN.1 representation of trusted keys is upstream
> > > > we can add policy to the keys as a sequence of policy
> > > > statements meaning the kernel can now construct and use the
> > > > policy session rather than the user having to do it and pass
> > > > the session down to the kernel.  This makes TPM 2.0 keys with
> > > > policy much easier.
> > > > 
> > > > The format of the policy statements is compatible with the
> > > > openssl_tpm2_engine policy implementation:
> > > > 
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/
> > > > 
> > > > And the seal_tpm2_data command in the above can be used to
> > > > create sealed keys (including with policy statements) for the
> > > > kernel.
> > > 
> > > I'd love to see that format properly defined and documented
> > > instead of just a reference to another implementation.
> > 
> > Well if you want to help me write an RFC, I can try to submit it.
> 
> The xml2rfc tool makes it fairly easy.

XML and easy ... there's two words you don't often see in a sentence
...

> See https://github.com/dwmw2/ietf-cert-best-practice for a template;
> in Appendix B there is an example of specifying an ASN.1 format.

OK, I'll add it to 

https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/

But I'll be expecting patches ...

> We should probably define not just the ASN.1 format but also a URI
> scheme for referencing objects in NVRAM. A TPMv2 version of 
> https://datatracker.ietf.org/doc/html/draft-mavrogiannopoulos-tpmuri-01
> might be a good idea.

I'm not so sure ... the keys are files not tokens and the pkcs11 URI
doesn't have a file pointer.  I suspect the correct way to represent
them would be to fully represent the key in the URI, which sounds like
a length explosion.

If you really want to use PKCS11 for TPM keys, I've actually got an
engine exporter for any openssl engine key:

https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl-pkcs11-export.git/

So you can refer to them with standard PKCS11 URI components instead of
making your own up.  I use it for TPM keys in firefox for instance.

James
David Woodhouse May 21, 2021, 4:12 p.m. UTC | #5
On Fri, 2021-05-21 at 08:55 -0700, James Bottomley wrote:
> On Fri, 2021-05-21 at 16:22 +0100, David Woodhouse wrote:
> > On Fri, 2021-05-21 at 07:28 -0700, James Bottomley wrote:
> > > On Fri, 2021-05-21 at 14:48 +0100, David Woodhouse wrote:
> > > > On Thu, 2021-05-20 at 17:43 -0700, James Bottomley wrote:
> > > > > Now that the ASN.1 representation of trusted keys is upstream
> > > > > we can add policy to the keys as a sequence of policy
> > > > > statements meaning the kernel can now construct and use the
> > > > > policy session rather than the user having to do it and pass
> > > > > the session down to the kernel.  This makes TPM 2.0 keys with
> > > > > policy much easier.
> > > > > 
> > > > > The format of the policy statements is compatible with the
> > > > > openssl_tpm2_engine policy implementation:
> > > > > 
> > > > > https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/
> > > > > 
> > > > > And the seal_tpm2_data command in the above can be used to
> > > > > create sealed keys (including with policy statements) for the
> > > > > kernel.
> > > > 
> > > > I'd love to see that format properly defined and documented
> > > > instead of just a reference to another implementation.
> > > 
> > > Well if you want to help me write an RFC, I can try to submit it.
> > 
> > The xml2rfc tool makes it fairly easy.
> 
> XML and easy ... there's two words you don't often see in a sentence
> ...
> 
> > See https://github.com/dwmw2/ietf-cert-best-practice for a template;
> > in Appendix B there is an example of specifying an ASN.1 format.
> 
> OK, I'll add it to 
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/
> 
> But I'll be expecting patches ...

Absolutely :)

> > We should probably define not just the ASN.1 format but also a URI
> > scheme for referencing objects in NVRAM. A TPMv2 version of 
> > https://datatracker.ietf.org/doc/html/draft-mavrogiannopoulos-tpmuri-01
> > might be a good idea.
> 
> I'm not so sure ... the keys are files not tokens and the pkcs11 URI
> doesn't have a file pointer.  I suspect the correct way to represent
> them would be to fully represent the key in the URI, which sounds like
> a length explosion.

Not files, and definitely nothing to do with PKCS#11.

I meant a URI for referring to keys which are in NVRAM. The kind you
currently use the '//nvkey:' prefix for.

We should standardise that form, as a URI, so that users can take that
same URI to *any* application and expect it to work. That's what 
https://tools.ietf.org/html/draft-mavrogiannopoulos-tpmuri-01 was
doing, for TPMv1.2.
James Bottomley May 21, 2021, 4:17 p.m. UTC | #6
On Fri, 2021-05-21 at 17:12 +0100, David Woodhouse wrote:
> On Fri, 2021-05-21 at 08:55 -0700, James Bottomley wrote:
> > On Fri, 2021-05-21 at 16:22 +0100, David Woodhouse wrote:
[...]
> > > We should probably define not just the ASN.1 format but also a
> > > URI scheme for referencing objects in NVRAM. A TPMv2 version of 
> > > https://datatracker.ietf.org/doc/html/draft-mavrogiannopoulos-tpmuri-01
> > > might be a good idea.
> > 
> > I'm not so sure ... the keys are files not tokens and the pkcs11
> > URI doesn't have a file pointer.  I suspect the correct way to
> > represent them would be to fully represent the key in the URI,
> > which sounds like a length explosion.
> 
> Not files, and definitely nothing to do with PKCS#11.
> 
> I meant a URI for referring to keys which are in NVRAM. The kind you
> currently use the '//nvkey:' prefix for.
> 
> We should standardise that form, as a URI, so that users can take
> that same URI to *any* application and expect it to work. That's
> what https://tools.ietf.org/html/draft-mavrogiannopoulos-tpmuri-01
> was doing, for TPMv1.2.

I'm not so sure we want to encourage that.  The persistent handle space
is really limited in TPM 2.0.  We just ran into a real world situation
where the TPM ran out after a handful.  It was an application that
loaded files into persistent handles ("because it's easier") and then
made use of them ... we're currently fixing it not to use persistent
handles because it doesn't need to.

James
David Woodhouse May 21, 2021, 5:53 p.m. UTC | #7
On Fri, 2021-05-21 at 09:17 -0700, James Bottomley wrote:
> I'm not so sure we want to encourage that.  The persistent handle space
> is really limited in TPM 2.0.  We just ran into a real world situation
> where the TPM ran out after a handful.  It was an application that
> loaded files into persistent handles ("because it's easier") and then
> made use of them ... we're currently fixing it not to use persistent
> handles because it doesn't need to.

Makes sense. We should fix StrongSwan then, because they're doing the
same thing.

https://wiki.strongswan.org/projects/strongswan/wiki/TpmPlugin

Of course, if we document the file format and make it ubiquitously
supported (including making an OpenSSL *provider* to replace the
obsolete ENGINEs, and chasing it into GnuTLS in 
https://gitlab.com/gnutls/gnutls/-/issues/594 ), that will go a long
way towards encouraging applications to use keys wrapped in files
instead of NVRAM...
Jarkko Sakkinen May 22, 2021, 10:45 p.m. UTC | #8
On Fri, May 21, 2021 at 02:48:55PM +0100, David Woodhouse wrote:
> On Thu, 2021-05-20 at 17:43 -0700, James Bottomley wrote:
> > Now that the ASN.1 representation of trusted keys is upstream we can
> > add policy to the keys as a sequence of policy statements meaning the
> > kernel can now construct and use the policy session rather than the
> > user having to do it and pass the session down to the kernel.  This
> > makes TPM 2.0 keys with policy much easier.
> > 
> > The format of the policy statements is compatible with the
> > openssl_tpm2_engine policy implementation:
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/
> > 
> > And the seal_tpm2_data command in the above can be used to create
> > sealed keys (including with policy statements) for the kernel.
> 
> I'd love to see that format properly defined and documented instead of
> just a reference to another implementation.

A valid point. How can we know that this is good for "everyone"?

Also, one major thing that this patch set is kselftest's. It's too
obnoxious to copy-paste examples from commit messages, and also
does not really create a good platform to discuss any possible
issues that these patches might have.

/Jarkko