mbox series

[v4,00/13] add integrity and security to TPM2 transactions

Message ID 20230403214003.32093-1-James.Bottomley@HansenPartnership.com (mailing list archive)
Headers show
Series add integrity and security to TPM2 transactions | expand

Message

James Bottomley April 3, 2023, 9:39 p.m. UTC
The interest in securing the TPM against interposers, both active and
passive has risen to fever pitch with the demonstration of key
recovery against windows bitlocker:

https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network

And subsequently the same attack being successful against all the
Linux TPM based security solutions:

https://www.secura.com/blog/tpm-sniffing-attacks-against-non-bitlocker-targets

The attacks fall into two categories:

1. Passive Interposers, which sit on the bus and merely observe
2. Active Interposers, which try to manipulate TPM transactions on the
   bus using man in the middle and packet stealing to create TPM state
   the interposer owner desires.

Our broadest interposer target is the use of TPM_RS_PW for password
authorization which sends the actual password to the TPM without any
obfuscation and effectively hands it to any interposer. The way to fix
this is to use real sessions for HMAC capabilities to ensure integrity
and to use parameter and response encryption to ensure confidentiality
of the data flowing over the TPM bus.  HMAC sessions by agreeing a
challenge with the TPM and then giving a response which is a HMAC of
the password and the challenge, so the application proves knowledge of
the password to the TPM without ever transmitting the password itself.
Using HMAC sessions when sending commands to the TPM also provides
some measure of protection against active interposers, since the
interposer can't interfere with or delete a HMAC'd command (because
they can't manufacture a response with the correct HMAC).

To protect TPM transactions where there isn't a shared secret
(i.e. the command is something like a PCR extension which doesn't
involve a TPM object with a password) we have to do a bit more work to
set up sessions with a passed in encrypted secret (called a salt) to
act in place of the shared secret in the HMAC.  This secret salt is
effectively a random number encrypted to a public key of the TPM.  The
final piece of the puzzle is using parameter input and response return
encryption, so any interposer can't see the data passing from the
application to the TPM and vice versa.

The most insidious interposer attack of all is a reset attack: since
the interposer has access to the TPM bus, it can assert the TPM reset
line any time it wants.  When a TPM resets it mostly comes back in the
same state except that all the PCRs are reset to their initial values.
Controlling the reset line allows the interposer to change the PCR
state after the fact by resetting the TPM and then replaying PCR
extends to get the PCRs into a valid state to release secrets, so even
if an attack event was recorded, the record is erased.  This reset
attack violates the fundamental princible of non-repudiability of TPM
logs.  Defeating the reset attack involves tying all TPM operations
within the kernel to a property which will change detectably if the
TPM is reset.  For that reason, we tie all TPM sessions to the null
hierarchy we obtain at start of day and whose seed changes on every
reset.  If an active interposer asserts a TPM reset, the new null
primary won't match the kernel's stored one and all TPM operations
will start failing because of HMAC mismatches in the sessions.  So if
the kernel TPM code keeps operating, it guarantees that a reset hasn't
occurred.

The final part of the puzzle is that the machine owner must have a
fixed idea of the EK of their TPM and should have certified this with
the TPM manufacturer.  On every boot, the certified EK public key
should be used to do a make credential/activate credential attestation
key insertion and then the null key certified with the attestation
key.  We can follow a trust on first use model where an OS
installation will extract and verify a public EK and save it to a read
only file.

This patch series adds a simple API which can ensure the above
properties as a layered addition to the existing TPM handling code.
This series now includes protections for PCR extend, getting random
numbers from the TPM and data sealing and unsealing.  It therefore
eliminates all uses of TPM2_RS_PW in the kernel and adds encryption
protection to sensitive data flowing into and out of the TPM.  The
first four patches add more sophisticated buffer handling to the TPM
which is needed to build the more complex encryption and
authentication based commands.  Patch 6 adds all the generic
cryptography primitives and patches 7-9 use them in critical TPM
operations where we want to avoid or detect interposers.  Patch 10
exports the name of the null key we used for boot/run time
verification and patch 11 documents the security guarantees and
expectations.

This was originally sent over four years ago, with the last iteration
being:

https://lore.kernel.org/linux-integrity/1568031515.6613.31.camel@HansenPartnership.com/

I'm dusting it off now because various forces at Microsoft and Google
via the Open Compute Platform are making a lot of noise about
interposers and we in the linux kernel look critically lacking in that
regard, particularly for TPM trusted keys.

---
v2 fixes the problems smatch reported and adds more explanation about
the code motion in the first few patches
v3 rebases the encryption to be against Ard's new library function, the
aescfb addition of which appears as patch 1.
v4 refreshes Ard's patch, adds kernel doc (including a new patch to
add it to the moved tpm-buf functions) updates and rewords some commit
logs

James

---

Ard Biesheuvel (1):
  crypto: lib - implement library version of AES in CFB mode

James Bottomley (12):
  tpm: move buffer handling from static inlines to real functions
  tpm: add kernel doc to buffer handling functions
  tpm: add buffer handling for TPM2B types
  tpm: add cursor based buffer functions for response parsing
  tpm: add buffer function to point to returned parameters
  tpm: export the context save and load commands
  tpm: Add full HMAC and encrypt/decrypt session handling code
  tpm: add hmac checks to tpm2_pcr_extend()
  tpm: add session encryption protection to tpm2_get_random()
  KEYS: trusted: Add session encryption protection to the seal/unseal
    path
  tpm: add the null key name as a sysfs export
  Documentation: add tpm-security.rst

 Documentation/security/tpm/tpm-security.rst |  216 ++++
 drivers/char/tpm/Kconfig                    |   13 +
 drivers/char/tpm/Makefile                   |    2 +
 drivers/char/tpm/tpm-buf.c                  |  307 +++++
 drivers/char/tpm/tpm-chip.c                 |    3 +
 drivers/char/tpm/tpm-sysfs.c                |   18 +
 drivers/char/tpm/tpm.h                      |   14 +
 drivers/char/tpm/tpm2-cmd.c                 |   52 +-
 drivers/char/tpm/tpm2-sessions.c            | 1158 +++++++++++++++++++
 drivers/char/tpm/tpm2-space.c               |    8 +-
 include/crypto/aes.h                        |    5 +
 include/linux/tpm.h                         |  257 ++--
 lib/crypto/Kconfig                          |    5 +
 lib/crypto/Makefile                         |    3 +
 lib/crypto/aescfb.c                         |  257 ++++
 security/keys/trusted-keys/trusted_tpm2.c   |   82 +-
 16 files changed, 2275 insertions(+), 125 deletions(-)
 create mode 100644 Documentation/security/tpm/tpm-security.rst
 create mode 100644 drivers/char/tpm/tpm-buf.c
 create mode 100644 drivers/char/tpm/tpm2-sessions.c
 create mode 100644 lib/crypto/aescfb.c

Comments

William Roberts April 4, 2023, 6:43 p.m. UTC | #1
On Mon, Apr 3, 2023 at 4:44 PM James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>
> The interest in securing the TPM against interposers, both active and
> passive has risen to fever pitch with the demonstration of key
> recovery against windows bitlocker:
>
> https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network
>
> And subsequently the same attack being successful against all the
> Linux TPM based security solutions:
>
> https://www.secura.com/blog/tpm-sniffing-attacks-against-non-bitlocker-targets
>

I fixed systemd, see the relevant PRS:
  - https://github.com/systemd/systemd/pulls?q=is%3Apr+is%3Aclosed+author%3Awilliamcroberts

They had some support where they would create a primary key on each
boot and just trust it, eventually
we:
1. Added a bind key as a stop gap
2. strengthened passwords for the bind key
3. Added verification of the tpm key to a trusted public blob and used
the persistent SRK.

I could drop the bind key now if the SRK is present as it's not
needed, but it shouldn't hurt anything.
The big issue is the period of 1 to 2 where a weak pin could be
cracked offline. This occurs in
version 252 but the salt was merged in 253 and using SRK is on main.

> The attacks fall into two categories:
>
> 1. Passive Interposers, which sit on the bus and merely observe
> 2. Active Interposers, which try to manipulate TPM transactions on the
>    bus using man in the middle and packet stealing to create TPM state
>    the interposer owner desires.
>
> Our broadest interposer target is the use of TPM_RS_PW for password
> authorization which sends the actual password to the TPM without any
> obfuscation and effectively hands it to any interposer. The way to fix
> this is to use real sessions for HMAC capabilities to ensure integrity
> and to use parameter and response encryption to ensure confidentiality
> of the data flowing over the TPM bus.  HMAC sessions by agreeing a
> challenge with the TPM and then giving a response which is a HMAC of
> the password and the challenge, so the application proves knowledge of
> the password to the TPM without ever transmitting the password itself.
> Using HMAC sessions when sending commands to the TPM also provides
> some measure of protection against active interposers, since the
> interposer can't interfere with or delete a HMAC'd command (because
> they can't manufacture a response with the correct HMAC).
>
> To protect TPM transactions where there isn't a shared secret
> (i.e. the command is something like a PCR extension which doesn't
> involve a TPM object with a password) we have to do a bit more work to
> set up sessions with a passed in encrypted secret (called a salt) to
> act in place of the shared secret in the HMAC.  This secret salt is
> effectively a random number encrypted to a public key of the TPM.  The
> final piece of the puzzle is using parameter input and response return
> encryption, so any interposer can't see the data passing from the
> application to the TPM and vice versa.
>
> The most insidious interposer attack of all is a reset attack: since
> the interposer has access to the TPM bus, it can assert the TPM reset
> line any time it wants.  When a TPM resets it mostly comes back in the
> same state except that all the PCRs are reset to their initial values.
> Controlling the reset line allows the interposer to change the PCR
> state after the fact by resetting the TPM and then replaying PCR
> extends to get the PCRs into a valid state to release secrets, so even
> if an attack event was recorded, the record is erased.  This reset
> attack violates the fundamental princible of non-repudiability of TPM
> logs.  Defeating the reset attack involves tying all TPM operations
> within the kernel to a property which will change detectably if the
> TPM is reset.  For that reason, we tie all TPM sessions to the null
> hierarchy we obtain at start of day and whose seed changes on every
> reset.  If an active interposer asserts a TPM reset, the new null
> primary won't match the kernel's stored one and all TPM operations
> will start failing because of HMAC mismatches in the sessions.  So if
> the kernel TPM code keeps operating, it guarantees that a reset hasn't
> occurred.
>
> The final part of the puzzle is that the machine owner must have a
> fixed idea of the EK of their TPM and should have certified this with
> the TPM manufacturer.  On every boot, the certified EK public key
> should be used to do a make credential/activate credential attestation
> key insertion and then the null key certified with the attestation
> key.  We can follow a trust on first use model where an OS
> installation will extract and verify a public EK and save it to a read
> only file.

Ahh I was wondering how you were going to bootstrap trust using the
NULL hierarchy.

>
> This patch series adds a simple API which can ensure the above
> properties as a layered addition to the existing TPM handling code.
> This series now includes protections for PCR extend, getting random
> numbers from the TPM and data sealing and unsealing.  It therefore
> eliminates all uses of TPM2_RS_PW in the kernel and adds encryption
> protection to sensitive data flowing into and out of the TPM.  The
> first four patches add more sophisticated buffer handling to the TPM
> which is needed to build the more complex encryption and
> authentication based commands.  Patch 6 adds all the generic
> cryptography primitives and patches 7-9 use them in critical TPM
> operations where we want to avoid or detect interposers.  Patch 10
> exports the name of the null key we used for boot/run time
> verification and patch 11 documents the security guarantees and
> expectations.
>
> This was originally sent over four years ago, with the last iteration
> being:
>
> https://lore.kernel.org/linux-integrity/1568031515.6613.31.camel@HansenPartnership.com/
>
> I'm dusting it off now because various forces at Microsoft and Google
> via the Open Compute Platform are making a lot of noise about
> interposers and we in the linux kernel look critically lacking in that
> regard, particularly for TPM trusted keys.
>
> ---
> v2 fixes the problems smatch reported and adds more explanation about
> the code motion in the first few patches
> v3 rebases the encryption to be against Ard's new library function, the
> aescfb addition of which appears as patch 1.
> v4 refreshes Ard's patch, adds kernel doc (including a new patch to
> add it to the moved tpm-buf functions) updates and rewords some commit
> logs
>
> James
>
> ---
>
> Ard Biesheuvel (1):
>   crypto: lib - implement library version of AES in CFB mode
>
> James Bottomley (12):
>   tpm: move buffer handling from static inlines to real functions
>   tpm: add kernel doc to buffer handling functions
>   tpm: add buffer handling for TPM2B types
>   tpm: add cursor based buffer functions for response parsing
>   tpm: add buffer function to point to returned parameters
>   tpm: export the context save and load commands
>   tpm: Add full HMAC and encrypt/decrypt session handling code
>   tpm: add hmac checks to tpm2_pcr_extend()
>   tpm: add session encryption protection to tpm2_get_random()
>   KEYS: trusted: Add session encryption protection to the seal/unseal
>     path
>   tpm: add the null key name as a sysfs export
>   Documentation: add tpm-security.rst
>
>  Documentation/security/tpm/tpm-security.rst |  216 ++++
>  drivers/char/tpm/Kconfig                    |   13 +
>  drivers/char/tpm/Makefile                   |    2 +
>  drivers/char/tpm/tpm-buf.c                  |  307 +++++
>  drivers/char/tpm/tpm-chip.c                 |    3 +
>  drivers/char/tpm/tpm-sysfs.c                |   18 +
>  drivers/char/tpm/tpm.h                      |   14 +
>  drivers/char/tpm/tpm2-cmd.c                 |   52 +-
>  drivers/char/tpm/tpm2-sessions.c            | 1158 +++++++++++++++++++
>  drivers/char/tpm/tpm2-space.c               |    8 +-
>  include/crypto/aes.h                        |    5 +
>  include/linux/tpm.h                         |  257 ++--
>  lib/crypto/Kconfig                          |    5 +
>  lib/crypto/Makefile                         |    3 +
>  lib/crypto/aescfb.c                         |  257 ++++
>  security/keys/trusted-keys/trusted_tpm2.c   |   82 +-
>  16 files changed, 2275 insertions(+), 125 deletions(-)
>  create mode 100644 Documentation/security/tpm/tpm-security.rst
>  create mode 100644 drivers/char/tpm/tpm-buf.c
>  create mode 100644 drivers/char/tpm/tpm2-sessions.c
>  create mode 100644 lib/crypto/aescfb.c
>
> --
> 2.35.3
>
James Bottomley April 4, 2023, 7:18 p.m. UTC | #2
On Tue, 2023-04-04 at 13:43 -0500, William Roberts wrote:
[...]
> > The final part of the puzzle is that the machine owner must have a
> > fixed idea of the EK of their TPM and should have certified this
> > with the TPM manufacturer.  On every boot, the certified EK public
> > key should be used to do a make credential/activate credential
> > attestation key insertion and then the null key certified with the
> > attestation key.  We can follow a trust on first use model where an
> > OS installation will extract and verify a public EK and save it to
> > a read only file.
> 
> Ahh I was wondering how you were going to bootstrap trust using the
> NULL hierarchy.

Well, actually, I changed my mind on the details of this one: the make
credential/activate credential round trip is a huge faff given that
there's no privacy issue.  I think what we should do is simply store
the name of a known signing EK on first install (using the standard P-
256 derivation of the EK template but with TPMA_OBJECT_SIGN
additionally set).  Then you can use the signing EK to certify the NULL
key directly and merely check the signing EK name against the stored
value to prove everything is correct.

James
William Roberts April 4, 2023, 7:42 p.m. UTC | #3
On Tue, Apr 4, 2023 at 2:18 PM James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>
> On Tue, 2023-04-04 at 13:43 -0500, William Roberts wrote:
> [...]
> > > The final part of the puzzle is that the machine owner must have a
> > > fixed idea of the EK of their TPM and should have certified this
> > > with the TPM manufacturer.  On every boot, the certified EK public
> > > key should be used to do a make credential/activate credential
> > > attestation key insertion and then the null key certified with the
> > > attestation key.  We can follow a trust on first use model where an
> > > OS installation will extract and verify a public EK and save it to
> > > a read only file.
> >
> > Ahh I was wondering how you were going to bootstrap trust using the
> > NULL hierarchy.
>
> Well, actually, I changed my mind on the details of this one: the make
> credential/activate credential round trip is a huge faff given that
> there's no privacy issue.  I think what we should do is simply store
> the name of a known signing EK on first install (using the standard P-
> 256 derivation of the EK template but with TPMA_OBJECT_SIGN
> additionally set).  Then you can use the signing EK to certify the NULL
> key directly and merely check the signing EK name against the stored
> value to prove everything is correct.
>

Yeah that model is much simpler. My guess is that on install it would
persist this
"Signing EK" to a specific address that is different from the typical
EK Address?
Any particular reason for using the Endorsement Hierarchy outside of
the lifespan of the seed only changing on revocation of the Manufacturers Cert?
Ie why not Owner Hierarchy?

> James
>
James Bottomley April 4, 2023, 8:19 p.m. UTC | #4
On Tue, 2023-04-04 at 14:42 -0500, William Roberts wrote:
> On Tue, Apr 4, 2023 at 2:18 PM James Bottomley
> <James.Bottomley@hansenpartnership.com> wrote:
> > 
> > On Tue, 2023-04-04 at 13:43 -0500, William Roberts wrote:
> > [...]
> > > > The final part of the puzzle is that the machine owner must
> > > > have a fixed idea of the EK of their TPM and should have
> > > > certified this with the TPM manufacturer.  On every boot, the
> > > > certified EK public key should be used to do a make
> > > > credential/activate credential attestation key insertion and
> > > > then the null key certified with the attestation key.  We can
> > > > follow a trust on first use model where an OS installation will
> > > > extract and verify a public EK and save it to a read only file.
> > > 
> > > Ahh I was wondering how you were going to bootstrap trust using
> > > the NULL hierarchy.
> > 
> > Well, actually, I changed my mind on the details of this one: the
> > make credential/activate credential round trip is a huge faff given
> > that there's no privacy issue.  I think what we should do is simply
> > store the name of a known signing EK on first install (using the
> > standard P-256 derivation of the EK template but with
> > TPMA_OBJECT_SIGN additionally set).  Then you can use the signing
> > EK to certify the NULL key directly and merely check the signing EK
> > name against the stored value to prove everything is correct.
> > 
> 
> Yeah that model is much simpler. My guess is that on install it would
> persist this "Signing EK" to a specific address that is different
> from the typical EK Address?

Actually, since this is used to prove trust in the TPM, we can't have
the TPM store it; it's going to have to be somewhere in the root
filesystem, like /etc.  Ideally it would be in the immutable part of
/etc so it is write once on install.

> Any particular reason for using the Endorsement Hierarchy outside of
> the lifespan of the seed only changing on revocation of the
> Manufacturers Cert? Ie why not Owner Hierarchy?

That's it really: it's the longest lived key of all those the TPM has.
If I'm deriving it once on install and keeping it immutable until
reinstall, I don't want tpm_clear upsetting the apple cart.

James
William Roberts April 4, 2023, 9:10 p.m. UTC | #5
On Tue, Apr 4, 2023 at 3:19 PM James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>
> On Tue, 2023-04-04 at 14:42 -0500, William Roberts wrote:
> > On Tue, Apr 4, 2023 at 2:18 PM James Bottomley
> > <James.Bottomley@hansenpartnership.com> wrote:
> > >
> > > On Tue, 2023-04-04 at 13:43 -0500, William Roberts wrote:
> > > [...]
> > > > > The final part of the puzzle is that the machine owner must
> > > > > have a fixed idea of the EK of their TPM and should have
> > > > > certified this with the TPM manufacturer.  On every boot, the
> > > > > certified EK public key should be used to do a make
> > > > > credential/activate credential attestation key insertion and
> > > > > then the null key certified with the attestation key.  We can
> > > > > follow a trust on first use model where an OS installation will
> > > > > extract and verify a public EK and save it to a read only file.
> > > >
> > > > Ahh I was wondering how you were going to bootstrap trust using
> > > > the NULL hierarchy.
> > >
> > > Well, actually, I changed my mind on the details of this one: the
> > > make credential/activate credential round trip is a huge faff given
> > > that there's no privacy issue.  I think what we should do is simply
> > > store the name of a known signing EK on first install (using the
> > > standard P-256 derivation of the EK template but with
> > > TPMA_OBJECT_SIGN additionally set).  Then you can use the signing
> > > EK to certify the NULL key directly and merely check the signing EK
> > > name against the stored value to prove everything is correct.
> > >
> >
> > Yeah that model is much simpler. My guess is that on install it would
> > persist this "Signing EK" to a specific address that is different
> > from the typical EK Address?
>
> Actually, since this is used to prove trust in the TPM, we can't have
> the TPM store it;

Hmm, I think we miscommunicated here. At some point you need to call
TPM2_CreatePrimary
with the "Signing EK" template which would require Endorsement
Hierarchy (EH) Auth. So I would
imagine this key would be persistend to avoid needing it all the time?
Then the use of
TPM2_Certify using the "EK Signing" key would also need EH Auth since
AuthPolicy is coupled to EH Auth
via PolicySecret. I'm just thinking every time these commands are
invoked, especially if this is used
during boot, where EH Auth would be coming from or am I missing something?

> it's going to have to be somewhere in the root
> filesystem, like /etc.  Ideally it would be in the immutable part of
> /etc so it is write once on install.
>

I'm assuming this would be the template or name of the "Signing EK"?

In systemd we just shove the name (Actually a serialized ESYS_TR) of
the SRK into
the LUKS data and ESAPI handles the check in session establishment.

> > Any particular reason for using the Endorsement Hierarchy outside of
> > the lifespan of the seed only changing on revocation of the
> > Manufacturers Cert? Ie why not Owner Hierarchy?
>
> That's it really: it's the longest lived key of all those the TPM has.
> If I'm deriving it once on install and keeping it immutable until
> reinstall, I don't want tpm_clear upsetting the apple cart.
>
> James
>
James Bottomley April 4, 2023, 9:33 p.m. UTC | #6
On Tue, 2023-04-04 at 16:10 -0500, William Roberts wrote:
> On Tue, Apr 4, 2023 at 3:19 PM James Bottomley
> <James.Bottomley@hansenpartnership.com> wrote:
> > 
> > On Tue, 2023-04-04 at 14:42 -0500, William Roberts wrote:
> > > On Tue, Apr 4, 2023 at 2:18 PM James Bottomley
> > > <James.Bottomley@hansenpartnership.com> wrote:
> > > > 
> > > > On Tue, 2023-04-04 at 13:43 -0500, William Roberts wrote:
> > > > [...]
> > > > > > The final part of the puzzle is that the machine owner must
> > > > > > have a fixed idea of the EK of their TPM and should have
> > > > > > certified this with the TPM manufacturer.  On every boot,
> > > > > > the certified EK public key should be used to do a make
> > > > > > credential/activate credential attestation key insertion
> > > > > > and then the null key certified with the attestation key. 
> > > > > > We can follow a trust on first use model where an OS
> > > > > > installation will extract and verify a public EK and save
> > > > > > it to a read only file.
> > > > > 
> > > > > Ahh I was wondering how you were going to bootstrap trust
> > > > > using the NULL hierarchy.
> > > > 
> > > > Well, actually, I changed my mind on the details of this one:
> > > > the make credential/activate credential round trip is a huge
> > > > faff given that there's no privacy issue.  I think what we
> > > > should do is simply store the name of a known signing EK on
> > > > first install (using the standard P-256 derivation of the EK
> > > > template but with TPMA_OBJECT_SIGN additionally set).  Then you
> > > > can use the signing EK to certify the NULL key directly and
> > > > merely check the signing EK name against the stored value to
> > > > prove everything is correct.
> > > > 
> > > 
> > > Yeah that model is much simpler. My guess is that on install it
> > > would persist this "Signing EK" to a specific address that is
> > > different from the typical EK Address?
> > 
> > Actually, since this is used to prove trust in the TPM, we can't
> > have the TPM store it;
> 
> Hmm, I think we miscommunicated here. At some point you need to call
> TPM2_CreatePrimary with the "Signing EK" template which would require
> Endorsement Hierarchy (EH) Auth.

That's right.  Then you hash what you get back and check it against the
name file.

>  So I would imagine this key would be persistend to avoid needing it
> all the time?

You could, but the benefit is marginal given how fast the Elliptic
Curve calculation can be done.  Remember the key is only needed for a
quote or a certification, so that's once per boot to certify the NULL
seed and possibly a handful of other uses.

> Then the use of TPM2_Certify using the "EK Signing" key would also
> need EH Auth since AuthPolicy is coupled to EH Auth via PolicySecret.
> I'm just thinking every time these commands are invoked, especially
> if this is used during boot, where EH Auth would be coming from or am
> I missing something?

No, but then TPM2_CreatePrimary needs the hierarchy authorizations. 
The standard assumption I tend to make is that they're empty for both
the endorsement and owner.

Although if there's a use case that actually wants them set for some
reason, then I think there might be a case for removing the policy from
the EK template, but if not, it's easier just to follow what the TCG
says with the addition of the signing permission.

> > it's going to have to be somewhere in the root
> > filesystem, like /etc.  Ideally it would be in the immutable part
> > of /etc so it is write once on install.
> > 
> 
> I'm assuming this would be the template or name of the "Signing EK"?

Just the name, I think, assuming everyone agrees on the template.  If
there's going to be a question about which template then we'd need
both.

James
William Roberts April 4, 2023, 9:44 p.m. UTC | #7
On Tue, Apr 4, 2023 at 4:33 PM James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>
> On Tue, 2023-04-04 at 16:10 -0500, William Roberts wrote:
> > On Tue, Apr 4, 2023 at 3:19 PM James Bottomley
> > <James.Bottomley@hansenpartnership.com> wrote:
> > >
> > > On Tue, 2023-04-04 at 14:42 -0500, William Roberts wrote:
> > > > On Tue, Apr 4, 2023 at 2:18 PM James Bottomley
> > > > <James.Bottomley@hansenpartnership.com> wrote:
> > > > >
> > > > > On Tue, 2023-04-04 at 13:43 -0500, William Roberts wrote:
> > > > > [...]
> > > > > > > The final part of the puzzle is that the machine owner must
> > > > > > > have a fixed idea of the EK of their TPM and should have
> > > > > > > certified this with the TPM manufacturer.  On every boot,
> > > > > > > the certified EK public key should be used to do a make
> > > > > > > credential/activate credential attestation key insertion
> > > > > > > and then the null key certified with the attestation key.
> > > > > > > We can follow a trust on first use model where an OS
> > > > > > > installation will extract and verify a public EK and save
> > > > > > > it to a read only file.
> > > > > >
> > > > > > Ahh I was wondering how you were going to bootstrap trust
> > > > > > using the NULL hierarchy.
> > > > >
> > > > > Well, actually, I changed my mind on the details of this one:
> > > > > the make credential/activate credential round trip is a huge
> > > > > faff given that there's no privacy issue.  I think what we
> > > > > should do is simply store the name of a known signing EK on
> > > > > first install (using the standard P-256 derivation of the EK
> > > > > template but with TPMA_OBJECT_SIGN additionally set).  Then you
> > > > > can use the signing EK to certify the NULL key directly and
> > > > > merely check the signing EK name against the stored value to
> > > > > prove everything is correct.
> > > > >
> > > >
> > > > Yeah that model is much simpler. My guess is that on install it
> > > > would persist this "Signing EK" to a specific address that is
> > > > different from the typical EK Address?
> > >
> > > Actually, since this is used to prove trust in the TPM, we can't
> > > have the TPM store it;
> >
> > Hmm, I think we miscommunicated here. At some point you need to call
> > TPM2_CreatePrimary with the "Signing EK" template which would require
> > Endorsement Hierarchy (EH) Auth.
>
> That's right.  Then you hash what you get back and check it against the
> name file.
>
> >  So I would imagine this key would be persistend to avoid needing it
> > all the time?
>
> You could, but the benefit is marginal given how fast the Elliptic
> Curve calculation can be done.  Remember the key is only needed for a
> quote or a certification, so that's once per boot to certify the NULL
> seed and possibly a handful of other uses.
>
> > Then the use of TPM2_Certify using the "EK Signing" key would also
> > need EH Auth since AuthPolicy is coupled to EH Auth via PolicySecret.
> > I'm just thinking every time these commands are invoked, especially
> > if this is used during boot, where EH Auth would be coming from or am
> > I missing something?
>
> No, but then TPM2_CreatePrimary needs the hierarchy authorizations.
> The standard assumption I tend to make is that they're empty for both
> the endorsement and owner.
>

That's been proven not to be a good assertion. Just look at the bugs on systemd
about not working if Owner Auth is set. I think it's important to look at models
that support auth being set for the hierarchy and minimizing the need on it.
Hierarchy Auth could even be a policy, thankfully I haven't bumped into that
yet.

If this "EK Signing" key is persisted and the AuthPolicy of the key
cleared we would only
need EH Auth one time versus assuming it's always empty. This would
essentially be
an SRK for the EH but includes sign attribute (ERK :-p).

But if we're shoving stuff into a read only config, these options
could be set in the config file
(ie use a persistent handle at location XXX, no auth, etc). But *not*
hardcoding EH auth into
the config file.

I would hate to see requirements requiring that hierarchy auth remains empty.

> Although if there's a use case that actually wants them set for some
> reason, then I think there might be a case for removing the policy from
> the EK template, but if not, it's easier just to follow what the TCG
> says with the addition of the signing permission.
>
> > > it's going to have to be somewhere in the root
> > > filesystem, like /etc.  Ideally it would be in the immutable part
> > > of /etc so it is write once on install.
> > >
> >
> > I'm assuming this would be the template or name of the "Signing EK"?
>
> Just the name, I think, assuming everyone agrees on the template.  If
> there's going to be a question about which template then we'd need
> both.
>
> James
>
William Roberts April 5, 2023, 6:39 p.m. UTC | #8
On Mon, Apr 3, 2023 at 4:44 PM James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>
> The interest in securing the TPM against interposers, both active and
> passive has risen to fever pitch with the demonstration of key
> recovery against windows bitlocker:
>
> https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network
>
> And subsequently the same attack being successful against all the
> Linux TPM based security solutions:
>
> https://www.secura.com/blog/tpm-sniffing-attacks-against-non-bitlocker-targets
>
> The attacks fall into two categories:
>
> 1. Passive Interposers, which sit on the bus and merely observe
> 2. Active Interposers, which try to manipulate TPM transactions on the
>    bus using man in the middle and packet stealing to create TPM state
>    the interposer owner desires.
>
> Our broadest interposer target is the use of TPM_RS_PW for password
> authorization which sends the actual password to the TPM without any
> obfuscation and effectively hands it to any interposer. The way to fix
> this is to use real sessions for HMAC capabilities to ensure integrity
> and to use parameter and response encryption to ensure confidentiality
> of the data flowing over the TPM bus.  HMAC sessions by agreeing a
> challenge with the TPM and then giving a response which is a HMAC of
> the password and the challenge, so the application proves knowledge of
> the password to the TPM without ever transmitting the password itself.
> Using HMAC sessions when sending commands to the TPM also provides
> some measure of protection against active interposers, since the
> interposer can't interfere with or delete a HMAC'd command (because
> they can't manufacture a response with the correct HMAC).
>
> To protect TPM transactions where there isn't a shared secret
> (i.e. the command is something like a PCR extension which doesn't
> involve a TPM object with a password) we have to do a bit more work to
> set up sessions with a passed in encrypted secret (called a salt) to
> act in place of the shared secret in the HMAC.  This secret salt is
> effectively a random number encrypted to a public key of the TPM.  The
> final piece of the puzzle is using parameter input and response return
> encryption, so any interposer can't see the data passing from the
> application to the TPM and vice versa.
>
> The most insidious interposer attack of all is a reset attack: since
> the interposer has access to the TPM bus, it can assert the TPM reset
> line any time it wants.  When a TPM resets it mostly comes back in the
> same state except that all the PCRs are reset to their initial values.
> Controlling the reset line allows the interposer to change the PCR
> state after the fact by resetting the TPM and then replaying PCR
> extends to get the PCRs into a valid state to release secrets, so even
> if an attack event was recorded, the record is erased.  This reset
> attack violates the fundamental princible of non-repudiability of TPM
> logs.  Defeating the reset attack involves tying all TPM operations
> within the kernel to a property which will change detectably if the
> TPM is reset.  For that reason, we tie all TPM sessions to the null
> hierarchy we obtain at start of day and whose seed changes on every
> reset.

Rather than doing this, wouldn't the session be flushed from the TPM on
reset and thus subsequent commands using the session and session key
fail?

If that's true, couldn't we just pin the trust to an existing trusted
key that we have the
name of and move on? The kernel would know that something happened when
session protections started failing without the complexity and time of
generating
a key in the NULL hierarchy and certifying it.

If an active interposer asserts a TPM reset, the new null
> primary won't match the kernel's stored one and all TPM operations
> will start failing because of HMAC mismatches in the sessions.  So if
> the kernel TPM code keeps operating, it guarantees that a reset hasn't
> occurred.
>
> The final part of the puzzle is that the machine owner must have a
> fixed idea of the EK of their TPM and should have certified this with
> the TPM manufacturer.  On every boot, the certified EK public key
> should be used to do a make credential/activate credential attestation
> key insertion and then the null key certified with the attestation
> key.  We can follow a trust on first use model where an OS
> installation will extract and verify a public EK and save it to a read
> only file.
>
> This patch series adds a simple API which can ensure the above
> properties as a layered addition to the existing TPM handling code.
> This series now includes protections for PCR extend, getting random
> numbers from the TPM and data sealing and unsealing.  It therefore
> eliminates all uses of TPM2_RS_PW in the kernel and adds encryption
> protection to sensitive data flowing into and out of the TPM.  The
> first four patches add more sophisticated buffer handling to the TPM
> which is needed to build the more complex encryption and
> authentication based commands.  Patch 6 adds all the generic
> cryptography primitives and patches 7-9 use them in critical TPM
> operations where we want to avoid or detect interposers.  Patch 10
> exports the name of the null key we used for boot/run time
> verification and patch 11 documents the security guarantees and
> expectations.
>
> This was originally sent over four years ago, with the last iteration
> being:
>
> https://lore.kernel.org/linux-integrity/1568031515.6613.31.camel@HansenPartnership.com/
>
> I'm dusting it off now because various forces at Microsoft and Google
> via the Open Compute Platform are making a lot of noise about
> interposers and we in the linux kernel look critically lacking in that
> regard, particularly for TPM trusted keys.
>
> ---
> v2 fixes the problems smatch reported and adds more explanation about
> the code motion in the first few patches
> v3 rebases the encryption to be against Ard's new library function, the
> aescfb addition of which appears as patch 1.
> v4 refreshes Ard's patch, adds kernel doc (including a new patch to
> add it to the moved tpm-buf functions) updates and rewords some commit
> logs
>
> James
>
> ---
>
> Ard Biesheuvel (1):
>   crypto: lib - implement library version of AES in CFB mode
>
> James Bottomley (12):
>   tpm: move buffer handling from static inlines to real functions
>   tpm: add kernel doc to buffer handling functions
>   tpm: add buffer handling for TPM2B types
>   tpm: add cursor based buffer functions for response parsing
>   tpm: add buffer function to point to returned parameters
>   tpm: export the context save and load commands
>   tpm: Add full HMAC and encrypt/decrypt session handling code
>   tpm: add hmac checks to tpm2_pcr_extend()
>   tpm: add session encryption protection to tpm2_get_random()
>   KEYS: trusted: Add session encryption protection to the seal/unseal
>     path
>   tpm: add the null key name as a sysfs export
>   Documentation: add tpm-security.rst
>
>  Documentation/security/tpm/tpm-security.rst |  216 ++++
>  drivers/char/tpm/Kconfig                    |   13 +
>  drivers/char/tpm/Makefile                   |    2 +
>  drivers/char/tpm/tpm-buf.c                  |  307 +++++
>  drivers/char/tpm/tpm-chip.c                 |    3 +
>  drivers/char/tpm/tpm-sysfs.c                |   18 +
>  drivers/char/tpm/tpm.h                      |   14 +
>  drivers/char/tpm/tpm2-cmd.c                 |   52 +-
>  drivers/char/tpm/tpm2-sessions.c            | 1158 +++++++++++++++++++
>  drivers/char/tpm/tpm2-space.c               |    8 +-
>  include/crypto/aes.h                        |    5 +
>  include/linux/tpm.h                         |  257 ++--
>  lib/crypto/Kconfig                          |    5 +
>  lib/crypto/Makefile                         |    3 +
>  lib/crypto/aescfb.c                         |  257 ++++
>  security/keys/trusted-keys/trusted_tpm2.c   |   82 +-
>  16 files changed, 2275 insertions(+), 125 deletions(-)
>  create mode 100644 Documentation/security/tpm/tpm-security.rst
>  create mode 100644 drivers/char/tpm/tpm-buf.c
>  create mode 100644 drivers/char/tpm/tpm2-sessions.c
>  create mode 100644 lib/crypto/aescfb.c
>
> --
> 2.35.3
>
James Bottomley April 5, 2023, 7:41 p.m. UTC | #9
On Wed, 2023-04-05 at 13:39 -0500, William Roberts wrote:
> On Mon, Apr 3, 2023 at 4:44 PM James Bottomley
> <James.Bottomley@hansenpartnership.com> wrote:
[...]
> > The most insidious interposer attack of all is a reset attack:
> > since the interposer has access to the TPM bus, it can assert the
> > TPM reset line any time it wants.  When a TPM resets it mostly
> > comes back in the same state except that all the PCRs are reset to
> > their initial values.
> > Controlling the reset line allows the interposer to change the PCR
> > state after the fact by resetting the TPM and then replaying PCR
> > extends to get the PCRs into a valid state to release secrets, so
> > even if an attack event was recorded, the record is erased.  This
> > reset attack violates the fundamental princible of non-
> > repudiability of TPM logs.  Defeating the reset attack involves
> > tying all TPM operations within the kernel to a property which will
> > change detectably if the TPM is reset.  For that reason, we tie all
> > TPM sessions to the null hierarchy we obtain at start of day and
> > whose seed changes on every reset.
> 
> Rather than doing this, wouldn't the session be flushed from the TPM
> on reset and thus subsequent commands using the session and session
> key fail?

That would happen only if we kept a context saved session, which we
can't because the current session manager doesn't do de-gapping.  To
get around this we start a new, short lived, session for most
operations.

There has been a thought that it would be faster if we did context save
a session to keep re-using it, so adding de-gapping is on the list
somewhere, it's just not near the top yet.

> If that's true, couldn't we just pin the trust to an existing trusted
> key that we have the name of and move on? The kernel would know that
> something happened when session protections started failing without
> the complexity and time of generating a key in the NULL hierarchy and
> certifying it.

If the goal is to check not only the kernel but also the boot
components (like OVMF/EDK2), then we need a handoff protocol.  The
beauty of the NULL seed is the name is a nice short thing to handoff. 
If we relied on sessions, we'd have to hand off a whole context saved
session and all its nonces, which is a bit of a security risk.

James
William Roberts April 7, 2023, 2:40 p.m. UTC | #10
On Wed, Apr 5, 2023 at 1:41 PM James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>
> On Wed, 2023-04-05 at 13:39 -0500, William Roberts wrote:
> > On Mon, Apr 3, 2023 at 4:44 PM James Bottomley
> > <James.Bottomley@hansenpartnership.com> wrote:
> [...]
> > > The most insidious interposer attack of all is a reset attack:
> > > since the interposer has access to the TPM bus, it can assert the
> > > TPM reset line any time it wants.  When a TPM resets it mostly
> > > comes back in the same state except that all the PCRs are reset to
> > > their initial values.
> > > Controlling the reset line allows the interposer to change the PCR
> > > state after the fact by resetting the TPM and then replaying PCR
> > > extends to get the PCRs into a valid state to release secrets, so
> > > even if an attack event was recorded, the record is erased.  This
> > > reset attack violates the fundamental princible of non-
> > > repudiability of TPM logs.  Defeating the reset attack involves
> > > tying all TPM operations within the kernel to a property which will
> > > change detectably if the TPM is reset.  For that reason, we tie all
> > > TPM sessions to the null hierarchy we obtain at start of day and
> > > whose seed changes on every reset.
> >
> > Rather than doing this, wouldn't the session be flushed from the TPM
> > on reset and thus subsequent commands using the session and session
> > key fail?
>
> That would happen only if we kept a context saved session, which we
> can't because the current session manager doesn't do de-gapping.  To
> get around this we start a new, short lived, session for most
> operations.
>
> There has been a thought that it would be faster if we did context save
> a session to keep re-using it, so adding de-gapping is on the list
> somewhere, it's just not near the top yet.
>

Rather than implement this half baked, why not just move this feature
to the top of the list,
userspace users are clamoring for this?

I had this on our TODO list at Intel, but I have been moved onto other
projects now and
don't have the resources to work on it or I would.

> > If that's true, couldn't we just pin the trust to an existing trusted
> > key that we have the name of and move on? The kernel would know that
> > something happened when session protections started failing without
> > the complexity and time of generating a key in the NULL hierarchy and
> > certifying it.
>
> If the goal is to check not only the kernel but also the boot
> components (like OVMF/EDK2), then we need a handoff protocol.  The
> beauty of the NULL seed is the name is a nice short thing to handoff.
> If we relied on sessions, we'd have to hand off a whole context saved
> session and all its nonces, which is a bit of a security risk.

Yeah I wouldn't hand off the session information. Bit for pre-kernel
things isn't this all bootstrapped with the
name of the "Signing EK '' stored on a filesystem? I think you
suggested a RO portion of /etc. Since that's
the root it would need to be available for the initial boot strap
before you can just hand of the name of the
NULL hierarchy key. But if Session Ungapping was implemented, it could
just be a handoff of the "Signing EK"
name. Which would reduce the need for a createprimary and certify command.

>
> James
>
Jarkko Sakkinen April 23, 2023, 5:42 a.m. UTC | #11
On Mon, 2023-04-03 at 17:39 -0400, James Bottomley wrote:
> The interest in securing the TPM against interposers, both active and
> passive has risen to fever pitch with the demonstration of key
> recovery against windows bitlocker:
> 
> https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network
> 
> And subsequently the same attack being successful against all the
> Linux TPM based security solutions:
> 
> https://www.secura.com/blog/tpm-sniffing-attacks-against-non-bitlocker-targets
> 
> The attacks fall into two categories:
> 
> 1. Passive Interposers, which sit on the bus and merely observe
> 2. Active Interposers, which try to manipulate TPM transactions on the
>    bus using man in the middle and packet stealing to create TPM state
>    the interposer owner desires.
> 
> Our broadest interposer target is the use of TPM_RS_PW for password
> authorization which sends the actual password to the TPM without any
> obfuscation and effectively hands it to any interposer. The way to fix
> this is to use real sessions for HMAC capabilities to ensure integrity
> and to use parameter and response encryption to ensure confidentiality
> of the data flowing over the TPM bus.  HMAC sessions by agreeing a
> challenge with the TPM and then giving a response which is a HMAC of
> the password and the challenge, so the application proves knowledge of
> the password to the TPM without ever transmitting the password itself.
> Using HMAC sessions when sending commands to the TPM also provides
> some measure of protection against active interposers, since the
> interposer can't interfere with or delete a HMAC'd command (because
> they can't manufacture a response with the correct HMAC).
> 
> To protect TPM transactions where there isn't a shared secret
> (i.e. the command is something like a PCR extension which doesn't
> involve a TPM object with a password) we have to do a bit more work to
> set up sessions with a passed in encrypted secret (called a salt) to
> act in place of the shared secret in the HMAC.  This secret salt is
> effectively a random number encrypted to a public key of the TPM.  The
> final piece of the puzzle is using parameter input and response return
> encryption, so any interposer can't see the data passing from the
> application to the TPM and vice versa.
> 
> The most insidious interposer attack of all is a reset attack: since
> the interposer has access to the TPM bus, it can assert the TPM reset
> line any time it wants.  When a TPM resets it mostly comes back in the
> same state except that all the PCRs are reset to their initial values.
> Controlling the reset line allows the interposer to change the PCR
> state after the fact by resetting the TPM and then replaying PCR
> extends to get the PCRs into a valid state to release secrets, so even
> if an attack event was recorded, the record is erased.  This reset
> attack violates the fundamental princible of non-repudiability of TPM
> logs.  Defeating the reset attack involves tying all TPM operations
> within the kernel to a property which will change detectably if the
> TPM is reset.  For that reason, we tie all TPM sessions to the null
> hierarchy we obtain at start of day and whose seed changes on every
> reset.  If an active interposer asserts a TPM reset, the new null
> primary won't match the kernel's stored one and all TPM operations
> will start failing because of HMAC mismatches in the sessions.  So if
> the kernel TPM code keeps operating, it guarantees that a reset hasn't
> occurred.
> 
> The final part of the puzzle is that the machine owner must have a
> fixed idea of the EK of their TPM and should have certified this with
> the TPM manufacturer.  On every boot, the certified EK public key
> should be used to do a make credential/activate credential attestation
> key insertion and then the null key certified with the attestation
> key.  We can follow a trust on first use model where an OS
> installation will extract and verify a public EK and save it to a read
> only file.
> 
> This patch series adds a simple API which can ensure the above
> properties as a layered addition to the existing TPM handling code.
> This series now includes protections for PCR extend, getting random
> numbers from the TPM and data sealing and unsealing.  It therefore
> eliminates all uses of TPM2_RS_PW in the kernel and adds encryption
> protection to sensitive data flowing into and out of the TPM.  The
> first four patches add more sophisticated buffer handling to the TPM
> which is needed to build the more complex encryption and
> authentication based commands.  Patch 6 adds all the generic
> cryptography primitives and patches 7-9 use them in critical TPM
> operations where we want to avoid or detect interposers.  Patch 10
> exports the name of the null key we used for boot/run time
> verification and patch 11 documents the security guarantees and
> expectations.
> 
> This was originally sent over four years ago, with the last iteration
> being:
> 
> https://lore.kernel.org/linux-integrity/1568031515.6613.31.camel@HansenPartnership.com/
> 
> I'm dusting it off now because various forces at Microsoft and Google
> via the Open Compute Platform are making a lot of noise about
> interposers and we in the linux kernel look critically lacking in that
> regard, particularly for TPM trusted keys.
> 
> ---
> v2 fixes the problems smatch reported and adds more explanation about
> the code motion in the first few patches
> v3 rebases the encryption to be against Ard's new library function, the
> aescfb addition of which appears as patch 1.
> v4 refreshes Ard's patch, adds kernel doc (including a new patch to
> add it to the moved tpm-buf functions) updates and rewords some commit
> logs
> 
> James
> 
> ---
> 
> Ard Biesheuvel (1):
>   crypto: lib - implement library version of AES in CFB mode
> 
> James Bottomley (12):
>   tpm: move buffer handling from static inlines to real functions
>   tpm: add kernel doc to buffer handling functions
>   tpm: add buffer handling for TPM2B types
>   tpm: add cursor based buffer functions for response parsing
>   tpm: add buffer function to point to returned parameters
>   tpm: export the context save and load commands
>   tpm: Add full HMAC and encrypt/decrypt session handling code
>   tpm: add hmac checks to tpm2_pcr_extend()
>   tpm: add session encryption protection to tpm2_get_random()
>   KEYS: trusted: Add session encryption protection to the seal/unseal
>     path
>   tpm: add the null key name as a sysfs export
>   Documentation: add tpm-security.rst
> 
>  Documentation/security/tpm/tpm-security.rst |  216 ++++
>  drivers/char/tpm/Kconfig                    |   13 +
>  drivers/char/tpm/Makefile                   |    2 +
>  drivers/char/tpm/tpm-buf.c                  |  307 +++++
>  drivers/char/tpm/tpm-chip.c                 |    3 +
>  drivers/char/tpm/tpm-sysfs.c                |   18 +
>  drivers/char/tpm/tpm.h                      |   14 +
>  drivers/char/tpm/tpm2-cmd.c                 |   52 +-
>  drivers/char/tpm/tpm2-sessions.c            | 1158 +++++++++++++++++++
>  drivers/char/tpm/tpm2-space.c               |    8 +-
>  include/crypto/aes.h                        |    5 +
>  include/linux/tpm.h                         |  257 ++--
>  lib/crypto/Kconfig                          |    5 +
>  lib/crypto/Makefile                         |    3 +
>  lib/crypto/aescfb.c                         |  257 ++++
>  security/keys/trusted-keys/trusted_tpm2.c   |   82 +-
>  16 files changed, 2275 insertions(+), 125 deletions(-)
>  create mode 100644 Documentation/security/tpm/tpm-security.rst
>  create mode 100644 drivers/char/tpm/tpm-buf.c
>  create mode 100644 drivers/char/tpm/tpm2-sessions.c
>  create mode 100644 lib/crypto/aescfb.c
> 

OK, so I have a kernel with the patches applied. How can I verify
that this working?

Are there any other user visible things than handle for the null
key? Even for that this lacks any useful instructions how to use
it while testing. For the null key I'm not even sure if the claim
is correct, given that kernel is always a middle-man, even when
user space uses /dev/tpm0. A bit more detail would help...

BR, Jarkko
Stefan Berger Dec. 4, 2023, 6:56 p.m. UTC | #12
On 4/3/23 17:39, James Bottomley wrote:
> The interest in securing the TPM against interposers, both active and
> passive has risen to fever pitch with the demonstration of key
> recovery against windows bitlocker:
> 
> https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network
> 
> And subsequently the same attack being successful against all the
> Linux TPM based security solutions:
> 
> https://www.secura.com/blog/tpm-sniffing-attacks-against-non-bitlocker-targets
> 
> The attacks fall into two categories:
> 
> 1. Passive Interposers, which sit on the bus and merely observe
> 2. Active Interposers, which try to manipulate TPM transactions on the
>     bus using man in the middle and packet stealing to create TPM state
>     the interposer owner desires.

I think this is another capability of an interposer that should be 
mentioned here, unless technically not possible but I would not know why:

3. Active Interposers that send their own commands to the TPM to for 
example cause DoS attacks.

If we protect PCR extensions now and the interposer can send his own PCR 
extensions and the TPM 2 accepts them (TPM doesn't have a mode to reject 
unprotected commands in general), why protect the PCR extensions from 
IMA then?

    Stefan
> 
> Our broadest interposer target is the use of TPM_RS_PW for password
> authorization which sends the actual password to the TPM without any
> obfuscation and effectively hands it to any interposer. The way to fix
> this is to use real sessions for HMAC capabilities to ensure integrity
> and to use parameter and response encryption to ensure confidentiality
> of the data flowing over the TPM bus.  HMAC sessions by agreeing a
> challenge with the TPM and then giving a response which is a HMAC of
> the password and the challenge, so the application proves knowledge of
> the password to the TPM without ever transmitting the password itself.
> Using HMAC sessions when sending commands to the TPM also provides
> some measure of protection against active interposers, since the
> interposer can't interfere with or delete a HMAC'd command (because
> they can't manufacture a response with the correct HMAC).
> 
> To protect TPM transactions where there isn't a shared secret
> (i.e. the command is something like a PCR extension which doesn't
> involve a TPM object with a password) we have to do a bit more work to
> set up sessions with a passed in encrypted secret (called a salt) to
> act in place of the shared secret in the HMAC.  This secret salt is
> effectively a random number encrypted to a public key of the TPM.  The
> final piece of the puzzle is using parameter input and response return
> encryption, so any interposer can't see the data passing from the
> application to the TPM and vice versa.
> 
> The most insidious interposer attack of all is a reset attack: since
> the interposer has access to the TPM bus, it can assert the TPM reset
> line any time it wants.  When a TPM resets it mostly comes back in the
> same state except that all the PCRs are reset to their initial values.
> Controlling the reset line allows the interposer to change the PCR
> state after the fact by resetting the TPM and then replaying PCR
> extends to get the PCRs into a valid state to release secrets, so even
> if an attack event was recorded, the record is erased.  This reset
> attack violates the fundamental princible of non-repudiability of TPM
> logs.  Defeating the reset attack involves tying all TPM operations
> within the kernel to a property which will change detectably if the
> TPM is reset.  For that reason, we tie all TPM sessions to the null
> hierarchy we obtain at start of day and whose seed changes on every
> reset.  If an active interposer asserts a TPM reset, the new null
> primary won't match the kernel's stored one and all TPM operations
> will start failing because of HMAC mismatches in the sessions.  So if
> the kernel TPM code keeps operating, it guarantees that a reset hasn't
> occurred.
> 
> The final part of the puzzle is that the machine owner must have a
> fixed idea of the EK of their TPM and should have certified this with
> the TPM manufacturer.  On every boot, the certified EK public key
> should be used to do a make credential/activate credential attestation
> key insertion and then the null key certified with the attestation
> key.  We can follow a trust on first use model where an OS
> installation will extract and verify a public EK and save it to a read
> only file.
> 
> This patch series adds a simple API which can ensure the above
> properties as a layered addition to the existing TPM handling code.
> This series now includes protections for PCR extend, getting random
> numbers from the TPM and data sealing and unsealing.  It therefore
> eliminates all uses of TPM2_RS_PW in the kernel and adds encryption
> protection to sensitive data flowing into and out of the TPM.  The
> first four patches add more sophisticated buffer handling to the TPM
> which is needed to build the more complex encryption and
> authentication based commands.  Patch 6 adds all the generic
> cryptography primitives and patches 7-9 use them in critical TPM
> operations where we want to avoid or detect interposers.  Patch 10
> exports the name of the null key we used for boot/run time
> verification and patch 11 documents the security guarantees and
> expectations.
> 
> This was originally sent over four years ago, with the last iteration
> being:
> 
> https://lore.kernel.org/linux-integrity/1568031515.6613.31.camel@HansenPartnership.com/
> 
> I'm dusting it off now because various forces at Microsoft and Google
> via the Open Compute Platform are making a lot of noise about
> interposers and we in the linux kernel look critically lacking in that
> regard, particularly for TPM trusted keys.
> 
> ---
> v2 fixes the problems smatch reported and adds more explanation about
> the code motion in the first few patches
> v3 rebases the encryption to be against Ard's new library function, the
> aescfb addition of which appears as patch 1.
> v4 refreshes Ard's patch, adds kernel doc (including a new patch to
> add it to the moved tpm-buf functions) updates and rewords some commit
> logs
> 
> James
> 
> ---
> 
> Ard Biesheuvel (1):
>    crypto: lib - implement library version of AES in CFB mode
> 
> James Bottomley (12):
>    tpm: move buffer handling from static inlines to real functions
>    tpm: add kernel doc to buffer handling functions
>    tpm: add buffer handling for TPM2B types
>    tpm: add cursor based buffer functions for response parsing
>    tpm: add buffer function to point to returned parameters
>    tpm: export the context save and load commands
>    tpm: Add full HMAC and encrypt/decrypt session handling code
>    tpm: add hmac checks to tpm2_pcr_extend()
>    tpm: add session encryption protection to tpm2_get_random()
>    KEYS: trusted: Add session encryption protection to the seal/unseal
>      path
>    tpm: add the null key name as a sysfs export
>    Documentation: add tpm-security.rst
> 
>   Documentation/security/tpm/tpm-security.rst |  216 ++++
>   drivers/char/tpm/Kconfig                    |   13 +
>   drivers/char/tpm/Makefile                   |    2 +
>   drivers/char/tpm/tpm-buf.c                  |  307 +++++
>   drivers/char/tpm/tpm-chip.c                 |    3 +
>   drivers/char/tpm/tpm-sysfs.c                |   18 +
>   drivers/char/tpm/tpm.h                      |   14 +
>   drivers/char/tpm/tpm2-cmd.c                 |   52 +-
>   drivers/char/tpm/tpm2-sessions.c            | 1158 +++++++++++++++++++
>   drivers/char/tpm/tpm2-space.c               |    8 +-
>   include/crypto/aes.h                        |    5 +
>   include/linux/tpm.h                         |  257 ++--
>   lib/crypto/Kconfig                          |    5 +
>   lib/crypto/Makefile                         |    3 +
>   lib/crypto/aescfb.c                         |  257 ++++
>   security/keys/trusted-keys/trusted_tpm2.c   |   82 +-
>   16 files changed, 2275 insertions(+), 125 deletions(-)
>   create mode 100644 Documentation/security/tpm/tpm-security.rst
>   create mode 100644 drivers/char/tpm/tpm-buf.c
>   create mode 100644 drivers/char/tpm/tpm2-sessions.c
>   create mode 100644 lib/crypto/aescfb.c
>
James Bottomley Dec. 4, 2023, 7:24 p.m. UTC | #13
On Mon, 2023-12-04 at 13:56 -0500, Stefan Berger wrote:
> 
> 
> On 4/3/23 17:39, James Bottomley wrote:
> > The interest in securing the TPM against interposers, both active
> > and
> > passive has risen to fever pitch with the demonstration of key
> > recovery against windows bitlocker:
> > 
> > https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network
> > 
> > And subsequently the same attack being successful against all the
> > Linux TPM based security solutions:
> > 
> > https://www.secura.com/blog/tpm-sniffing-attacks-against-non-bitlocker-targets
> > 
> > The attacks fall into two categories:
> > 
> > 1. Passive Interposers, which sit on the bus and merely observe
> > 2. Active Interposers, which try to manipulate TPM transactions on
> > the
> >     bus using man in the middle and packet stealing to create TPM
> > state the interposer owner desires.
> 
> I think this is another capability of an interposer that should be 
> mentioned here, unless technically not possible but I would not know
> why:
> 
> 3. Active Interposers that send their own commands to the TPM to for 
> example cause DoS attacks.
> 
> If we protect PCR extensions now and the interposer can send his own
> PCR extensions and the TPM 2 accepts them (TPM doesn't have a mode to
> reject unprotected commands in general), why protect the PCR
> extensions from IMA then?

Well the PCRs are world writable in a standard system, so anyone with
access, i.e. anyone in the tpm group, can arbitrarily extend them and
destroy the replay.  So I ignored this because while an interposer can
do this, you don't have to be an interposer to cause log replay
disruption like this.

The actual threat to PCR extends from an interposer is silent discards
where the attacker seeks to fake the log after the fact to match a
quote they've discarded a suspicious event from.  Thus the HMAC check
is actually the return one, which allows the kernel to know the write
succeeded.

James
Stefan Berger Dec. 4, 2023, 9:02 p.m. UTC | #14
On 12/4/23 14:24, James Bottomley wrote:
> On Mon, 2023-12-04 at 13:56 -0500, Stefan Berger wrote:
>>
>>
>> On 4/3/23 17:39, James Bottomley wrote:
>>> The interest in securing the TPM against interposers, both active
>>> and
>>> passive has risen to fever pitch with the demonstration of key
>>> recovery against windows bitlocker:
>>>
>>> https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network
>>>
>>> And subsequently the same attack being successful against all the
>>> Linux TPM based security solutions:
>>>
>>> https://www.secura.com/blog/tpm-sniffing-attacks-against-non-bitlocker-targets
>>>
>>> The attacks fall into two categories:
>>>
>>> 1. Passive Interposers, which sit on the bus and merely observe
>>> 2. Active Interposers, which try to manipulate TPM transactions on
>>> the
>>>      bus using man in the middle and packet stealing to create TPM
>>> state the interposer owner desires.
>>
>> I think this is another capability of an interposer that should be
>> mentioned here, unless technically not possible but I would not know
>> why:
>>
>> 3. Active Interposers that send their own commands to the TPM to for
>> example cause DoS attacks.
>>
>> If we protect PCR extensions now and the interposer can send his own
>> PCR extensions and the TPM 2 accepts them (TPM doesn't have a mode to
>> reject unprotected commands in general), why protect the PCR
>> extensions from IMA then?
> 
> Well the PCRs are world writable in a standard system, so anyone with
> access, i.e. anyone in the tpm group, can arbitrarily extend them and
> destroy the replay.  So I ignored this because while an interposer can
> do this, you don't have to be an interposer to cause log replay
> disruption like this.

Presumably the folks in the tpm group are trusted while the interpose is 
not.

> 
> The actual threat to PCR extends from an interposer is silent discards
> where the attacker seeks to fake the log after the fact to match a
> quote they've discarded a suspicious event from.  Thus the HMAC check

Well, it's not that simple to fake the log unless you are root and then 
all bets are off when it comes to sending commands to the TPM.

> is actually the return one, which allows the kernel to know the write
> succeeded.
> 
> James
>
James Bottomley Dec. 5, 2023, 1:50 p.m. UTC | #15
On Mon, 2023-12-04 at 16:02 -0500, Stefan Berger wrote:
> On 12/4/23 14:24, James Bottomley wrote:
[...]
> > The actual threat to PCR extends from an interposer is silent
> > discards where the attacker seeks to fake the log after the fact to
> > match a quote they've discarded a suspicious event from.  Thus the
> > HMAC check
> 
> Well, it's not that simple to fake the log unless you are root and
> then all bets are off when it comes to sending commands to the TPM.

It's not just faking logs: if I can discard the true measurements and
insert my own, I can recover any object sealed to a PCR policy.  Even
if I can only discard the last few bad measurements and insert good
ones, I can still likely succeed.

If an attacker gains root, the TPM still can't be faked out.  As long
as the PCRs have accurate measurements, those measurements can be
quoted.  The theory is that the event that allowed the root exploit got
recorded before the exploit happened (of course there's a huge problem
of whether the right thing is being recorded) because post boot
computer hacking cannot violate causality.

The interposer at boot is a more interesting problem, but that's
documented.

James