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:
- tpm2-tss https://github.com/tpm2-software/tpm2-tss
- tpm2-tools https://github.com/tpm2-software/tpm2-tools
- tpm2-tss-engine https://github.com/tpm2-software/tpm2-tss-engine
- tpm2-openssl https://github.com/tpm2-software/tpm2-openssl
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
- https://github.com/google/go-tpm
- https://github.com/google/go-tpm-tools
- https://github.com/salrashid123/signer
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