This is my personal blog. The views expressed on these pages are mine alone and not those of my employer.

This is a short howto on setting up TPM-backed SSL. This means that the secret key belonging to an SSL cert is protected by the TPM and cannot be copied off of the machine or otherwise inspected.

Meaning even if you get hacked the attackers cannot impersonate you, if you manage to kick them off or just shut down the server. The secret key is safe. It has never been outside the TPM and never will be.

This can be used for both client and server certs.

Prerequisites

A TPM chip. Duh. May need to be turned on in the BIOS. Could be called “security chip” or something. If you don’t have a TPM chip but still want to follow along (maybe add TPM support to some program) then you can install a TPM emulator. See links at the end on how to install a TPM emulator.

A working CA that will sign your CSR. I will assume you’re running your own CA, but you can send the CSR to someone else to sign if you want cert creating step.

Installed “stuff”: $ aptitude install tpm-tools libengine-tpm-openssl

Initialize TPM

Make sure you can communicate with the TPM chip: $ tpm_version TPM 1.2 Version Info: Chip Version: 1.2.4.1 Spec Level: 2 Errata Revision: 2 TPM Vendor ID: INTC Vendor Specific data: 00040001 0003040e TPM Version: 01010000 Manufacturer Info: 494e5443

Clear the chip: $ tpm_clear --force $ tpm_setenable --enable --force $ tpm_setactive --active

These steps may require reboots. They will probably tell you if that’s the case.

Take ownership and create SRK: $ tpm_takeownership -u -y Enter SRK password: [just press enter] Confirm password: [just press enter]

Yes really, empty password. This password protects TPM operations, so worst case is that someone with shell access can put some load on your TPM chip. They can’t use it to crack keys or anything. This is not a password that protects your secrets, they’re already secure. You may want to supply an owner password. If so, leave out the -y option.

Create SSL certificate

Use script from libengine-tpm-openssl to create key: create_tpm_key foo.key

Create CSR for key: openssl req -keyform engine -engine tpm -key foo.key -new -out foo.csr

Sign the CSR with your CA: openssl x509 -req -days 365 -in foo.csr -CA ca.crt -CAkey ca.key -CAserial serial -out foo.crt

Test it

On the server:

$ openssl s_server -accept 12345 -cert /path/to/server.crt -key /path/to/server.key -CAfile CA/ca.crt -Verify 1

On the client

$ openssl s_client -keyform engine -engine tpm -connect server-name-here:12345 -cert foo.crt -key foo.key

Use in your code

Instead of using SSL_CTX_load_verify_locations() , use ENGINE_*() and SSL_CTX_use_PrivateKey()

Without TPM:

void loadpriv ( SSL_CTX * ctx , const char * file ) { SSL_CTX_use_PrivateKey_file ( ctx , file , SSL_FILETYPE_PEM ); }

With TPM:

void loadpriv ( SSL_CTX * ctx , const char * file ) { ENGINE_load_builtin_engines (); ENGINE * engine = ENGINE_by_id ( "tpm" ); ENGINE_init ( engine ); UI_METHOD * ui_method = UI_OpenSSL (); EVP_PKEY * pkey = ENGINE_load_private_key ( engine , file , ui_method , NULL ); SSL_CTX_use_PrivateKey ( ctx , pkey ); }

Error handling left as an exercise for the reader.

Use in the real world

Huh. I haven’t actually seen this implemented in any Open Source software (besides the openssl command line interface) Well, actually curl and stunnel4 appear that they could support it, but it’s not clear how. Here is someone else wondering how to get stunnel to do it. It’s from 2006 with no replies.

The only thing I have that uses the TPM chip is my Chromebook. Client certs there are protected by it by default.

Please leave comments if you know of any TPM support in Open Source stuff.

tlssh

I have added support for tlssh to use TPM on both the server and client side. Add -E tpm on the client side, and have something like this on the server side config (or only on one side. There’s no requirement that both sides use TPM):

PrivkeyEngine tpm TpmSrkPassword PrivkeyPassword secretpasswordhere

That last line is just needed if the key has a password. The client can be configured in the same way to not have to ask for the passwords.

If PrivkeyEngine tpm or -E tpm is supplied the secret key will be assumed to be TPM protected and should be in the form of a BEGIN TSS KEY BLOB section instead of a PEM format BEGIN RSA PRIVATE KEY section.

Performance

Oh, it’s slow. Really slow. Luckily it’s just used in the handshake. I haven’t done proper benchmarks, but let’s just say you won’t be using it to power your webmail. I may do some benchmarking in a coming blog post.

See Benchmarking TPM backed SSL for details.

Misc notes