Further cleanup of the I2C busy handling to avoid delay and added additional code comments. Added key gen to benchmark. Updated README.md. Configure check to ensure advanced IO is enabled for I2C.

pull/33/head
David Garske 2018-09-05 19:28:09 -07:00
parent 911a5a7226
commit 7f768a2afa
4 changed files with 179 additions and 81 deletions

175
README.md
View File

@ -58,9 +58,11 @@ The Raspberry 3 uses the native `spi_dev` interface and defaults to `/dev/spidev
This has only been tested and confirmed working with Rasbian 4.4.x.
### SPI IO Callback
### IO Callback
For interfacing to your hardware platform see the example `tpm2_demo.c` callback function `TPM2_IoCb`. Here you can modify or insert your own IO callback code for the TPM demo.
For interfacing to your hardware platform see the example `examples/tpm_io.c` callback function `TPM2_IoCb`. Here you can modify or insert your own IO callback code for the TPM demo.
There are examples here for Linux, STM32 CubeMX and Atmel ASF. The advanced IO option is required for I2C support because it adds the register and read/write flag as parameter to the IO callback.
### Hardware
@ -84,20 +86,37 @@ sudo make install
sudo ldconfig
```
### Building Infineon SLB9670
Build wolfTPM:
```
./autogen.sh
./configure
make
./examples/wrap/wrap_test
./examples/native/native_test
./examples/bench/bench
./examples/csr/csr
./examples/pkcs7/pkcs7
./examples/tls/tls_client
```
### Building ST ST33TP*
Build wolfTPM:
```
./autogen.sh
./configure --enable-st33 [--enable-i2c]
make
```
### Build options and defines
```
--enable-debug Add debug code/turns off optimizations (yes|no|verbose) - DEBUG_WOLFTPM, WOLFTPM_DEBUG_VERBOSE
--enable-examples Enable Examples (default: enabled)
--enable-wrapper Enable wrapper code (default: enabled) - WOLFTPM2_NO_WRAPPER
--enable-wolfcrypt Enable wolfCrypt hooks for RNG, Auth Sessions and Parameter encryption (default: enabled) - WOLFTPM2_NO_WOLFCRYPT
--enable-advio Enable Advanced IO (default: disabled) - WOLFTPM_ADV_IO
--enable-st33 Enable ST33 TPM Support (default: disabled) - WOLFTPM_ST33
--enable-i2c Enable I2C TPM Support (default: disabled) - WOLFTPM_I2C
```
## Release Notes
@ -137,15 +156,15 @@ make
* TPM 2.0 demo code in `examples/tpm/tpm2_demo.c` with support for STM32 CubeMX SPI as reference.
## Examples
## Running Examples
### TPM2 Wrapper Tests
```
./examples/wrap/wrap_test
TPM2 Demo for Wrapper API's
RSA Encrypt Test Passed
RSA Encrypt/Decrypt Test Passed
RSA Encrypt/Decrypt OAEP Test Passed
ECC Sign/Verify Passed
ECC DH Generation Passed
NV Test on index 0x1800200 with 1024 bytes passed
@ -153,29 +172,49 @@ NV Test on index 0x1800200 with 1024 bytes passed
### TPM2 Benchmarks
Note: Key Generation is using existing template from hierarchy seed.
Run on Infineon OPTIGA SLB9670:
```
./examples/bench/bench
TPM2 Benchmark using Wrapper API's
RSA 2048 Public 65 ops took 1.005 sec, avg 15.466 ms, 64.657 ops/sec
RSA 2048 Private 3 ops took 1.343 sec, avg 447.759 ms, 2.233 ops/sec
RSA 2048 Pub OAEP 12 ops took 1.040 sec, avg 86.657 ms, 11.540 ops/sec
RSA 2048 Priv OAEP 2 ops took 1.032 sec, avg 515.885 ms, 1.938 ops/sec
ECDSA 256 sign 14 ops took 1.037 sec, avg 74.101 ms, 13.495 ops/sec
ECDSA 256 verify 8 ops took 1.027 sec, avg 128.417 ms, 7.787 ops/sec
ECDHE 256 agree 8 ops took 1.040 sec, avg 130.003 ms, 7.692 ops/sec
RSA 2048 key gen 5 ops took 1.116 sec, avg 223.111 ms, 4.482 ops/sec
RSA 2048 Public 65 ops took 1.012 sec, avg 15.572 ms, 64.219 ops/sec
RSA 2048 Private 3 ops took 1.365 sec, avg 455.050 ms, 2.198 ops/sec
RSA 2048 Pub OAEP 11 ops took 1.011 sec, avg 91.889 ms, 10.883 ops/sec
RSA 2048 Priv OAEP 2 ops took 1.039 sec, avg 519.707 ms, 1.924 ops/sec
ECC 256 key gen 5 ops took 1.016 sec, avg 203.186 ms, 4.922 ops/sec
ECDSA 256 sign 14 ops took 1.056 sec, avg 75.396 ms, 13.263 ops/sec
ECDSA 256 verify 8 ops took 1.040 sec, avg 129.948 ms, 7.695 ops/sec
ECDHE 256 agree 8 ops took 1.049 sec, avg 131.094 ms, 7.628 ops/sec
```
### TPM Native Tests
Run on ST ST33TP SPI:
```
./examples/bench/bench
TPM2 Benchmark using Wrapper API's
RSA 2048 key gen 3 ops took 3.889 sec, avg 1296.452 ms, 0.771 ops/sec
RSA 2048 Public 64 ops took 1.014 sec, avg 15.840 ms, 63.131 ops/sec
RSA 2048 Private 4 ops took 1.017 sec, avg 254.190 ms, 3.934 ops/sec
RSA 2048 Pub OAEP 63 ops took 1.003 sec, avg 15.924 ms, 62.797 ops/sec
RSA 2048 Priv OAEP 4 ops took 1.027 sec, avg 256.862 ms, 3.893 ops/sec
ECC 256 key gen 5 ops took 1.157 sec, avg 231.497 ms, 4.320 ops/sec
ECDSA 256 sign 23 ops took 1.027 sec, avg 44.657 ms, 22.393 ops/sec
ECDSA 256 verify 14 ops took 1.068 sec, avg 76.265 ms, 13.112 ops/sec
ECDHE 256 agree 5 ops took 1.248 sec, avg 249.669 ms, 4.005 ops/sec
```
### TPM2 Native Tests
```
./examples/native/native_test
TPM2 Demo using Native API's
TPM2: Caps 0x30000697, Did 0x001b, Vid 0x15d1, Rid 0x10
TPM2: Caps 0x1a7e2882, Did 0x0000, Vid 0x104a, Rid 0x4e
TPM2_Startup pass
TPM2_SelfTest pass
TPM2_GetTestResult: Size 10, Rc 0x0
TPM2_GetTestResult: Size 12, Rc 0x0
TPM2_IncrementalSelfTest: Rc 0x0, Alg 0x1 (Todo 0)
TPM2_GetCapability: Property FamilyIndicator 0x322e3000
TPM2_GetCapability: Property PCR Count 24
@ -212,46 +251,92 @@ TPM2_PolicyGetDigest: size 32
TPM2_PCR_Read: Index 0, Digest Sz 20, Update Counter 22
wc_Hash of PCR[0]: size 32
TPM2_PolicyPCR failed 0x1c4: TPM_RC_AUTHSIZE
TPM2_PolicyPCR: Updated
TPM2_PolicyRestart: Done
TPM2_HashSequenceStart: sequenceHandle 0x80000000
TPM2_HashSequenceStart: sequenceHandle 0x80000002
Hash SHA256 test success
TPM2_CreatePrimary: Endorsement 0x80000000 (314 bytes)
TPM2_CreatePrimary: Storage 0x80000001 (282 bytes)
TPM2_LoadExternal: 0x80000002
TPM2_CreatePrimary: Endorsement 0x80000002 (314 bytes)
TPM2_CreatePrimary: Storage 0x80000004 (282 bytes)
TPM2_LoadExternal: 0x80000006
TPM2_MakeCredential: credentialBlob 68, secret 256
TPM2_ReadPublic Handle 0x80000002: pub 314, name 34, qualifiedName 34
Create HMAC-SHA256 Key success, public 48, Private 141
TPM2_Load New HMAC Key Handle 0x80000002
TPM2_ReadPublic Handle 0x80000006: pub 314, name 34, qualifiedName 34
Create HMAC-SHA256 Key success, public 48, Private 137
TPM2_Load New HMAC Key Handle 0x80000006
TPM2_PolicyCommandCode: success
TPM2_ObjectChangeAuth failed 0x9a2: TPM_RC_BAD_AUTH
TPM2_ObjectChangeAuth: private 2
TPM2_ObjectChangeAuth: private 137
TPM2_ECC_Parameters: CurveID 3, sz 256, p 32, a 32, b 32, gX 32, gY 32, n 32, h 1
TPM2_Create: New ECDSA Key: pub 88, priv 126
TPM2_Load ECDSA Key Handle 0x80000002
TPM2_Load ECDSA Key Handle 0x80000006
TPM2_Sign: ECC S 32, R 32
TPM2_VerifySignature: Tag 32802
TPM2_Create: New ECDH Key: pub 88, priv 126
TPM2_Load ECDH Key Handle 0x80000002
TPM2_Load ECDH Key Handle 0x80000006
TPM2_ECDH_KeyGen: zPt 68, pubPt 68
TPM2_Create: New RSA Key: pub 278, priv 222
TPM2_Load RSA Key Handle 0x80000002
TPM2_Load RSA Key Handle 0x80000006
TPM2_RSA_Encrypt: 256
TPM2_RSA_Decrypt: 32
RSA Encrypt/Decrypt test passed
TPM2_NV_ReadPublic failed 0x18b: TPM_RC_HANDLE
TPM2_NV_ReadPublic failed 0x18b: TPM_RC_HANDLE
TPM2_NV_ReadPublic failed 0x18b: TPM_RC_HANDLE
TPM2_NV_ReadPublic failed 0x18b: TPM_RC_HANDLE
TPM2_NV_ReadPublic failed 0x18b: TPM_RC_HANDLE
TPM2_NV_ReadPublic failed 0x18b: TPM_RC_HANDLE
TPM2_NV_ReadPublic failed 0x18b: TPM_RC_HANDLE
TPM2_NV_ReadPublic failed 0x18b: TPM_RC_HANDLE
TPM2_NV_ReadPublic failed 0x18b: TPM_RC_HANDLE
TPM2_NV_ReadPublic failed 0x18b: TPM_RC_HANDLE
TPM2_NV_DefineSpace failed 0x184: TPM_RC_VALUE
TPM2_NV_DefineSpace: 0x1bfffff
TPM2_NV_ReadPublic: Sz 14, Idx 0x1bfffff, nameAlg 11, Attr 0x2020002, authPol 0, dataSz 32, name 34
Create AES128 CFB Key success, public 50, Private 142
TPM2_Load New AES Key Handle 0x80000006
Encrypt/Decrypt test success
```
### TPM2 CSR Example
```
./examples/csr/csr
TPM2 CSR Example
Generated/Signed Cert (DER 860, PEM 1236)
-----BEGIN CERTIFICATE REQUEST-----
MIIDWDCCAkACAQIwgZsxCzAJBgNVBAYTAlVTMQ8wDQYDVQQIDAZPcmVnb24xETAP
BgNVBAcMCFBvcnRsYW5kMQ0wCwYDVQQEDARUZXN0MRAwDgYDVQQKDAd3b2xmU1NM
MQwwCgYDVQQLDANSU0ExGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG
SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBANtFRTX9CIW489vdmfy0qoffKtXBIfEGo07XgbvHPqk/KLx9NpK4
fDLRdh5Kh7mDIGQI0hKDQMQ4GRTzRlE+wXlTqGQaQohac1LRxe21RCCKn0ZXvbCJ
Wd1cIAGQyDyOb8WYCquQB79r2pIAKnVbedu+G1jx3tVrwB8ZCosKF86au7cEDxvD
sdmt2vcEIlMcgfWQNo8TkWEKW33qu/rOOfJAUkVOUKENvj8zz/Iw4pX9nImiclMC
/pMcgjpnFUlG5a0Jwg2PR7pXyRYUCciMq20UF5LDZG3NmFirVqigOmBIFsrpVCjt
wf/Ep6DxFgmy7KNJ/0kzQByySvjKrIOqynsCAwEAAaB3MHUGCSqGSIb3DQEJDjFo
MGYwHQYDVR0OBBYEFBHIhJ44Ide+SKGpL2neKuusXBZxMEUGA1UdJQQ+MDwGCCsG
AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYI
KwYBBQUHAwkwDQYJKoZIhvcNAQELBQADggEBACGHTZE5BVonf9OM3bYZvl2SiKdj
fo+f8a5COgBgCiNK8DPXCr+RMfp7jy8+3NP0bUPppi46F6Eq80YIZuQJgoyd0l8l
F+0KXq/FuoHtTLH7joHCKcYta1yPpnvKAG9195aIruAHesXwDxklqTvlVx3/e9No
YtmWUMdrLvTZrI1L1/0OuHbPgCGmdyHOXEh0xY0VTE1I0ff0b8UC3dQCsf8uROhO
fXXYwZz9LLSdO/QuDSxXThEe4m1/AUJkiaQ/T2zNEiR5Imk+jluXLz8bVM7w+HMt
l/076ekjTI+7PwzBZIG2F3nOIDUmHwe0lAWdU8h9IoAlM6kS22fh6gZZqQg=
-----END CERTIFICATE REQUEST-----
Generated/Signed Cert (DER 467, PEM 704)
-----BEGIN CERTIFICATE REQUEST-----
MIIBzzCCAXUCAQIwgZsxCzAJBgNVBAYTAlVTMQ8wDQYDVQQIDAZPcmVnb24xETAP
BgNVBAcMCFBvcnRsYW5kMQ0wCwYDVQQEDARUZXN0MRAwDgYDVQQKDAd3b2xmU1NM
MQwwCgYDVQQLDANFQ0MxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG
SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH
A0IABIokJgsrMSW8f6si4S1saUXABXbqWKWVQn+D6z9LQe/wkPqozP/hV/3qTtpE
I/E3HjcHqRY+nsosjlEz36mzrRagdzB1BgkqhkiG9w0BCQ4xaDBmMB0GA1UdDgQW
BBRyZJhX+sHZEE117OKL0/CPVGbAKzBFBgNVHSUEPjA8BggrBgEFBQcDAQYIKwYB
BQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgGCCsGAQUFBwMJMAoG
CCqGSM49BAMCA0gAMEUCIQCR9cbyRt3cbEZUIOBa4GNSRTlgFdB3X1EOwm+cA5/k
6AIgBm+EU6m5SDsk7BYmxTQAhgJFrelwymOa7m16kAXnFuU=
-----END CERTIFICATE REQUEST-----
```
### TPM2 PKCS 7 Example
```
./examples/pkcs7/pkcs7
TPM2 PKCS7 Example
PKCS7 Signed Container 1625
PKCS7 Container Verified (using TPM)
PKCS7 Container Verified (using software)
```
## Examples with Debug Enabled
### TPM2 Wrapper Tests with Debug Enabled

View File

@ -141,6 +141,20 @@ fi
AM_CONDITIONAL([HAVE_LIBWOLFSSL], [test "x$ENABLED_WOLFCRYPT" = "xyes"])
# I2C Support
AC_ARG_ENABLE([i2c],
[AS_HELP_STRING([--enable-i2c],[Enable I2C TPM Support (default: disabled)])],
[ ENABLED_I2C=$enableval ],
[ ENABLED_I2C=no ]
)
if test "x$ENABLED_I2C" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_I2C"
fi
AM_CONDITIONAL([BUILD_I2C], [test "x$ENABLED_I2C" = "xyes"])
# Advanced IO
AC_ARG_ENABLE([advio],
[AS_HELP_STRING([--enable-advio],[Enable Advanced IO (default: disabled)])],
@ -148,7 +162,7 @@ AC_ARG_ENABLE([advio],
[ ENABLED_ADVIO=no ]
)
if test "x$ENABLED_ADVIO" = "xyes"
if test "x$ENABLED_ADVIO" = "xyes" || test "x$ENABLED_I2C" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_ADV_IO"
fi
@ -169,20 +183,6 @@ fi
AM_CONDITIONAL([BUILD_ST33], [test "x$ENABLED_ST33" = "xyes"])
# I2C Support
AC_ARG_ENABLE([i2c],
[AS_HELP_STRING([--enable-i2c],[Enable I2C TPM Support (default: disabled)])],
[ ENABLED_I2C=$enableval ],
[ ENABLED_I2C=no ]
)
if test "x$ENABLED_I2C" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_I2C"
fi
AM_CONDITIONAL([BUILD_I2C], [test "x$ENABLED_I2C" = "xyes"])
# HARDEN FLAGS
AX_HARDEN_CC_COMPILER_FLAGS

View File

@ -130,10 +130,17 @@ int TPM2_Wrapper_Bench(void* userCtx)
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
if (rc != 0) goto exit;
rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle,
&publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
if (rc != 0) goto exit;
bench_stats_start(&count, &start);
do {
if (count > 0) {
rc = wolfTPM2_UnloadHandle(&dev, &rsaKey.handle);
if (rc != 0) goto exit;
}
rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle,
&publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
if (rc != 0) goto exit;
} while (bench_stats_sym_check(start, &count));
bench_stats_asym_finish("RSA", 2048, "key gen", count, start);
/* Perform RSA encrypt / decrypt (no pad) */
message.size = 256; /* test message 0x11,0x11,etc */
@ -190,10 +197,17 @@ int TPM2_Wrapper_Bench(void* userCtx)
TPMA_OBJECT_sign | TPMA_OBJECT_noDA,
TPM_ECC_NIST_P256, TPM_ALG_ECDSA);
if (rc != 0) goto exit;
rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle,
&publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
if (rc != 0) goto exit;
bench_stats_start(&count, &start);
do {
if (count > 0) {
rc = wolfTPM2_UnloadHandle(&dev, &eccKey.handle);
if (rc != 0) goto exit;
}
rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle,
&publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
if (rc != 0) goto exit;
} while (bench_stats_sym_check(start, &count));
bench_stats_asym_finish("ECC", 256, "key gen", count, start);
/* Perform sign / verify */
message.size = WC_SHA256_DIGEST_SIZE; /* test message 0x11,0x11,etc */

View File

@ -81,14 +81,7 @@
#if defined(__linux__)
#if defined(WOLFTPM_I2C)
#include <linux/wait.h>
#define TPM_I2C_TRIES 10
#define TPM_I2C_GUARD_US 0xFA
/* function to ensure min amount of time has passed between operations */
static void i2c_check_time(void)
{
usleep(TPM_I2C_GUARD_US);
}
#define TPM_I2C_TRIES 10
static int i2c_read(int fd, word32 reg, byte* data, int len)
{
int rc;
@ -99,7 +92,7 @@
rdwr.msgs = msgs;
rdwr.nmsgs = 2;
buf[0] = reg & 0xFF; /* address */
buf[0] = (reg & 0xFF); /* address */
msgs[0].flags = 0;
msgs[0].buf = buf;
@ -107,15 +100,17 @@
msgs[0].addr = TPM2_I2C_ADDR;
msgs[1].flags = I2C_M_RD;
msgs[1].buf = (unsigned char*)data;
msgs[1].buf = data;
msgs[1].len = len;
msgs[1].addr = TPM2_I2C_ADDR;
/* The I2C device may hold clock low to indicate busy, which results in
* ioctl failure here. Typically the retry completes in 1-3 retries.
* Its important to keep device open during these retries */
do {
rc = ioctl(fd, I2C_RDWR, &rdwr);
if (rc != -1)
break;
i2c_check_time();
} while (--timeout > 0);
return (rc == -1) ? TPM_RC_FAILURE : TPM_RC_SUCCESS;
@ -129,12 +124,14 @@
byte buf[MAX_SPI_FRAMESIZE+1];
int timeout = TPM_I2C_TRIES;
/* TIS layer should never provide a buffer larger than this,
but double check for good coding practice */
if (len > MAX_SPI_FRAMESIZE)
return BAD_FUNC_ARG;
rdwr.msgs = msgs;
rdwr.nmsgs = 1;
buf[0] = reg & 0xFF; /* address */
buf[0] = (reg & 0xFF); /* address */
XMEMCPY(buf + 1, data, len);
msgs[0].flags = 0;
@ -142,11 +139,13 @@
msgs[0].len = len + 1;
msgs[0].addr = TPM2_I2C_ADDR;
/* The I2C device may hold clock low to indicate busy, which results in
* ioctl failure here. Typically the retry completes in 1-3 retries.
* Its important to keep device open during these retries */
do {
rc = ioctl(fd, I2C_RDWR, &rdwr);
if (rc != -1)
break;
i2c_check_time();
} while (--timeout > 0);
return (rc == -1) ? TPM_RC_FAILURE : TPM_RC_SUCCESS;