In this part, we will use the TCG and IBM Software Stack to implement some basic commands. The hardware can be any embedded device with a TPM chip.Refer to the blog article on how to build an image for a board using Yocto.
Yocto support
Currently, only the TPM2-TSS software stack is officially supported in Yocto. Adding it to your custom image recipe can be done using:
For TPM2.0:
$ IMAGE_INSTALL += “ tpm2.0-tools libtss2 resourcemgr trousers ”
|
For TPM1.2:
$ IMAGE_INSTALL += “ tpm-tools resourcemgr trousers ”
|
Concerning the lack of functions for TPM2-TSS software stack and for debug purposes, we have a solution for the IBM TPM2 software stack in Yocto.
Basics
This part uses TCG TPM2 Software Stack. The TPM can be accessed from Linux using tpm2.0-tools alongside with TPM2.0-TSS stack.
First of all, let’s look at some self-contained tools. The resource manager needs to be run before running any other command:
List all persistent objects present in the Trusted Platform Module (keys for e.g):
Generate a random 32 bytes buffer:
$ tpm2_getrandom -s 32 -o random.out
|
Caculate the SHA1 hash value of file random.out and output into hash.out:
$ tpm2_hash -H n -g 0x0004 -I random.out -o hash.out -t tk.out
|
NV Storage
This part uses TCG TPM2 Software Stack.
The NV storage is a secure memory in the Trusted Platform Module that can be used to store any type of data such X509 certificates.
Define NV index with index number 0x1c00012, size 32 bytes, and attribute word 0x2000A:
# 0x40000001 corresponds to TPM_RH_OWNER
$ tpm2_nvdefine -x 0x1c00012 -a 0x40000001 -s 32 -t 0x2000a
|
List NV spaces:
Write content from file random.out into NV index 0x1c00012:
$ tpm2_nvwrite -x 0x1c00012 -a 0x40000001 -f random.out
|
We can read for instance the first 20 bytes of the file we wrote in the NV space starting from offset 0:
$ tpm2_nvread -x 0x1c00012 -a 0x40000001 -o 0 -s 20
|
When we do not need this space anymore, we can release the NV spaces:
$ tpm2_nvrelease -x 0x1c00012 -a 0x40000001
|
Asymmetric signature
Using contexts
This part uses TCG TPM2 Software Stack.
Create a Primary Object in endorsement hierarchy, with RSA keys & SHA256 algorithm and object context saved in file primary_ctx:
$ tpm2_createprimary -A e -g 0x000B -G 0x0001 -C primary_ctx
|
Create a RSA key under the previous primary key, with SHA256 algorithm, with public portion saved in key.pub and private portion saved in key.priv:
$ tpm2_create -g 0x000B -G 0x0023 -c primary_ctx -o key_pub -O key_priv
|
Load the created RSA key inside the TPM (transient storage meaning that the key will be deleted when the TPM is reset):
$ tpm2_load -c primary_ctx -u key_pub -r key_priv -n anyname -C eccsigning_key_ctx
|
Sign a message generated previously (limited from the Trusted Platform Module to 1024 bytes of payload):
$ tpm2_sign -c eccsigning_key_ctx -g 0x000B -m random.out -s signature.bin
|
Loads the PUBLIC part only of the key inside the TPM (Keys loaded using tpm2_loadexternal cannot be changed to persistent keys, they stay transient meaning that they will be removed if the TPM is reset):
$ tpm2_loadexternal -H n -u key_pub -C eccsigning_key_ctx2
|
Verify the signature:
$ tpm2_verifysignature -c eccsigning_key_ctx2 -g 0x000B -m random.out -s signature.bin -t ticket3
|
Using a keypair generated from Trusted Platform Module
This part uses IBM TPM2 Software Stack.
Create a primary storage key with handle 0x80000000 (if there is no previous transient handle key, otherwise it will be 0x80000001 or 0x80000002 and so on):
(OPTIONAL) Make the primary transient key with handle 0x80000000 persistent (Note that the range for persistent and transient handles is different):
$ evictcontrol -hi p -ho 80000000 -hp 81800000
|
Generate a key from the TPM using parent handle 0x80000000 (or 0x81800000 if you made the key persistent) and store the private part in tpmpriv.bin and the public part in tpmpub.bin:
$ create -st -hp 0x80000000 -opr tpmpriv.bin -opu tpmpub.bin
|
Load the key inside the TPM with a TRANSIENT handle for example 0x80000001:
$ load -hp 80000000 -ipu tpmpub.bin -ipr tpmpriv.bin
|
Make the transient key with handle 0x80000001 persistent (Note that the range for persistent and transient handles is different):
$ evictcontrol -hi p -ho 80000001 -hp 81800001
|
Sign a message generated previously (limited from the TPM to 1024 bytes of payload):
$ sign -hk 81800001 -halg sha256 -if random.out -os sig.bin
|
Verify signature:
$ verifysignature -hk 81800001 -halg sha256 -if random.out -is sig.bin
|
Using a keypair generated with OpenSSL
This part uses IBM TPM2 Software Stack.
The steps are similar to previously but instead of creating a key from parent handle, we will import OpenSSL keypair into the Trusted Platform Module using parent handle.
Generate an OpenSSL key:
$ openssl genrsa -out keypair.pem 2048
|
Create a primary storage key with handle 0x80000000 (if there is no previous transient handle key, otherwise it will be 0x80000001 or 0x80000002 and so on):
(OPTIONAL) Make the primary transient key with handle 0x80000000 persistent (Note that the range for persistent and transient handles is different):
$ evictcontrol -hi p -ho 80000000 -hp 81800000
|
Import OpenSSL keypair into the Trusted Platform Module using parent handle 0x80000000 (or 0x81800000 if you made the key persistent). This function is not API compatible and has been made for test, debugging purposes. It returns an available transient handle for example 0x80000001:
$ importpem -hp 80000000 -ipem keypair.pem -opu tmppub.bin -opr tmppriv.bin -halg sha256
|
Make the transient key with handle 0x80000001 persistent (Note that the range for persistent and transient handles is different):
$ evictcontrol -hi p -ho 80000001 -hp 81800001
|
Sign a message generated previously (limited from the TPM to 1024 bytes of payload):
$ sign -hk 81800001 -halg sha256 -if random.out -os sig.bin
|
Verify signature:
$ verifysignature -hk 81800001 -halg sha256 -if random.out -is sig.bin
|