In this chapter, the authors demonstrate how to talk to a TPM (both 1.1 and 1.2) at the lowest level. This will be useful for programmers who want to talk to the TPM directly, either in BIOS or a device driver.
There are currently two different TPM device programming interfaces. The TPM 1.1b-compliant devices use a device interface that is vendor specific. Because of the lack of a standardized device interface, each vendor is forced to define its own interface. This interface is typically very simple because the TPM 1.1b specification places only modest requirement on the device interface. To curtail the myriad of incompatible device interfaces, TCG decided to standardize the PC client interface as part of its 1.2 TPM specification. This device interface supports dynamic root of trust and consequently requires a more sophisticated interface that supports locality and special LPC bus cycles.
In this chapter, we will examine how to write a TPM device driver. We start with the TDDL interface and illustrate how to program the TPM 1.1b and 1.2 low-level device interfaces to implement part of the TDDL interface. The code examples have been developed on Linux, but in the interest of staying operating system-neutral, we have removed all the Linux-specific device driver boilerplates. Instead we focused on the core device driver functions that are similar for any operating system.
The TDDL interface is the standard interface that applications use for communicating directly with the TPM. This interface is part of the TSS library and is in fact used by the TSS stack to talk to the TPM. Although this interface is available for use by applications, its direct use is typically best avoided. The TDDL interface is a single-threaded synchronous interface, and it assumes that all TPM commands are serialized by the caller of the interface. If this interface is used together with TSS library calls, then the results may be undefined.
The TDDL interface is straightforward. It includes calls to open and close access to the TPM device, cancel any outstanding commands, get and set vendor-specific device capabilities, get the device status, and transmit a command blob to the TPM and receive a response. Unlike the actual device interfaces that are discussed later in the chapter, the TDDL interface is the same for TPMs that follow the 1.1b or the 1.2 specification.
In the next sections, we are going to examine how to implement the device driver equivalent of the Tddli_TransmitData function with a TPM 1.1b- and a TPM 1.2-compliant device.