Take Control of TCPA

Can you trust “Trusted Computing”? Learn how it works with free software that lets you store your own keys securely.

Enabling and Clearing the TPM

Before looking at these specific TPM commands, we
should cover one of the more mystifying aspects of
the TPM—how to get it started. Fortunately,
the BIOS is responsible for starting up and clearing
the TPM, so this really is not as complex as it
looks to be in the TPM specification. At power-on, the
TPM is activated but not started. The BIOS
then must issue a TPM_Startup command. This command
can do one of three things: deactivate
the TPM, start up the TPM with a reset of
the PCR registers or start up the TPM with
a restore of PCR values from their saved states
(as with a resume). If the BIOS deactivates the
TPM, it remains deactivated until the next power
cycle; no software command can reactivate
it. A startup with clearing of the PCRs is done at
boot time, so all PCR values are calculated
correctly during boot. The TPM device driver is
responsible for making a TPM_SaveState request at
suspend time to ensure that valid PCR values are
available at resume time.

The BIOS also is responsible for performing a
TPM_ForceClear if desired. The clear command
is a complete reset of the TPM, and it
unloads all keys and handles and clears
the SRK and owner authorization secret.
TPM_ForceClear requires proof of physical
presence, which normally is given by holding
down the Fn key (blue key at the bottom left)
when powering on the system.

The control of TPM deactivation and clearing
by the BIOS is set in the BIOS setup mode.
To get started with the TPM, then, hold down the Fn key
and press the Power-On button. When the BIOS screen appears, release Fn, and
press F1 to enter BIOS setup mode. Next, select Config→Security
System,
then select Enable and Clear entries.
These steps enable operation of the TPM and
clear the chip, so it is ready for us to
take ownership.

Talking to the TPM

The TPM device driver, tpm.o, is a loadable kernel
module that provides a character device interface to
the TPM chip. It is registered officially as Linux
major number 10, minor number 224. Applications
normally access it through the special file
/dev/tpm.

To send a command to the TPM, /dev/tpm is
opened for read/write, a command packet is written
and the response packet is read. The TPM can process
only one command at a time, so the entire request
must be sent and the entire response must be read before
another request can be made.

All command packets have a common structure:

16-bit unsigned TAG

type of packet

32-bit unsigned Length

length of total packet

32-bit unsigned Ordinal

TPM command number

variable

command data

All response packets have a similar structure:

16-bit unsigned TAG

type of packet

32-bit unsigned Length

length of total packet

32-bit unsigned Return

return code

variable

returned data

All 16- and 32-bit values are in network byte
order (big endian) and must be converted to and
from host byte order. On writes to the TPM,
write exactly the number of bytes in the packet,
as indicated in the packet's total length field.
When reading the response, you should attempt to
read 4,096 bytes (the defined maximum TPM packet
size), and the return value of the read
indicates how many bytes are in the returned packet.
This should match the returned packet's
length field exactly. The return code is zero for a
successful command, and a positive value is
a specific error code.

A function for sending/receiving TPM packets can
look something like the following (error
handling omitted for clarity):

Once the TPM is enabled and cleared through
the BIOS setup and the TPM device driver is loaded,
we can try some simple TPM commands.
The TCPA main specification details some 73
TPM commands. Fortunately, we can demonstrate
the desired signing and sealing functionality
in this tutorial with only 14 of these commands.

The simplest command is TPM_Reset,
a request to flush any existing authorization
handles. TPM_Reset is a nice command to test a
driver and library, as it is short, fixed and
should always succeed, returning a result code of
zero. Here is the example code for TPM_Reset:

It is important to size blob[] to allow the returned
TPM data to be up to the maximum allowed packet size
of 4,096 bytes.

The TPM_GetCapability command is another simple
function that can return several items of
information about a given TPM. It can return the
version of the current TPM, the total number of
key slots in the TPM (typically ten), the number
of loaded keys and their handles and the number
of PCR registers (typically 16). Here is the
example code for using TPM_GetCapability to read
the TPM version:

TPM_PcrRead returns the 20 bytes (160 bits) of
a specified PCR register. It is useful to check
that any desired TPM measurements are being made
by the modified GRUB loader.

TPM_ReadPubek is used to read the TPM's fixed
public endorsement key (Pubek). Pubek initially must
be read so it can be used by the
owner to encrypt sensitive data in the
TPM_TakeOwnership command. Once ownership is
established, the owner typically disables
reading of the Pubek for privacy reasons; after that,
then this command fails.