Solving Bigger Problems with the TPM 2.0

  • Will Arthur
  • David Challener
  • Kenneth Goldman
Open Access


Throughout this book, we have described examples of how you can use particular TPM commands in programs. This chapter looks at how some of those commands can be combined to create programs that use multiple features of the TPM. These ideas couldn’t be implemented easily with TPM 1.2, but TPM 2.0 has added features that make it easy to solve these problems.


Random Number Generator Dictionary Attack Empty Buffer Storage Hierarchy Optimal Asymmetric Encryption Padding 

Throughout this book, we have described examples of how you can use particular TPM commands in programs. This chapter looks at how some of those commands can be combined to create programs that use multiple features of the TPM. These ideas couldn’t be implemented easily with TPM 1.2, but TPM 2.0 has added features that make it easy to solve these problems.

Remote Provisioning of PCs with IDevIDsUsing the EK

Each client’s TPM comes with an endorsement key (EK). This is a storage key, and it comes with a certificate indicating that it’s from an authentic TPM. An enterprise may also have a list of EK certificates, corresponding to client machines it has bought. Enterprises would like to have a unique signing key on each system (usually called a device identity [IDevID]), which can be used to initiate a VPN connection. But, being a storage key, the EK can’t be used as a VPN key. TPM 1.2 had a complicated protocol that could be used to create a certificate for a signing key created in the TPM, which proved that the key was generated in a TPM. However, no commercially available CAs followed that protocol.

TPM 2.0 has an EK that is slightly more robust than the 1.2 EK. A 2.0 EK can be used to wrap other keys. In particular, it’s possible for an enterprise to create a restricted signing key and encrypt it such in a way that only the TPM that has that EK can import it. This is similar to (although more secure than) the “send a PKCS #12 file” technique used today to provision keys. Using this approach, PKCS #12 files that contain the private key are created and sent to clients. Clients are then given a password through a side channel, which they use to decrypt the PK12 file; they then store the private portion in a (hopefully) secure place. This technique exposes the private key at some point and is only as secure as the password. The TPM protocols are much more secure.

There are basically three ways you can name the signing key that is being created as an IDevID:
  • Technique 1: Create the IDevID in a server-side TPM or TPM emulator, and use the standard CA to create a certificate for it. Then duplicate this key so that it can be imported into a system that has the client’s EK resident. This is called duplicating the key so that its new parent is the EK.

  • Technique 2: Create the IDevID and certify it. Wrap it up so that it looks like a duplicated TPM key and can be imported into the client’s EK.

  • Technique 3: Create the IDevID and certify it. Import it locally into a TPM or TPM emulator, and then duplicate it to have its new parent be the client TPM’s EK.

These three techniques are implemented slightly differently, as discussed in the following sections.

Technique 1

In this case, because the key is to be duplicated by the TPM, several things must be true. First, the key must be duplicable. This means it isn’t a fixedTPM key, and it isn’t a fixedParent key. Further, it must have a policy, because only keys with a policy can be duplicated. One of the following must be true for that policy:
  • Use TPM2_PolicyCommandCode with TPM2_Duplicate as a parameter

  • Use TPM2_PolicyDuplicateSelect

Either of these must be in at least one branch of the policy. You don’t want the key to be duplicated beyond the target TPM, so if you use the first option, you have to add a further restriction to that policy branch—perhaps a TPM2_PolicySigned. In this case, the second solution is better: you simply fix the target of duplication (the new parent of the key) to be the EK public key.

Further, for the IDevID key to act like an AIK, it must be a restricted signing key. Use TPM2_Create to create the key on the server.

Next you have to use your enterprise CA to make a certificate for this key. Before this is done, the EK’s certificate is checked to make certain it’s valid. Then the certificate can say that the IDevID belongs to the PC with that EK. Because the key is a signing key, this shouldn’t be difficult—a normal CA protocol should work.

To duplicate the key, you now create three files, each of which represents a parameter that will be used to import the IDevID key into the target PC with the specified EK. You use the TPM (or emulator) with TPM2_Duplicate command to do this. (Of course, you first have to start and satisfy the branch of the policy that allows duplication.) This command has three outputs, which will be put into three different files:
  • TPM2B_PUBLIC: This structure is a description of the IDevID key, including its public part

  • TPM2B_PRIVATE: This structure contains the private portion of the IDevID, symmetrically encrypted; and an HMAC value that binds it to the public portion

  • An encrypted value that allows a TPM with the correct EK to regenerate a seed

These three outputs are inputs to the TPM2_Import command. The seed is used by the TPM to generate an AES key, which is used to decrypt the private key, and an HMAC key, which is used to verify that the public and private portions of the key haven’t been meddled with.

Finally, you send the three files to the target PC. There, if the EK isn’t currently resident, it’s regenerated using TPM2_CreatePrimary. Then you use TPM2_Import, passing it the three files that were given to the PC as parameters. The TPM2_Import command returns a normal TPM-encrypted blob, which can be used to load the IDEVID key into the TPM using the TPM2_Load command whenever the EK is present in the TPM.

The advantage of this technique is that the TPM (or emulator) does much of the work. The disadvantage is that the end user has to create a policy and also has to rely on the random number generator of the TPM or emulator. A hardware random number generator may be too slow, and a software one may not be high enough quality.

Technique 2

If you want to use a TPM to do duplication, you have to use a policy. But you can create the key entirely outside a TPM and wrap it up like a duplicated key, ready to be imported into the TPM with the referenced EK. If you do this, you don’t need to associate a policy (other than the empty buffer) with the key. In this case, you need to write software that creates the three files to be used as parameters in the TPM2_Import command.

The first file contains the public data of the IDevID; the second holds the private data of the IDevID, encrypted with an AES key, together with an HMAC of both the public and private portions of the IDevID; and the third allows the TPM with the referenced EK to calculate a seed from which the AES key and the HMAC key are derived. If the EK is an RSA key, the third file is merely the seed, encrypted with the public EK. A number of details must be determined to create these files; they’re described well in the specification, particularly in parts 1 and 2.

If the IDevID is an RSA public key, it uses the TPM2B_PUBLIC structure (defined in Part 2, section 12.2.5.) This structure refers to a TPMT_PUBLIC structure, which is defined in section 12.2.4. The TPMT_PUBLIC structure in turn refers to a number of other structures and parameters:

  • The TPMI_ALG_HASH, which is TPM_ALG_SHA256

  • A TPMA_OBJECT bitmap, which describes the kind of key (you specify whether it’s a signing key, duplicable, and so on, just as though you were creating the key)

The next two parameters in the TPMT_PUBLIC structure are unions:
  • TPMU_PUBLIC_PARMS (see section Given that your key is TPM_ALG_RSA, it becomes TPMS_RSA_PARMS. (

  • TPMU_PUBLIC_ID ( Given that your key is TPM_ALG_RSA, it becomes TPMS_PUBLIC_KEY_RSA (the length and contents of the RSA public key).

We create the third file before the second one, though logically the public and private files go together. This is because we will need the third file to encrypt the second one. The third file is a seed encrypted with the new parent object. The seed can be generated using any random number generator (the TPM has a good one), and it should be the size of the hash—in this case, 256 bits long. Once you have this seed, you can use it to calculate two keys: an HMAC key to be used to prove the integrity of the linkage between the public and private sections of the key, and a symmetric encryption key to encrypt the private section. The HMAC key is found using equation 37, in section 22.5 of Part 1:

HMACkey := KDFa (pNameAlg, seedValue, "INTEGRITY", NULL, NULL, bits)

The encryption key you use is found in equation 35, just above the previous one:

symKey := KDFa (pNameAlg, seedValue, "STORAGE", name, NULL, bits)

You now must encrypt the seed with the EK public key. This is done in accordance with the annexes in Part 1. In particular for RSA, B.10.3 indicates that Optimal Asymmetric Encryption Padding (OAEP) using the RSA public key is used (as described in more detail in B.4, using DUPLICATE as the L parameter).

The private data is a TPM2B_PRIVATE structure, found in Part 2 12.3.7. It consists of a size and an encrypted private area. The encrypted private area consists of two pieces: an integrity area and a sensitive area. The sensitive area is calculated first.

The sensitive area consists of a TPMT_SENSITIVE area found in table 188 of This is the TPMU_SENSITIVE_COMPOSITE, which table 187 says (for a TPM_ALG_RSA key) is a TPM2B_PRIVATE_KEY_RSAj. Table 160 specifies that this is one of the two primes, preceded by a 2-byte field containing the number of bits in the prime. It’s encrypted using AES in cipher-feedback mode, where the IV is zero. This is found in equation 36, section 22.4, Part 1.

The integrity digest is an HMAC over the public and encrypted private data using the HMAC key calculated from the seed. This is calculated using the following equation:

outerHMAC := SHA256 (HMACkey, encrypted Sensitive area || TPM2B_PUBLIC)

The integrity digest is prepended to the sensitive area, and a size of the result (2 bytes) is prepended to this, to create the final private data structure. Once this is done, these three files can be sent to the remote client PC, where they are imported using TPM2_Import and the EK as the new parent.

This technique is somewhat complicated, but it lets you create the key in any manner the administrator wishes and is the only way to create a duplicated key that has a null policy. This approach guarantees that it isn’t possible to duplicate the key from the target PC’s TPM to any other TPM, because the TPM always requires a policy to duplicate a key.

Technique 3

If you would like to generate your IDevID key yourself, perhaps because you have a trusted random number generator, but you don’t wish to do the hard part of generating the three files, you can import the key directly into a local TPM (or emulator) and let it do the hard work of duplicating the key. This still requires the end user to generate the public data of the key in TPM format, including having a policy that allows for duplication. But the generation of the seed—deriving an AES key from the seed and encrypting the private portion, generating the HMAC from the seed, and calculating the HMAC of the public and private portions of the data—is left to the TPM to accomplish.

This approach uses the TPM2_LoadExternal command, which doesn’t require that the private key be encrypted when it’s loaded. At this point the user continues using the same steps in as Technique 1 after the key was created. Then the user loads the public portion of the EK, satisfies the policy for duplication, and duplicates the key to the EK. Doing so produces the three files, which the user can load into the TPM once the user is assured that the EK is indeed loaded on their system.

Data Backups

Most PCs today have a lot of extra space on their hard drives. Most enterprises have many PCs with data that should be periodically backed up. It would be ideal if those PCs could back up their data on other PCs in the business. That way, as an enterprise expands with more PCs, the need to back up data and the available space on which to back up the data grow at the same rate. There are algorithms for backing up data in m copies, so that only n of the m copies need to be present to recover the data, and these algorithms can be made space efficient. However, this book doesn’t describe those techniques, because we’re concerned with another problem with this approach: how do you keep this backed-up data secure?

First, of course, the data must be encrypted in a way that only allows the owner of the data to access it. This can be done by having the TPM create an HMAC key and loading it in the TPM’s persistent storage using TPM2_EvictControl. The filename can be HMACed to create a derived AES key that can then be used to encrypt the file before it’s backed up. (This provides a different key for each file and makes it easy to recover the AES key for those with access to use the HMAC key.) Alternatively, you can ask the TPM to generate an AES key (using its random number generator, so the key is unique for each file); that key can be encrypted with a public key whose private key is known to the TPM, and that AES key is used to encrypt the file. In either case, the HMAC key or private key should be backed up to another system’s TPM in case of TPM failure.

Separation of Privilege

The end user today has to select and set authorization values for the storage hierarchy (owner authorization) for security, endorsement hierarchy (for privacy administration), and dictionary attack reset parameter (for TPM administration). This splits control of the TPM for different type of administrators. But finer control of these commands (particularly the owner authorization) may be required.

Chapter 10 gave a number of examples of different policies, but didn’t examine how a policy for the storage hierarchy can be split. The owner of the storage hierarchy can create NV indexes, create primary storage hierarchies, and make keys persistent (and evict them from persistency), among other things. An administrator may very well want to allow an end user to create primary keys but not make them persistent, or make NV indexes but not evict persistent keys in the storage hierarchy.

If a storage root key (SRK) is made by an administrator and made persistent, then without owner authorization, it isn’t possible to change the authorization value associated with this key. This is important, because that authorization is usually the empty buffer, in order to allow any software to use the SRK value stored in the TPM. If malicious code were to evict this key and then re-create it with a different authorization, it would be a type of denial of service attack.

But the end user may wish to allow software to use different algorithms than the default algorithm set chosen for the SRK. In this case, the owner may wish to allow the creation of SRK-like keys with different algorithm sets. As a result, the owner may wish software to be able to use keys created with TPM2_CreatePrimary. However, the owner may not wish to allow those keys to become persistent, because that uses precious resources in the TPM—another form of denial of service.

Finally, the owner may wish to allow software to create some NV RAM indexes that have a limited amount of space. But not all of these things can be done by choosing a correct policy.

To separate privilege, the owner first creates a long, random password for the owner-authorization value and then makes sure it’s held secure. This requires that the end user use the policy to accomplish their goals. Next, branches of that policy are created for each command code that the owner wishes the end user to be able to use. To allow use of TPM2_CreatePrimary, one branch can be TPM2_PolicyCommandCode with TPM2_CreatePrimary as a parameter. To allow only the creation of certain NVRAM indexes, the TPM2_PolicyCpHash command is used, with parameters for TPM2_NV_DefineSpace and specific parameters indicating the index to be created and the public parameters of that index, for each index that the owner wishes the end user to be able to create. (This is similar to opening a port in a firewall—just because it’s there doesn’t mean it will be used.)

Securing a Server’s Logon

Passwords are weak. Originally, usernames and passwords were stored on servers. That approach was vulnerable if someone got hold of the list. So, a shadow file system was set up to make it harder to get to the real list. But that was still too weak. Instead of storing passwords, the hashes of the passwords were stored. However, dictionary attacks and rainbow tables made this technique also vulnerable. Next, salted hashes (concatenating a random number before a password was hashed) were tried, but the salt itself had to be available for the computer to use to verify the password. In this case, very fast computers could do dictionary attacks against a salted list of passwords. So the server started doing many iterations of a hash—hashing the hash of the hash of the password, perhaps 1,000 times—to try to make dictionary attacks more expensive while not doing so many hashes that verifying a password took too long. Then cloud computing came along, making even this defense insufficient.

The TPM can be used to solve this problem. Instead of having the salt in the clear, a keyed hash can be used with the key stored in the TPM. The HMAC is over the user ID and password. If this is done, then even if the entire list of HMACed passwords were published, it wouldn’t do an attacker any good—not having the key, they would have to rely on the TPM to do the HMACing. This reduces the risk of parallelization attacks or offline attacks using very fast computers.

Implementing this is relatively easy. In Linux, authentication is done using pluggable authentication modules (PAMs); they’re designed specifically to allow different forms of authentication to be added to Linux.

First a large random number is created—say, a 256-bit number—which you use as your HMAC key. This is created with the TPM2_GetRandom command of the TPM or the Tpm2_GetRandom function in the FAPI. These commands ask how many bytes you want: in this case, you ask for 32 bytes. You call this result M and store it in a safe in case your TPM ever dies or the motherboard is replaced.

Next you need to load M into the TPM. You can do this with the TPM2_Load command. You choose an empty buffer password for M, because you want to use it without authorization. (You want to store M persistently, so you can’t use the TPM2_LoadExternal command.) You load it into the storage hierarchy using the owner authorization. Then you use TPM2_EvictControl to make M persist in the TPM. This call also gives it a persistent handle, which can thereafter be used to identify M in the TPM.

Now you need to write a PAM (which is outside the scope of this book). When given a new password, it uses the TPM2_HMAC command to HMAC the user ID and password with M. When a user ID and password are passed in for authorization, the PAM likewise HMACs them with M and then compares the result with what is in the user ID / HMAC list.

The HMAC command is relatively fast, so this shouldn’t delay the authentication procedure significantly, but it should be a good defense against attacks that steal the password file and try to reverse-engineer it with offline attacks of any sort.

Locking Firmware in an Embedded System, but Allowing for Upgrades

Healthcare systems need to be secure. Unfortunately, there has been a lot of research showing that devices such as pacemakers and glucose-control systems aren’t terribly secure. One way of making a system more secure is to be certain the firmware used to run the device is approved by the manufacturer. This means a public key has to be available to the device, to verify that the firmware that is being loaded has been correctly signed by the manufacturer. But where can you store the key?

The obvious solution is to store the key in the TPM. This public key can be loaded using the TPM2_LoadExternal command and then made persistent using the TPM2_EvictControl command. Now commands that are used to update the firmware can use the certified TPM2_VerifySignature command to verify that the new firmware is indeed signed by the manufacturer before it’s loaded. Writing cryptographic code isn’t easy to do without making mistakes, so having certified code to do the cryptographic calculations is a real advantage.

As a side note, a similar approach could be used for documents: passports or even currency could come with signatures. A portable scanner with a TPM in it could have public keys preloaded that match the authority that made the documents and could be quickly used to verify the signature. If a counterfeiter started producing large numbers of fake bills, they would first require a large number of real bills from which to copy the signatures. If they copied only a few bills, once found, those certificates could be easily revoked.


TPM 2.0 is more than just a collection of algorithms that can be performed in hardware. It’s an enabler of new functionality. The examples in this chapter haven’t (to our knowledge) been attempted in commercial or open source software yet, but we’re excited to see that happen. Even if only the solution for strengthening the storage of passwords were implemented, it would be a big win for the community. Security problems are everywhere, and TPM 2.0 can be used as a tool to provide solutions for those problems.

Copyright information

© Will Arthur 2015

Authors and Affiliations

  • Will Arthur
    • 1
  • David Challener
    • 1
  • Kenneth Goldman
    • 1
  1. 1.SCUS

Personalised recommendations