The Hardware

There are already many versions of TPM standard. The first versions were not all compatible (from Atmel, STM, Infineon...), therefore since the 1.2 version of the standard it seems we have a consensus.

So, we will see the procedure to use a 1.2 TPM.

I have for example a DELL Optiplex 755 which provides a ST Microelectronics TPM conform with version 1.2. This conformance is important since the Linux kernel does not provide a specific implementation for all chips.

You can see what TPMs are supported with your kernel version with the following command :

 $ ls -la /lib/modules/`uname -r`/kernel/drivers/char/tpm
 drwxr-xr-x 2 root root  4096 2008-06-24 10:33 .
 drwxr-xr-x 9 root root  4096 2008-06-24 10:33 ..
 -rw-rr 1 root root  9012 2008-06-18 20:13 tpm_atmel.ko
 -rw-rr 1 root root 10960 2008-06-18 20:13 tpm_bios.ko
 -rw-rr 1 root root 13440 2008-06-18 20:13 tpm_infineon.ko
 -rw-rr 1 root root 20392 2008-06-18 20:13 tpm.ko
 -rw-rr 1 root root 10712 2008-06-18 20:13 tpm_nsc.ko
 -rw-rr 1 root root 17432 2008-06-18 20:13 tpm_tis.ko

The tpm_tis module is the generic one to use fully 1.2 compatible TPMs. We will use this one.


Before doing anything, you must enable the TPM in the BIOS of your motherboard. If you need to reset the TPM BIOS, this usually requires a full power off and back on of the computer.

Linux kernel

We use two generic modules tpm_bios and tpm and the specific one tpm_tis.

First load the generic modules :

 $ sudo modprobe tpm_bios
 $ sudo modprobe tpm

And then the tpm_tis module with specific parameters. In fact, we user the force option to probe rather than using the ACPI entry and the interrupts option to desactivate the IRQ.

 $ sudo modprobe tpm_tis force=1 interrupts=0
 $ dmesg
 [xxx.yyy] tpm_tis tpm_tis: 1.2 TPM (device-id 0x4A10, rev-id 78)

If you have something like this, all works fine !

If your TPM does not seem to be detected go to the last section Kernel development corner.

TPM management tools

There are many softwares to manage your TPM, the more efficients I think are TrouSerS and Trusted Computing for the Java(tm) Platform.

In this tutorial, we will use TrouSerS . It provides an open-source TCG Software Stack and many TPM tools.

So, we will no see how to take ownership and initialize your TPM. We will use the TPM tools provided with TrouSerS, you can refer to your local manpages of to this documentation.

Prepare the tools

Tools installation :

 $ sudo aptitude install tpm-tools trousers

Trousers is daemon which centralize all the communication with the TPM. All communication are base on Local or Remote Procedure Call (RPC). You can restrict its usage to local programs. First of all, check if it is running :

 $ sudo /etc/init.d/tcsd start

Check if the TPM is accessible :

 $ sudo tpm_version
     TPM Version:    01010000
     Manufacturer Info:    53544d20

Initialize the TPM

So the first step is to take ownership. This operation will prompt for owner and SRK passwords which are very important and must not be lost.

 $ sudo tpm_takeownership
 Enter owner password: xxxxxx
 Confirm password: xxxxxx
 Enter SRK password: yyyyyyyy
 Confirm password: yyyyyyyy

Ownership can only be realized once, any other attempt will fail.

The operation may take awhile, the TPM is generating an initializing some internal cryptographic values. The owner password is for adminstration and other sensitive tasks. The SRK is the Storage Root Key which will be required whenever you load a key into the TPM.

If you have the following error :

 Tspi_TPM_GetPubEndorsementKey failed: 0x00000023 - layer=tpm, code=0023 (35), No EK

This is because your TPM does not have an Endorsement Key. Then, launch the following command which will take awhile :

 $ sudo tpm_createek

Now the TPM has an owner, we can get the Public Endorsement Key. The Endorsement Key is typically a 2,048-bit RSA public and private key pair, which is created randomly on the chip at manufacture time and cannot be changed. The private key never leaves the chip, while the public key is used for attestation and for encryption of sensitive data sent to the chip.

To get the public key, your owner password will be required :

 $sudo tpm_getpubek
 Tspi_TPM_GetPubEndorsementKey failed: 0x00000008 - layer=tpm, code=0008 (8), 
                        The TPM target command has been disabled
 Enter owner password: 
 Public Endorsement Key:
   Version:   01010000
   Usage:     0x0002 (Unknown)
   Flags:     0x00000000 (!VOLATILE, !MIGRATABLE, !REDIRECTION)
   AuthUsage: 0x00 (Never)
   Algorithm:         0x00000020 (Unknown)
   Encryption Scheme: 0x00000012 (Unknown)
   Signature Scheme:  0x00000010 (Unknown)
   Public Key:
 	a71def6a f09b39cb e0e55779 b1e6dfe5 26ca2278 b6fce7cf f1c242c5 545694d8
 	1a5804ad 5a3b1d5c c18c3d93 fda2e201 78a86e4e c93e4bb7 e1851eab ca98cbe5
 	81c06522 1357777c e0e55779 1bac9e9c 8208f203 f1477705 0317fe2b db233d4d
 	a71def6a f09b39cb e0e55779 b1e6dfe5 26ca2278 b6fce7cf f1c242c5 545694d8



TrustedGRUB is an extension of the standard GRUB bootloader. It has been modified to detect and support the TPM functionalities.­ The main feature of TrustedGRUB is to measure arbitrary files during the boot process and extend the Platform Configuration Registers (PCR).

PCR are registers inside the TPM memory which are updated at each boot.

The PCR are used as follow :

  • PCR 0 to 3 for the BIOS, ROMS...
  • PCR 4 contains MBR information and stage1
  • PCR 8 contains bootloader information stage2 part1
  • PCR 9 contains bootloader information stage2 part2
  • PCR 12 contains all commandline arguments from menu.lst and those entered in the shell
  • PCR 13 contains all files checked via the checkfile-routine
  • PCR 14 contains all files which are actually loaded (e.g., Linux kernel, initrd, modules...)
  • PCR 15 to 23 are not used

You can see your currents PCR values with the following command :

 $ sudo cat /sys/class/misc/tpm0/device/pcrs 
 PCR-00: 9C 22 FD 7F A5 88 83 75 13 74 CD DD 12 EA 7B 40 F6 AD F5 F7 
 PCR-01: A8 9F B8 F8 8C AA 95 90 E6 12 9B 63 3B 14 4A 68 51 44 90 D5 
 PCR-02: A8 9F B8 F8 8C AA 95 90 E6 12 9B 63 3B 14 4A 68 51 44 90 D5 
 PCR-03: A8 9F B8 F8 8C AA 95 90 E6 12 9B 63 3B 14 4A 68 51 44 90 D5 
 PCR-04: 44 85 2F BD 5D 44 F9 5B 5E D3 97 16 DF 8E 3C 6E BE 63 A1 20 
 PCR-05: 19 0A 15 23 AF AC 1D C2 6D 48 AA 3D AE 50 FF 89 AE 79 F2 98 
 PCR-06: A8 9F B8 F8 8C AA 95 90 E6 12 9B 63 3B 14 4A 68 51 44 90 D5 
 PCR-07: A8 9F B8 F8 8C AA 95 90 E6 12 9B 63 3B 14 4A 68 51 44 90 D5 
 PCR-08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
 PCR-09: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
 PCR-10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
 PCR-11: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
 PCR-12: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
 PCR-13: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
 PCR-14: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
 PCR-15: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

PCR up to 8 are not extended without any compliant boot loader.


So, you can download the latest version of TrustedGrub at the following address.

The procedure is the following :

 $ tar -xzvf TrustedGRUB-1.1.3.tgz
 $ cd TrustedGRUB-1.1.3/

Read the file README.tGRUB, you need some specific tools to compile it :

 $ sudo aptitude install aclocale automake autoconf gcc

Then start compiling :

 $ ./
 - Deflating TrustedGRUB
 - Configuring TrustedGRUB
 - Compiling TrustedGRUB

Then, before installing anything copy your actual configuration and prepare a liveCD ;)

 $ sudo mv /boot/grub /boot/grub_old

Remove you actual Grub version :

 $ sudo dpkg -r grub

And then install the new one :

 $ cd TrustedGRUB-1.1.3/
 $ sudo make install

And copy the files for the boot process :

 $ sudo mkdir /boot/grub
 $ sudo cp ../default /boot/grub/
 $ sudo cp stage1/stage1 /boot/grub
 $ sudo cp stage2/stage2 /boot/grub

Copy your old menu list :

 $ sudo cp /boot/grub_old/menu.lst /boot/grub

And finally install Grub :

 $ sudo grub
 root (hdX,Y)
 setup (hdX)

Where X is the disk number and Y the partition number (generally X=0 and Y=0).

You can now restart with a new TrustedGRUB !!

Chain of trust and integrity checking

After restarting the system we can list the PCR and see how they are updated. But the TPM is only a passive component, the security must be ensured by the software at each step. For this reason, new versions of TrustedGRUB come with to additional functionalities :

  1. the checkfile option
  2. the pcr_verify utility.

The checkfile allows to specify in the /boot/grub/menu.lst file, additional files or programs to check at startup. Grub will extend the PCR-13 with a SHA1 of these files.

The first thing to do is to indicate to grub to verify additional files, and where found them (disk and path) :

 title  TrustedGRUB Test
 root  (hd0,0)
 kernel  /boot/vmlinuz-2.6.xx ro quiet splash
 initrd  /boot/initrd.img-2.6.xx
 checkfile (hd?,?)/somewhere/check.file

Then, create the file /somewhere/check.file, with the following content :

 fedb1cff009e115f7f5f7b4533667a787798832d (hd0,1)/test1.file
 485214eab2de87284de9d4e323e428bf60e0aa77 (hd0,1)/grub-0.92.tar.bz2
 a6e171e989849dd44735a513c4270a0837c09174 (hd0,1)/test2.file

You must respect the following constraints :

  • The check file MUST NOT be larger than 8096 Bytes.
  • The first component is a 40 byte alphanumeric value, created with sha1sum.
  • The second component has to be the driver followed by the absolute path of the file.
  • Each line must end with an end-line character.

If you use a wrong syntax your system will not boot !!

TSS Stack

The TrouSerS software suite provides an open-source TCG Software Stack. It is licensed under the Common Public License (CPL).

TrouSers provides the following services :

  • RSA key pair generation
  • RSA encryption and decryption using PKCS v1.5 and OAEP padding
  • RSA sign/verify
  • Extend data into the TPM's PCRs and log these events
  • Seal data to arbitrary PCRs
  • Random Number Generation
  • RSA key storage

To install it, proceed as the following :

 $ sudo aptitude install trousers

The TSS stack is designed to be used locally or remotely. If you want to allow remote commands you must update the configuration file located in /etc/tcsd.conf :

 $ sudo more /etc/tcsd.conf
 # Option: remote_ops
 # Values: TCS operation names, separated by commas (no whitespace)
 # Description: A list of TCS commands which will be allowed to be executed
 #  on this machine's TCSD by TSP's on non-local hosts (over the internet).
 #  By default, access to all operations is denied.
 # possible values:  seal - encrypt data bound to PCR values
 #		    unseal - decrypt data bound to PCR values
 #		    registerkey - store keys in system persistent storage Disk write access!
 #		    unregisterkey - remove keys from system persistent storage Disk write access!
 #		    loadkey - load a key into the TPM
 #		    createkey - create a key using the TPM
 #		    sign - encrypt data using a private key
 #		    random - generate random numbers
 #		    getcapability - query the TCS/TPM for its capabilities
 #		    unbind - decrypt data
 #		    quote - request a signed blob containing all PCR values
 #		    readpubek - access the TPM's Public EndorsementKey
 #		    getregisteredkeybypublicinfo - Search system persistent storage for a public key
 #		    getpubkey - Retrieve a loaded key's public data from inside the TPM
 #		    selftest - execute selftest and test results ordinals
 remote_ops = <UPDATE HERE>

All these functionalities can be accessed locally with the tpm_tools but for a more convenient usage, it exists a graphical user interface : ''TPM Keyring''.

To compile this software will be need additional packages :


Then run :

 $ cvs co applications/tpm_keyring2
 $ cd applications/tpm_keyring2/

To compile tpm_keyring on Ubuntu you must edit the ''Makefile' file and replace :






depending on the version you use.

Then :

 $ make

You can now run tpm_keyring :

 $ ./tpm_keyring

For more information please refer to the following tutorial.

Kernel development corner

Will be updated soon.

By default, the Linux kernel gets in the ACPI tables the information about the supported TPM available on a platform. Even if the TPM device can be found in the ACPI tables, the driver will not find the device if its identifier is not referenced. Most of the TPMs are compatible with the standard tpm_tis module driver but the kernel does not reference all new hardware components. For many of them, the support concists in adding the device HID in the module source.

For example, the Linux kernel version has the following HID :

 in file drivers/char/tpm/tpm_tis.c
 static struct pnp_device_id tpm_pnp_tbl __devinitdata = {
 	{"PNP0C31", 0},		/* TPM */
 	{"ATM1200", 0},		/* Atmel */
 	{"IFX0102", 0},		/* Infineon */
 	{"BCM0101", 0},		/* Broadcom */
 	{"NSC1200", 0},		/* National */
 	/* Add new here */
 	{"", 0},		/* User Specified */
 	{"", 0}			/* Terminator */

To get all information about your TPM device, you can use a tool iasl, provided by The ACPI Component Architecture Project. This tool is a compiler which allows you yo disassemble the binary ACPI table and dump them in a readable text format.

You can download it here : UNIX Format Source Code and Build Environment.

To compile iasl :

 $ tar -xzvf acpica-unix-20080609.tar.gz
 $ cd acpica-unix-20080609/compiler
 $ make

First get a local copy of your ACPI tables :

 $ sudo cp /proc/acpi/dsdt .
 $ sudo chmod a+r dsdt

To get all informations from the ACPI tables run the following command to disassemble :

 acpica-unix-20080609/compiler/iasl -d dsdt
 Intel ACPI Component Architecture
 AML Disassembler version 20080609 Jun 13 2008
 Copyright (C) 2000 - 2008 Intel Corporation
 Supports ACPI Specification Revision 3.0a
 Loading Acpi table from file dsdt
 Acpi table DSDT successfully installed and loaded
 Pass 1 parse of DSDT
 Pass 2 parse of DSDT
 Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
 Parsing completed
 Disassembly completed, written to "dsdt.dsl"

You now have a text readable version of your ACPI tables in the file dsdt.dsl.

Search the word TPM in the file, you will have a section starting with something like :

 Device (TPM)
                     Name (_HID, EisaId ("BCM0102"))
                     Name (_CID, EisaId ("PNP0C31"))
                     Method (_STA, 0, NotSerialized)
                         SX10 ()
                         SX30 (0x0E)
                         SX11 ()
                         Store (SX42 (), Local0)
                         SX12 ()
                         Return (Local0)

The line containing your device HID is the following :

 Name (_HID, EisaId ("BCM0102"))

Add the value BCM0102 in the pnp_device_id structure of the tpm_tis module to support your TPM device. (See this post for an example Broadcom TPM with DELL Latitude D630).

And recompile the module to test !!