Trusted Platform Module 2.0 » History » Version 130
Version 129 (Andreas Steffen, 03.01.2021 10:30) → Version 130/158 (Andreas Steffen, 03.01.2021 10:40)
h1. Trusted Platform Module 2.0
{{>toc}}
h2. Connect to a TPM 2.0 Device
h3. Install the tpm2-tss Software Stack and the tpm2-tools Command Set
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":https://trustedcomputinggroup.org/resource/tcg-tss-2-0-system-level-api-sapi-specification/ is needed. An excellent open source "tpm2-tss":https://github.com/tpm2-software/tpm2-tss library is available from the "tpm2-software":https://github.com/tpm2-software project which also offers a set of "tpm2-tools":https://github.com/tpm2-software/tpm2-tools which itself uses the "TCG TSS 2.0 Enhanced System Level API":https://trustedcomputinggroup.org/resource/tcg-tss-2-0-enhanced-system-api-esapi-specification/.
When using the latest *strongswan-5.9.1* version with a *Linux 5.4* kernel or newer, we recommend these latest versions:
* *tpm2-tss* version 3.0.3: https://github.com/tpm2-software/tpm2-tss/releases/tag/3.0.3
* *tpm2-tools* version 5.0: https://github.com/tpm2-software/tpm2-tools/releases/tag/5.0
Support for earlier strongSwan versions and Linux kernels can be found [[TpmPluginOld|here]].
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:
<pre>
tpm2_getcap handles-persistent
- 0x81000001
- 0x81000002
- 0x81010001
</pre>
A manual showing all *tpm2-tools* functions with their arguments can be found "here":https://github.com/tpm2-software/tpm2-tools/tree/5.0/man. 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:
<pre>
sudo usermod -a -G tss <username>
</pre>
h3. 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 [[IpsecPki|pki]] tool we can now list the persistent key stored under the handle *0x81010001*
<pre>
pki --print --type priv --keyid 0x81010001 --debug 2
</pre>
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:
<pre>
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
</pre>
Apparently the analyzed persistent key can be used for encryption only because no signature algorithm is defined:
<pre>
TPM 2.0 via TSS2 v2 available
signature algorithm is NULL with ERROR hash
</pre>
Debug level 2 shows that [[IpsecPki|pki]] extracts the public key from the TPM and converts it into a standard PKCS#1 format:
<pre>
L0 - subjectPublicKeyInfo:
L1 - algorithm:
L2 - algorithmIdentifier:
L3 - algorithm:
'rsaEncryption'
L1 - subjectPublicKey:
-- > --
L0 - RSAPublicKey:
L1 - modulus:
L1 - publicExponent:
-- < --
</pre>
At the end of the output the fingerprint of the 2048 bit RSA key is listed:
<pre>
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
</pre>
h2. Derive Persistent Endorsement Keys
h3. RSA Endorsement Key
The "tpm2_createek":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_createek.1.md 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":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_getcap.1.md command we can check that the newly derived Endorsement Key has been persisted in the NV RAM
<pre>
tpm2_getcap handles-persistent
- 0x81000001
- 0x81000002
- 0x81010001
- 0x81010002
</pre>
Listing the key properties shows that the 2048 bit Endorsement Key already exists under the handle *0x81010001* analyzed in the previous section
<pre>
pki --print --type priv --keyid 0x81010002
TPM 2.0 via TSS2 v2 available
signature algorithm is NULL with ERROR hash
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
</pre>
h3. Delete Persisted Keys
We therefore delete the duplicate key with the following "tpm2_evictcontrol":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_evictcontrol.1.md command
<pre>
tpm2_evictcontrol -c 0x81010002
persistent-handle: 0x81010002
action: evicted
</pre>
The key removal can be verified with
<pre>
tpm2_getcap handles-persistent
- 0x81000001
- 0x81000002
- 0x81010001
</pre>
h3. ECC Endorsement Key
Again using the "tpm2_createek":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_createek.1.md 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
<pre>
pki --print --type priv --keyid 0x81010002
TPM 2.0 via TSS2 v2 available
signature algorithm is NULL with ERROR hash
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
</pre>
h2. Endorsement Key Certificates
h3. Fetched via URL
Endorsement Key certificates issued for Intel firmware TPMs can be automatically downloaded from an Intel web server using the "tpm2_getcertificate":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_getekcertificate.1.md 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 [[IpsecPki|pki]] tool we can list the downloaded EK certificate belonging to the ECC key:
<pre>
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
</pre>
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":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_readpublic.1.md 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
<pre>
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
</pre>
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.
h3. 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:
<pre>
tpm2_getcap handles-nv-index
- 0x1410001
- 0x1410002
- 0x1410004
- 0x1880001
- 0x1880011
- 0x1C00002
- 0x1C0000A
- 0x1C00012
- 0x1C10102
- 0x1C10103
- 0x1C10104
- 0x1C101C0
</pre>
Using the "tpm2_nvreadpublic":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_nvreadpublic.1.md command we can look for large data objects which are prime candidates for X.509 certificates:
<pre>
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
...
</pre>
We can use [[IpsecPki|pki]] the pki tool to directly list the properties of the EK certificates:
<pre>
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
</pre>
<pre>
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
</pre>
or we can first retrieve the binary certificate blob from the NV RAM using the "tpm2_nvread":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_nvread.1.md command:
tpm2_nvread 0x01c00012 -C o -o ek_ecc384.crt
and then list the properties of the EK certificate file:
<pre>
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
</pre>
We see that the STMicroelectronics device apparently devices supports 384 bit ECC keys
<pre>
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
</pre>
keys.
h2. Generate Persistent Attestation Keys
h3. RSA Attestation Key
A 2048 bit RSA Attestation Key (AK) bound to the EK with handle *0x81010001* can be created with the "tpm2_createak":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_createak.1.md 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":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_evictcontrol.1.md command:
<pre>
tpm2_evictcontrol -C o -c ak_rsa.ctx 0x81010003
persistent-handle: 0x81010003
action: persisted
</pre>
The properties of the RSA AK which is a signing key can be displayed with the command
<pre>
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
</pre>
h3. 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":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_createak.1.md 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":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_evictcontrol.1.md command:
<pre>
tpm2_evictcontrol -C o -c ak_ecc.ctx 0x81010004
persistent-handle: 0x81010004
action: persisted
</pre>
The properties of the ECC AK which is a signing key can be displayed with the command
<pre>
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
</pre>
h2. Generate PKCS#10 Certificate Requests
h3. RSA Certificate Request
<pre>
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>
</pre>
<pre>
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
</pre>
h3. ECC Certificate Request
<pre>
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>
</pre>
<pre>
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
</pre>
h2. Create a Demo Root CA
The following *pki* command creates a 256 bit ECDSA private key for the Demo CA
<pre>
pki --gen --type ecdsa --size 256 --outform pem > demoCaKey.pem
</pre>
Next we create a self-signed Root CA certificate
<pre>
pki --self --ca --type ecdsa --in demoCaKey.pem --dn="C=US, O=TNC Demo, CN=TNC Demo CA" --lifetime 3652 --outform pem > demoCaCert.pem
</pre>
h2. Issue an RSA AIK Certificate
Based on the RSA AK public key exported from the TPM, the following *pki* command generates an Attestation Identity Key (AIK) certificate signed by the Demo CA
<pre>
pki --issue --cacert demoCaCert.pem --cakey demoCaKey.pem --type pub --in ak_rsa_pub.der --dn "C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com" --san raspi5.example.com --lifetime 3651 > raspi5_ak_rsa_Cert.der
</pre>
h2. Issue an ECC AIK Certificate
Based on the ECC AK public key exported from the TPM, the following *pki* command generates an Attestation Identity Key (AIK) certificate signed by the Demo CA
<pre>
pki --issue --cacert demoCaCert.pem --cakey demoCaKey.pem --type pub --in ak_ecc_pub.der --dn "C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com" --san raspi5.example.com --lifetime 3651 > raspi5_ak_ecc_Cert.der
</pre>
Many certification authorities issue certificates based on PKCS#10 certificate requests. This approach is also possible. First a certificate request is generated on the host the TPM resides on
<pre>
pki --req --keyid 0x81010004 --dn "C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com" --san raspi5.example.com > ak_ecc_req.der
</pre>
When you are prompted for a smartcard PIN just press <enter> since this TPM private key is not protected by a PIN. In a second step the CA issues the AIK certificate based on the PKCS#10 certificate request
<pre>
pki --issue --cacert demoCaCert.pem --cakey demoCaKey.pem --type pkcs10 --in ak_ecc_req.der --lifetime 3651 > raspi5_ak_ecc_Cert.der
</pre>
h2. Store the ECC AIK Certificate in the NV RAM of the TPM
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
<pre>
ls -l raspi5_ak_ecc_Cert.der
-rw-r--r-- 1 root root 449 Feb 17 2017 raspi5_ak_ecc_Cert.der
</pre>
We then define a memory location with a size of 449 bytes that can be accessed via the handle 0x01800004 which is also called the NV index
<pre>
tpm2_nvdefine -x 0x01800004 -a 0x40000001 -s 449 -t 0x2000A
</pre>
Then we write the certificate file to the NV RAM destination
<pre>
tpm2_nvwrite -x 0x01800004 -a 0x40000001 raspi5_ak_ecc_Cert.der
</pre>
h2. List of NV Indexes
A list of all defined NV indexes can be obtained with
tpm2_nvlist
<pre>
2 NV indexes defined.
0. NV Index: 0x1500015
{
Hash algorithm(nameAlg):4
The Index attributes(attributes):0x44040004
The size of the data area(dataSize):4
}
1. NV Index: 0x1800004
{
Hash algorithm(nameAlg):11
The Index attributes(attributes):0x2002000a
The size of the data area(dataSize):449
}
</pre>
h2. Remove NV Index
The memory assigned to a given NV index can be released with the command
<pre>
tpm2_nvrelease -x 0x01800001 -a 0x40000001
</pre>
h2. Configure TPM Private Key Access via VICI Interface
Configuration of TPM private key access as tokens in the secrets section of *swanctl.conf*
secrets {
token_ak_rsa {
handle = 81010002
pin = 123456
}
token_ak_ecc {
handle = 81010004
}
}
Since the use of the RSA AK private key is password-protected, the PIN *123456* is added.
h2. Define IPsec Connection with RSA AK Client Key
This connection configuration in *swanctl.conf* uses the RSA AK certificate for client authentication
<pre>
connections {
rsa {
local_addrs = 10.10.0.105
remote_addrs = 10.10.0.104
local {
auth = pubkey
certs = raspi5_ak_rsa_Cert.der
}
remote {
auth = pubkey
id = raspi4.example.com
}
children {
rsa {
mode = transport
esp_proposals = aes128-sha256-curve25519
}
}
version = 2
proposals = aes128-sha256-curve25519
}
}
</pre>
h2. Define IPsec Connection with ECC AK Client Key
This connection configuration in *swanctl.conf* references the ECC AK certificate used for client authentication via its handle, i.e. the NV index
<pre>
connections {
ecc {
local_addrs = 10.10.0.105
remote_addrs = 10.10.0.104
local {
auth = pubkey
cert-tpm {
handle = 0x01800004
}
}
remote {
auth = pubkey
id = raspi4.example.com
}
children {
ecc {
mode = transport
esp_proposals = aes128-sha256-curve25519
}
}
version = 2
proposals = aes128-sha256-curve25519
}
}
</pre>
h2. Starting the strongSwan Daemon
<pre>
systemctl start strongswan-swanctl
</pre>
<pre>
Feb 19 10:52:01 raspi5 systemd[1]: Starting strongSwan IPsec IKEv1/IKEv2 daemon using swanctl...
Feb 19 10:52:01 raspi5 charon-systemd[21165]: loaded plugins: charon-systemd charon-systemd random nonce x509 constraints openssl pem pkcs1 pkcs8 pkcs12 pubkey mgf1 ntru curve25519 eap-identity eap-ttls eap-tnc tnc-tnccs tnc-imc tnccs-20 socket-default kernel-netlink vici tpm
Feb 19 10:52:01 raspi5 charon-systemd[21165]: spawning 16 worker threads
Feb 19 10:52:01 raspi5 charon-systemd[21165]: loaded certificate 'C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com'
Feb 19 10:52:01 raspi5 charon-systemd[21165]: loaded certificate 'C=US, O=TNC Demo, CN=TNC Demo CA'
</pre>
The RSA AK private key is attached to the *charon-systemd* daemon via the TPM 2.0 resource manager
<pre>
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 - manufacturer: IFX (SLB9670) rev: 01.16 2015
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 - algorithms: RSA SHA1 HMAC AES KEYEDHASH XOR SHA256 RSASSA RSAES RSAPSS OAEP ECDSA ECDH SM2 KDF1_SP800_56A KDF1_SP800_108 ECC SYMCIPHER CFB
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 - ECC curves: NIST_P256 BN_P256
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 via TSS2 v2 available
Feb 19 10:52:01 raspi5 charon-systemd[21165]: AIK signature algorithm is RSASSA with SHA256 hash
Feb 19 10:52:01 raspi5 charon-systemd[21165]: loaded RSA private key from token
F</pre>
The ECC AK private key is attached to the *charon-systemd* daemon via the TPM 2.0 resource manager
<pre>
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 - manufacturer: IFX (SLB9670) rev: 01.16 2015
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 - algorithms: RSA SHA1 HMAC AES KEYEDHASH XOR SHA256 RSASSA RSAES RSAPSS OAEP ECDSA ECDH SM2 KDF1_SP800_56A KDF1_SP800_108 ECC SYMCIPHER CFB
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 - ECC curves: NIST_P256 BN_P256
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 via TSS2 v2 available
Feb 19 10:52:02 raspi5 charon-systemd[21165]: AIK signature algorithm is ECDSA with SHA256 hash
Feb 19 10:52:02 raspi5 charon-systemd[21165]: loaded ECDSA private key from token
</pre>
The ECC AIK certificate is loaded by the *charon-systemd* daemon via the TPM 2.0 resource manager
<pre>
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 - manufacturer: IFX (SLB9670) rev: 01.16 2015
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 - algorithms: RSA SHA1 HMAC AES KEYEDHASH XOR SHA256 RSASSA RSAES RSAPSS OAEP ECDSA ECDH SM2 KDF1_SP800_56A KDF1_SP800_108 ECC SYMCIPHER CFB
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 - ECC curves: NIST_P256 BN_P256
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 via TSS2 v2 available
Feb 19 10:52:02 raspi5 charon-systemd[21165]: loaded certificate from TPM NV index 0x01800004
</pre>
The two connection definitions are received by the *charon-systemd* daemon from the *swanctl* command line tool via the VICI interface
<pre>
Feb 19 10:52:02 raspi5 charon-systemd[21165]: id not specified, defaulting to cert subject 'C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com'
Feb 19 10:52:02 raspi5 charon-systemd[21165]: added vici connection: rsa
Feb 19 10:52:02 raspi5 charon-systemd[21165]: id not specified, defaulting to cert subject 'C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com'
Feb 19 10:52:02 raspi5 charon-systemd[21165]: added vici connection: ecc
</pre>
The *swanctl* command line tool reports its actions
<pre>
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded certificate from '/etc/swanctl/x509/raspi5_ak_rsa_Cert.der'
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded certificate from '/etc/swanctl/x509ca/demoCaCert.pem'
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded key token_ak_rsa from token [keyid: f49e857dde4e67f5fb870398673f207cf33f2b66]
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded key token_ak_ecc from token [keyid: c70e63f87f6ff65500e5057f5a3e6b6ce7d2d513]
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded connection 'rsa'
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded connection 'ecc'
Feb 19 10:52:02 raspi5 swanctl[21183]: successfully loaded 2 connections, 0 unloaded
</pre>
<pre>
Feb 19 10:52:02 raspi5 systemd[1]: Started strongSwan IPsec IKEv1/IKEv2 daemon using swanctl.
</pre>
The following *swanctl* command shows the two loaded connections
<pre>
swanctl --list-conns
</pre>
<pre>
rsa: IKEv2, reauthentication every 10800s, no rekeying
local: 10.10.0.105
remote: 10.10.0.104
local public key authentication:
id: C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com
certs: C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com
remote public key authentication:
id: raspi4.example.com
rsa: TRANSPORT, rekeying every 3600s or 300000000 bytes or 500000 packets
local: dynamic
remote: dynamic
</pre>
<pre>
ecc: IKEv2, reauthentication every 10800s, no rekeying
local: 10.10.0.105
remote: 10.10.0.104
local public key authentication:
id: C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com
certs: C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com
remote public key authentication:
id: raspi4.example.com
ecc: TRANSPORT, rekeying every 3600s or 300000000 bytes or 500000 packets
local: dynamic
remote: dynamic
</pre>
The loaded certificates can also be displayed
<pre>
swanctl --list-certs
</pre>
You can clearly see that the connection between the AK certificates and their matching AK private key has been established (..., has private key)
<pre>
List of X.509 End Entity Certificates
subject: "C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com"
issuer: "C=US, O=TNC Demo, CN=TNC Demo CA"
validity: not before Feb 19 09:33:43 2017, ok
not after Aug 29 10:33:43 2026, ok (expires in 3477 days)
serial: 11:57:33:3e:2a:8e:8a:32
altNames: raspi5.example.com
authkeyId: 21:02:7e:2d:de:8b:77:48:75:de:56:2f:b5:d4:62:ec:c3:09:15:f2
subjkeyId: f4:9e:85:7d:de:4e:67:f5:fb:87:03:98:67:3f:20:7c:f3:3f:2b:66
pubkey: RSA 2048 bits, has private key
keyid: 71:21:f5:d4:7e:59:4a:88:16:ca:57:85:98:3d:36:a7:b1:d5:75:fa
subjkey: f4:9e:85:7d:de:4e:67:f5:fb:87:03:98:67:3f:20:7c:f3:3f:2b:66
subject: "C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com"
issuer: "C=US, O=TNC Demo, CN=TNC Demo CA"
validity: not before Feb 17 23:17:19 2017, ok
not after Aug 30 00:17:19 2026, ok (expires in 3478 days)
serial: 52:9d:3e:42:6f:71:63:3d
altNames: raspi5.example.com
authkeyId: 21:02:7e:2d:de:8b:77:48:75:de:56:2f:b5:d4:62:ec:c3:09:15:f2
subjkeyId: c7:0e:63:f8:7f:6f:f6:55:00:e5:05:7f:5a:3e:6b:6c:e7:d2:d5:13
pubkey: ECDSA 256 bits, has private key
keyid: 71:49:7c:42:41:e7:c6:81:bc:31:73:f0:0f:7e:4a:e1:2d:53:00:38
subjkey: c7:0e:63:f8:7f:6f:f6:55:00:e5:05:7f:5a:3e:6b:6c:e7:d2:d5:13
</pre>
<pre>
List of X.509 CA Certificates
subject: "C=US, O=TNC Demo, CN=TNC Demo CA"
issuer: "C=US, O=TNC Demo, CN=TNC Demo CA"
validity: not before Aug 31 10:29:27 2016, ok
not after Aug 31 10:29:27 2026, ok (expires in 3479 days)
serial: 02:c8:85:e1:ef:fa:8f:20
flags: CA CRLSign self-signed
subjkeyId: 21:02:7e:2d:de:8b:77:48:75:de:56:2f:b5:d4:62:ec:c3:09:15:f2
pubkey: ECDSA 256 bits
keyid: a1:b5:e0:29:d0:4c:a7:62:bd:ca:a3:b4:af:18:42:2c:4a:01:55:9a
subjkey: 21:02:7e:2d:de:8b:77:48:75:de:56:2f:b5:d4:62:ec:c3:09:15:f2
</pre>
h2. IKEv2 Authentication with RSA AIK Certificate
With the following *swanctl* command the "rsa" connection is established
<pre>
swanctl --initiate --child rsa
</pre>
<pre>
Feb 19 10:52:21 raspi5 charon-systemd[21165]: vici initiate 'rsa'
Feb 19 10:52:21 raspi5 charon-systemd[21165]: initiating IKE_SA rsa[1] to 10.10.0.104
Feb 19 10:52:21 raspi5 charon-systemd[21165]: generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) V ]
Feb 19 10:52:21 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[500] to 10.10.0.104[500] (1257 bytes)
Feb 19 10:52:21 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[500] to 10.10.0.105[500] (1259 bytes)
Feb 19 10:52:21 raspi5 charon-systemd[21165]: parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) CERTREQ N(HASH_ALG) V ]
Feb 19 10:52:21 raspi5 charon-systemd[21165]: received strongSwan vendor ID
Feb 19 10:52:21 raspi5 charon-systemd[21165]: received cert request for "C=US, O=TNC Demo, CN=TNC Demo CA"
Feb 19 10:52:21 raspi5 charon-systemd[21165]: sending cert request for "C=US, O=TNC Demo, CN=TNC Demo CA"
</pre>
The RSA AK private key stored in the TPM 2.0 is used to generate an *RSA_EMSA_PKCS1_SHA2_256* signature which is sent in the AUTH payload of the IKE_AUTH request. The matching client certificate is sent int the CERT payload.
<pre>
Feb 19 10:52:24 raspi5 charon-systemd[21165]: authentication of 'C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com' (myself) with RSA_EMSA_PKCS1_SHA2_256 successful
Feb 19 10:52:24 raspi5 charon-systemd[21165]: sending end entity cert "C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com"
</pre>
<pre>
Feb 19 10:52:24 raspi5 charon-systemd[21165]: establishing CHILD_SA rsa
Feb 19 10:52:24 raspi5 charon-systemd[21165]: generating IKE_AUTH request 1 [ IDi CERT CERTREQ IDr AUTH N(USE_TRANSP) SA TSi TSr N(MOBIKE_SUP) N(ADD_6_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
Feb 19 10:52:24 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[4500] to 10.10.0.104[4500] (1296 bytes)
Feb 19 10:52:24 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[4500] to 10.10.0.105[4500] (752 bytes)
Feb 19 10:52:24 raspi5 charon-systemd[21165]: parsed IKE_AUTH response 1 [ IDr CERT AUTH N(USE_TRANSP) SA TSi TSr N(AUTH_LFT) N(MOBIKE_SUP) N(NO_ADD_ADDR) ]
Feb 19 10:52:24 raspi5 charon-systemd[21165]: received end entity cert "C=US, O=TNC Demo, CN=raspi4.example.com"
Feb 19 10:52:24 raspi5 charon-systemd[21165]: using certificate "C=US, O=TNC Demo, CN=raspi4.example.com"
Feb 19 10:52:24 raspi5 charon-systemd[21165]: using trusted ca certificate "C=US, O=TNC Demo, CN=TNC Demo CA"
Feb 19 10:52:24 raspi5 charon-systemd[21165]: reached self-signed root ca with a path length of 0
Feb 19 10:52:24 raspi5 charon-systemd[21165]: authentication of 'raspi4.example.com' with ECDSA_WITH_SHA256_DER successful
Feb 19 10:52:24 raspi5 charon-systemd[21165]: IKE_SA rsa[1] established between 10.10.0.105[C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com]...10.10.0.104[raspi4.example.com]
Feb 19 10:52:24 raspi5 charon-systemd[21165]: scheduling reauthentication in 10507s
Feb 19 10:52:24 raspi5 charon-systemd[21165]: maximum IKE_SA lifetime 11587s
Feb 19 10:52:24 raspi5 charon-systemd[21165]: CHILD_SA rsa{1} established with SPIs c23deb9d_i ce48d08e_o and TS 10.10.0.105/32 === 10.10.0.104/32
Feb 19 10:52:24 raspi5 charon-systemd[21165]: received AUTH_LIFETIME of 10103s, scheduling reauthentication in 9023s
Feb 19 10:52:24 raspi5 charon-systemd[21165]: peer supports MOBIKE
</pre>
The following *swanctl* command shows the established IPsec connection
<pre>
swanctl --list-sas
</pre>
<pre>
rsa: #1, ESTABLISHED, IKEv2, 7ba3b4d06c051ecb_i* 14e1769a8aeb7f28_r
local 'C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com' @ 10.10.0.105[4500]
remote 'raspi4.example.com' @ 10.10.0.104[4500]
AES_CBC-128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/CURVE_25519
established 252s ago, reauth in 8771s
rsa: #1, reqid 1, INSTALLED, TRANSPORT, ESP:AES_CBC-128/HMAC_SHA2_256_128
installed 252s ago, rekeying in 3258s, expires in 3708s
in c23deb9d, 640 bytes, 10 packets, 3s ago
out ce48d08e, 640 bytes, 10 packets, 3s ago
local 10.10.0.105/32
remote 10.10.0.104/32
</pre>
With this *swanctl* command the "rsa" connection is terminated
<pre>
swanctl --terminate --ike rsa
</pre>
<pre>
Feb 19 10:59:16 raspi5 charon-systemd[21165]: vici terminate IKE_SA 'rsa'
Feb 19 10:59:16 raspi5 charon-systemd[21165]: deleting IKE_SA rsa[1] between 10.10.0.105[C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com]...10.10.0.104[raspi4.example.com]
Feb 19 10:59:16 raspi5 charon-systemd[21165]: sending DELETE for IKE_SA rsa[1]
Feb 19 10:59:16 raspi5 charon-systemd[21165]: generating INFORMATIONAL request 2 [ D ]
Feb 19 10:59:16 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[4500] to 10.10.0.104[4500] (80 bytes)
Feb 19 10:59:16 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[4500] to 10.10.0.105[4500] (80 bytes)
Feb 19 10:59:16 raspi5 charon-systemd[21165]: parsed INFORMATIONAL response 2 [ ]
Feb 19 10:59:16 raspi5 charon-systemd[21165]: IKE_SA deleted
</pre>
h2. IKEv2 Authentication with ECC AIK Certificate
Next we initiate the "ecc" connection
<pre>
swanctl --initiate --child ecc
</pre>
<pre>
Feb 19 11:00:32 raspi5 charon-systemd[21165]: vici initiate 'ecc'
Feb 19 11:00:32 raspi5 charon-systemd[21165]: initiating IKE_SA ecc[2] to 10.10.0.104
Feb 19 11:00:32 raspi5 charon-systemd[21165]: generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) V ]
Feb 19 11:00:32 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[500] to 10.10.0.104[500] (1257 bytes)
Feb 19 11:00:32 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[500] to 10.10.0.105[500] (1259 bytes)
Feb 19 11:00:32 raspi5 charon-systemd[21165]: parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) CERTREQ N(HASH_ALG) V ]
Feb 19 11:00:32 raspi5 charon-systemd[21165]: received strongSwan vendor ID
Feb 19 11:00:32 raspi5 charon-systemd[21165]: received cert request for "C=US, O=TNC Demo, CN=TNC Demo CA"
Feb 19 11:00:32 raspi5 charon-systemd[21165]: sending cert request for "C=US, O=TNC Demo, CN=TNC Demo CA"
</pre>
The ECC AK private key stored in the TPM 2.0 is used to generate an *ECDSA_WITH_SHA256_DER* signature which is sent in the AUTH payload of the IKE_AUTH request. The matching client certificate is sent int the CERT payload.
<pre>
Feb 19 11:00:34 raspi5 charon-systemd[21165]: authentication of 'C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com' (myself) with ECDSA_WITH_SHA256_DER successful
Feb 19 11:00:34 raspi5 charon-systemd[21165]: sending end entity cert "C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com"
</pre>
<pre>
Feb 19 11:00:34 raspi5 charon-systemd[21165]: establishing CHILD_SA ecc
Feb 19 11:00:34 raspi5 charon-systemd[21165]: generating IKE_AUTH request 1 [ IDi CERT CERTREQ IDr AUTH N(USE_TRANSP) SA TSi TSr N(MOBIKE_SUP) N(ADD_6_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
Feb 19 11:00:34 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[4500] to 10.10.0.104[4500] (912 bytes)
Feb 19 11:00:34 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[4500] to 10.10.0.105[4500] (752 bytes)
Feb 19 11:00:34 raspi5 charon-systemd[21165]: parsed IKE_AUTH response 1 [ IDr CERT AUTH N(USE_TRANSP) SA TSi TSr N(AUTH_LFT) N(MOBIKE_SUP) N(NO_ADD_ADDR) ]
Feb 19 11:00:34 raspi5 charon-systemd[21165]: received end entity cert "C=US, O=TNC Demo, CN=raspi4.example.com"
Feb 19 11:00:34 raspi5 charon-systemd[21165]: using certificate "C=US, O=TNC Demo, CN=raspi4.example.com"
Feb 19 11:00:34 raspi5 charon-systemd[21165]: using trusted ca certificate "C=US, O=TNC Demo, CN=TNC Demo CA"
Feb 19 11:00:34 raspi5 charon-systemd[21165]: reached self-signed root ca with a path length of 0
Feb 19 11:00:34 raspi5 charon-systemd[21165]: authentication of 'raspi4.example.com' with ECDSA_WITH_SHA256_DER successful
Feb 19 11:00:34 raspi5 charon-systemd[21165]: IKE_SA ecc[2] established between 10.10.0.105[C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com]...10.10.0.104[raspi4.example.com]
Feb 19 11:00:34 raspi5 charon-systemd[21165]: scheduling reauthentication in 10180s
Feb 19 11:00:34 raspi5 charon-systemd[21165]: maximum IKE_SA lifetime 11260s
Feb 19 11:00:34 raspi5 charon-systemd[21165]: CHILD_SA ecc{2} established with SPIs c2c16cd0_i c47ea6f6_o and TS 10.10.0.105/32 === 10.10.0.104/32
Feb 19 11:00:34 raspi5 charon-systemd[21165]: received AUTH_LIFETIME of 9880s, scheduling reauthentication in 8800s
Feb 19 11:00:34 raspi5 charon-systemd[21165]: peer supports MOBIKE
</pre>
The establed IKE and CHILD SAs are displayed
<pre>
swanctl --list-sas
</pre>
<pre>
ecc: #2, ESTABLISHED, IKEv2, b7f2652777b0996a_i* 12282b5964ff0658_r
local 'C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com' @ 10.10.0.105[4500]
remote 'raspi4.example.com' @ 10.10.0.104[4500]
AES_CBC-128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/CURVE_25519
established 126s ago, reauth in 8674s
ecc: #2, reqid 2, INSTALLED, TRANSPORT, ESP:AES_CBC-128/HMAC_SHA2_256_128
installed 126s ago, rekeying in 3252s, expires in 3834s
in c2c16cd0, 320 bytes, 5 packets, 2s ago
out c47ea6f6, 320 bytes, 5 packets, 2s ago
local 10.10.0.105/32
remote 10.10.0.104/32
</pre>
The IKE and CHILD SAs are terminated
<pre>
swanctl --terminate --ike ecc
</pre>
<pre>
Feb 19 11:04:32 raspi5 charon-systemd[21165]: vici terminate IKE_SA 'ecc'
Feb 19 11:04:32 raspi5 charon-systemd[21165]: deleting IKE_SA ecc[2] between 10.10.0.105[C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com]...10.10.0.104[raspi4.example.com]
Feb 19 11:04:32 raspi5 charon-systemd[21165]: sending DELETE for IKE_SA ecc[2]
Feb 19 11:04:32 raspi5 charon-systemd[21165]: generating INFORMATIONAL request 2 [ D ]
Feb 19 11:04:32 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[4500] to 10.10.0.104[4500] (80 bytes)
Feb 19 11:04:32 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[4500] to 10.10.0.105[4500] (80 bytes)
Feb 19 11:04:32 raspi5 charon-systemd[21165]: parsed INFORMATIONAL response 2 [ ]
Feb 19 11:04:32 raspi5 charon-systemd[21165]: IKE_SA deleted
</pre>
{{>toc}}
h2. Connect to a TPM 2.0 Device
h3. Install the tpm2-tss Software Stack and the tpm2-tools Command Set
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":https://trustedcomputinggroup.org/resource/tcg-tss-2-0-system-level-api-sapi-specification/ is needed. An excellent open source "tpm2-tss":https://github.com/tpm2-software/tpm2-tss library is available from the "tpm2-software":https://github.com/tpm2-software project which also offers a set of "tpm2-tools":https://github.com/tpm2-software/tpm2-tools which itself uses the "TCG TSS 2.0 Enhanced System Level API":https://trustedcomputinggroup.org/resource/tcg-tss-2-0-enhanced-system-api-esapi-specification/.
When using the latest *strongswan-5.9.1* version with a *Linux 5.4* kernel or newer, we recommend these latest versions:
* *tpm2-tss* version 3.0.3: https://github.com/tpm2-software/tpm2-tss/releases/tag/3.0.3
* *tpm2-tools* version 5.0: https://github.com/tpm2-software/tpm2-tools/releases/tag/5.0
Support for earlier strongSwan versions and Linux kernels can be found [[TpmPluginOld|here]].
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:
<pre>
tpm2_getcap handles-persistent
- 0x81000001
- 0x81000002
- 0x81010001
</pre>
A manual showing all *tpm2-tools* functions with their arguments can be found "here":https://github.com/tpm2-software/tpm2-tools/tree/5.0/man. 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:
<pre>
sudo usermod -a -G tss <username>
</pre>
h3. 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 [[IpsecPki|pki]] tool we can now list the persistent key stored under the handle *0x81010001*
<pre>
pki --print --type priv --keyid 0x81010001 --debug 2
</pre>
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:
<pre>
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
</pre>
Apparently the analyzed persistent key can be used for encryption only because no signature algorithm is defined:
<pre>
TPM 2.0 via TSS2 v2 available
signature algorithm is NULL with ERROR hash
</pre>
Debug level 2 shows that [[IpsecPki|pki]] extracts the public key from the TPM and converts it into a standard PKCS#1 format:
<pre>
L0 - subjectPublicKeyInfo:
L1 - algorithm:
L2 - algorithmIdentifier:
L3 - algorithm:
'rsaEncryption'
L1 - subjectPublicKey:
-- > --
L0 - RSAPublicKey:
L1 - modulus:
L1 - publicExponent:
-- < --
</pre>
At the end of the output the fingerprint of the 2048 bit RSA key is listed:
<pre>
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
</pre>
h2. Derive Persistent Endorsement Keys
h3. RSA Endorsement Key
The "tpm2_createek":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_createek.1.md 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":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_getcap.1.md command we can check that the newly derived Endorsement Key has been persisted in the NV RAM
<pre>
tpm2_getcap handles-persistent
- 0x81000001
- 0x81000002
- 0x81010001
- 0x81010002
</pre>
Listing the key properties shows that the 2048 bit Endorsement Key already exists under the handle *0x81010001* analyzed in the previous section
<pre>
pki --print --type priv --keyid 0x81010002
TPM 2.0 via TSS2 v2 available
signature algorithm is NULL with ERROR hash
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
</pre>
h3. Delete Persisted Keys
We therefore delete the duplicate key with the following "tpm2_evictcontrol":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_evictcontrol.1.md command
<pre>
tpm2_evictcontrol -c 0x81010002
persistent-handle: 0x81010002
action: evicted
</pre>
The key removal can be verified with
<pre>
tpm2_getcap handles-persistent
- 0x81000001
- 0x81000002
- 0x81010001
</pre>
h3. ECC Endorsement Key
Again using the "tpm2_createek":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_createek.1.md 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
<pre>
pki --print --type priv --keyid 0x81010002
TPM 2.0 via TSS2 v2 available
signature algorithm is NULL with ERROR hash
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
</pre>
h2. Endorsement Key Certificates
h3. Fetched via URL
Endorsement Key certificates issued for Intel firmware TPMs can be automatically downloaded from an Intel web server using the "tpm2_getcertificate":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_getekcertificate.1.md 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 [[IpsecPki|pki]] tool we can list the downloaded EK certificate belonging to the ECC key:
<pre>
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
</pre>
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":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_readpublic.1.md 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
<pre>
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
</pre>
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.
h3. 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:
<pre>
tpm2_getcap handles-nv-index
- 0x1410001
- 0x1410002
- 0x1410004
- 0x1880001
- 0x1880011
- 0x1C00002
- 0x1C0000A
- 0x1C00012
- 0x1C10102
- 0x1C10103
- 0x1C10104
- 0x1C101C0
</pre>
Using the "tpm2_nvreadpublic":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_nvreadpublic.1.md command we can look for large data objects which are prime candidates for X.509 certificates:
<pre>
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
...
</pre>
We can use [[IpsecPki|pki]] the pki tool to directly list the properties of the EK certificates:
<pre>
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
</pre>
<pre>
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
</pre>
or we can first retrieve the binary certificate blob from the NV RAM using the "tpm2_nvread":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_nvread.1.md command:
tpm2_nvread 0x01c00012 -C o -o ek_ecc384.crt
and then list the properties of the EK certificate file:
<pre>
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
</pre>
We see that the STMicroelectronics device apparently devices supports 384 bit ECC keys
<pre>
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
</pre>
keys.
h2. Generate Persistent Attestation Keys
h3. RSA Attestation Key
A 2048 bit RSA Attestation Key (AK) bound to the EK with handle *0x81010001* can be created with the "tpm2_createak":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_createak.1.md 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":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_evictcontrol.1.md command:
<pre>
tpm2_evictcontrol -C o -c ak_rsa.ctx 0x81010003
persistent-handle: 0x81010003
action: persisted
</pre>
The properties of the RSA AK which is a signing key can be displayed with the command
<pre>
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
</pre>
h3. 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":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_createak.1.md 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":https://github.com/tpm2-software/tpm2-tools/blob/5.0/man/tpm2_evictcontrol.1.md command:
<pre>
tpm2_evictcontrol -C o -c ak_ecc.ctx 0x81010004
persistent-handle: 0x81010004
action: persisted
</pre>
The properties of the ECC AK which is a signing key can be displayed with the command
<pre>
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
</pre>
h2. Generate PKCS#10 Certificate Requests
h3. RSA Certificate Request
<pre>
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>
</pre>
<pre>
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
</pre>
h3. ECC Certificate Request
<pre>
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>
</pre>
<pre>
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
</pre>
h2. Create a Demo Root CA
The following *pki* command creates a 256 bit ECDSA private key for the Demo CA
<pre>
pki --gen --type ecdsa --size 256 --outform pem > demoCaKey.pem
</pre>
Next we create a self-signed Root CA certificate
<pre>
pki --self --ca --type ecdsa --in demoCaKey.pem --dn="C=US, O=TNC Demo, CN=TNC Demo CA" --lifetime 3652 --outform pem > demoCaCert.pem
</pre>
h2. Issue an RSA AIK Certificate
Based on the RSA AK public key exported from the TPM, the following *pki* command generates an Attestation Identity Key (AIK) certificate signed by the Demo CA
<pre>
pki --issue --cacert demoCaCert.pem --cakey demoCaKey.pem --type pub --in ak_rsa_pub.der --dn "C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com" --san raspi5.example.com --lifetime 3651 > raspi5_ak_rsa_Cert.der
</pre>
h2. Issue an ECC AIK Certificate
Based on the ECC AK public key exported from the TPM, the following *pki* command generates an Attestation Identity Key (AIK) certificate signed by the Demo CA
<pre>
pki --issue --cacert demoCaCert.pem --cakey demoCaKey.pem --type pub --in ak_ecc_pub.der --dn "C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com" --san raspi5.example.com --lifetime 3651 > raspi5_ak_ecc_Cert.der
</pre>
Many certification authorities issue certificates based on PKCS#10 certificate requests. This approach is also possible. First a certificate request is generated on the host the TPM resides on
<pre>
pki --req --keyid 0x81010004 --dn "C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com" --san raspi5.example.com > ak_ecc_req.der
</pre>
When you are prompted for a smartcard PIN just press <enter> since this TPM private key is not protected by a PIN. In a second step the CA issues the AIK certificate based on the PKCS#10 certificate request
<pre>
pki --issue --cacert demoCaCert.pem --cakey demoCaKey.pem --type pkcs10 --in ak_ecc_req.der --lifetime 3651 > raspi5_ak_ecc_Cert.der
</pre>
h2. Store the ECC AIK Certificate in the NV RAM of the TPM
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
<pre>
ls -l raspi5_ak_ecc_Cert.der
-rw-r--r-- 1 root root 449 Feb 17 2017 raspi5_ak_ecc_Cert.der
</pre>
We then define a memory location with a size of 449 bytes that can be accessed via the handle 0x01800004 which is also called the NV index
<pre>
tpm2_nvdefine -x 0x01800004 -a 0x40000001 -s 449 -t 0x2000A
</pre>
Then we write the certificate file to the NV RAM destination
<pre>
tpm2_nvwrite -x 0x01800004 -a 0x40000001 raspi5_ak_ecc_Cert.der
</pre>
h2. List of NV Indexes
A list of all defined NV indexes can be obtained with
tpm2_nvlist
<pre>
2 NV indexes defined.
0. NV Index: 0x1500015
{
Hash algorithm(nameAlg):4
The Index attributes(attributes):0x44040004
The size of the data area(dataSize):4
}
1. NV Index: 0x1800004
{
Hash algorithm(nameAlg):11
The Index attributes(attributes):0x2002000a
The size of the data area(dataSize):449
}
</pre>
h2. Remove NV Index
The memory assigned to a given NV index can be released with the command
<pre>
tpm2_nvrelease -x 0x01800001 -a 0x40000001
</pre>
h2. Configure TPM Private Key Access via VICI Interface
Configuration of TPM private key access as tokens in the secrets section of *swanctl.conf*
secrets {
token_ak_rsa {
handle = 81010002
pin = 123456
}
token_ak_ecc {
handle = 81010004
}
}
Since the use of the RSA AK private key is password-protected, the PIN *123456* is added.
h2. Define IPsec Connection with RSA AK Client Key
This connection configuration in *swanctl.conf* uses the RSA AK certificate for client authentication
<pre>
connections {
rsa {
local_addrs = 10.10.0.105
remote_addrs = 10.10.0.104
local {
auth = pubkey
certs = raspi5_ak_rsa_Cert.der
}
remote {
auth = pubkey
id = raspi4.example.com
}
children {
rsa {
mode = transport
esp_proposals = aes128-sha256-curve25519
}
}
version = 2
proposals = aes128-sha256-curve25519
}
}
</pre>
h2. Define IPsec Connection with ECC AK Client Key
This connection configuration in *swanctl.conf* references the ECC AK certificate used for client authentication via its handle, i.e. the NV index
<pre>
connections {
ecc {
local_addrs = 10.10.0.105
remote_addrs = 10.10.0.104
local {
auth = pubkey
cert-tpm {
handle = 0x01800004
}
}
remote {
auth = pubkey
id = raspi4.example.com
}
children {
ecc {
mode = transport
esp_proposals = aes128-sha256-curve25519
}
}
version = 2
proposals = aes128-sha256-curve25519
}
}
</pre>
h2. Starting the strongSwan Daemon
<pre>
systemctl start strongswan-swanctl
</pre>
<pre>
Feb 19 10:52:01 raspi5 systemd[1]: Starting strongSwan IPsec IKEv1/IKEv2 daemon using swanctl...
Feb 19 10:52:01 raspi5 charon-systemd[21165]: loaded plugins: charon-systemd charon-systemd random nonce x509 constraints openssl pem pkcs1 pkcs8 pkcs12 pubkey mgf1 ntru curve25519 eap-identity eap-ttls eap-tnc tnc-tnccs tnc-imc tnccs-20 socket-default kernel-netlink vici tpm
Feb 19 10:52:01 raspi5 charon-systemd[21165]: spawning 16 worker threads
Feb 19 10:52:01 raspi5 charon-systemd[21165]: loaded certificate 'C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com'
Feb 19 10:52:01 raspi5 charon-systemd[21165]: loaded certificate 'C=US, O=TNC Demo, CN=TNC Demo CA'
</pre>
The RSA AK private key is attached to the *charon-systemd* daemon via the TPM 2.0 resource manager
<pre>
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 - manufacturer: IFX (SLB9670) rev: 01.16 2015
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 - algorithms: RSA SHA1 HMAC AES KEYEDHASH XOR SHA256 RSASSA RSAES RSAPSS OAEP ECDSA ECDH SM2 KDF1_SP800_56A KDF1_SP800_108 ECC SYMCIPHER CFB
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 - ECC curves: NIST_P256 BN_P256
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 via TSS2 v2 available
Feb 19 10:52:01 raspi5 charon-systemd[21165]: AIK signature algorithm is RSASSA with SHA256 hash
Feb 19 10:52:01 raspi5 charon-systemd[21165]: loaded RSA private key from token
F</pre>
The ECC AK private key is attached to the *charon-systemd* daemon via the TPM 2.0 resource manager
<pre>
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 - manufacturer: IFX (SLB9670) rev: 01.16 2015
Feb 19 10:52:01 raspi5 charon-systemd[21165]: TPM 2.0 - algorithms: RSA SHA1 HMAC AES KEYEDHASH XOR SHA256 RSASSA RSAES RSAPSS OAEP ECDSA ECDH SM2 KDF1_SP800_56A KDF1_SP800_108 ECC SYMCIPHER CFB
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 - ECC curves: NIST_P256 BN_P256
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 via TSS2 v2 available
Feb 19 10:52:02 raspi5 charon-systemd[21165]: AIK signature algorithm is ECDSA with SHA256 hash
Feb 19 10:52:02 raspi5 charon-systemd[21165]: loaded ECDSA private key from token
</pre>
The ECC AIK certificate is loaded by the *charon-systemd* daemon via the TPM 2.0 resource manager
<pre>
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 - manufacturer: IFX (SLB9670) rev: 01.16 2015
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 - algorithms: RSA SHA1 HMAC AES KEYEDHASH XOR SHA256 RSASSA RSAES RSAPSS OAEP ECDSA ECDH SM2 KDF1_SP800_56A KDF1_SP800_108 ECC SYMCIPHER CFB
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 - ECC curves: NIST_P256 BN_P256
Feb 19 10:52:02 raspi5 charon-systemd[21165]: TPM 2.0 via TSS2 v2 available
Feb 19 10:52:02 raspi5 charon-systemd[21165]: loaded certificate from TPM NV index 0x01800004
</pre>
The two connection definitions are received by the *charon-systemd* daemon from the *swanctl* command line tool via the VICI interface
<pre>
Feb 19 10:52:02 raspi5 charon-systemd[21165]: id not specified, defaulting to cert subject 'C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com'
Feb 19 10:52:02 raspi5 charon-systemd[21165]: added vici connection: rsa
Feb 19 10:52:02 raspi5 charon-systemd[21165]: id not specified, defaulting to cert subject 'C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com'
Feb 19 10:52:02 raspi5 charon-systemd[21165]: added vici connection: ecc
</pre>
The *swanctl* command line tool reports its actions
<pre>
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded certificate from '/etc/swanctl/x509/raspi5_ak_rsa_Cert.der'
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded certificate from '/etc/swanctl/x509ca/demoCaCert.pem'
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded key token_ak_rsa from token [keyid: f49e857dde4e67f5fb870398673f207cf33f2b66]
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded key token_ak_ecc from token [keyid: c70e63f87f6ff65500e5057f5a3e6b6ce7d2d513]
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded connection 'rsa'
Feb 19 10:52:02 raspi5 swanctl[21183]: loaded connection 'ecc'
Feb 19 10:52:02 raspi5 swanctl[21183]: successfully loaded 2 connections, 0 unloaded
</pre>
<pre>
Feb 19 10:52:02 raspi5 systemd[1]: Started strongSwan IPsec IKEv1/IKEv2 daemon using swanctl.
</pre>
The following *swanctl* command shows the two loaded connections
<pre>
swanctl --list-conns
</pre>
<pre>
rsa: IKEv2, reauthentication every 10800s, no rekeying
local: 10.10.0.105
remote: 10.10.0.104
local public key authentication:
id: C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com
certs: C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com
remote public key authentication:
id: raspi4.example.com
rsa: TRANSPORT, rekeying every 3600s or 300000000 bytes or 500000 packets
local: dynamic
remote: dynamic
</pre>
<pre>
ecc: IKEv2, reauthentication every 10800s, no rekeying
local: 10.10.0.105
remote: 10.10.0.104
local public key authentication:
id: C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com
certs: C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com
remote public key authentication:
id: raspi4.example.com
ecc: TRANSPORT, rekeying every 3600s or 300000000 bytes or 500000 packets
local: dynamic
remote: dynamic
</pre>
The loaded certificates can also be displayed
<pre>
swanctl --list-certs
</pre>
You can clearly see that the connection between the AK certificates and their matching AK private key has been established (..., has private key)
<pre>
List of X.509 End Entity Certificates
subject: "C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com"
issuer: "C=US, O=TNC Demo, CN=TNC Demo CA"
validity: not before Feb 19 09:33:43 2017, ok
not after Aug 29 10:33:43 2026, ok (expires in 3477 days)
serial: 11:57:33:3e:2a:8e:8a:32
altNames: raspi5.example.com
authkeyId: 21:02:7e:2d:de:8b:77:48:75:de:56:2f:b5:d4:62:ec:c3:09:15:f2
subjkeyId: f4:9e:85:7d:de:4e:67:f5:fb:87:03:98:67:3f:20:7c:f3:3f:2b:66
pubkey: RSA 2048 bits, has private key
keyid: 71:21:f5:d4:7e:59:4a:88:16:ca:57:85:98:3d:36:a7:b1:d5:75:fa
subjkey: f4:9e:85:7d:de:4e:67:f5:fb:87:03:98:67:3f:20:7c:f3:3f:2b:66
subject: "C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com"
issuer: "C=US, O=TNC Demo, CN=TNC Demo CA"
validity: not before Feb 17 23:17:19 2017, ok
not after Aug 30 00:17:19 2026, ok (expires in 3478 days)
serial: 52:9d:3e:42:6f:71:63:3d
altNames: raspi5.example.com
authkeyId: 21:02:7e:2d:de:8b:77:48:75:de:56:2f:b5:d4:62:ec:c3:09:15:f2
subjkeyId: c7:0e:63:f8:7f:6f:f6:55:00:e5:05:7f:5a:3e:6b:6c:e7:d2:d5:13
pubkey: ECDSA 256 bits, has private key
keyid: 71:49:7c:42:41:e7:c6:81:bc:31:73:f0:0f:7e:4a:e1:2d:53:00:38
subjkey: c7:0e:63:f8:7f:6f:f6:55:00:e5:05:7f:5a:3e:6b:6c:e7:d2:d5:13
</pre>
<pre>
List of X.509 CA Certificates
subject: "C=US, O=TNC Demo, CN=TNC Demo CA"
issuer: "C=US, O=TNC Demo, CN=TNC Demo CA"
validity: not before Aug 31 10:29:27 2016, ok
not after Aug 31 10:29:27 2026, ok (expires in 3479 days)
serial: 02:c8:85:e1:ef:fa:8f:20
flags: CA CRLSign self-signed
subjkeyId: 21:02:7e:2d:de:8b:77:48:75:de:56:2f:b5:d4:62:ec:c3:09:15:f2
pubkey: ECDSA 256 bits
keyid: a1:b5:e0:29:d0:4c:a7:62:bd:ca:a3:b4:af:18:42:2c:4a:01:55:9a
subjkey: 21:02:7e:2d:de:8b:77:48:75:de:56:2f:b5:d4:62:ec:c3:09:15:f2
</pre>
h2. IKEv2 Authentication with RSA AIK Certificate
With the following *swanctl* command the "rsa" connection is established
<pre>
swanctl --initiate --child rsa
</pre>
<pre>
Feb 19 10:52:21 raspi5 charon-systemd[21165]: vici initiate 'rsa'
Feb 19 10:52:21 raspi5 charon-systemd[21165]: initiating IKE_SA rsa[1] to 10.10.0.104
Feb 19 10:52:21 raspi5 charon-systemd[21165]: generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) V ]
Feb 19 10:52:21 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[500] to 10.10.0.104[500] (1257 bytes)
Feb 19 10:52:21 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[500] to 10.10.0.105[500] (1259 bytes)
Feb 19 10:52:21 raspi5 charon-systemd[21165]: parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) CERTREQ N(HASH_ALG) V ]
Feb 19 10:52:21 raspi5 charon-systemd[21165]: received strongSwan vendor ID
Feb 19 10:52:21 raspi5 charon-systemd[21165]: received cert request for "C=US, O=TNC Demo, CN=TNC Demo CA"
Feb 19 10:52:21 raspi5 charon-systemd[21165]: sending cert request for "C=US, O=TNC Demo, CN=TNC Demo CA"
</pre>
The RSA AK private key stored in the TPM 2.0 is used to generate an *RSA_EMSA_PKCS1_SHA2_256* signature which is sent in the AUTH payload of the IKE_AUTH request. The matching client certificate is sent int the CERT payload.
<pre>
Feb 19 10:52:24 raspi5 charon-systemd[21165]: authentication of 'C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com' (myself) with RSA_EMSA_PKCS1_SHA2_256 successful
Feb 19 10:52:24 raspi5 charon-systemd[21165]: sending end entity cert "C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com"
</pre>
<pre>
Feb 19 10:52:24 raspi5 charon-systemd[21165]: establishing CHILD_SA rsa
Feb 19 10:52:24 raspi5 charon-systemd[21165]: generating IKE_AUTH request 1 [ IDi CERT CERTREQ IDr AUTH N(USE_TRANSP) SA TSi TSr N(MOBIKE_SUP) N(ADD_6_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
Feb 19 10:52:24 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[4500] to 10.10.0.104[4500] (1296 bytes)
Feb 19 10:52:24 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[4500] to 10.10.0.105[4500] (752 bytes)
Feb 19 10:52:24 raspi5 charon-systemd[21165]: parsed IKE_AUTH response 1 [ IDr CERT AUTH N(USE_TRANSP) SA TSi TSr N(AUTH_LFT) N(MOBIKE_SUP) N(NO_ADD_ADDR) ]
Feb 19 10:52:24 raspi5 charon-systemd[21165]: received end entity cert "C=US, O=TNC Demo, CN=raspi4.example.com"
Feb 19 10:52:24 raspi5 charon-systemd[21165]: using certificate "C=US, O=TNC Demo, CN=raspi4.example.com"
Feb 19 10:52:24 raspi5 charon-systemd[21165]: using trusted ca certificate "C=US, O=TNC Demo, CN=TNC Demo CA"
Feb 19 10:52:24 raspi5 charon-systemd[21165]: reached self-signed root ca with a path length of 0
Feb 19 10:52:24 raspi5 charon-systemd[21165]: authentication of 'raspi4.example.com' with ECDSA_WITH_SHA256_DER successful
Feb 19 10:52:24 raspi5 charon-systemd[21165]: IKE_SA rsa[1] established between 10.10.0.105[C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com]...10.10.0.104[raspi4.example.com]
Feb 19 10:52:24 raspi5 charon-systemd[21165]: scheduling reauthentication in 10507s
Feb 19 10:52:24 raspi5 charon-systemd[21165]: maximum IKE_SA lifetime 11587s
Feb 19 10:52:24 raspi5 charon-systemd[21165]: CHILD_SA rsa{1} established with SPIs c23deb9d_i ce48d08e_o and TS 10.10.0.105/32 === 10.10.0.104/32
Feb 19 10:52:24 raspi5 charon-systemd[21165]: received AUTH_LIFETIME of 10103s, scheduling reauthentication in 9023s
Feb 19 10:52:24 raspi5 charon-systemd[21165]: peer supports MOBIKE
</pre>
The following *swanctl* command shows the established IPsec connection
<pre>
swanctl --list-sas
</pre>
<pre>
rsa: #1, ESTABLISHED, IKEv2, 7ba3b4d06c051ecb_i* 14e1769a8aeb7f28_r
local 'C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com' @ 10.10.0.105[4500]
remote 'raspi4.example.com' @ 10.10.0.104[4500]
AES_CBC-128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/CURVE_25519
established 252s ago, reauth in 8771s
rsa: #1, reqid 1, INSTALLED, TRANSPORT, ESP:AES_CBC-128/HMAC_SHA2_256_128
installed 252s ago, rekeying in 3258s, expires in 3708s
in c23deb9d, 640 bytes, 10 packets, 3s ago
out ce48d08e, 640 bytes, 10 packets, 3s ago
local 10.10.0.105/32
remote 10.10.0.104/32
</pre>
With this *swanctl* command the "rsa" connection is terminated
<pre>
swanctl --terminate --ike rsa
</pre>
<pre>
Feb 19 10:59:16 raspi5 charon-systemd[21165]: vici terminate IKE_SA 'rsa'
Feb 19 10:59:16 raspi5 charon-systemd[21165]: deleting IKE_SA rsa[1] between 10.10.0.105[C=US, O=TNC Demo, OU=AIK RSA, CN=raspi5.example.com]...10.10.0.104[raspi4.example.com]
Feb 19 10:59:16 raspi5 charon-systemd[21165]: sending DELETE for IKE_SA rsa[1]
Feb 19 10:59:16 raspi5 charon-systemd[21165]: generating INFORMATIONAL request 2 [ D ]
Feb 19 10:59:16 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[4500] to 10.10.0.104[4500] (80 bytes)
Feb 19 10:59:16 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[4500] to 10.10.0.105[4500] (80 bytes)
Feb 19 10:59:16 raspi5 charon-systemd[21165]: parsed INFORMATIONAL response 2 [ ]
Feb 19 10:59:16 raspi5 charon-systemd[21165]: IKE_SA deleted
</pre>
h2. IKEv2 Authentication with ECC AIK Certificate
Next we initiate the "ecc" connection
<pre>
swanctl --initiate --child ecc
</pre>
<pre>
Feb 19 11:00:32 raspi5 charon-systemd[21165]: vici initiate 'ecc'
Feb 19 11:00:32 raspi5 charon-systemd[21165]: initiating IKE_SA ecc[2] to 10.10.0.104
Feb 19 11:00:32 raspi5 charon-systemd[21165]: generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) V ]
Feb 19 11:00:32 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[500] to 10.10.0.104[500] (1257 bytes)
Feb 19 11:00:32 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[500] to 10.10.0.105[500] (1259 bytes)
Feb 19 11:00:32 raspi5 charon-systemd[21165]: parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) CERTREQ N(HASH_ALG) V ]
Feb 19 11:00:32 raspi5 charon-systemd[21165]: received strongSwan vendor ID
Feb 19 11:00:32 raspi5 charon-systemd[21165]: received cert request for "C=US, O=TNC Demo, CN=TNC Demo CA"
Feb 19 11:00:32 raspi5 charon-systemd[21165]: sending cert request for "C=US, O=TNC Demo, CN=TNC Demo CA"
</pre>
The ECC AK private key stored in the TPM 2.0 is used to generate an *ECDSA_WITH_SHA256_DER* signature which is sent in the AUTH payload of the IKE_AUTH request. The matching client certificate is sent int the CERT payload.
<pre>
Feb 19 11:00:34 raspi5 charon-systemd[21165]: authentication of 'C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com' (myself) with ECDSA_WITH_SHA256_DER successful
Feb 19 11:00:34 raspi5 charon-systemd[21165]: sending end entity cert "C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com"
</pre>
<pre>
Feb 19 11:00:34 raspi5 charon-systemd[21165]: establishing CHILD_SA ecc
Feb 19 11:00:34 raspi5 charon-systemd[21165]: generating IKE_AUTH request 1 [ IDi CERT CERTREQ IDr AUTH N(USE_TRANSP) SA TSi TSr N(MOBIKE_SUP) N(ADD_6_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
Feb 19 11:00:34 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[4500] to 10.10.0.104[4500] (912 bytes)
Feb 19 11:00:34 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[4500] to 10.10.0.105[4500] (752 bytes)
Feb 19 11:00:34 raspi5 charon-systemd[21165]: parsed IKE_AUTH response 1 [ IDr CERT AUTH N(USE_TRANSP) SA TSi TSr N(AUTH_LFT) N(MOBIKE_SUP) N(NO_ADD_ADDR) ]
Feb 19 11:00:34 raspi5 charon-systemd[21165]: received end entity cert "C=US, O=TNC Demo, CN=raspi4.example.com"
Feb 19 11:00:34 raspi5 charon-systemd[21165]: using certificate "C=US, O=TNC Demo, CN=raspi4.example.com"
Feb 19 11:00:34 raspi5 charon-systemd[21165]: using trusted ca certificate "C=US, O=TNC Demo, CN=TNC Demo CA"
Feb 19 11:00:34 raspi5 charon-systemd[21165]: reached self-signed root ca with a path length of 0
Feb 19 11:00:34 raspi5 charon-systemd[21165]: authentication of 'raspi4.example.com' with ECDSA_WITH_SHA256_DER successful
Feb 19 11:00:34 raspi5 charon-systemd[21165]: IKE_SA ecc[2] established between 10.10.0.105[C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com]...10.10.0.104[raspi4.example.com]
Feb 19 11:00:34 raspi5 charon-systemd[21165]: scheduling reauthentication in 10180s
Feb 19 11:00:34 raspi5 charon-systemd[21165]: maximum IKE_SA lifetime 11260s
Feb 19 11:00:34 raspi5 charon-systemd[21165]: CHILD_SA ecc{2} established with SPIs c2c16cd0_i c47ea6f6_o and TS 10.10.0.105/32 === 10.10.0.104/32
Feb 19 11:00:34 raspi5 charon-systemd[21165]: received AUTH_LIFETIME of 9880s, scheduling reauthentication in 8800s
Feb 19 11:00:34 raspi5 charon-systemd[21165]: peer supports MOBIKE
</pre>
The establed IKE and CHILD SAs are displayed
<pre>
swanctl --list-sas
</pre>
<pre>
ecc: #2, ESTABLISHED, IKEv2, b7f2652777b0996a_i* 12282b5964ff0658_r
local 'C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com' @ 10.10.0.105[4500]
remote 'raspi4.example.com' @ 10.10.0.104[4500]
AES_CBC-128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/CURVE_25519
established 126s ago, reauth in 8674s
ecc: #2, reqid 2, INSTALLED, TRANSPORT, ESP:AES_CBC-128/HMAC_SHA2_256_128
installed 126s ago, rekeying in 3252s, expires in 3834s
in c2c16cd0, 320 bytes, 5 packets, 2s ago
out c47ea6f6, 320 bytes, 5 packets, 2s ago
local 10.10.0.105/32
remote 10.10.0.104/32
</pre>
The IKE and CHILD SAs are terminated
<pre>
swanctl --terminate --ike ecc
</pre>
<pre>
Feb 19 11:04:32 raspi5 charon-systemd[21165]: vici terminate IKE_SA 'ecc'
Feb 19 11:04:32 raspi5 charon-systemd[21165]: deleting IKE_SA ecc[2] between 10.10.0.105[C=US, O=TNC Demo, OU=AIK ECC, CN=raspi5.example.com]...10.10.0.104[raspi4.example.com]
Feb 19 11:04:32 raspi5 charon-systemd[21165]: sending DELETE for IKE_SA ecc[2]
Feb 19 11:04:32 raspi5 charon-systemd[21165]: generating INFORMATIONAL request 2 [ D ]
Feb 19 11:04:32 raspi5 charon-systemd[21165]: sending packet: from 10.10.0.105[4500] to 10.10.0.104[4500] (80 bytes)
Feb 19 11:04:32 raspi5 charon-systemd[21165]: received packet: from 10.10.0.104[4500] to 10.10.0.105[4500] (80 bytes)
Feb 19 11:04:32 raspi5 charon-systemd[21165]: parsed INFORMATIONAL response 2 [ ]
Feb 19 11:04:32 raspi5 charon-systemd[21165]: IKE_SA deleted
</pre>