Trusted Computing for Mac OS X

© Amit Singh. All Rights Reserved. Written in October 2006

Executive Summary

If you do not have the time, patience, or inclination to read this entire document, please consider reading the executive summary rather than reading an incorrect reinterpretation somewhere else.


The Trusted Computing Platform Alliance (TCPA) was a collaborative initiative involving major industry players such as Compaq, Hewlett-Packard, IBM, Intel, Microsoft, and some others. The successor to the TCPA is the Trusted Computing Group (TCG), whose goal is to develop vendor-neutral standard specifications for trusted computing. Unfortunately, there are several aspects of trusted computing that are often misunderstood—in particular, its relationship to the controversial idea of Digital Rights Management (DRM). We will not discuss the pros and cons of trusted computing here: far too many expositions haven been written both for and against the concept. The purpose of this document is to discuss a specific piece of hardware found in certain Apple computer models: the Trusted Platform Module (TPM).

TPMs and Trusted Platforms

A Trusted Platform is a computing platform that has a "trusted" component: say, some tamper-resistant built-in hardware. Usually the resistance in question is to an external attack and not to an attack by the owner. In the case of the TCG platform, the TPM is that trusted piece of (rather complex) hardware. A TPM can be thought of as the core of a trusted subsystem. Its logical constituents include functional units and memory. Examples of functional units include a SHA-1 hardware accelerator and a true random number generator. Examples of memory types include working memory, non-volatile storage, and EEPROM. The TPM specification requires certain features, and in some cases, requires a minimum number of certain resources. In the next section, we will see the feature set of the specific TPM used by Apple.

Note that the strict definition of a trusted computing platform includes other requirements besides a TPM. For example, there must be a Core Root of Trust for Measurement (CRTM) and supporting software. The CRTM can be thought of as some set of instructions that execute during the boot process.

Are TPMs Evil?

People often associate TCG (the erstwhile TCPA) with Microsoft's infamous Palladium project. People also typically use TCG synonymously with DRM. Sure, you can use a TPM to perform some work in a DRM scheme, but from a "crackability" standpoint, you won't automatically be any better unless several other additional measures are taken (and the potential use of many such measures is valid cause for concern). It is also believed that a TPM can somehow prevent or control program execution—it cannot. A TPM cannot participate in execution decisions—it is still software that has to make these decisions. The TPM also doesn't know, and cannot know, about black or white lists of computer serial numbers. This is not to say that there are no justifiable privacy concerns or controversies with the use of trusted computing. An extreme and contrived scenario could be if the TPM is abused by a vendor, say, one that refuses to let the customer disable the TPM or change its ownership—that is a bad thing. However, in doing so, the vendor will have to go against the specification. As with anything else, a TPM could be part of both evil and non-evil uses. This is a never-ending discussion with a very wide scope, and we haven't even started discussing the general notions of "trust" and "security." There already is no dearth of such discussions, so let us move on with the issue at hand.

The Infineon TPM1.2

Infineon TPM1.2

In recent Apple computers that do have an onboard Infineon TPM, the module is an SLB 9635 TT 1.2. In my experience, the 9635 is one of the "nicer" modules if one has to do low-level programming for it. Before we look at its key features, let me refer you once again to the TCG web site for detailed documentation on what these features mean and what they do.

Some important hardware details of the 9635 are as follows.

The TPM is not a cryptographic accelerator. It is not meant to aid in bulk encryption. Moreover, the specification does not contain any cryptographic throughput requirements.

Perhaps the most critical Apple-specific thing to note about the TPM is that Apple's firmware is not TCG-aware in that there's no Apple-provided provision for asserting "physical presence." Some sensitive TPM operations (such as "clearing" the TPM, which results in a new TPM owner being established and any previous owner being forgotten) require physical human presence to be asserted. For example, to assert physical presence on some computers with TCG-aware firmware, one must press the Fn key at power-on time, enter the BIOS, and clear the TPM from within the BIOS. There is also a software-initiated way to assert physical presence, which is what we will use. The key thing to realize is that the software method is normally only possible when the firmware is TCG-unaware. If not, the firmware locks physical presence, disallowing the software method and resulting in stricter security.

Another way of looking at the firmware's TCG-unawareness is that there is no firmware-level TPM driver included. An EFI driver can certainly be written though.

A TPM Device Driver for Mac OS X

The TPM is a very interesting and complex piece of hardware with many uses. For example, you could use the TPM from within your own programs to:

"Apple's TPM Keys"

The media has been discussing "Apple's use of TPM" for a long time now. There have been numerous reports of system attackers bypassing "Apple's TPM protection" and finding "Apple's TPM keys." Nevertheless, it is important to note that Apple does not use the TPM. If you have a TPM-equipped Macintosh computer, you can use the TPM for its intended purpose, with no side effect on the normal working of Mac OS X.

Of course, to use the TPM under Mac OS X, you first need a device driver. I am releasing a Mac OS X TPM driver under the GPLv2 open source license. You will also need utility programs and programming libraries, unless you feel like implementing everything from scratch. I modified the excellent TrouSerS software suite to work on Mac OS X—the modified source is also available for download.

No TPM for You! Next!

At the time of this writing (October 2006), the newest Apple computer models, such as the MacPro and possibly the revised MacBook Pro and the revised iMac, do not contain an onboard Infineon TPM. Apple could bring the TPM back, perhaps, if there were enough interest (after all, it is increasingly common to find TPMs in current notebook computers), but that's another story.


All of the software being made available here is in source form. You should be able to compile it with nothing more than a standard installation of Apple's Xcode suite. The TPM driver requires an Intel-based Macintosh computer with an onboard Infineon TPM. The operating system must be Mac OS X 10.4.x, although the driver should also be forward compatible with the forthcoming Mac OS X 10.5.

Terms and Conditions



PackageDescriptionDownload Link
TPM DriverAn open-source Mac OS X TPM device driver for the Infineon TPM1.2.osxbook-tpm-driver-1.0.0.tar.gz
TrouSerSAn open-source TCG Software Stack implementation.osxbook-trousers-0.2.8.tar.gz
TPM Tools An open-source package designed for user and application ennoblement of Trusted Computing using a TPM. osxbook-tpm-tools-1.2.5.tar.gz
libtpmAn open-source bare bones (compared to TrouSerS) library containing functions for direct interaction with the TPM.osxbook-libtpm-2.0c.tar.gz

Getting Started

In this section, we will see an overview of compiling and using the TPM driver and software. The following discussion assumes that you have downloaded and unpacked all four packages in the ~/tpm/ directory—if you use another directory, simply substitute its name in the command-line examples shown in this document.

First, you should determine if your computer has a TPM and that it is visible to the I/O Kit. To do so, you can check if an appropriate entry exists in the I/O Registry. For example, you can grep the output of the ioreg command for the string "TPM". I haven't looked at all possible Apple computer models with TPMs to be able to tell you if the output will be identical to what's shown here in all cases, or if all models even have the same type of TPM.

$ ioreg | grep TPM | +-o TPM <class IOACPIPlatformDevice, registered, ...

Whereas we will install the TrouSerS package under the /usr/local/ directory hierarchy, we will not install the TPM Tools and libtpm packages—we can work with them from within their respective source directories. (If you wish, you can install them too.) The TrouSerS package contains programming libraries and headers that the compilation of the TPM Tools package requires. Therefore, it is more convenient to simply install it, allowing TPM Tools to be compiled without jumping through hoops.

The TPM Driver

The driver is sort of a hybrid I/O Kit-style and BSD-style entity. You should be able to trivially compile it. If you want the driver to be automatically loaded at system-boot time, you can copy it to the /System/Library/Extensions/ directory and then touch the directory. Alternatively, you can manually load the driver using the kextload command, which is what we will do here.

$ cd ~/tpm/osxbook-tpm-driver-1.0.0 $ xcodebuild === BUILDING NATIVE TARGET OSXBookTPM WITH CONFIGURATION Release === ... ** BUILD SUCCEEDED ** $ cp -pR build/Release/OSXBookTPM.kext ~/tpm/ $ cd ~/tpm $ sudo chown -R root:wheel OSXBookTPM.kext $ sudo kextload -v OSXBookTPM.kext kextload: extension OSXBookTPM.kext appears to be valid kextload: loading extension OSXBookTPM.kext kextload: OSXBookTPM.kext loaded successfully kextload: loading personalities named: kextload: Infineon SLB 9635 TT 1.2 kextload: sending 1 personality to the kernel kextload: matching started for OSXBookTPM.kext

If the driver loaded and started correctly, you should be able to see its properties in the I/O Registry—say, using the ioreg command-line tool.

$ ioreg -x -n com_osxbook_driver_InfineonTPM | less ... | | +-o com_osxbook_driver_InfineonTPM <class ...> | | { | | "addr-len" = 0x2 | | "vendor-id" = "0x15d1" | | "CFBundleIdentifier" = "com.osxbook.driver.InfineonTPM" | | "IOClass" = "com_osxbook_driver_InfineonTPM" | | "IONameMatched" = "IFX0101" | | "base" = 0x4700 | | "version" = "0x000b" | | "IOProbeScore" = 0x0 | | "info-url" = "" | | "IOMatchCategory" = "IODefaultMatchCategory" | | "IONameMatch" = "IFX0101" | | "port-len" = 0xc | | "addr" = 0x4e | | "model" = "SLB 9635 TT 1.2" | | "product-id" = "0x000b" | | "IOProviderClass" = "IOService" | | "data" = 0x4f | | } ...

The driver also creates a character device node called tpm. By default, the device is only accessible to the superuser. Note that the major number is dynamically assigned and is irrelevant to us.

$ ls -l /dev/tpm crw------- 1 root wheel 15, 0 Oct 30 20:55 /dev/tpm

When the driver loads, it itself sends the TPM_ORD_Startup and TPM_ORD_ContinueSelfTest commands to the TPM. If this behavior is not desired, the tpmStartup() class method can be edited in the source file OSXBookTPM.cpp. The driver also has rudimentary handling of power change events.

When you are done using the driver, you can unload it using the kextunload command.

$ sudo kextunload -v ~/tpm/OSXBookTPM.kext kextunload: unload kext ~/tpm/OSXBookTPM.kext succeeded


The TrouSerS package downloadable from this page is pre-configured to install under /usr/local/. If you wish to change that or any other options, you can specify them to the configure script. Then, you can simply build and install the package. Note that my tweaks to TrouSerS to get it to work on Mac OS X are quick-and-dirty—a more pedantic patch would do a few things more cleanly.

$ cd ~/tpm/osxbook-trousers-0.2.8 $ ./configure --prefix=/usr/local --with-gui=none --disable-nls checking build system type... i686-apple-darwin8.8.1 checking host system type... i686-apple-darwin8.8.1 ... $ make ... $ sudo make install ... # You will see errors regarding groupadd, useradd, and chown # You can ignore these for now (see caveat below)

Besides libraries and headers, installing the TrouSerS package gives us a user-space daemon called tcsd, which is meant to work as the only portal to the TPM device driver. In other words, after the daemon is started, all trusted computing programs communicate with the daemon and not directly with the TPM driver. However, in our experimental environments, we will make some concessions that should not be made in a production environment. Specifically, the following caveats must be noted.

TPM Tools

The TPM Tools package contains several useful programs that will be essential to your experiments in trusted computing. In particular, you will need some of these programs to set up the TPM initially. The package should be configured and compiled, but as noted earlier, you need not install it.

$ cd ~/tpm/osxbook-tpm-tools-1.2.5 $ ./configure --prefix=/usr/local --with-gui=none --disable-nls checking build system type... i686-apple-darwin8.8.1 checking host system type... i686-apple-darwin8.8.1 ... $ make ...

At this point, you should have binaries for several programs in the src/cmds/ and src/tpm_mgmt/ directories within the TPM Tools package. The manual pages for these programs are in the src/man/* directories. There are a couple of things to note regarding the Mac OS X port.

The Storage Root Key (SRK)

The TPM uses the SRK to protect other keys that could be stored opaquely outside the TPM. The SRK is the root of a key hierarchy in which each key is encrypted using the key at the next level in the hierarchy.


The libtpm package available on this page is a modified version of IBM's older TPM library. libtpm has far less functionality as compared to TrouSerS (which, by the way, is also courtesy of IBM). However, because of its "raw" nature and close interaction with the TPM driver, libtpm is quite useful for experimentation. In the utils/ subdirectory, you will find several utility programs, some of which have been superseded by those in the TrouSerS package. I added a demo program called extendpcr, which can be used to change the value of a PCR, say, to show how data cannot be unsealed when PCR values differ from those expected.

The libtpm package can be trivially configured and built. As with the TPM Tools package, you need not install it.

$ cd ~/tpm/osxbook-libtpm-2.0c $ ./configure --prefix=/usr/local checking build system type... i686-apple-darwin8.8.1 checking host system type... i686-apple-darwin8.8.1 ... $ make ...

Now that we have compiled everything, we are ready to experiment with the TPM.

Using the TPM: A Quick Tour

Before you can explore the TPM's capabilities, you need to do a specific sequence of operations to initialize things and take ownership of the TPM. We will use utilities from the TPM Tools package to do so. Almost all of these utilities requires tcsd to be running.

Before we start tcsd for the first time, we need to create the /usr/local/var/lib/tpm/ directory for its use. If this directory already exists (perhaps because you updated the appropriate Makefile to do the right thing on Mac OS X), you can skip this step. Thereafter, we can run the daemon. We will run it foregrounded (the -f option) for our experiments.

$ sudo mkdir -p /usr/local/var/lib/tpm $ sudo tcsd -f TCSD tcsd_conf.c:547 Config file /usr/local/etc/tcsd.conf not found. TCSD tcsd_conf.c:548 Using default configuration settings. TCSD tcsd_conf.c:649 resetting mode of /usr/local/var/lib/tpm to: 01777 trousers 0.2.8 (with TPM 1.2 DUAL patch by IAIK) Mac OS X support by *** ATTENTION *** Experimental software (allows physical presence assertion in all runlevels!) TCSD up and running

As noted earlier, the daemon has been modified to not require single-user mode for physical presence assertion. It prints a warning calling attention to this fact.

At this point, the TPM is without an owner. Our next goal is to "take ownership" of the TPM through a sequence of actions that may seem circuitous, but has a rationale behind it. (Please refer to the specification for understanding the rationale.) Even now, without the TPM having an owner, we can perform certain operations.

For example, we can use the tpm_getpubek tool to retrieve the Public Endorsement Key. In the case of the TPM1.2, the corresponding TPM command actually becomes disabled after we take ownership of the TPM—unless explicitly configured otherwise, you will require the owner password even to retrieve this key. By the way, some people think the term "pubek" is unfortunately named.

Endorsement Key (EK)

Each TPM has an embedded unique Endorsement Key (EK)—an RSA key pair—that is used to recognize a genuine TPM. The TPM owner can use the EK to anonymously establish signature key pairs called Attestation Identity Keys (AIKs).

$ cd ~/tpm/osxbook-tpm-tools-1.2.5/src/tpm_mgmt/ $ ./tpm_getpubek Public Endorsement Key: Version: 01010000 Usage: 0x0002 (Unknown) Flags: 0x00000000 (!VOLATILE, !MIGRATABLE, !REDIRECTION) AuthUsage: 0x00 (Never) Algorithm: 0x00000001 (RSA) Encryption Scheme: 0x00000012 (Unknown) Signature Scheme: 0x00000010 (Unknown) Key Size: 2048 bits Public Key: 8ea55a0e 22a28eed 114d3e65 81abaef1 32a13257 b7bbc418 e11092d8 8d79a277 ... fa651831 923ce1c7 cf141ba0 2c70fa67 8fd7d70b e2cd9f2b 0980e135 4af2deed

We can also retrieve the contents of the Platform Configuration Registers (PCRs). The tpm_demo tool from the libtpm package lets us do that. Note that since the libtpm programs directly talk to the /dev/tpm device, they need to be run as the superuser.

$ cd ~/tpm/osxbook-libtpm-2.0c/utils/ $ sudo ./tpm_demo TPM version 24 PCR registers are available PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... PCR-23: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 Key slots are available No keys are loaded

Since we cannot do anything much more exciting without being the TPM's owner, let us proceed to taking ownership. The numbering on the steps listed below is ad hoc.

Taking ownership as described below requires the machine to be rebooted twice. Each time the system comes up, you must load the TPM driver and run tcsd, either manually or through some startup arrangement. As noted earlier, the driver must be loaded and the daemon must be running to make use of almost all programs in the TPM Tools package.

Step 1. Assert Physical Presence, Clear the TPM, Reboot

$ cd ~/tpm/osxbook-tpm-tools-1.2.5/src/tpm_mgmt/ $ ./tpm_setpresence --assert $ ./tpm_clear --force TPM Successfuly Cleared. You need to reboot to complete this operation. After reboot the TPM will be in the default state: unowned, disabled and inactive. $ sudo reboot

Step 2. Assert Physical Presence, Enable the TPM, Activate the TPM, Reboot

$ cd ~/tpm/osxbook-tpm-tools-1.2.5/src/tpm_mgmt/ $ ./tpm_setpresence --assert $ ./tpm_setenable --enable --force $ ./tpm_setactive --active Action requires a reboot to take affect [sic] $ sudo reboot

Step 3. Run Self Test, Assert Physical Presence, Take Ownership

In this step, you will choose two passwords: the owner password and the Storage Root Key (SRK) password. Many future operations will require these passwords. If you forget these passwords, you can start at Step 1 to clear things (depending on several factors, you could lose data that you had already protected using the old passwords in doing so, but that discussion is beyond the scope of this document).

$ cd ~/tpm/osxbook-tpm-tools-1.2.5/src/tpm_mgmt/ $ ./tpm_selftest TPM Test Results: ffff $ ./tpm_setpresence --assert $ ./tpm_takeownership Enter owner password: ******** Confirm password: ******** Enter SRK password: ******** Confirm password: ******** $

If the tpm_takeownership command finished without complaining, then congratulations—the TPM is yours (and you are not required to reboot this time). If you now try running the tpm_getpubek tool, it will need the owner password to be able to retrieve the Public Endorsement Key.

$ cd ~/tpm/osxbook-tpm-tools-1.2.5/src/tpm_mgmt/ $ ./tpm_getpubek Tspi_TPM_GetPubEndorsementKey failed: 0x00000008 - layer=tpm, code=0008 (8), Disabled command Enter owner password: ******** Public Endorsement Key: Version: 01010000 ...

Next, let us ask the TPM to create a key pair. We will save the "wrapped" private key and the public key as two files. Thereafter, we can load this key into an available key slot within the TPM. Once loaded, the key can be used for its intended purpose. Here, we will use the key for signing some data. We will use tools from the libtpm package for this experiment.

$ cd ~/tpm/osxbook-libtpm-2.0c/utils/ # Let us try to list loaded key handles; we see no keys in key slots. $ sudo ./listkeys $ # Let us create a key as a child of the SRK. # key123 is the new key's password. # The newly created key pair is saved in files { testkey.key, testkey.pem }. # 0x40000000 is the well-known SRK handle. $ sudo ./createkey -p <SRK password> -k key123 testkey 0x40000000 $ ls testkey* testkey.key testkey.pem # Let us load the newly created key into the TPM. $ sudo ./loadkey Usage: loadkey <parent key handle> <key file name> [<parent key password>] $ sudo ./loadkey 0x40000000 testkey.key <SRK password> New Key Handle = 05B67F25 # Let us see if it is there still (of course). # This will tell us the key slot being used and the key's handle. $ sudo ./listkeys Key handle 00 05B67F25 # Let us sign a data file with our newly loaded key. $ echo hello > data.txt $ sudo ./signfile -k key123 0x05B67F25 data.txt data.sign $ ls -l data.sign -rw-r--r-- 1 root amit 256 Oct 30 23:01 data.sign # We can now verify the signature. A zero return value means all is well. $ sudo ./verifyfile Usage: verifyfile <sig file> <data file> <pubkey file> $ sudo ./verifyfile data.sign data.txt testkey.pem $ echo $? 0

Finally, we can make things a little more interesting by "sealing" some data to the TPM's SRK and a specific PCR's value. We will first do a successful unsealing of the sealed data. Then, we will change the PCR's value, after which we should not be able to unseal the data. For this experiment we will use the tpm_sealdata and tpm_unseal_file programs from the TrouSerS package. We will also use the extendpcr and tpm_demo programs from the libtpm package.

Let us choose PCR 15 for our experiment.

$ cd ~/tpm/osxbook-libtpm-2.0c/utils/ $ sudo ./tpm_demo ... PCR-15: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...

We can use extendpcr to extend a PCR's value. Note that we say extend and not set because the PCR's new value is a function of both the old value and the event hash sent to it as part of an extend operation.

$ cd ~/tpm/osxbook-libtpm-2.0c/utils/ $ echo event1 | sudo ./extendpcr 15 $ sudo ./tpm_demo ... PCR-15: 60 2F BF 61 87 11 75 E9 80 83 29 3D 0D 51 91 73 31 67 48 2C ...

If we now seal some data to the SRK and PCR 15, we will only be able to unseal it when the PCR's value matches that at the time of sealing (and the SRK doesn't change, of course).

$ cd ~/tpm/osxbook-tpm-tools-1.2.5/src/cmds/ $ echo "Sensitive Data" | ./tpm_sealdata -p 15 > data.sealed SRK Password: ******** $ ls -l data.sealed -rw-r--r-- 1 amit amit 1270 Oct 30 01:39 data.sealed $ ./tpm_unseal_file data.sealed SRK Password: ******** Sensitive Data $

We see that we can unseal the data by providing the SRK password. Now let us extend PCR 15's value again and see what happens.

$ cd ~/tpm/osxbook-libtpm-2.0c/utils/ $ echo event2 | sudo ./extendpcr 15 $ sudo ./tpm_demo ... PCR-15: C0 EF 40 B8 95 82 E1 A9 24 AB C2 F5 18 2A 77 0C E6 A5 D3 C0 ...

We see that the PCR's value has changed, as expected. Therefore, the unsealing operation should no longer succeed.

$ cd ~/tpm/osxbook-tpm-tools-1.2.5/src/cmds/ $ ./tpm_unseal_file data.sealed SRK Password: ******** Tspi_Data_Unseal: 0x00000018 - layer=tpm, code=0018 (24), Wrong PCR value $

Have fun exploring the TPM and its capabilities.

Mac OS X Internals: A Systems Approach

Further Reading

Executive Summary