TPM/J 0.3 User's Guide

1. Introduction

This document provides a brief overview of the TPM/J package structure, as well as documentation on how to start using the TPM/J software tools in the tools package.

2. System Requirements

3. TPM/J Packages

4. Library and Other settings

Classpath Settings

The class files for TPM/J are provided in tpmj.jar, or the bin directory in the distribution. Make sure to include either tpmj.jar or the bin directory in your classpath when running TPM/J.

Also, some TPM/J classes and methods require the Bouncy Castle Provider library. A redistributable .jar file (bcprov-jdk15-131.jar) is included in the TPM/J distribution under the lib directory. This .jar file should also be included in your classpath when running TPM/J.

The settpmjclasspath.sh file shows how you might set your classpath for use with Linux or Mac OS X, assuming that the TPM/J files are under ~/tpm/tpmj. To use it, run it as:

. settpmjclasspath.sh
(The . and the space after it is necessary. Otherwise, the classpath setting won't stick.)

Linux

For Linux, TPM/J reads and writes to the /dev/tpm0 device provided by the standard Linux TPM driver, which was based on the tpmdd project. The latest versions of the Linux kernel should already include this driver by default, so there should be no need to install tpmdd separately. (Note that you may have to change the permissions for the /dev/tpm0 device or use sudo when running Java in order to avoid permissions problems.)

Windows XP

For Windows XP, TPM/J currently works if you have ifxtpm.dll in your Windows' system32 directory or in your PATH. This is the TDDL-level library provided in software based on Infineon's TPM software stack. Note that the TPM software bundled by several manufacturers are actually Infineon-based even if they are not Infineon-branded and the TPM chip itself is not an Infineon chip. (An example is that HP ProtectTools suite that we used with our HP DC7600 machine. It is based on Infineon's software, and has ifxtpm.dll, although the HP DC7600 machine itself has a Broadcom TPM 1.2 chip.)

The file IFXTPMJNIProxy.dll in the lib directory of the TPM/J distribution is also required. Thus, to use TPM/J under Windows, you have to run Java with the -D option pointing java.library.path to the lib directory. e.g.,

java -Djava.library.path=C:\TPMJ\lib ...
(In Eclipse, you can add the following under VM Arguments when setting up your application to "Run as a Java Application":
-Djava.library.path=${workspace_loc:TPMJ}/lib )

Windows Vista

Thomas Müller (xnos.org) has contributed code for using TPM/J under Windows Vista using the TDDL-like interface of the TBS. To use this, you need to have the TBSProxy.dll file in the lib directory of the TPM/J distribution. Thus, as with Windows XP above, you have to run Java with the -D option pointing java.library.path to the lib directory. e.g.,
java -Djava.library.path=C:\TPMJ\lib ...
(In Eclipse, you can add the following under VM Arguments when setting up your application to "Run as a Java Application":
-Djava.library.path=${workspace_loc:TPMJ}/lib

Note that under Vista, you need to run your TPM/J application as an Administrator. (If you are running the applications from Eclipse, you must run Eclipse as administrator. If you are running the applications from the command line, then the command prompt must be run as administrator.)

Note also that by default, many TPM commands are blocked in TBS, so many TPM/J tools will fail to work. To unblock these commands, you should run the Group Policy Editor: gpedit.msc | Computer Configuration | Administrative Templates | System | Trusted Platform Module Services | Ignore the default list of blocked TPM commands = enabled . Alternatively, run tpm.msc and under Command Management, make sure that the commands you need are unblocked.

Warning! If you are already using the TPM in Vista for other functionality (e.g., BitLocker), take extra precaution when using TPM/J, especially the blocked commands, as these may interfere with your applications.

To maintain compatibility with Vista-assigned authorization data, the TPM/J 0.3 tools package now defaults to encoding passwords using what used to be the -i ("Infineon-style") option in previous versions. Also note that Vista uses a "well-known" value of all-zeros for the SRK authorization value. You can indicate this by using "" (empty string) in place of the SRK password on the command-line when using the TPM/J command-line tools.

Note: using the current implementation of the TPM/J Vista TBS driver class, the LoadKey tool works, but the key that it loads is unloaded when the program exits. The reason for this is that TPM/J creates a new TBS session every time the TPM driver class is initialized, and there is currently no way to make two applications running in a different Java VM share the same TBS session. When the program exits, the TBS session is closed, and Vista releases all the resources used by that session, so the key does not remain loaded in the TPM.

Because of this problem, using other TPM/J tools (such as TPMSign, TPMUnbind, etc.), that depend on having a key handle available, does not work under Vista right now. However, note that within the same program, loading a key, and using the resulting key handle works. An example is actually part of the CreateKey and CreateAIK tools.

We are working on modified versions of the TPM/J tools which will allow the user to specify an unloaded key file instead of a loaded key handle. This feature should be in the next release.

Intel Mac OS X

TPM/J works under an Intel Mac with a TPM chip, using the TPM driver ported by Amit Singh. Please follow the instructions in Amit Singh's article to build and install the driver. If you follow his instructions, you should end up with the file OSXBookTPM.kext in your ~/tpm/ directory. You must then load this driver by running:
sudo kextload -v OSXBookTPM.kext
You may need to run this every time you reboot.

Note:You do not need to build, install, TrouSerS, tpmlib, or any of the other packages aside from OSXBookTPM.kext that is included on Amit Singh's web page.

Once the driver is loaded, you should see the /dev/tpm device, which should work the same way that the /dev/tpm0 device works under Linux. TPM/J automatically knows to use /dev/tpm when running under Mac OS X, so you can use TPM/J the same way as you would under Linux. (Note that you may have to change the permissions for /dev/tpm device or use sudo when running Java in order to avoid permissions problems.)

5. TPM Tools

The classes in the tools package provide command-line tools that can be used to manage and use the TPM without having to write your own code.

Notes

How do I?

Get information about the TPM and its current status

To get current information about the TPM, including flags, PCR values, and active handles, run:
java edu.mit.csail.tpmj.tools.TPMInfo [ownerPwd]
On a TPM 1.2 chip, if the TPM already has an owner, you will need to supply the owner password to be able to read the public key of the EK.

Perform a Full Self Test

On some systems (we have seen this happen particularly with the Infineon TPM 1.2 chip on an Intel Mac Mini), some operations (e.g., taking ownership, creating AIKs, etc.) fail unless you do a self test.

To do this, use tools.special.TPMSelfTest:

java edu.mit.csail.tpmj.tools.special.TPMSelfTest

Reset Authorization Sessions

When running some of the programs, you may get exceptions which cause the program to exit without cleaning up. When this happens, there may be authorization sessions left open. The TPM can only keep track of a few authorizations total at a time before running out of "space" or "resources". If you are getting an error about TPM space or resources, try to run TPMResetAuth, which will free all outstanding authorization sessions.
java edu.mit.csail.tpmj.tools.TPMResetAuth
If this doesn't work, look into evicting keys, or releasing transport sessions which may be open. Flushing specific handles can also be done using the TPMFlush tool.

Clear the TPM

The easiest way to clear the TPM in most systems (and maybe the only way on some systems) would be to do it through the boot-up BIOS. How to do this may vary from system to system.

On an Intel Mac, there is no BIOS utility for accessing the TPM, and instead, the TPM can be clear and enabled directly via software. In this case, to clear the TPM, run tools.TPMForceClear:

java edu.mit.csail.tpmj.tools.special.TPMForceClear
After running this, you should REBOOT the machine.

Warning! Note that clearing your TPM will invalidate any data or keys that have previously been encrypted/protected by the TPM. If you have used another tool to encrypt or seal data using the TPM, or if you have set up a personal storage drive, or use full-volume encryption or any other mechanism that uses TPM-protected keys, then you will not be able to decrypt any data encrypted by the TPM after the TPM is cleared. Please use this tool with caution!

Activate the TPM

The easiest way (if not the only way) to activate the TPM in most systems would be to do it through the boot-up BIOS. How to do this may vary from system to system.

On an Intel Mac, there is no BIOS utility for accessing the TPM, and instead, the TPM can be clear and enabled directly via software. In this case, to enable and activate the TPM, run tools.TPMActivate:

java edu.mit.csail.tpmj.tools.special.TPMActivate
(This assumes that the TPM is already in a cleared and disabled state.) After running this, you should REBOOT the machine.

Take ownership of the TPM

Once the TPM has already been cleared, and then enabled and activated, you need to take ownership of it before you can use it for real applications. Use tools.TPMTakeOwnership to take ownership of your TPM:
java edu.mit.csail.tpmj.tools.TPMTakeOwnership <ownerPassword> [srkPassword] 

Arguments:
- ownerPassword - The new owner password for the TPM.
- srkPassword - The new SRK password to the TPM.

Notes:

Example:

java edu.mit.csail.tpmj.tools.TPMTakeOwnership tpmowner
This takes ownership with owner password "tpmowner" (using Infineon/Vista encoding), and null SRK password (with no authorization).

Change the owner password

Use tools.TPMChangeOwnerAuth:
java edu.mit.csail.tpmj.tools.TPMChangeOwnerAuth <oldPwd> <newPwd>

Example:

java edu.mit.csail.tpmj.tools.TPMChangeOwnerAuth -ptpmowner tpmowner
This changes the owner password from "tpmowner" encoded using the old (TPM/J v0.2) default encoding (i.e., plain 8-bit ASCII without null terminator) to the new default encoding style (i.e., UTF-16LE without null terminator, as used by Infineon and Vista Windows stacks for Windows).

Change the SRK password

Use tools.TPMChangeSRKAuth:
java edu.mit.csail.tpmj.tools.TPMChangeSRKAuth <ownerPwd> <newSRKPwd>
NOTE: This tool does not have the ability to change whether authorization is needed to use the SRK or not. If you took ownership with a "null" SRK password, then even if you change the SRK password the SRK will still be usable without an authorization session. (However, if you do use authorization, then the new password will be required.)

Create a new AIK

Use tools.TPMCreateAIK to create a new AIK:
java edu.mit.csail.tpmj.tools.TPMCreateAIK <fileName> <aikPwd> <labelPrivCA> <ownerPwd> [srkPwd] 
Arguments: Notes:

Example:

java edu.mit.csail.tpmj.tools.TPMCreateAIK aik.key test 0x1234567890123456789012345678901234567890 tpmowner
This creates a file with an AIK key, with password "test", assuming ownership was taken using the TPMTakeOwnership example above. The hex string starting with 0x is the 20-byte digest, labelPrivCADigest, for the Privacy CA.

Create a new TPM key

Use tools.TPMCreateKey to create a new bind, signing, storage or legacy key:
java edu.mit.csail.tpmj.tools.TPMCreateKey <fileName> 
      [keyType] [keyPwd] [parentHandle] [parentPwd] [/m migPwd] 

Output:
- a key blob (TPM_KEY format) under <fileName> containing the new wrapped key

Arguments:
- fileName - The file that the new key will be stored to.
- keyType - 's' (signing), 'b' (bind), 'e' (storage), or 'l' (legacy). Deafults to 'l'.
- keyPwd - The usage password for the new key.
- parentHandle - The handle number of the previously-loaded parent key, or "SRK" for the SRK.
- parentPwd - The usage password for the parent. (Can be null.)
- For migratable keys, use /m followed by space, and the migration password.

Notes:
- Some of the tests will fail depending on the type of the key:

- This operation can take a while (e.g. a few minutes) to complete.
- Some demos may assume a key file testkey.key with key password "test" and migration password "test", and parent SRK, with null SRK password

Example 1 (creating a legacy key):

java edu.mit.csail.tpmj.tools.TPMCreateKey testkey.key l test SRK /m test
This creates a file containing a new migratable TPM_KEY blob with key and migration passwords equal to "test", using the SRK as the parent, assuming the SRK password was set to null using the TPMTakeOwnership example above.

Example 2 (creating a storage key):

java edu.mit.csail.tpmj.tools.TPMCreateKey storage1.key e storetest SRK
This creates a file containing a non-migratable storage key blob with password "storetest", and having the SRK as its parent with no authorization (as in the TPMTakeOwnership example above). (Note that the keyType for a storage key is "e", not "s", which is the keyType for a signing key.)

The resulting key can later be loaded and used for wrapping and loading a child key, as in the example below.

Create an RSA private-public keypair in software, and then wrap it for the TPM

Use tools.TPMWrapKey to generate an RSA keypair in software, and then create an SRK-wrapped TPM key for the TPM:
java edu.mit.csail.tpmj.tools.TPMWrapKey <fileName> 
      [keyType] [keyPwd] [migPwd] 
      [parentHandle | "SRK" | parentFileName] [parentPwd] [/ownerPwd pwd] 

Output:

Arguments:

Example 1: Using SRK as parent, with knowledge of the owner password

java edu.mit.csail.tpmj.tools.TPMWrapKey wrappedkey.key l test test SRK /ownerPwd tpmowner
This creates a file containing a new migratable TPM_KEY blob with key and migration passwords equal to "test", using the SRK as the parent, assuming the SRK password and owner password were set using the TPMTakeOwnership example above.

Example 2: Using SRK as parent, without knowledge of the owner password but with SRK public key in file srk.pubkey

java edu.mit.csail.tpmj.tools.TPMWrapKey wrappedkey.key l test test SRK
In this case, getting the SRK public key from the TPM will fail (since the TPM owner password is not null), and the program will look for the srk.pubkey file generated by TPMTakeOwnership in the current directory and use the public key stored there. (If SRK password is known, you can add it after "SRK" in the command-line.)

Example 3: Using a loaded non-SRK storage key
First, load the parent key (in the case, the storage key created by the example above):

java edu.mit.csail.tpmj.tools.TPMLoadKey storage1.key
(Note that this assumes storage1.key has the SRK as its parent, and the SRK has no authorization password.)

Now, suppose this returns a key handle 0x5e70328.
Then, run TPM WrapKey:
java edu.mit.csail.tpmj.tools.TPMWrapKey wrappedchild.key l test test 0x5e70328 storetest
This will produce a key wrapped (encrypted) according to the public key of storage1.key.

Example 4: Using parent's key blob file without parent password

java edu.mit.csail.tpmj.tools.TPMWrapKey wrappedchild.key l test test storage1.key
This will produce a key wrapped (encrypted) according to the public key of storage1.key, even if you do not know the authorization password for storage1.key. Note, however, that the key tests (signing, etc.) will fail because the program will not be able to load the child key.

Load a key into the TPM

Use tools.TPMLoadKey to load a key into the TPM:
java edu.mit.csail.tpmj.tools.TPMLoadKey <fileName> [parentHandle | "SRK" ] [parentPwd] 
Output: the key handle of the loaded key

Arguments:
- parentHandle should be the handle number of the loaded parent key
Use "SRK" for the SRK. Default is SRK.
- If parentPwd is not given, null password with no authorization is assumed.

Example 1: Load a key that is the child of the SRK (with no SRK authorization)

java edu.mit.csail.tpmj.tools.TPMLoadKey storage1.key
This assumes storage1.key, created by the example above, which has the SRK as its parent, and the SRK has no authorization password.)

Example 2: Load a child of another storage key

java edu.mit.csail.tpmj.tools.TPMLoadKey wrappedchild.key 0x5e70328 storetest
This assumes storage1.key has already been loaded with key handle 0x5e70328, and that wrappedchild.key is the key created in the example above.

Sign a data file using a loaded key

First, load the key you want to use into the TPM. The key must be either a signing key or a legacy key. Then, use tools.TPMSign to sign a data file given the key's handle.
java edu.mit.csail.tpmj.tools.TPMSign <fileName> <keyHandle> [keyPwd] 
Output: The file <fileName>.sig containing the bytes comprising the RSA signature of the data in fileName. (It actually contains the signature of the SHA-1 hash of the data.)

Verify the signature of a data file

Run tools.TPMVerifySig:

java edu.mit.csail.tpmj.tools.TPMVerifySig <dataFile> <keyFile>
Inputs:

Note: This is done completely in software (without using the TPM) using the public key information stored in the given .key or .pubkey file. It is possible to verify a signature without knowing the private key or authorization password of the key.

Encrypt (bind) a data file

Run tools.TPMBind:

java edu.mit.csail.tpmj.tools.TPMBind <dataFile> <keyFile>
Inputs: Output: file <dataFile>.enc containing the encrypted form of the data

Notes:

Decrypt (unbind) a data file

First, load the key you want to use into the TPM. The key must be either a binding key or a legacy key. Run tools.TPMUnbind:

java edu.mit.csail.tpmj.tools.TPMUnbind <fileName> <keyHandle> [keyPwd]
Output: <fileName>.plain containing decryption of <fileName>

Evict keys from the TPM

Use tools.TPMEvictKey to evict one or all loaded keys from the TPM:
java edu.mit.csail.tpmj.tools.TPMEvictKey <keyHandle | "all">
Notes:
- Sometimes, errors encountered during demos would cause loaded keys not to be unloaded. This uses up space on the TPM which would prevent other keys from being loaded.  If you are encountering problems, try using TPMEvictKey to clear the space used by these keys.

Flush a key, authorization, or transport session

Use tools.TPMFlush to evict/flush a specific handle of a certain type
java edu.mit.csail.tpmj.tools.TPMFlush <type> <handle | "all">

Types:
a - authorization session
c - context
k - key
t - transport session

Read PCRs (without quoting)

Use the TPMReadPCRs tool:
java edu.mit.csail.tpmj.tools.TPMReadPCRs

Extend a PCR

Use the TPMExtend tool:
java edu.mit.csail.tpmj.tools.TPMExtend <pcrNum> [data]
Notes:

Quote all PCRs using a loaded key

First, load the key you want to use into the TPM. The key must be either a signing key or an AIK. Then, use tools.TPMQuote:
java edu.mit.csail.tpmj.tools.TPMQuote <fileName> <keyHandle> [keyPwd]

Inputs:

Outputs:

Verify a quote

Run tools.TPMVerifyQuote:

java edu.mit.csail.tpmj.tools.TPMVerifyQuote <dataFile> <keyFile>
Inputs:

Note: This is done completely in software (without using the TPM) using the public key information stored in the given .key or .pubkey file. It is possible to verify a quote without knowing the private key or authorization password of the key.

Seal a data file

Run tools.TPMSeal:

java edu.mit.csail.tpmj.tools.TPMSeal <dataFile> <keyHandle> <keyPwd> <dataPwd> [pcrNums...]
Inputs: Output: file <dataFile>.sealed containing a TPM_STORED_DATA structure

Notes:

Unseal a data file

Run tools.TPMUnseal:

java edu.mit.csail.tpmj.tools.TPMUnseal <dataFile> <keyHandle> <keyPwd> <dataPwd>
Inputs: Output: file <dataFile>.unsealed containing a TPM_STORED_DATA structure

Notes:

Create a new monotonic counter (TPM 1.2 only)

Use tools.TPMCreateCounter to create a monotonic counter:
java edu.mit.csail.tpmj.tools.TPMCreateCounter <ownerPwd> [counterLabel] [counterPwd]

Arguments:
- ownerPwd - The password of the owner of the TPM.
- counterLabel - The label for the monotonic counter.
This must be 4 bytes long. Defaults to 'CNTR'. - counterPwd - Authorization password for counter. Defaults to all-zeroes.

Notes:
- If the new TPM counter ID is returned as -1, the counter creation probably failed.

Read a monotonic counter (TPM 1.2 only)

java edu.mit.csail.tpmj.tools.TPMReadCounter <counterID>

NOTE: counterID is the counter handle number (not the label)

Increment a monotonic counter (TPM 1.2 only)

java edu.mit.csail.tpmj.tools.TPMIncCounter <counterID> [counterPwd]
Notes:

Release monotonic counters from the TPM

Use tools.TPMReleaseCounters to release one or all of the monotonic counters from the TPM:
java edu.mit.csail.tpmj.tools.TPMReleaseCounters <handle | "all"> [counterPwd] [/ownerPwd password]

Notes:

Example 1: Releasing all counters using owner password

java edu.mit.csail.tpmj.tools.TPMReleaseCounters all /ownerPwd tpmowner
This assumes that the owner password is "tpmowner".

Example 2: Releasing a specific counter using the specific counter password

java edu.mit.csail.tpmj.tools.TPMReleaseCounters 0xa1a608c test
This assumes that the counter has handle 0xa1a608c and password "test".

Example 3: Releasing a specific counter using the owner password

java edu.mit.csail.tpmj.tools.TPMReleaseCounters 0xa1a608c /ownerPwd tpmowner

"Count-stamp" a data file (sign it with a monotonic counter value)

First, load the key you want to use into the TPM. Usually, this should be an AIK. (Otherwise, one can produce a fake countstamp using the TPM_Sign operation on the TPM.)

Then, use counters.CreateCountStamp to sign a data file given the key's handle.
java edu.mit.csail.tpmj.tools.TPMCreateCountStamp <fileName> <R|I> <counterID> <counterPwd> <keyHandle> [keyPwd]\n\n"

Notes:

Output: Binary file <filename>.cntstmp, containing the TPMCountStamp of the SHA-1 hash of the file contents. TPMCountStamp is a TPM/J-specific data structure (not TCG-defined) containing the log of the transport session used to wrap the read or increment TPM command.

Verify the countstamp of a data file

Run counters.TPMVerifyCountStamp:
java edu.mit.csail.tpmj.tools.TPMVerifyCountStamp <dataFile> <keyFile>

Inputs:

Note:

  • This program will print the contents of the time stamp (including the counter ID, label, and value, and the hash of the data that was stamped).
  • It compares the stamped hash and the data file's hash and then finally checks that the signature on the time stamp is authentic, given the provided public key.
  • This is done completely in software (without using the TPM) using the public key information stored in the given .key or .pubkey file. It is possible to verify the time stamp without knowing the private key or authorization password of the key.

  • Lead author (v0.3): Luis Sarmenta (lfgs at mit dot edu)
    Original author (v0.2): Jonathan Rhodes (jrhodes at mit dot edu)
    Last edit by: Luis Sarmenta on April 3, 2007