TPM2 and Linux

Recently Microsoft started mandating TPM2 as a hardware requirement for all platforms running recent versions of windows.  This means that eventually all shipping systems (starting with laptops first) will have a TPM2 chip.  The reason this impacts Linux is that TPM2 is radically different from its predecessor TPM1.2; so different, in fact, that none of the existing TPM1.2 software on Linux (trousers, the libtpm.so plug in for openssl, even my gnome keyring enhancements) will work with TPM2.  The purpose of this blog is to explore the differences and how we can make ready for the transition.

What are the Main 1.2 vs 2.0 Differences?

The big one is termed Algorithm Agility.  TPM1.2 had SHA1 and RSA2048 only.  TPM2 is designed to have many possible algorithms, including support for elliptic curve and a host of government mandated (Russian and Chinese) crypto systems.  There’s no requirement for any shipping TPM2 to support any particular algorithms, so you actually have to ask your TPM what it supports.  The bedrock for TPM2 in the West seems to be RSA1024-2048, ECC and AES for crypto and SHA1 and SHA256 for hashes1.

What algorithm agility means is that you can no longer have root keys (EK and SRK see here for details) like TPM1.2 did, because a key requires a specific crypto algorithm.  Instead TPM2 has primary “seeds” and a Key Derivation Function (KDF).  The way this works is that a seed is simply a long string of random numbers, but it is used as input to the KDF along with the key parameters and the algorithm and out pops a real key based on the seed.  The KDF is deterministic, so if you input the same algorithm and the same parameters you get the same key again.  There are four primary seeds in the TPM2: Three permanent ones which only change when the TPM2 is cleared: endorsement (EPS), Platform (PPS) and Storage (SPS).  There’s also a Null seed, which is used for ephemeral keys and changes every reboot.  A key derived from the SPS can be regarded as the SRK and a key derived from the EPS can be regarded as the EK. Objects descending from these keys are called members of hierarchies2. One of the interesting aspects of the TPM is that the root of a hierarchy is a key not a seed (because you need to exchange secret information with the TPM), and that there can be multiple of these roots with different key algorithms and parameters.

Additionally, the mechanism for making use of keys has changed slightly.  In TPM 1.2 to import a secret key you wrapped it asymmetrically to the SRK and then called LoadKeyByBlob to get a use handle.  In TPM2 this is a two stage operation, firstly you import a wrapped (or otherwise protected) private key with TPM2_Import, but that returns a private key structure encrypted with the parent key’s internal symmetric key.  This symmetrically encrypted key is then loaded (using TPM2_Load) to obtain a use handle whenever needed.  The philosophical change is from online keys in TPM 1.2 (keys which were resident inside the TPM) to offline keys in TPM2 (keys which now can be loaded when needed).  This philosophy has been reinforced by reducing the space available to keep keys loaded in TPM2 (see later).

Playing with TPM2

If you have a recent laptop, chances are you either have or can software upgrade to a TPM2.  I have a dell XPS13 the skylake version which comes with a software upgradeable Nuvoton TPM.  Dell kindly provides a 1.2->2 switching program here, which seems to work under Freedos (odin boot) so I have a physical TPM2 based system.  For those of you who aren’t so lucky, you can still play along, but you need a TPM2 emulator.  The best one is here; simply download and untar it then type make in the src directory and run it as ./tpm_server.  It listens on two TCP ports, 2321 and 2322, for TPM commands so there’s no need to install it anywhere, it can be run directly from the source directory.

After that, you need the interface software called tss2.  The source is here, but Fedora 25 and recent Ubuntu already package it.  I’ve also built openSUSE packages here.  The configuration of tss2 is controlled by environment variables.  The most important one is TPM_INTERFACE_TYPE which tells it how to connect to the TPM2.  If you’re using a simulator, you set this to “socsim” and if you have a real TPM2 device you set it to “dev”.  One final thing about direct device connection: in tss2 there’s no daemon like trousers had to broker the connection, all your users connect directly to the TPM2 device /dev/tpm0.  To do this, the device has to support read and write by arbitrary users, so its permissions need to be 0666.  I’ve got a udev script to achieve this

# tpm 2 devices need to be world readable
SUBSYSTEM=="tpm", ACTION=="add", MODE="0666"

Which goes in /etc/udev/rules.d/80-tpm-2.rules on openSUSE.  The next thing you need to do, if you’re running the simulator, is power it on and start it up (for a real device, this is done by the bios):

tsspowerup
tssstartup

The simulator will now create a NVChip file wherever you started it to store NV ram based objects, which it will read on next start up.  The first thing you need to do is create an SRK and store it in NV memory.  Microsoft uses the well known key handle 81000001 for this, so we’ll do the same.  The reason for doing this is that a real TPM takes ages to run the KDF for RSA keys because it has to look for prime numbers:

jejb@jarvis:~> TPM_INTERFACE_TYPE=socsim time tsscreateprimary -hi o -st -rsa
Handle 80000000
0.03 user 0.00 system 0:00.06 elapsed

jejb@jarvis:~> TPM_INTERFACE_TYPE=dev time tsscreateprimary -hi o -st -rsa
Handle 80000000
0.04 user 0.00 system 0:20.51 elapsed

As you can see: the simulator created a primary storage key (the SRK) in a few milliseconds, but it took my real TPM2 20 seconds to do it3 … not something you want to wait for, hence the need to store this permanently under a well known key handle and get rid of the temporary copy

tssevictcontrol -hi o -ho 80000000 -hp 81000001
tssflushcontext -ha 80000000

tssevictcontrol tells the TPM to copy the key at transient handle 800000004  to permanent NV handle 81000001 and tssflushcontext erases the transient key.  Flushing transient objects is very important, because TPM2 has a lot less transient storage space than TPM1.2 did; usually only about three handles worth.  You can tell how much you have by doing

tssgetcapability -cap 6|grep -i transient
TPM_PT 0000010e value 00000003 TPM_PT_HR_TRANSIENT_MIN - the minimum number of transient objects that can be held in TPM RAM

Where the value (00000003) tells me that the TPM can store at least 3 transient objects.  After that you’ll start getting out of space errors from it.

The final step in taking ownership of a TPM2 is to set the authorization passwords.  Each of the four hierarchies (Null, Owner, Endorsement, Platform) and the Lockout has a possible authority password.  The Platform authority is cleared on startup, so there’s not much point setting it (it’s used by the BIOS or Firmware to perform TPM functions).  Of the other four, you really only need to set Owner, Endorsement and Lockout (I use the same password for all of them).

tsshierarchychangeauth -hi l -pwdn <your password>
tsshierarchychangeauth -hi e -pwdn <your password>
tsshierarchychangeauth -hi o -pwdn <your password>

After this is done, you’re all set.  Note that as well as these authorizations, each object can have its own authorization (or even policy), so the SRK you created earlier still has no password, allowing it to be used by anyone.  Note also that the owner authorization controls access to the NV memory, so you’ll need to supply it now to make other objects persistent.

An Aside about Real TPM2 devices and the Resource Manager

Although I’m using the code below to store my keys in the TPM2, there’s a couple of practical limitations which means it won’t work for you if you have multiple TPM2 using applications without a kernel update.  The two problems are

  1. The Linux Kernel TPM2 device /dev/tpm0 only allows one user at once.  If a second application tries to open the device it will get an EBUSY which causes TSS_Create() to fail.
  2. Because most applications make use of transient key slots and most TPM2s have only a couple of these, simultaneous users can end up running out of these and getting unexpected out of space errors.

The solution to both of these is something called a Resource Manager (RM).  What the RM does is effectively swap transient objects in and out of the TPM as needed to prevent it from running out of space.  Linux has an issue in that both the kernel and userspace are potential users of TPM keys so the resource manager has to live inside the kernel.  Jarkko Sakkinen has preliminary resource manager patches here, and they will likely make it into kernel 4.11 or 4.12.  I’m currently running my laptop with the RM patches applied, so multiple applications work for me, but since these are preliminary patches, I wouldn’t currently advise others to do this.  The way these patches work is that once you declare to the kernel via an ioctl that you want to use the RM, every time you send a command to the TPM, your context gets swapped in, the command is executed, the context is swapped out and the response sent meaning that no other user of the TPM sees your transient objects.  The moment you send the ioctl, the TPM device allows another user to open it as well.

Using TPM2 as a keystore

Once the implementation is sorted out, openssl and gnome-keyring patches can be produced for TPM2.  The only slight wrinkle is that for create_tpm2_key you require a parent key to exist in the NV storage (at the 81000001 handle we talked about previously).  So to convert from a password protected openssh RSA key to a TPM2 based one, you do

create_tpm2_key -a -p 81000001 -w id_rsa id_rsa.tpm
mv id_rsa.tpm id_rsa

And then gnome keyring manager will work nicely (make sure you keep a copy of your original private key in case you want to move to a new laptop or reseed the TPM2).  If you use the same TPM2 password as your original key password, you won’t even need to update the gnome loginkeyring for the new password.

Conclusions

Because of the lack of an in-kernel Resource Manager, TPM2 is ready for experimentation in Linux but definitely not ready for prime time yet (unless you’re willing to patch your kernel).  Hopefully this will change in the 4.11 or 4.12 kernel when the Resource Manager finally goes upstream5.

Looking forwards to the new stack, the lack of a central daemon is really a nice feature: tcsd crashing used to kill all of my TPM key based applications, but with tss2 having no central daemon, everything has just worked(tm) so far.  A kernel based RM also means that the kernel can happily use the TPM (for its trusted keys and disk encryption) without interfering with whatever userspace is doing.

  1. to see what your tpm supports, do tssgetcapability -cap 0
  2. Hierarchies are technically traced all the way back to the authorization for them, so SRK to SPS to Owner authority; EK to EPS to Endorsement authority etc
  3. The reason it takes so long is that the KDF has to find the two primes that make up the modulus, so the KDF finds a number of the right size, it has to be checked for primeness, and if it’s not prime, a KDF input counter is incremented and the KDF produces another number of the correct size which must again be checked for primeness and so on
  4. The initial hex byte prefix actually identifies the handle type: 80 is transient object, 81 is permanent object, 40 is permanent resources and so on
  5. Resource Manager patches are now posted here

15 thoughts on “TPM2 and Linux

    1. jejb Post author

      OK, missed that since it’s yet another different package name and build.opensuse.org has a fairly literal search function. We now have libtss2-0 (Ubuntu) tss2 (Fedora) and tpm2-0-tss (SUSE) … it would be nice to get some package name uniformity.

      Reply
      1. jejb Post author

        Actually, I tell a lie. tpm2-0-tss is based on the Intel TSS which is currently not usable because it’s incomplete. I suppose I should mention we have at least three TSS2 projects. The actual programming interface, called ESAPI, isn’t standardised yet (that’s why it’s not present in the Intel one). The two projects with currently usable APIs are the IBM one and the Google one

        Reply
  1. Nuutti Kotivuori

    In TPM 2.0, has there been any change in tamper resistance? Trousers faq 3.4 says this: http://trousers.sourceforge.net/faq.html#3.4

    —-
    3.4 – Is the TPM chip itself tamper resistant?

    No. The TPM chip itself will detect that it has been physically tanpered with, but will only report this by setting a bit inside the chip. This bit can be read by software, but the TPM will not auto-disable itself, zero any of its internal memory, or otherwise self-destruct in any way. The TPM is not designed to protect against attacks from the platform owner, that is, the person who owns the physical machine that the TPM resides on.
    —-

    Is this still the case, or does TPM 2.0 mandate something else?

    Reply
    1. jejb Post author

      There is a mandate that TPM2 should be resistant to physical attack. The TCG site is down at the moment, but the details are in the PC Client Protection Profile for TPM 2.0 (FPT_PHP.3 Resistance to physical attack). If I remember correctly, it basically punts the problem off to the manufacturer, though.

      Reply
    2. prince_gbanga

      > The TPM is not designed to protect against attacks from the platform owner, that is, the person who owns the physical machine that the TPM resides on.

      Really? Then what good is remote attestation? Isn’t the whole idea behind that to prove to the remote party that the machine is running the software it claims to be running?

      > There are cultural and political forces barring adoption of technology that takes away the individual’s right to use their general purpose computer as they see fit.

      Maybe so, but from where I sit society seems to be resolving this tension by shrinking the definition of “general purpose computer” until it only describes geeky things in expensive university laboratories.

      All these so-called “mobile” devices are not general purpose in the sense you describe (even if they are general in the technological sense).

      Reply
  2. Pingback: Bottomley: TPM2 and Linux | Linux Press

  3. Nathaniel McCallum

    1. Is anyone working on a PKCS#11 module?
    2. Is there a decent, simple example of C-API key creation/use out there?

    Reply
    1. jejb Post author

      gnome-keyring is architecturally a pkcs11 backend store module with frontend protocol handlers. Any tpm key you place into it, you can use via pkcs11. If you’ve created some TPM based ssh keys and got gnutls installed, just do

      p11tool –login –list-all-keys ‘pkcs11:model=1.0;manufacturer=Gnome%20Keyring;serial=1%3aSSH%3aHOME;token=SSH%20Keys’

      To show them via URL. Any of the gnutls tools will make use of the URL for the public or private parts.

      In openssl_tpm_engine, create_tpm2_key is a demonstration of using the C API to create a key; is that what you’re looking for?

      Reply
      1. Nathaniel McCallum

        So, PKCS#11 through GNOME Keyring is less-than-ideal. The openssl_tpm_engine might be a good option (I didn’t know it had TPM2 support yet).

        My primary interest is for the José project: https://github.com/latchset/jose. But I also may be working directly on TPM2 support in Fedora/Red Hat soon. I’d love to chat with you a bit if you have some time. Feel free to email me.

        Reply
        1. jejb Post author

          The posted openssl_tpm_engine patches for TPM2 all use this tss2 library, which is neatly packaged by fedora so at least you don’t have to start from ground zero like I did with openSUSE.

          I’m happy to answer questions in email, but, since I bet a lot of other people might be interested, what about via a mailing list? The tss2 project has an upstream one that might serve (although it is sourceforge, so the adverts can be annoying) or feel free to suggest an alternative one.

          Reply
  4. Dr. Greg Wettstein

    Congratulations to James for a good general review of TPM2.

    It may be worth noting to your readers that not all TPM2 implementations are created equal. When the comment is made that Microsoft is ‘mandating TPM2 as a hardware requirement’ what this actually translates into is that Microsoft mandates a TSS2 compliant programming interface to the TPM2 functionality cohort which is documented by the TCG. This does not translate into the fact that there is actually a hardware implementation of the functionality with the security implications which that translates into.

    Presumably to cut costs, Intel, from Skylake forward, implements the ‘TPM2 functionality’ in the form of what is called ‘Platform Trust Technology’ or PTT, in addition to supporting a genuine hardware device. PTT is a software implementation of TPM2 functionality which presumably runs on the Management Engine (ME) with all the requisite architectural considerations which that entails.

    The platforms which we are currently developing on allow selection of either a TPM2 hardware implementation or the PTT software implementation through the BIOS/UEFI setup process. At least through Linux 4.4 it has been our experience that it is a bit of a dodgy prospect as to whether or not the Linux kernel driver can effectively communicate with a PTT implementation.

    All of this a bit of a function of what happens when a decision is made to define what are two separate device implementations with one hardware definition (ACPI MSFT0101)….. :-)(

    Reply
  5. Pingback: Win 10 强制硬件需支持 TPM2,Linux 受影响 | News Pod

  6. Pingback: TPM2 and Linux | Life in Linux Kernel

  7. Marcos

    Hi,
    Nice article. I am trying to have TPM2 installed in a CentOS 7.0 Linux machine (skylake) with my kernel updated to 4.11.0. TPM is enabled in the BIOS. Maybe you can help me whether my steps are correct.

    1. I downloaded the IBM TPM 2.0 sw from http://ibmswtpm.sourceforge.net/ibmswtpm2.html
    Then I was able to build it without any problem and got the tpm_server binary.
    2. Then I downloaded the IBM TPM 2.0 TSS from https://sourceforge.net/projects/ibmtpm20tss
    Then I was able to build it without any problem and creating libtss.so and the header files in the tss2
    folder. I copied this tss2 folder to /usr/include/tss2 and also copied my libtss.so file to /usr/lib64/ folder.
    3. Next, I downloaded the “IBM tpm 2.0 tools” from https://github.com/01org/tpm2.0-tools.
    The problem is that my build is failing.
    I follow the ‘manual’ txt file inside the folder:
    ./bootstrap
    bootstrap build is failing saying that GIT_DISCOVERY_ACROSS_FILESYSTEM not set.
    I don’t have access to the network, so I installed all the required packages via DVD rom.

    ./configure
    Then I decided to continue the build by running “./configure”. It fails saying that can’t find “sapi”
    package. I was not able to find where this package is either. Maybe you know??

    4. As building the tpm2.0 tools failed, I tried to find a RPM package.
    I got one from:
    https://centos.pkgs.org/7/epel-x86_64/tpm2-tools-1.1.0-4.el7.x86_64.rpm.html
    So, I copied it from my windows machine to my pen drive and then transfer from this pen drive to my
    Linux machine.
    When I tried to install the RPM, it fails.
    I checked the dependencies and it seems that it can’t find:
    libtcti-device-so.0
    libsapi.so.0
    tpm2-tss(x86-64) = 1.0.2.el7
    libtcti-socket.so.0

    So, I really would appreciate if you can give me some help or ideas about what I am doing wrong.
    Thanks
    Rgds
    Marcos

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *