Trusted Platform Module 2.0

Private keys and X.509 certificates stored in a TPM 2.0 device can be accessed and used by the pki tool (using the --keyid and --cakeyid options), the pt-tls-client (using the --keyid and --certid options), and of course the strongSwan IKE daemon.

Connect to a TPM 2.0 Device

Install TPM 2.0 Software Stack and Tools

In order to connect to a TPM 2.0 hardware or firmware device a software stack implementing the TCG TSS 2.0 System Level API is needed. An excellent open source tpm2-tss library is available from the tpm2-software project that also offers a set of tpm2-tools using the TCG TSS 2.0 Enhanced System Level API.

Infineon TPM 2.0
Figure 1. TPM 2.0 implemented as a hardware device

When using a strongSwan version newer than 5.9.0 with Linux 5.4 kernel or newer, we recommend these latest versions:

Fedora 36 and Ubuntu 22.04 come with version 3.2.0 of the tpm2-tss library and version 5.2 of the tpm2-tools, whereas Debian 11 supports the slightly older tpm2-tss 3.0.3 and tpm2-tools 5.0 versions, so that for these Linux distributions no manual compilation of the two packages is necessary. For older Linux releases it is recommended to download and install the latest tarballs from the tpm2-software site.

In order to test if we can connect to the TPM 2.0 device, we list all persistent keys stored in the Non-Volatile (NV) RAM:

$ tpm2_getcap handles-persistent

- 0x81000001
- 0x81000002
- 0x81010001

The man pages of all tpm2-tools functions with their arguments can be found here. The access to the /dev/tpmrm0 TPM resource manager device requires root rights on most Linux platforms. But e.g. with Ubuntu, adding the user to the tss group enables direct access to the TPM device:

$ sudo usermod -a -G tss <username>

Enable the strongSwan tpm Plugin

The strongSwan libtpmtss tpm plugin and the TSS2 interface are enabled and built with the following options

$ ./configure --enable-tss-tss2 --enable-tpm  ...

With the strongSwan pki tool we can now list the persistent key stored under the handle 0x81010001

$ pki --print --type priv --keyid 0x81010001 --debug 2

With debug level 2 some basic information on the TPM device is shown. A second generation Intel firmware TPM running on the Intel Management Engine is employed. Both SHA1 and SHA256 PCR banks are available:

TPM 2.0 - manufacturer: INTC (Intel) rev: 01.38 2018
TPM 2.0 - algorithms: RSA SHA1 HMAC AES MGF1 KEYEDHASH XOR SHA256 RSASSA RSAES RSAPSS OAEP ECDSA ECDH ECDAA ECSCHNORR KDF1_SP800_56A KDF1_SP800_108 ECC SYMCIPHER CTR OFB CBC CFB ECB
TPM 2.0 - ECC curves: NIST_P256 BN_P256
TPM 2.0 - PCR banks: SHA1 SHA256

Apparently the analyzed persistent key can be used for encryption only:

TPM 2.0 via TSS2 v2 available
encryption algorithm is AES-CFB with 128 bits

Debug level 2 shows that pki extracts the public key from the TPM and converts it into a standard PKCS#1 format:

L0 - subjectPublicKeyInfo:
L1 - algorithm:
L2 - algorithmIdentifier:
L3 - algorithm:
  'rsaEncryption'
L1 - subjectPublicKey:
-- > --
L0 - RSAPublicKey:
L1 - modulus:
L1 - publicExponent:
-- < --

At the end of the output the fingerprint of the 2048 bit RSA key is listed:

  privkey:   RSA 2048 bits
  keyid:     ee:c7:bf:5a:de:0f:11:84:2c:86:2b:69:84:ba:65:b9:81:d2:a9:45
  subjkey:   df:f2:e9:e7:79:98:f0:d2:0b:62:db:c0:5c:2c:eb:45:73:85:e9:79

Derive Persistent Endorsement Keys

RSA Endorsement Key

The tpm2_createek command derives a 2048 bit RSA Endorsement Key (EK) in a deterministic way from the secret Endorsement Primary Seed unique to each TPM device and makes the key persistent in the non-volatile memory of the TPM under the object handle 0x81010002

$ tpm2_createek -G rsa -c 0x81010002

Using the tpm2_getcap command we can check that the newly derived Endorsement Key has been persisted in the NV RAM

$ tpm2_getcap handles-persistent

- 0x81000001
- 0x81000002
- 0x81010001
- 0x81010002

Listing the key properties shows that the 2048 bit Endorsement Key already exists under the handle 0x81010001 analyzed in the previous section

$ pki --print --type priv --keyid 0x81010002

TPM 2.0 via TSS2 v2 available
encryption algorithm is AES-CFB with 128 bits
  privkey:   RSA 2048 bits
  keyid:     ee:c7:bf:5a:de:0f:11:84:2c:86:2b:69:84:ba:65:b9:81:d2:a9:45
  subjkey:   df:f2:e9:e7:79:98:f0:d2:0b:62:db:c0:5c:2c:eb:45:73:85:e9:79

Delete Persisted Keys

We therefore delete the duplicate key with the following tpm2_evictcontrol command

$ tpm2_evictcontrol -c 0x81010002

persistent-handle: 0x81010002
action: evicted

The key removal can be verified with

$ tpm2_getcap handles-persistent

- 0x81000001
- 0x81000002
- 0x81010001

ECC Endorsement Key

Again using the tpm2_createek command we derive a 256 bit ECC Endorsement Key (EK) in a deterministic way from the secret Endorsement Primary Seed unique to each TPM device and make the key persistent in the non-volatile memory of the TPM under the object handle 0x81010002:

$ tpm2_createek -G ecc -c 0x81010002 -u ek_ecc.pub

Optionally we saved the public key in a TPM 2.0 proprietary format in the file ek_ecc.pub. The fingerprint of the ECC EK private key can be directly displayed with the command

$ pki --print --type priv --keyid 0x81010002

TPM 2.0 via TSS2 v2 available
encryption algorithm is AES-CFB with 128 bits
  privkey:   ECDSA 256 bits
  keyid:     25:db:73:13:0f:c9:c8:91:68:30:8e:02:89:c1:0d:65:bd:ad:69:2a
  subjkey:   9c:b9:fb:b0:32:81:24:82:a7:07:b2:bd:bd:d3:7c:2b:22:7f:74:bf

Endorsement Key Certificates

Fetched via URL

Endorsement Key certificates issued for Intel firmware TPMs can be automatically downloaded from an Intel web server using the tpm2_getcertificate command:

$ tpm2_getekcertificate -o ek_ecc.crt -u ek_ecc.pub

For successful retrieval the public key ek_ecc.pub in the TPM 2.0 proprietary format is required. Using the pki tool we can list the downloaded EK certificate belonging to the ECC key:

$ pki --print --type x509 --in ek_ecc.crt

  subject:  ""
  issuer:   "C=US, ST=CA, L=Santa Clara, O=Intel Corporation, OU=TPM EK intermediate for CNL_EPID_POST_B1LP_PROD_2 pid:9, CN=www.intel.com"
  validity:  not before Sep 04 02:00:00 2019, ok
             not after  Jan 01 00:59:59 2050, ok (expires in 10600 days)
  serial:    07:99:3b:c6:88:aa:7d:72:b0:24:24:05:09:01:bb:42:55:70:1a:43
  altNames:  tcg-at-tpmManufacturer=id:494E5443, tcg-at-tpmModel=CNL, tcg-at-tpmVersion=id:00020000
  CRL URIs:  https://trustedservices.intel.com/content/CRL/ekcert/CNLEPIDPOSTB1LPPROD2_EK_Device.crl
  certificatePolicies:
             1.2.840.113741.1.5.2.1
             CPS: https://trustedservices.intel.com/content/CRL/ekcert/EKcertPolicyStatement.pdf
  authkeyId: 17:a0:05:75:d0:5e:58:e3:88:12:10:bb:98:b1:04:5b:b4:c3:06:39
  subjkeyId: 9c:b9:fb:b0:32:81:24:82:a7:07:b2:bd:bd:d3:7c:2b:22:7f:74:bf
  pubkey:    ECDSA 256 bits
  keyid:     25:db:73:13:0f:c9:c8:91:68:30:8e:02:89:c1:0d:65:bd:ad:69:2a
  subjkey:   9c:b9:fb:b0:32:81:24:82:a7:07:b2:bd:bd:d3:7c:2b:22:7f:74:bf

For the RSA 2048 Endorsement Key we first have to extract the public keyfile ek_rsa.pub in the TPM 2.0 proprietary format using the tpm2_readpublic command because we forgot to do this in the first place:

$ tpm2_readpublic -Q -c 0x81010001 -o ek_rsa.pub

Now we can retrieve the RSA EK certificate, too:

$ tpm2_getekcertificate -o ek_rsa.crt -u ek_rsa.pub

and view the contents with the pki --print command

$ pki --print --type x509 --in ek_rsa.crt

  subject:  ""
  issuer:   "C=US, ST=CA, L=Santa Clara, O=Intel Corporation, OU=TPM EK intermediate for CNL_EPID_POST_B1LP_PROD_2 pid:9, CN=www.intel.com"
  validity:  not before Sep 04 02:00:00 2019, ok
             not after  Jan 01 00:59:59 2050, ok (expires in 10600 days)
  serial:    14:26:0b:eb:12:a2:82:87:af:3b:75:e0:a1:a4:87:60:72:95:55:92
  altNames:  tcg-at-tpmManufacturer=id:494E5443, tcg-at-tpmModel=CNL, tcg-at-tpmVersion=id:00020000
  CRL URIs:  https://trustedservices.intel.com/content/CRL/ekcert/CNLEPIDPOSTB1LPPROD2_EK_Device.crl
  certificatePolicies:
             1.2.840.113741.1.5.2.1
             CPS: https://trustedservices.intel.com/content/CRL/ekcert/EKcertPolicyStatement.pdf
  authkeyId: 17:a0:05:75:d0:5e:58:e3:88:12:10:bb:98:b1:04:5b:b4:c3:06:39
  subjkeyId: df:f2:e9:e7:79:98:f0:d2:0b:62:db:c0:5c:2c:eb:45:73:85:e9:79
  pubkey:    RSA 2048 bits
  keyid:     ee:c7:bf:5a:de:0f:11:84:2c:86:2b:69:84:ba:65:b9:81:d2:a9:45
  subjkey:   df:f2:e9:e7:79:98:f0:d2:0b:62:db:c0:5c:2c:eb:45:73:85:e9:79

We can easily check that in both EK certificates the key fingerprints (keyid and subjkey match with those of the EK keys persisted in the TPM.

Stored in Non-Volatile RAM

Most hardware TPMs are shipped with their Endorsement Key Certificates stored in NV RAM. E.g. on an STMicroelectronics TPM device the following data objects are stored in an NV index:

$ tpm2_getcap handles-nv-index

- 0x1410001
- 0x1410002
- 0x1410004
- 0x1880001
- 0x1880011
- 0x1C00002
- 0x1C0000A
- 0x1C00012
- 0x1C10102
- 0x1C10103
- 0x1C10104
- 0x1C101C0

Using the tpm2_nvreadpublic command we can look for large data objects which are prime candidates for X.509 certificates:

$ tpm2_nvreadpublic

  ...
0x1c00002:
  name: 000b5c112bd5f410d0abe96a50e94ff721a005c32567e4b1112ab0a8fb7e0289b7f2
  hash algorithm:
    friendly: sha256
    value: 0xB
  attributes:
    friendly: ppwrite|writedefine|write_stclear|ppread|ownerread|authread|no_da|written|platformcreate
    value: 0x1600762
  size: 1033

0x1c0000a:
  name: 000b1948300e66afad594b7a8e8368d53ddd36908fb2b46dd7b5a88051b50e4047ab
  hash algorithm:
    friendly: sha256
    value: 0xB
  attributes:
    friendly: ppwrite|writedefine|write_stclear|ppread|ownerread|authread|no_da|written|platformcreate
    value: 0x1600762
  size: 639

0x1c00012:
  name: 000cde411e123085083eedb1c9312e08dd8d229df6a5e16996035a2e3000d860b372c924de0354a6af4c7886656d2065814f
  hash algorithm:
    friendly: sha384
    value: 0xC
  attributes:
    friendly: ppwrite|writedefine|write_stclear|ppread|ownerread|authread|no_da|written|platformcreate
    value: 0x1600762
  size: 707
  ...

We can use pki --print command to directly list the properties of the EK certificates:

$ pki --print --type x509 --keyid 0x01c00002

TPM 2.0 via TSS2 v2 available
loaded certificate from TPM NV index 0x01c00002
  subject:  ""
  issuer:   "C=CH, O=STMicroelectronics NV, CN=STM TPM EK Intermediate CA 06"
  validity:  not before Feb 11 01:00:00 2020, ok
             not after  Jan 01 01:00:00 2031, ok (expires in 3650 days)
  serial:    72:78:a1:2c:87:b6:aa:45:c4:1f:57:ff:d1:3d:cf:93:42:34:b9:c9
  altNames:  tcg-at-tpmManufacturer=id:53544D20, tcg-at-tpmModel=ST33HTPHAHD4, tcg-at-tpmVersion=id:00010101
  authkeyId: fb:17:d7:0d:73:48:70:e9:19:c4:e8:e6:03:97:5e:66:4e:0e:43:de
  subjkeyId: e9:3d:51:32:04:42:73:3e:fc:bb:9e:f8:0c:21:9a:53:ec:73:80:94
  pubkey:    RSA 2048 bits
  keyid:     d3:e3:71:79:df:32:53:34:60:0f:1f:38:dc:d4:6d:53:59:1b:c5:3c
  subjkey:   e9:3d:51:32:04:42:73:3e:fc:bb:9e:f8:0c:21:9a:53:ec:73:80:94
$ pki --print --type x509 --keyid 0x01c0000a

TPM 2.0 via TSS2 v2 available
loaded certificate from TPM NV index 0x01c0000a
  subject:  ""
  issuer:   "C=CH, O=STMicroelectronics NV, CN=STM TPM ECC Intermediate CA 02"
  validity:  not before Mar 09 01:00:00 2020, ok
             not after  Jan 01 01:00:00 2031, ok (expires in 3650 days)
  serial:    51:e8:fc:b2:64:8d:1d:36:a5:bc:d7:c9:63:c1:d6:de:e7:25:09:a4
  altNames:  tcg-at-tpmManufacturer=id:53544D20, tcg-at-tpmModel=ST33HTPHAHD4, tcg-at-tpmVersion=id:00010101
  authkeyId: 66:2d:8f:1c:ec:df:f1:47:a8:b6:f0:ea:29:6a:f7:f2:4c:ad:f9:cf
  subjkeyId: d1:e8:fc:b2:64:8d:1d:36:a5:bc:d7:c9:63:c1:d6:de:e7:25:09:a4
  pubkey:    ECDSA 256 bits
  keyid:     8b:62:31:bf:08:9d:39:74:6d:05:fd:35:eb:2e:13:64:12:86:03:16
  subjkey:   d1:e8:fc:b2:64:8d:1d:36:a5:bc:d7:c9:63:c1:d6:de:e7:25:09:a4

or we can first retrieve the binary certificate blob from the NV RAM using the tpm2_nvread command:

$ tpm2_nvread 0x01c00012 -C o -o ek_ecc384.crt

and then list the properties of the EK certificate file:

$ pki --print --type x509 --in ek_ecc384.crt

  subject:  ""
  issuer:   "C=CH, O=STMicroelectronics NV, CN=STM TPM ECC384 Intermediate CA 01"
  validity:  not before Feb 08 01:00:00 2020, ok
             not after  Jan 01 01:00:00 2031, ok (expires in 3650 days)
  serial:    39:ed:ae:d4:89:9e:52:08:9f:42:8a:f5:d5:58:7b:50:a6:24:f3:63
  altNames:  tcg-at-tpmManufacturer=id:53544D20, tcg-at-tpmModel=ST33HTPHAHD4, tcg-at-tpmVersion=id:00010101
  authkeyId: bd:96:3e:9a:d5:74:aa:d9:4f:ad:6c:bf:41:6d:d8:5b:4a:55:99:42
  subjkeyId: b9:ed:ae:d4:89:9e:52:08:9f:42:8a:f5:d5:58:7b:50:a6:24:f3:63
  pubkey:    ECDSA 384 bits
  keyid:     04:68:52:c4:00:ab:10:75:82:57:99:45:1e:7c:12:01:5a:8e:50:c9
  subjkey:   b9:ed:ae:d4:89:9e:52:08:9f:42:8a:f5:d5:58:7b:50:a6:24:f3:63

We see that the STMicroelectronics device apparently supports 384 bit ECC keys

TPM 2.0 - manufacturer: STM  () rev: 01.38 2018 FIPS 140-2
TPM 2.0 - algorithms: RSA SHA1 HMAC AES MGF1 KEYEDHASH XOR SHA256 SHA384 RSASSA RSAES RSAPSS OAEP ECDSA ECDH ECDAA ECSCHNORR KDF1_SP800_56A KDF1_SP800_108 ECC SYMCIPHER SHA3_256 SHA3_384 CTR OFB CBC CFB ECB
TPM 2.0 - ECC curves: NIST_P256 NIST_P384 BN_P256
TPM 2.0 - PCR banks: SHA1 SHA256

Generate Persistent Attestation Keys

RSA Attestation Key

A 2048 bit RSA Attestation Key (AK) bound to the RSA EK with handle 0x81010001 can be created with the tpm2_createak command:

$ tpm2_createak -C 0x81010001 -G rsa -g sha256 -s rsassa -c ak_rsa.ctx -u ak_rsa.pub -n ak_rsa.name

and made persistent under the handle 0x81010003 with the tpm2_evictcontrol command:

$ tpm2_evictcontrol -C o -c ak_rsa.ctx 0x81010003

persistent-handle: 0x81010003
action: persisted

The properties of the RSA AK which is a signing key can be displayed with the command

$ pki --print --type priv --keyid 0x81010003

TPM 2.0 via TSS2 v2 available
signature algorithm is RSASSA with SHA256 hash
  privkey:   RSA 2048 bits
  keyid:     df:b7:8f:95:61:8f:70:84:f4:03:e8:7e:83:a6:dd:5f:c5:ff:72:b5
  subjkey:   48:82:62:15:74:a2:10:c5:75:70:c2:d6:7d:59:9f:22:d9:4f:9c:07

ECC Attestation Key

A 256 bit ECC Attestation Key (AK) bound to the ECC EK with handle 0x81010002 can be created with the tpm2_createak command:

$ tpm2_createak -C 0x81010002 -G ecc -g sha256 -s ecdsa -c ak_ecc.ctx -u ak_ecc.pub -n ak_ecc.name

and made persistent under the handle 0x81010004 with the tpm2_evictcontrol command:

$ tpm2_evictcontrol -C o -c ak_ecc.ctx 0x81010004

persistent-handle: 0x81010004
action: persisted

The properties of the ECC AK which is a signing key can be displayed with the command

$ pki --print --type priv --keyid 0x81010004

TPM 2.0 via TSS2 v2 available
signature algorithm is ECDSA with SHA256 hash
  privkey:   ECDSA 256 bits
  keyid:     ba:64:37:a4:0e:c8:42:67:8c:55:5a:f9:1b:2a:eb:ff:5f:40:c3:e3
  subjkey:   cc:83:49:87:2b:9e:f3:cb:b8:35:12:02:87:ff:14:89:28:44:a6:04

Generate PKCS#10 Certificate Requests

RSA Certificate Request

The pki --req tool can directly generate a PKCS#10 certificate request self-signed by the TPM 2.0 private key and containing the corresponding public key as well as the desired end entity identity:

$ pki --req --type priv --keyid 0x81010003 --dn "C=CH, O=strongSec GmbH, OU=AK RSA, CN=edu.strongsec.com" --san edu.strongsec.com --outform pem > ak_rsa_req.pem

TPM 2.0 via TSS2 v2 available
signature algorithm is RSASSA with SHA256 hash
Smartcard PIN: <return>

Since we didn’t configure a password when creating the AK, just press <return> when prompted for the PIN. With openssl we can verify the contents of the generated certificate request:

$ openssl req -in ak_rsa_req.pem -noout -text

Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = CH, O = strongSec GmbH, OU = AK RSA, CN = edu.strongsec.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:9e:cc:3c:be:0a:37:86:db:ab:a5:01:49:a4:be:
                    0f:10:0e:32:50:12:27:64:52:85:0f:21:5e:c7:14:
                    f4:d9:7f:95:0a:22:91:73:9f:60:07:45:d3:8e:4b:
                    6d:94:00:83:44:ed:9c:f2:c0:14:9c:33:01:46:d0:
                    78:e4:10:ae:51:3a:9c:c2:b7:a0:c7:04:66:80:bb:
                    c2:bc:02:5b:d6:de:da:93:98:de:a7:cd:a5:5d:c1:
                    8a:bb:13:8b:d9:21:88:c0:61:40:d2:30:eb:0d:dd:
                    63:8d:a4:e0:b0:1a:bb:18:7f:6e:62:e1:bf:b3:39:
                    fa:c2:80:32:88:6a:da:f0:24:90:5c:16:b6:bb:30:
                    5d:96:25:24:cf:f2:03:19:0f:56:58:f2:32:00:51:
                    8b:0a:c3:15:81:db:34:ee:a4:64:5b:b6:3c:e6:d3:
                    df:e3:16:80:07:0e:13:91:4d:18:9c:b3:fd:ca:72:
                    78:72:56:e9:13:4c:1d:a2:03:f0:e1:8d:cd:54:1c:
                    68:ea:46:47:1c:f9:f9:97:7a:f1:59:96:58:6c:d8:
                    8e:a9:15:fc:4d:93:5d:fa:51:5d:33:5a:bb:77:59:
                    18:3e:6b:f6:45:f7:92:c2:12:0a:bb:64:af:0b:ff:
                    0d:08:7a:18:90:d9:10:63:b1:6a:19:78:da:9d:ab:
                    7a:87
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name:
                DNS:edu.strongsec.com
    Signature Algorithm: sha256WithRSAEncryption
         35:89:16:59:fc:ab:64:a9:a1:89:cc:d0:e6:a9:06:19:e1:5e:
         11:98:20:ea:ca:f0:5f:06:3c:11:ff:72:98:96:92:08:91:68:
         d8:bd:e6:05:ed:ef:49:cf:22:6d:da:ab:2c:10:a7:df:59:a3:
         0e:e4:bf:f6:8a:62:0b:28:eb:62:89:d0:50:d0:df:2f:5a:2d:
         39:c6:7b:ac:34:6c:85:93:be:0d:9b:70:15:47:73:2f:00:da:
         52:e3:65:c2:02:f9:88:0f:b8:f5:24:dc:db:43:15:fe:bc:8c:
         98:96:81:aa:6d:aa:4c:6e:38:a2:89:27:5c:8d:27:5d:16:1a:
         fa:3b:e7:81:69:58:db:a9:9a:c7:ea:06:d2:1c:13:ba:ee:92:
         a4:8a:64:e3:5f:19:2c:d3:54:4f:3c:da:52:fc:9a:35:72:5c:
         a9:d4:93:7c:e3:69:08:2b:fb:4e:35:84:7e:e3:eb:95:86:2e:
         5b:e5:01:c1:69:53:86:f9:6b:38:31:83:97:76:8b:ba:3d:9c:
         28:5b:84:b0:9b:e9:91:8b:db:9e:4d:3b:03:db:f4:84:a6:8d:
         b2:18:9f:3a:3e:f9:36:64:15:98:4f:69:37:6b:9e:b2:92:a0:
         9c:ab:05:35:65:28:b8:df:92:4b:fe:d1:40:6d:05:e2:4f:4e:
         75:15:8c:22

ECC Certificate Request

We repeat the same for the ECC Attestation Key:

$ pki --req --type priv --keyid 0x81010004 --dn "C=CH, O=strongSec GmbH, OU=AK ECC, CN=edu.strongsec.com" --san edu.strongsec.com --outform pem > ak_ecc_req.pem

TPM 2.0 via TSS2 v2 available
signature algorithm is ECDSA with SHA256 hash
Smartcard PIN: <return>

and verify that the certificate request has been self-signed by the ECC AK private-key:

$ openssl req -in ak_ecc_req.pem -noout -text

Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = CH, O = strongSec GmbH, OU = AK ECC, CN = edu.strongsec.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:80:e7:cd:47:9e:c7:71:08:98:82:22:ed:99:1f:
                    40:50:bd:44:da:a1:ca:ac:0b:e2:13:7f:f3:ae:63:
                    99:61:74:a2:b6:15:ae:5c:27:9e:bd:f2:27:91:95:
                    d1:ee:8f:99:93:ca:7b:4e:4e:87:a1:00:9e:94:24:
                    b1:13:d1:11:2c
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name:
                DNS:edu.strongsec.com
    Signature Algorithm: ecdsa-with-SHA256
         30:46:02:21:00:a0:3a:98:28:79:4b:bf:bd:90:92:d0:86:a2:
         69:34:9c:61:6b:87:8e:d0:30:8b:69:b0:94:bd:20:1a:c2:d8:
         e8:02:21:00:8e:e1:3d:5a:84:69:a1:dc:eb:c3:68:7d:80:7c:
         3b:73:c8:40:08:a2:88:56:94:03:9f:49:52:60:40:a1:9a:9f

Issuing Attestion Key Certificates

Certification Authority

X.509 end entity certificates have to be signed by an in-house or official external Certification Authority (CA). In our example we are using the strongSec 2016 Root CA which was generated in 2016 with the pki --gen command

$ pki --gen --type rsa --size 4096 --outform pem > cakey.pem

creating a 4096 bit RSA key pair and then creating a self-signed CA certificate with a lifetime of 10 years

$ pki --self --ca --type rsa --in cakey.pem --dn="C=CH, O=strongSec GmbH, CN=strongSec 2016 Root CA" --lifetime 3652 --outform pem > cacert.pem

as the following listing shows:

$ pki --print --type x509 --in cacert.pem

  subject:  "C=CH, O=strongSec GmbH, CN=strongSec 2016 Root CA"
  issuer:   "C=CH, O=strongSec GmbH, CN=strongSec 2016 Root CA"
  validity:  not before Sep 02 10:25:01 2016, ok
             not after  Sep 02 10:25:01 2026, ok (expires in 2067 days)
  serial:    7c:24:43:4b:b7:dc:ef:7e
  flags:     CA CRLSign self-signed
  subjkeyId: 6d:c2:af:37:49:41:b9:fd:f4:45:8b:aa:e0:03:3b:b9:e5:7b:9c:b5
  pubkey:    RSA 4096 bits
  keyid:     6c:79:f3:7a:b0:df:ac:69:03:b2:ac:6a:ed:82:3a:d2:66:93:b1:21
  subjkey:   6d:c2:af:37:49:41:b9:fd:f4:45:8b:aa:e0:03:3b:b9:e5:7b:9c:b5

RSA Attestation Key Certificate

The PKCS#10 certificate request exported from the TPM is used to generate an RSA Attestation Key certificate signed by the Root CA:

$ pki --issue --cacert cacert.pem --cakey cakey.pem -type pkcs10 --in ak_rsa_req.pem --dn "C=CH, O=strongSec GmbH, OU=AK RSA, CN=edu.strongsec.com" --san "edu.strongsec.com" --crl http://www.strongsec.com/ca/strongsec.crl --flag serverAuth --lifetime 1827 > ak_rsa_cert.der

having the following content

$ pki --print --type x509 --in ak_rsa_cert.der

  subject:  "C=CH, O=strongSec GmbH, OU=AK RSA, CN=edu.strongsec.com"
  issuer:   "C=CH, O=strongSec GmbH, CN=strongSec 2016 Root CA"
  validity:  not before Dec 23 15:26:22 2020, ok
             not after  Dec 23 15:26:22 2025, ok (expires in 1814 days)
  serial:    79:e5:74:2f:a4:df:b8:d2
  altNames:  edu.strongsec.com
  flags:     serverAuth
  CRL URIs:  http://www.strongsec.com/ca/strongsec.crl
  authkeyId: 6d:c2:af:37:49:41:b9:fd:f4:45:8b:aa:e0:03:3b:b9:e5:7b:9c:b5
  subjkeyId: 48:82:62:15:74:a2:10:c5:75:70:c2:d6:7d:59:9f:22:d9:4f:9c:07
  pubkey:    RSA 2048 bits
  keyid:     df:b7:8f:95:61:8f:70:84:f4:03:e8:7e:83:a6:dd:5f:c5:ff:72:b5
  subjkey:   48:82:62:15:74:a2:10:c5:75:70:c2:d6:7d:59:9f:22:d9:4f:9c:07

ECC Attestation Key Certificate

The second PKCS#10 certificate request exported from the TPM is used to generate an ECC Attestation Key certificate signed by the Root CA:

$ pki --issue --cacert cacert.pem --cakey cakey.pem -type pkcs10 --in ak_ecc_req.pem --dn "C=CH, O=strongSec GmbH, OU=AK ECC, CN=edu.strongsec.com" --san "edu.strongsec.com" --crl http://www.strongsec.com/ca/strongsec.crl --flag serverAuth --lifetime 1827 > ak_ecc_cert.der

having the following content

$ pki --print --type x509 --in ak_ecc_cert.der

  subject:  "C=CH, O=strongSec GmbH, OU=AK ECC, CN=edu.strongsec.com"
  issuer:   "C=CH, O=strongSec GmbH, CN=strongSec 2016 Root CA"
  validity:  not before Dec 23 15:27:40 2020, ok
             not after  Dec 23 15:27:40 2025, ok (expires in 1814 days)
  serial:    65:fd:5b:98:47:11:f6:45
  altNames:  edu.strongsec.com
  flags:     serverAuth
  CRL URIs:  http://www.strongsec.com/ca/strongsec.crl
  authkeyId: 6d:c2:af:37:49:41:b9:fd:f4:45:8b:aa:e0:03:3b:b9:e5:7b:9c:b5
  subjkeyId: cc:83:49:87:2b:9e:f3:cb:b8:35:12:02:87:ff:14:89:28:44:a6:04
  pubkey:    ECDSA 256 bits
  keyid:     ba:64:37:a4:0e:c8:42:67:8c:55:5a:f9:1b:2a:eb:ff:5f:40:c3:e3
  subjkey:   cc:83:49:87:2b:9e:f3:cb:b8:35:12:02:87:ff:14:89:28:44:a6:04

Storing Certificates in the NV RAM

A TPM 2.0 has a certain amount of Non Volatile Random Access Memory (NV RAM) that can be used to store arbitrary data, e.g. the X.509 certificates matching the persistent keys. If both the certificates and keys are persisted in the TPM then the system disk of the host can be reformatted at any time without loosing the machine or user credentials.As with smartcards the needed amount of memory must be reserved first so we check the size of the X.509 ECC certificate

$ ls -l ak_ecc_cert.der

-rw-rw-r-- 1 andi andi 1001 Dez 23 15:31 ak_ecc_cert.der

The tpm2_nvdefine command allocates a memory location with a size of 1001 bytes that can be accessed via the handle 0x01800004 which is also called the NV index

$ tpm2_nvdefine 0x01800004 -C o -s 1001 -a 0x2000A

nv-index: 0x1800004

Then we write the certificate file to the NV RAM destination using the tpm2_nvwrite command:

$ tpm2_nvwrite 0x01800004 -C o -i ak_ecc_cert.der

Removing Certificates from NV RAM

First we store the RSA AK certificate in the NV RAM under the handle 0x0180003, again by first determining the size of the object to be persisted:

$ ls -l ak_rsa_cert.der

-rw-rw-r-- 1 andi andi 1204 Dez 23 15:30 ak_rsa_cert.der

allocating space for it

$ tpm2_nvdefine 0x01800003 -C o -s 1204 -a 0x2000A

nv-index: 0x1800003

and finally storing the certificate

$ tpm2_nvwrite 0x01800003 -C o -i ak_rsa_cert.der

We decide to use the RSA AK certificate externally, though. Thus we release the memory assigned to NV index 0x01800003 via the tpm2_nvundefine command:

$ tpm2_nvundefine 0x01800003 -C o

New TPM 2.0 Devices with stronger RSA and ECC Keys

Starting with version 5.3 of the tpm2-tools, RSA keys with lengths > 2048 bits and ECC keys with lengths > 256 bits are supported. Also signatures can be based on sha384 or sha512 hashes if the TPM 2.0 firmware supports them.

E.g. the following TPM 2.0 device manufactured by STMicroelectronics has support for NIST_P384 ECC keys and signatures based on `"SHA384" hashes:

TPM 2.0 - manufacturer: STM  () rev: 01.38 2018 FIPS 140-2
TPM 2.0 - algorithms: RSA SHA1 HMAC AES MGF1 KEYEDHASH XOR SHA256 SHA384 RSASSA RSAES RSAPSS OAEP ECDSA ECDH ECDAA ECSCHNORR KDF1_SP800_56A KDF1_SP800_108 ECC SYMCIPHER SHA3_256 SHA3_384 CTR OFB CBC CFB ECB
TPM 2.0 - ECC curves: NIST_P256 NIST_P384 BN_P256
TPM 2.0 - PCR banks: SHA1 SHA256

Endorsement Keys

An EK with an RSA 3072 bit key is derived with the following command

$ tpm2_createek -G rsa3072 -c 0x81010001

and an EK with an ECC 384 bit key with the command

$ tpm2_createek -G ecc384 -c 0x81010002

Attestation Keys

An AK with an RSA 3072 bit key is derived with the following command

$ tpm2_createak -C 0x81010001 -G rsa3072 -g sha256 -s rsassa -c ak_rsa.ctx -u ak_rsa.pub -n ak_rsa.name

and an AK with an ECC 384 bit key with the command

$ tpm2_createak -C 0x81010002 -G ecc384 -g sha384 -s ecdsa -c ak_ecc.ctx -u ak_ecc.pub -n ak_ecc.name

IBM TPM 2.0 Simulator

A tpm-server Docker container with a readily installed IBM TPM 2.0 Simulator plus the tpm2-tools and the strongSwan pki tool allows you to freely experiment with the larger RSA and ECC keys.

Publications