diff --git a/.gitignore b/.gitignore index f0a75ef..ac5bc94 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,7 @@ examples/wrap/wrap_test examples/native/native_test examples/bench/bench examples/csr/csr - +examples/tls/tls_client examples/pkcs7/pkcs7 pkcs7tpmsigned.p7s diff --git a/IDE/OPENSTM32/Inc/user_settings.h b/IDE/OPENSTM32/Inc/user_settings.h index 2097db7..17465a7 100644 --- a/IDE/OPENSTM32/Inc/user_settings.h +++ b/IDE/OPENSTM32/Inc/user_settings.h @@ -38,8 +38,8 @@ extern "C" { #define HAVE_LWIP_NATIVE -#define WOLF_TPM2 - +//#define DEBUG_WOLFTPM +//#define USE_HW_SPI_CS /* ------------------------------------------------------------------------- */ /* Math Configuration */ diff --git a/IDE/OPENSTM32/Src/main.c b/IDE/OPENSTM32/Src/main.c index fc87d9a..eea6b99 100644 --- a/IDE/OPENSTM32/Src/main.c +++ b/IDE/OPENSTM32/Src/main.c @@ -209,19 +209,22 @@ static void MX_RTC_Init(void) /* SPI1 init function */ static void MX_SPI1_Init(void) { - hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; +#ifdef USE_HW_SPI_CS hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT; - hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; +#else + hspi1.Init.NSS = SPI_NSS_SOFT; +#endif + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; /* 32=1.8MHz, 128=470kHz */ hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - hspi1.Init.CRCPolynomial = 10; + hspi1.Init.CRCPolynomial = 7; if (HAL_SPI_Init(&hspi1) != HAL_OK) { Error_Handler(); diff --git a/IDE/OPENSTM32/Src/wolftpm_example.c b/IDE/OPENSTM32/Src/wolftpm_example.c index 20491f5..4cfa703 100644 --- a/IDE/OPENSTM32/Src/wolftpm_example.c +++ b/IDE/OPENSTM32/Src/wolftpm_example.c @@ -88,7 +88,7 @@ void wolfTPMDemo(void const * argument) case 'm': printf("\nTPM 2.0 Test\n"); -#ifdef WOLF_TPM2 +#ifndef WOLFTPM2_NO_WRAPPER args.return_code = TPM2_Wrapper_Test(&hspi1); #endif printf("TPM 2.0 Test: Return code %d\n", args.return_code); diff --git a/README.md b/README.md index 471ef29..a3e8808 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,21 @@ Portable TPM 2.0 project designed for embedded use. ## Project Features * This implementation provides all TPM 2.0 API’s in compliance with the specification. +* Wrappers provided to simplify Key Generation, RSA encrypt/decrypt, ECC sign/verify, ECDH and NV. +* Testing done using the Infineon OPTIGA SLB9670 and LetsTrust TPM modules. * This uses the TPM Interface Specification (TIS) to communicate over SPI. +* Platform support Raspberry Pi and STM32 with CubeMX. * The design allows for easy portability to different platforms: * Native C code designed for embedded use. * Single IO callback for hardware SPI interface. * No external dependencies. * Compact code size and minimal memory use. -* Examples for the Raspberry Pi and STM32 with CubeMX. -* Includes example code for most TPM2 native API’s. -* Includes wrappers for Key Generation, RSA encrypt/decrypt, ECC sign/verify and ECDH. -* Testing done using the Infineon OPTIGA SLB9670 module and LetsTrust TPM for Raspberry Pi. +* Includes example code for: + * Most TPM2 native API’s + * All TPM2 wrappers + * PKCS 7 + * Certificate Signing Request (CSR) + * TLS Client ## TPM 2.0 Overview @@ -72,7 +77,9 @@ Build wolfSSL: ``` ./autogen.sh -./configure --enable-ecc --enable-sha512 && make +./configure --enable-ecc --enable-sha512 +make +make check sudo make install sudo ldconfig ``` @@ -81,14 +88,35 @@ Build wolfTPM: ``` ./autogen.sh -./configure && make +./configure +make ./examples/wrap/wrap_test ./examples/native/native_test +./examples/bench/bench +./examples/csr/csr +./examples/pkcs7/pkcs7 +./examples/tls/tls_client ``` ## Release Notes +### wolfTPM Release 1.3 (07/20/2018) + +* Fixed the TIS TPM_BASE_ADDRESS to conform to specification. (PR #19) +* Fixed static analysis warnings. (PR #20) +* Fixed minor build warnings with different compilers. (PR #21) +* Fixed TPM failure for RSA exponents less than 7 by using software based RSA. (PR #23) +* Added TPM bechmarking support. (PR #16) +* Added functions to import/export public keys as wolf format. (PR #15) +* Added PKCS7 example to show sign/verify with TPM. (PR #17) +* Added CSR example to generate certificate request based on TPM key. (PR #17) +* Added CSR signing script `./certs/certreq.sh` to create certificate using self-signed CA. (PR #17) +* Added TLS Client example that uses TPM based key for client certificate. (PR #17) +* Added support for wolfSSL `WOLF_CRYPT_DEV` callbacks to enable TPM based ECC and RSA private keys. (PR #17) +* Added ability to clear/reset TPM using `./examples/wrap/wrap_test 1` (PR #17) +* Moved some of the example configuration into `./examples/tpm_io.h`. (PR #17) + ### wolfTPM Release 1.1 (03/09/2018) * Added TPM2 wrapper layer to simplify key creation, RSA encrypt/decrypt, ECC sign/verify and ECDH. diff --git a/configure.ac b/configure.ac index 50a1ebd..03d9a3e 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ # All right reserved. AC_COPYRIGHT([Copyright (C) 2014-2018 wolfSSL Inc.]) -AC_INIT([wolftpm],[1.1.0],[https://github.com/wolfssl/wolfTPM/issues],[wolftpm],[http://www.wolfssl.com]) +AC_INIT([wolftpm],[1.3.0],[https://github.com/wolfssl/wolfTPM/issues],[wolftpm],[http://www.wolfssl.com]) AC_PREREQ([2.63]) AC_CONFIG_AUX_DIR([build-aux]) @@ -23,7 +23,7 @@ AC_ARG_PROGRAM AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([src/config.h]) -WOLFTPM_LIBRARY_VERSION=2:0:0 +WOLFTPM_LIBRARY_VERSION=3:0:0 # | | | # +------+ | +---+ # | | | diff --git a/examples/tls/tls_client.c b/examples/tls/tls_client.c index 253015b..dcd3ff1 100644 --- a/examples/tls/tls_client.c +++ b/examples/tls/tls_client.c @@ -442,7 +442,7 @@ int TPM2_TLS_Client(void* userCtx) rc = wolfSSL_get_error(ssl, 0); } } while (rc == WOLFSSL_ERROR_WANT_READ || rc == WOLFSSL_ERROR_WANT_WRITE); - if (rc != 0) { + if (rc != WOLFSSL_SUCCESS) { goto exit; } diff --git a/examples/tpm_io.c b/examples/tpm_io.c index 2900223..4baf688 100644 --- a/examples/tpm_io.c +++ b/examples/tpm_io.c @@ -38,7 +38,13 @@ #include #include #include - #define TPM2_SPI_DEV "/dev/spidev0.1" + #ifdef WOLFTPM_ST33 + /* ST33HTPH SPI uses CE0 */ + #define TPM2_SPI_DEV "/dev/spidev0.0" + #else + /* OPTIGA SLB9670 and LetsTrust TPM use CE1 */ + #define TPM2_SPI_DEV "/dev/spidev0.1" + #endif static int gSpiDev = -1; #define TPM2_USER_CTX &gSpiDev @@ -63,8 +69,16 @@ int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, HAL_StatusTypeDef status; __HAL_SPI_ENABLE(hspi); - status = HAL_SPI_TransmitReceive(hspi, (byte*)txBuf, rxBuf, xferSz, 5000); +#ifndef USE_HW_SPI_CS + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET); /* active low */ +#endif + + status = HAL_SPI_TransmitReceive(hspi, (byte*)txBuf, rxBuf, xferSz, 250); +#ifndef USE_HW_SPI_CS + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET); +#endif __HAL_SPI_DISABLE(hspi); + if (status == HAL_OK) ret = TPM_RC_SUCCESS; diff --git a/src/tpm2.c b/src/tpm2.c index aa26288..edd2250 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -4550,6 +4550,11 @@ const char* TPM2_GetRCString(int rc) { /* for negative return codes use wolfCrypt */ if (rc < 0) { + switch (rc) { + TPM_RC_STR(TPM_RC_TIMEOUT, "Hardware timeout"); + default: + break; + } return wc_GetErrorString(rc); } diff --git a/src/tpm2_tis.c b/src/tpm2_tis.c index a210bd7..ccef629 100755 --- a/src/tpm2_tis.c +++ b/src/tpm2_tis.c @@ -130,7 +130,7 @@ int TPM2_TIS_StartupWait(TPM2_CTX* ctx, int timeout) return 0; } while (rc == TPM_RC_SUCCESS && --timeout > 0); - return TPM_RC_INITIALIZE; + return TPM_RC_TIMEOUT; } int TPM2_TIS_CheckLocality(TPM2_CTX* ctx, int locality) @@ -146,7 +146,7 @@ int TPM2_TIS_CheckLocality(TPM2_CTX* ctx, int locality) return locality; } - return TPM_RC_INITIALIZE; + return TPM_RC_TIMEOUT; } int TPM2_TIS_RequestLocality(TPM2_CTX* ctx, int timeout) @@ -169,7 +169,7 @@ int TPM2_TIS_RequestLocality(TPM2_CTX* ctx, int timeout) } while (--timeout > 0); } - return TPM_RC_INITIALIZE; + return TPM_RC_TIMEOUT; } int TPM2_TIS_GetInfo(TPM2_CTX* ctx) diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index c44c634..5e1ee24 100755 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -338,6 +338,17 @@ int wolfTPM2_LoadRsaPublicKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, if (rsaPubSz > sizeof(pub.publicArea.unique.rsa.buffer)) return BUFFER_E; + /* To support TPM hardware and firmware versions that do not allow small exponents */ +#ifndef WOLFTPM_NO_SOFTWARE_RSA + /* The TPM reference implementation does not support an exponent size + smaller than 7 nor does it allow keys to be created on the TPM with a + public exponent less than 2^16 + 1. */ + if (exponent < 7) { + printf("TPM based RSA with exponent %u not allowed! Using soft RSA\n", exponent); + return TPM_RC_KEY; + } +#endif + XMEMSET(&pub, 0, sizeof(pub)); pub.publicArea.type = TPM_ALG_RSA; pub.publicArea.nameAlg = TPM_ALG_NULL; @@ -926,11 +937,12 @@ int wolfTPM2_RsaDecrypt(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, int wolfTPM2_ReadPCR(WOLFTPM2_DEV* dev, int pcrIndex, int alg, byte* digest, - int* digest_len) + int* p_digest_len) { int rc; PCR_Read_In pcrReadIn; PCR_Read_Out pcrReadOut; + int digest_len; if (dev == NULL) return BAD_FUNC_ARG; @@ -942,18 +954,19 @@ int wolfTPM2_ReadPCR(WOLFTPM2_DEV* dev, int pcrIndex, int alg, byte* digest, return rc; } - if (digest_len) - *digest_len = (int)pcrReadOut.pcrValues.digests[0].size; + digest_len = (int)pcrReadOut.pcrValues.digests[0].size; if (digest) - XMEMCPY(digest, pcrReadOut.pcrValues.digests[0].buffer, - pcrReadOut.pcrValues.digests[0].size); + XMEMCPY(digest, pcrReadOut.pcrValues.digests[0].buffer, digest_len); #ifdef DEBUG_WOLFTPM printf("TPM2_PCR_Read: Index %d, Digest Sz %d, Update Counter %d\n", - pcrIndex, *digest_len, (int)pcrReadOut.pcrUpdateCounter); - TPM2_PrintBin(digest, *digest_len); + pcrIndex, digest_len, (int)pcrReadOut.pcrUpdateCounter); + TPM2_PrintBin(digest, digest_len); #endif + if (p_digest_len) + *p_digest_len = digest_len; + return rc; } diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index f9b9802..4ae6eec 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -52,7 +52,7 @@ #endif #ifndef TPM_TIMEOUT_TRIES -#define TPM_TIMEOUT_TRIES 1000000 +#define TPM_TIMEOUT_TRIES 100000 #endif #ifndef MAX_SYM_BLOCK_SIZE @@ -600,6 +600,9 @@ typedef enum { TPM_RC_E = 0xE00, TPM_RC_F = 0xF00, TPM_RC_N_MASK = 0xF00, + + /* use negative codes for internal errors */ + TPM_RC_TIMEOUT = -100, } TPM_RC_T; typedef INT32 TPM_RC; /* type is unsigned 16-bits, but internally use signed 32-bit */ diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index 6967117..4b1e514 100755 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -115,7 +115,7 @@ WOLFTPM_API int wolfTPM2_RsaDecrypt(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, TPM_ALG_ID padScheme, const byte* in, int inSz, byte* msg, int* msgSz); WOLFTPM_API int wolfTPM2_ReadPCR(WOLFTPM2_DEV* dev, - int pcrIndex, int alg, byte* digest, int* digest_len); + int pcrIndex, int alg, byte* digest, int* p_digest_len); WOLFTPM_API int wolfTPM2_NVCreate(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, word32 nvIndex, word32 nvAttributes, word32 maxSize, const byte* auth, int authSz); diff --git a/wolftpm/version.h b/wolftpm/version.h index 17ece8a..69b391c 100644 --- a/wolftpm/version.h +++ b/wolftpm/version.h @@ -34,8 +34,8 @@ extern "C" { #endif -#define LIBWOLFTPM_VERSION_STRING "1.1.0" -#define LIBWOLFTPM_VERSION_HEX 0x01001000 +#define LIBWOLFTPM_VERSION_STRING "1.3.0" +#define LIBWOLFTPM_VERSION_HEX 0x01003000 #ifdef __cplusplus }