Skip to content

TPM2

Introduction

The ctrlX CORE devices provide the capability to securely generate and store keys with a hardware security module, specifically a Trusted Platform Module 2.0 (TPM2).

This TPM can be used additionally to Certificate Management described in Getting Started - Package Manifest.

Connecting apps to the TPM2

The app.deviceadmin provides a socket interface, which allows to use the TPM2. Behind the scenes, there is a "Access Broker/Ressource Manager" working, managing concurrent sessions accessing the TPM2.

Following steps are necessary to connect to TPM2 socket:

  • Adapt your snapcraft.yaml
    • Needed plugs
      • tpm2-socket: Provides your snap with the tpm2.sock file.
      • (Optional) system-configuration: Provides a file with environment variables for configuring your TSS, called "envvars".
    • Provide your app with the plugs
  • Use the TPM inside your application
    • Compile the TSS as you need
    • Source the envvars
    • Use the TSS as usual ...

More details on the Trusted Software Stack (TSS) below.

Example snapcraft.yaml

plugs:
  tpm2-socket:
    interface: content
    content: tpm2-socket
    target: $SNAP_DATA/tpm2-socket
  system-configuration:
    interface: content
    content: system-configuration
    target: $SNAP_DATA/system-configuration

apps:
  example-app:
    [...]
    plugs: [tpm2-socket, system-configuration, network]

See also the sample in samples-snap/tpm2-webserver

Integration with Certificate Manager

If you provide the package-certificate slots, and use the appropriate directory structure, TPM2 usage perfectly integrates into Certificate Manager.

Using the TPM2 inside software

After having everything in place, the usage of the TPM is straightforward. Instead of connecting to /dev/tpmrm0, use $SNAP_DATA/tpm2-socket/tpm2.sock. envvars provides you with everything needed, for example:

  export TPM2TOOLS_TCTI="cmd:nc -U $SNAP_DATA/tpm2-socket/tpm2.sock"

Storage Root Key (SRK)

The SRK of the TPM is permanently stored at 0x81000001 provided by TPM2_SRK_PARENT environment variable.

Note

Although the SRK is stored in NVRAM of TPM, it cannot be guaranteed to be always present. It must be tolerable by your application, that the SRK was replaced by another key, or even is totally absent.

Following two examples or snippets, how to generate the SRK with the correct Primary-Key-Template.

echo "0000000: 0001" | xxd -r - unique.dat
dd if=/dev/zero bs=1 count=256 >> unique.dat
tpm2_createprimary \
    --hierarchy=owner \
    --key-algorithm=rsa2048:aes128cfb \
    --hash-algorithm=sha256 \
    --key-context=prim.ctx \
    -a 'restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda' \
    --unique-data=unique.dat

In Golang, use following template:

import "github.com/google/go-tpm/tpm2"

var DefaultSrkTemplate = tpm2.Public{
        Type:       tpm2.AlgRSA,
        NameAlg:    tpm2.AlgSHA256,
        Attributes: tpm2.FlagFixedTPM | tpm2.FlagFixedParent | tpm2.FlagSensitiveDataOrigin | tpm2.FlagUserWithAuth | tpm2.FlagNoDA | tpm2.FlagRestricted | tpm2.FlagDecrypt,
        AuthPolicy: nil,
        RSAParameters: &tpm2.RSAParams{
            Symmetric: &tpm2.SymScheme{
                Alg:     tpm2.AlgAES,
                KeyBits: 128,
                Mode:    tpm2.AlgCFB,
            },
            Sign:        nil,
            KeyBits:     2048,
            ExponentRaw: 0,
            ModulusRaw:  make([]byte, 256),
        },
    }

For further details for golang, please see the Golang example.

Trusted Software Stack

You will need some of the following parts of the TSS inside your snap:

More information and more tools:

Usage with OpenSSL

tpm2-tss-engine as an example, setting first the environment variables:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SNAP/usr/lib/x86_64-linux-gnu/engines-1.1
export OPENSSL_ENGINES=$SNAP/usr/lib/x86_64-linux-gnu/engines-1.1

You can then use OpenSSL option -engine tpm2tss together with files generated by tpm2tss-genkey. Existing keys from tpm2-tools or the Certificate Manager can be converted:

tpm2tss-genkey -P $TPM2_SRK_PARENT -u key.pub -r key.priv key.tpm2tss

Other languages

Useful projects:

Golang

Attention

If using go-tpm, you need to implement your own functions for opening, reading and writing the TPM socket, as the integrated functions close and reopen the socket with every read/write sequence. See: https://github.com/google/go-tpm/blob/master/tpmutil/run_other.go

Python