TrouSerS PKCS#11 interface docs

Quick Setup Guide

  1. make and install TrouSerS, openCryptoki and tpm-tools. TrouSerS must be installed prior to the build of openCryptoki.
  2. Make sure your TPM's SRK password is set to NULL. Since there are no appropriate ways to set the TPM's SRK password using PKCS#11 calls, this must be done outside the scope of PKCS#11. The TPM STDLL currently has the password for the SRK hard-coded to a hash of 0 bytes, so your TPM must match. If you've not yet taken ownership of your TPM, use tpm_takeownership, else the SRK password can be changed using tpm_changeownerauth.
  3. Log in to PKCS#11 as the Security Officer (SO) and then as USER, calling C_SetPIN to change the two PINs to something other than the default. This can be done with tpmtoken_init. Its a good security practice to use different PINs for the SO and USER.
  4. Optional: Move the PEM backup files to a secure location. These files will be located in the /usr/local/var/lib/opencryptoki/tpm/$USER directory by default.
  5. Your PKCS#11 apps should be ready to run! Please report problems to

Full-length Overview


The PKCS#11 standard defines an API to be used to interact with devices that hold cryptographic data and perform cryptographic functions. Providing PKCS#11 support for the TPM will allow applications to easily exploit the capabilities of the TPM.

As part of the PKCS#11 support, a key hierarchy must be defined to form a relationship between the PKCS#11 data store and the TPM's key wrapping hierarchy. This key hierarchy must meet some general requirements in order to be useful:

Key Hierarchy

The key hierarchy is implemented in the PKCS#11 TPM STDLL, which is the glue between the PKCS#11 interface APIs and the TSS APIs. The TPM STDLL performs all the TSS operations that are required to translate PKCS#11 calls to TSS calls. The key hierarchy consists of two branches of keys wrapped under the TPM's Storage Root Key (SRK). The two branches of the key hierarchy together provide a way for users to store data protected by their password and a way to store data which requires no password.

A conceptual overview of the layout of keys in the TPM token. Each line between two object represents the lower object being wrapped by the private key of the object above it. The dotted lines represent the connection between keys and the objects containing the randomly generated auth data for each key. In order to unwrap any of the auth data objects, the appropriate leaf key must be loaded, which will require either the PKCS#11 USER or SO password.

The keys which form the roots of these trees are the Private Root Key and the Public Root Key as depicted above. Both of these keys are generated in software. One copy of each of these software keys is encrypted with the USER PIN (for the Private Root Key) or SO PIN (for the Public Root Key), which is passed into PKCS#11 when C_SetPIN is called for the first time. This encrypted copy of the software key is stored on disk as an openssl PEM file, outside the PKCS#11 data store, for backup and migration purposes. The second copy of the software generated key is wrapped by the TPM's Storage Root Key and then stored in the PKCS#11 data store. These wrapped keys are created in the TPM as no-auth migratable storage keys.

The encrypted software copies of the keys can be left alone, or moved off the machine at the user's discretion. If they're moved off the machine, this would eliminate a brute force attack on the passwords of each key. However, if the keys are found during a PKCS#11 PIN change operation, the password used to encrypt them will be changed along with the password of the wrapped key objects.

The tree of keys underneath the Private Root Key will be referred to as the Private Key Hierarchy and the keys underneath the Public Root Key will be referred to as the Public Key Hierarchy. Each individual Linux user will have his/her own PKCS#11 data store in the /usr/local//var/lib/opencryptoki/tpm directory. This requires that each user initialize his/her own data store before using the PKCS#11 TPM token.

Private Key Hierarchy

The Private Key Hierarchy consists of the Private Root Key, the Private Leaf Key and a set of sub-keys. Wrapped by the SRK, the Private Root Key is the parent key of all keys created by an individual user.

The Private Root Key is an auth-less key, since authorization will be tested by loading the Private Leaf Key. Wrapped by the root key, the leaf key will require authorization data – a password. The leaf key must be loaded into the TPM in order to decrypt the authorization data associated with the user's other asymmetric (RSA) keys. When a user requests that new RSA key be created, some random authorization data for the new key will be created internally to the TPM token, the root key will be loaded and the new key will be wrapped underneath it. Once creation of the new key is complete, the random authorization data that was generated will be wrapped with the leaf key and stored in a way that ties it to the newly created key. Since the leaf key requires authorization, future usage of the new key will require the leaf key authorization to be supplied in order to decrypt the random authorization data created for the new key. In this way, one password can be supplied to "unwrap" an arbitrary number of user created keys.

Public Key Hierarchy

The Public key hierarchy works similarly to the Private Key Hierarchy, with a small twist. When a user is logged into the PKCS#11 token as SO (Security Officer), all keys that are created and imported will be protected by the SO PIN, just as those in the Private hierarchy are protected by the USER PIN. However, if the user is not logged in at all, new keys will be wrapped by the Public Root Key without creating any authorization data that goes along with them. Anyone will be able to access these keys, regardless of how they are logged in.


In order for a user to move his/her PKCS#11 data store from one platform to another, the backup copies of both the Private Root Key and the Public Root Key must be decrypted and re-wrapped to the new TPM's SRK. Luckily, this can happen automatically at PKCS#11 C_Login time without user intervention. During login, if the load of the Private Root Key (if logged in as USER) or Public Root Key (if logged in as SO) fails, then we know that the SRK has changed and was unable to decrypt the key. Since the root keys do not require authorization, there should be no problem loading them, other than when the SRK changes. If the load of one of these keys fails, the TPM token tries to decrypt the backup key using the supplied password and if successful, will automatically re-wrap it to the new SRK and replace the old key in the PKCS#11 data store. At this point, the user is migrated (for either USER or SO, depending on how he/she was logged in) without having to take any unusual steps. After logging in as both SO and USER on the new platform, the user's data store is completely migrated to the new platform.


A layout of files created by the TPM token code after calling C_SetPIN for both the USER and SO PKCS#11 users is as follows:

        |-- MK_PRIVATE
        |-- NVTOK.DAT
	|-- PRIVATE_ROOT_KEY.pem --> encrypted, openssl generated, Private Poot Key
	|-- PUBLIC_ROOT_KEY.pem --> encrypted, openssl generated, Public Poot Key
        `-- TOK_OBJ
            |-- 00000000 -.
            |-- 10000000  |
            |-- 20000000  |
            |-- 40000000  |
	    |-- 50000000  |--> PKCS#11 data store objects, hidden from external view
            |-- 60000000  |
            |-- 80000000  |
	    |-- 90000000 -`
            |-- IDX.TMP
            `-- OBJ.IDX
As noted above, the PEM files can be moved to a secure location to prevent an unauthorized user from gaining access to try a brute force attack on your password. During a PIN change operation, if the appropriate PEM file is found, its password is updated along with the PKCS#11 object by the TPM token. If the PEM file is not found, the user must manually change the PEM file's password so that it matches the current PIN for the appropriate user at migration time. During a migration these files must be present in order to re-wrap them to the new machine's SRK. The following commands can be used to change the password on a PEM file:

	$ openssl rsa -in PUBLIC_ROOT_KEY.pem -aes256 -out new_pass.pem
	$ mv new_pass.pem PUBLIC_ROOT_KEY.pem
AES-256-CBC must be used to encrypt the PEM file, since that's what the TPM token code will be expecting.

For corrections, comments or suggestions, contact Author: Kent Yoder. Logo