Trusted Platform Module (TPM)

New in version 1.11.26.

Some computers come with a TPM, which is a small side processor which can perform certain operations which include RSA key generation and signing, a random number generator, accessing a small amount of NVRAM, and a set of PCRs which can be used to measure software state (this is TPMs most famous use, for authenticating a boot sequence).

The TPM NVRAM and PCR APIs are not supported by Botan at this time, patches welcome.

Currently only v1.2 TPMs are supported, and the only TPM library supported is TrouSerS (http://trousers.sourceforge.net/). Hopefully both of these limitations will be removed in a future release, in order to support newer TPM v2.0 systems. The current code has been tested with an ST TPM running in a Lenovo laptop.

Test for TPM support with the macro BOTAN_HAS_TPM, include <botan/tpm.h>.

First, create a connection to the TPM with a TPM_Context. The context is passed to all other TPM operations, and should remain alive as long as any other TPM object which the context was passed to is still alive, otherwise errors or even an application crash are possible. In the future, the API may change to using shared_ptr to remove this problem.

class TPM_Context
TPM_Context(pin_cb cb, const char *srk_password)

The (somewhat improperly named) pin_cb callback type takes a std::string as an argument, which is an informative message for the user. It should return a string containing the password entered by the user.

Normally the SRK password is null. Use nullptr to signal this.

The TPM contains a RNG of unknown design or quality. If that doesn’t scare you off, you can use it with TPM_RNG which implements the standard RandomNumberGenerator interface.

class TPM_RNG
TPM_RNG(TPM_Context &ctx)

Initialize a TPM RNG object. After initialization, reading from this RNG reads from the hardware? RNG on the TPM.

The v1.2 TPM uses only RSA, but because this key is implemented completely in hardware it uses a different private key type, with a somewhat different API to match the TPM’s behavior.

class TPM_PrivateKey
TPM_PrivateKey(TPM_Context &ctx, size_t bits, const char *key_password)

Create a new RSA key stored on the TPM. The bits should be either 1024 or 2048; the TPM interface hypothetically allows larger keys but in practice no v1.2 TPM hardware supports them.

The TPM processor is not fast, be prepared for this to take a while.

The key_password is the password to the TPM key ?

std::string register_key(TPM_Storage_Type storage_type)

Registers a key with the TPM. The storage_type can be either TPM_Storage_Type::User or TPM_Storage_Type::System. If System, the key is stored on the TPM itself. If User, it is stored on the local hard drive in a database maintained by an intermediate piece of system software (which actual interacts with the physical TPM on behalf of any number of applications calling the TPM API).

The TPM has only some limited space to store private keys and may reject requests to store the key.

In either case the key is encrypted with an RSA key which was generated on the TPM and which it will not allow to be exported. Thus (so goes the theory) without physically attacking the TPM

Returns a UUID which can be passed back to constructor below.

TPM_PrivateKey(TPM_Context &ctx, const std::string &uuid, TPM_Storage_Type storage_type)

Load a registered key. The UUID was returned by the register_key function.

std::vector<uint8_t> export_blob() const

Export the key as an encrypted blob. This blob can later be presented back to the same TPM to load the key.

TPM_PrivateKey(TPM_Context &ctx, const std::vector<uint8_t> &blob)

Load a TPM key previously exported as a blob with export_blob.

std::unique_ptr<Public_Key> public_key() const

Return the public key associated with this TPM private key.

TPM does not store public keys, nor does it support signature verification.

TSS_HKEY handle() const

Returns the bare TSS key handle. Use if you need to call the raw TSS API.

A TPM_PrivateKey can be passed to a PK_Signer constructor and used to sign messages just like any other key. Only PKCS #1 v1.5 signatures are supported by the v1.2 TPM.

std::vector<std::string> TPM_PrivateKey::registered_keys(TPM_Context &ctx)

This static function returns the list of all keys (in URL format) registered with the system