From 6d46b26bde4b2e952e5c4fd5ee0f2623680b7cf5 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 13 Jul 2020 09:55:36 -0700 Subject: [PATCH] Added dynamic module detection at run-time when using internal TIS. --- README.md | 28 ++++++--- configure.ac | 105 ++++++++++++++++++++++++++++------ examples/bench/bench.c | 2 +- examples/native/native_test.c | 49 +++++----------- examples/tpm_io.c | 43 ++++++++++++-- examples/wrap/wrap_test.c | 4 +- src/tpm2.c | 12 +++- src/tpm2_tis.c | 70 ++++++++++++----------- src/tpm2_wrap.c | 53 ++++++----------- wolftpm/tpm2.h | 17 +++++- wolftpm/tpm2_types.h | 20 ++++++- 11 files changed, 260 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index ae207ee..fc6a392 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ There are examples here for Linux, STM32 CubeMX, Atmel ASF and BareBox. The adva Tested with: * Infineon OPTIGA (TM) Trusted Platform Module 2.0 SLB 9670. -* LetsTrust: http://letstrust.de (https://buyzero.de/collections/andere-platinen/products/letstrust-hardware-tpm-trusted-platform-module). Compact Raspberry Pi TPM 2.0 board based on Infineon SLB 9670. + - LetsTrust: [http://letstrust.de] ( Compact Raspberry Pi TPM 2.0 board based on Infineon SLB 9670. * ST ST33TP* TPM 2.0 module (SPI and I2C) * Microchip ATTPM20 module * Nuvoton NPCT65X or NPCT75x TPM2.0 module @@ -85,6 +85,10 @@ ST ST33TP SPI TPM2: Caps 0x1a7e2882, Did 0x0000, Vid 0x104a, Rid 0x4e Mfg STM (2), Vendor , Fw 74.8 (1151341959), FIPS 140-2 1, CC-EAL4 0 +ST ST33TP I2C +TPM2: Caps 0x1a7e2882, Did 0x0000, Vid 0x104a, Rid 0x4e +Mfg STM (2), Vendor , Fw 74.9 (1151341959), FIPS 140-2 1, CC-EAL4 0 + Microchip ATTPM20 TPM2: Caps 0x30000695, Did 0x3205, Vid 0x1114, Rid 0x 1 Mfg MCHP (3), Vendor , Fw 512.20481 (0), FIPS 140-2 0, CC-EAL4 0 @@ -118,21 +122,26 @@ autogen.sh requires: automake and libtool: `sudo apt-get install automake libtoo ### Build options and defines ``` ---enable-debug Add debug code/turns off optimizations (yes|no|verbose) - DEBUG_WOLFTPM, WOLFTPM_DEBUG_VERBOSE, WOLFTPM_DEBUG_IO +--enable-debug Add debug code/turns off optimizations (yes|no|verbose|io) - DEBUG_WOLFTPM, WOLFTPM_DEBUG_VERBOSE, WOLFTPM_DEBUG_IO --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, requires advio) - WOLFTPM_I2C ---enable-mchp Enable Microchip TPM Support (default: disabled) - WOLFTPM_MCHP -WOLFTPM_TIS_LOCK Enable Linux Named Semaphore for locking access to SPI device for concurrent access between processes. +--enable-checkwaitstate Enable TIS / SPI Check Wait State support (default: depends on chip) - WOLFTPM_CHECK_WAIT_STATE +--enable-smallstack Enable options to reduce stack usage +--enable-tislock Enable Linux Named Semaphore for locking access to SPI device for concurrent access between processes - WOLFTPM_TIS_LOCK + +--enable-autodetect Enable Runtime Module Detection (default: enable - when no module specified) - WOLFTPM_AUTODETECT +--enable-infineon Enable Infineon SLB9670 TPM Support (default: disabled) +--enable-st Enable ST ST33TPM Support (default: disabled) - WOLFTPM_ST33 +--enable-microchip Enable Microchip ATTPM20 Support (default: disabled) - WOLFTPM_MCHP --enable-nuvoton Enable Nuvoton NPCT65x/NPCT75x Support (default: disabled) - WOLFTPM_NUVOTON + WOLFTPM_USE_SYMMETRIC Enables symmetric AES/Hashing/HMAC support for TLS examples. -WOLFTPM2_USE_SW_ECDHE Disables use of TPM for ECC ephemeral key generation and shared secret. +WOLFTPM2_USE_SW_ECDHE Disables use of TPM for ECC ephemeral key generation and shared secret for TLS examples. TLS_BENCH_MODE Enables TLS benchmarking mode. NO_TPM_BENCH Disables the TPM benchmarking example. ---enable-smallstack Enable options to reduce stack usage ``` ### Building Infineon SLB9670 @@ -168,7 +177,10 @@ Build wolfTPM: ``` ./autogen.sh -./configure --enable-mchp +./configure --enable-microchip +make +``` + ### Building Nuvoton Build wolfTPM: diff --git a/configure.ac b/configure.ac index b930ed9..8c1724d 100644 --- a/configure.ac +++ b/configure.ac @@ -94,10 +94,15 @@ else fi # Verbose Logging -if test "x$ax_enable_debug" = "xverbose" +if test "x$ax_enable_debug" = "xverbose" || test "x$ax_enable_debug" = "xio" then AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_DEBUG_VERBOSE" fi +# IO Logging +if test "x$ax_enable_debug" = "xio" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_DEBUG_IO" +fi # Examples @@ -176,26 +181,35 @@ fi # STM ST33 Support -AC_ARG_ENABLE([st33], - [AS_HELP_STRING([--enable-st33],[Enable ST33 TPM Support (default: disabled)])], +AC_ARG_ENABLE([st33],, [ ENABLED_ST33=$enableval ], [ ENABLED_ST33=no ] ) +AC_ARG_ENABLE([st], + [AS_HELP_STRING([--enable-st],[Enable ST ST33 TPM Support (default: disabled)])], + [ ENABLED_ST=$enableval ], + [ ENABLED_ST=no ] + ) -if test "x$ENABLED_ST33" = "xyes" +if test "x$ENABLED_ST33" = "xyes" || test "x$ENABLED_ST" = "xyes" then + ENABLED_ST33=yes AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_ST33" fi - -# Microchip ATTPM20 Support -AC_ARG_ENABLE([mchp], - [AS_HELP_STRING([--enable-mchp],[Enable TPM 2.0 Support (default: disabled)])], +# Microchip ATTPM20 +AC_ARG_ENABLE([mchp],, [ ENABLED_MCHP=$enableval ], [ ENABLED_MCHP=no ] ) -if test "x$ENABLED_MCHP" = "xyes" +AC_ARG_ENABLE([microchip], + [AS_HELP_STRING([--enable-microchip],[Enable Microchip ATPM2.0 Support (default: disabled)])], + [ ENABLED_MICROCHIP=$enableval ], + [ ENABLED_MICROCHIP=no ] + ) +if test "x$ENABLED_MCHP" = "xyes" || test "x$ENABLED_MICROCHIP" = "xyes" then + ENABLED_MICROCHIP=yes AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_MCHP" fi @@ -211,14 +225,36 @@ then fi # Infineon SLB9670 -ENABLED_INFINEON=no -if test "x$ENABLED_MCHP" = "xno" && test "x$ENABLED_ST33" = "xno" +AC_ARG_ENABLE([infineon], + [AS_HELP_STRING([--enable-infineon],[Enable Infineon SLB9670 TPM Support (default: disabled)])], + [ ENABLED_INFINEON=$enableval ], + [ ENABLED_INFINEON=no ] + ) +if test "x$ENABLED_INFINEON" = "xyes" then AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_SLB9670" - ENABLED_INFINEON=yes fi +# TIS / SPI Check Wait State support +AC_ARG_ENABLE([checkwaitstate], + [AS_HELP_STRING([--enable-checkwaitstate],[Enable TIS / SPI Check Wait State support (default: depends on chip)])], + [ ENABLED_CHECKWAITSTATE=$enableval ], + [ ENABLED_CHECKWAITSTATE=no ] + ) + + +# TIS Layer Named Semaphore locking for concurrent access between processes. +AC_ARG_ENABLE([tislock], + [AS_HELP_STRING([--enable-tislock],[TIS Layer Named Semaphore locking for concurrent access between processes. (default: disabled)])], + [ ENABLED_TIS_LOCK=$enableval ], + [ ENABLED_TIS_LOCK=no ] + ) +if test "x$ENABLED_TIS_LOCK" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_TIS_LOCK" +fi + # Small Stack AC_ARG_ENABLE([smallstack], [AS_HELP_STRING([--enable-smallstack],[Enable Small Stack Usage (default: disabled)])], @@ -234,6 +270,35 @@ then AM_CFLAGS="$AM_CFLAGS -DMAX_COMMAND_SIZE=1024 -DMAX_RESPONSE_SIZE=1024 -DWOLFTPM2_MAX_BUFFER=1500 -DMAX_SESSION_NUM=1 -DMAX_DIGEST_BUFFER=973" fi +# Runtime Module Detection +AC_ARG_ENABLE([autodetect], + [AS_HELP_STRING([--enable-autodetect],[Enable Runtime Module Detection (default: enable - when no module specified)])], + [ ENABLED_AUTODETECT=$enableval ], + [ ENABLED_AUTODETECT=test ] + ) + +if test "x$ENABLED_AUTODETECT" = "xtest" +then + # If a module hasn't been selected then enable auto-detection + if test "x$ENABLED_INFINEON" = "xno" && test "x$ENABLED_MCHP" = "xno" && test "x$ENABLED_ST" = "xno" && test "x$ENABLED_NUVOTON" = "xno" + then + ENABLED_AUTODETECT=yes + fi +fi + +if test "x$ENABLED_AUTODETECT" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_AUTODETECT" +fi + + +# TIS / SPI Check Wait State support +# Required for all but Infineon only +if test "x$ENABLED_CHECKWAITSTATE" = "xyes" || test "x$ENABLED_AUTODETECT" = "xyes" || test "x$ENABLED_INFINEON" = "xno" +then + ENABLED_CHECKWAITSTATE=yes + AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_CHECK_WAIT_STATE" +fi # HARDEN FLAGS @@ -249,11 +314,13 @@ AM_CONDITIONAL([BUILD_WRAPPER], [test "x$ENABLED_WRAPPER" = "xyes"]) AM_CONDITIONAL([HAVE_LIBWOLFSSL], [test "x$ENABLED_WOLFCRYPT" = "xyes"]) AM_CONDITIONAL([BUILD_I2C], [test "x$ENABLED_I2C" = "xyes"]) AM_CONDITIONAL([BUILD_ADVIO], [test "x$ENABLED_ADVIO" = "xyes"]) -AM_CONDITIONAL([BUILD_ST33], [test "x$ENABLED_ST33" = "xyes"]) -AM_CONDITIONAL([BUILD_MCHP], [test "x$ENABLED_MCHP" = "xyes"]) +AM_CONDITIONAL([BUILD_ST], [test "x$ENABLED_ST" = "xyes"]) +AM_CONDITIONAL([BUILD_MICROCHIP], [test "x$ENABLED_MICROCHIP" = "xyes"]) AM_CONDITIONAL([BUILD_INFINEON], [test "x$ENABLED_INFINEON" = "xyes"]) AM_CONDITIONAL([BUILD_DEVTPM], [test "x$ENABLED_DEVTPM" = "xyes"]) AM_CONDITIONAL([BUILD_NUVOTON], [test "x$ENABLED_NUVOTON" = "xyes"]) +AM_CONDITIONAL([BUILD_CHECKWAITSTATE], [test "x$ENABLED_CHECKWAITSTATE" = "xyes"]) +AM_CONDITIONAL([BUILD_AUTODETECT], [test "x$ENABLED_AUTODETECT" = "xyes"]) @@ -367,9 +434,13 @@ echo " * Wrappers: $ENABLED_WRAPPER" echo " * Examples: $ENABLED_EXAMPLES" echo " * wolfCrypt: $ENABLED_WOLFCRYPT" echo " * Advanced IO: $ENABLED_ADVIO" -echo " * Infineon SLB9670 $ENABLED_INFINEON" -echo " * STM ST33: $ENABLED_ST33" -echo " * Microchip ATTPM20: $ENABLED_MCHP" echo " * I2C: $ENABLED_I2C" echo " * Linux kernel TPM device: $ENABLED_DEVTPM" +echo " * TIS/SPI Check Wait State: $ENABLED_CHECKWAITSTATE" + +echo " * Infineon SLB9670 $ENABLED_INFINEON" +echo " * STM ST33: $ENABLED_ST" +echo " * Microchip ATTPM20: $ENABLED_MICROCHIP" echo " * Nuvoton NPCT75x: $ENABLED_NUVOTON" + +echo " * Runtime Module Detection: $ENABLED_AUTODETECT" diff --git a/examples/bench/bench.c b/examples/bench/bench.c index 5817565..29d13e3 100644 --- a/examples/bench/bench.c +++ b/examples/bench/bench.c @@ -156,7 +156,7 @@ static int bench_sym_aes(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* storageKey, XMEMSET(&aesKey, 0, sizeof(aesKey)); rc = wolfTPM2_GetKeyTemplate_Symmetric(&publicTemplate, keyBits, algo, - YES, YES); + NO, YES); if (rc != 0) goto exit; rc = wolfTPM2_CreateAndLoadKey(dev, &aesKey, &storageKey->handle, &publicTemplate, (byte*)gUsageAuth, sizeof(gUsageAuth)-1); diff --git a/examples/native/native_test.c b/examples/native/native_test.c index 5c1b30e..8d951b7 100644 --- a/examples/native/native_test.c +++ b/examples/native/native_test.c @@ -98,14 +98,10 @@ int TPM2_Native_Test(void* userCtx) ECC_Parameters_In eccParam; ECDH_KeyGen_In ecdh; ECDH_ZGen_In ecdhZ; - #ifdef WOLFTPM_MCHP - EncryptDecrypt_In encDec; - #else EncryptDecrypt2_In encDec; - #endif HMAC_In hmac; HMAC_Start_In hmacStart; -#ifdef WOLFTPM_ST33 +#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) SetCommandSet_In setCmdSet; #endif byte maxInput[MAX_COMMAND_SIZE]; @@ -137,11 +133,7 @@ int TPM2_Native_Test(void* userCtx) ECC_Parameters_Out eccParam; ECDH_KeyGen_Out ecdh; ECDH_ZGen_Out ecdhZ; - #ifdef WOLFTPM_MCHP - EncryptDecrypt_Out encDec; - #else EncryptDecrypt2_Out encDec; - #endif HMAC_Out hmac; HMAC_Start_Out hmacStart; byte maxOutput[MAX_RESPONSE_SIZE]; @@ -1195,17 +1187,19 @@ int TPM2_Native_Test(void* userCtx) session[0].auth.size = 0; XMEMSET(session[0].auth.buffer, 0, sizeof(session[0].auth.buffer)); -#ifdef WOLFTPM_ST33 - /* Enable TPM2_EncryptDecrypt2 command */ - XMEMSET(&cmdIn.setCmdSet, 0, sizeof(cmdIn.setCmdSet)); - cmdIn.setCmdSet.authHandle = TPM_RH_PLATFORM; - cmdIn.setCmdSet.commandCode = TPM_CC_EncryptDecrypt2; - cmdIn.setCmdSet.enableFlag = 1; - rc = TPM2_SetCommandSet(&cmdIn.setCmdSet); - if (rc != TPM_RC_SUCCESS) { - printf("TPM2_SetCommandSet failed 0x%x: %s\n", rc, - TPM2_GetRCString(rc)); - goto exit; +#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) + if (TPM2_GetVendorID() == TPM_VENDOR_STM) { + /* Enable TPM2_EncryptDecrypt2 command */ + XMEMSET(&cmdIn.setCmdSet, 0, sizeof(cmdIn.setCmdSet)); + cmdIn.setCmdSet.authHandle = TPM_RH_PLATFORM; + cmdIn.setCmdSet.commandCode = TPM_CC_EncryptDecrypt2; + cmdIn.setCmdSet.enableFlag = 1; + rc = TPM2_SetCommandSet(&cmdIn.setCmdSet); + if (rc != TPM_RC_SUCCESS) { + printf("TPM2_SetCommandSet failed 0x%x: %s\n", rc, + TPM2_GetRCString(rc)); + goto exit; + } } #endif @@ -1221,16 +1215,9 @@ int TPM2_Native_Test(void* userCtx) cmdIn.create.inSensitive.sensitive.userAuth.size); cmdIn.create.inPublic.publicArea.type = TPM_ALG_SYMCIPHER; cmdIn.create.inPublic.publicArea.nameAlg = TPM_ALG_SHA256; -#ifdef WOLFTPM_MCHP - /* workaround for issue with both sign and decrypt being set */ cmdIn.create.inPublic.publicArea.objectAttributes = ( TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | TPMA_OBJECT_noDA | TPMA_OBJECT_decrypt); -#else - cmdIn.create.inPublic.publicArea.objectAttributes = ( - TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | - TPMA_OBJECT_noDA | TPMA_OBJECT_sign | TPMA_OBJECT_decrypt); -#endif cmdIn.create.inPublic.publicArea.parameters.symDetail.sym.algorithm = TPM_ALG_AES; cmdIn.create.inPublic.publicArea.parameters.symDetail.sym.keyBits.aes = MAX_AES_KEY_BITS; cmdIn.create.inPublic.publicArea.parameters.symDetail.sym.mode.aes = TEST_AES_MODE; @@ -1275,11 +1262,7 @@ int TPM2_Native_Test(void* userCtx) XMEMCPY(cmdIn.encDec.inData.buffer, message.buffer, cmdIn.encDec.inData.size); cmdIn.encDec.decrypt = NO; cmdIn.encDec.mode = TEST_AES_MODE; -#ifdef WOLFTPM_MCHP - rc = TPM2_EncryptDecrypt(&cmdIn.encDec, &cmdOut.encDec); -#else rc = TPM2_EncryptDecrypt2(&cmdIn.encDec, &cmdOut.encDec); -#endif if (rc == TPM_RC_COMMAND_CODE) { /* some TPM's may not support command */ printf("TPM2_EncryptDecrypt2: Is not a supported feature without enabling due to export controls\n"); } @@ -1298,11 +1281,7 @@ int TPM2_Native_Test(void* userCtx) cmdOut.encDec.outData.size); cmdIn.encDec.decrypt = YES; cmdIn.encDec.mode = TEST_AES_MODE; -#ifdef WOLFTPM_MCHP - rc = TPM2_EncryptDecrypt(&cmdIn.encDec, &cmdOut.encDec); -#else rc = TPM2_EncryptDecrypt2(&cmdIn.encDec, &cmdOut.encDec); -#endif if (rc == TPM_RC_COMMAND_CODE) { /* some TPM's may not support command */ printf("TPM2_EncryptDecrypt2: Is not a supported feature without enabling due to export controls\n"); } diff --git a/examples/tpm_io.c b/examples/tpm_io.c index 51b9d55..dc67866 100644 --- a/examples/tpm_io.c +++ b/examples/tpm_io.c @@ -62,18 +62,26 @@ #else /* SPI */ #ifdef WOLFTPM_MCHP - /* Microchip ATTPM20 */ - /* SPI uses CE0 */ - #define TPM2_SPI_DEV "/dev/spidev0.0" + /* Microchip ATTPM20 uses CE0 */ + #define TPM2_SPI_DEV_CS "0" #elif defined(WOLFTPM_ST33) /* STM ST33HTPH SPI uses CE0 */ - #define TPM2_SPI_DEV "/dev/spidev0.0" + #define TPM2_SPI_DEV_CS "0" #elif defined(WOLFTPM_NUVOTON) /* Nuvoton NPCT75x uses CE0 */ #define TPM2_SPI_DEV_CS "0" #else /* OPTIGA SLB9670 and LetsTrust TPM use CE1 */ - #define TPM2_SPI_DEV "/dev/spidev0.1" + #define TPM2_SPI_DEV_CS "1" + #endif + + #ifdef WOLFTPM_AUTODETECT + #undef TPM2_SPI_DEV + /* this will try incrementing spidev chip selects */ + static char TPM2_SPI_DEV[] = "/dev/spidev0.0"; + #define MAX_SPI_DEV_CS '4' + static int foundSpiDev = 0; + #else #define TPM2_SPI_DEV "/dev/spidev0."TPM2_SPI_DEV_CS #endif #endif @@ -215,6 +223,10 @@ int mode = 0; /* Mode 0 (CPOL=0, CPHA=0) */ int bits_per_word = 8; /* 8-bits */ + #ifdef WOLFTPM_AUTODETECT + tryagain: + #endif + spiDev = open(TPM2_SPI_DEV, O_RDWR); if (spiDev >= 0) { struct spi_ioc_transfer spi; @@ -276,6 +288,27 @@ close(spiDev); } + + #ifdef WOLFTPM_AUTODETECT + /* if response is not 0xFF then we "found" something */ + if (!foundSpiDev) { + if (rxBuf[0] != 0xFF) { + #ifdef DEBUG_WOLFTPM + printf("Found TPM @ %s\n", TPM2_SPI_DEV); + #endif + foundSpiDev = 1; + } + else { + int devLen = (int)XSTRLEN(TPM2_SPI_DEV); + /* tries spidev0.[0-4] */ + if (TPM2_SPI_DEV[devLen-1] <= MAX_SPI_DEV_CS) { + TPM2_SPI_DEV[devLen-1]++; + goto tryagain; + } + } + } + #endif + (void)ctx; (void)userCtx; diff --git a/examples/wrap/wrap_test.c b/examples/wrap/wrap_test.c index 20cd3cc..636c9f6 100644 --- a/examples/wrap/wrap_test.c +++ b/examples/wrap/wrap_test.c @@ -185,7 +185,7 @@ int TPM2_Wrapper_Test(void* userCtx) rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent | TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | - TPMA_OBJECT_restricted | TPMA_OBJECT_sign | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA); + TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA); if (rc != 0) goto exit; rc = wolfTPM2_CreatePrimaryKey(&dev, &storageKey, TPM_RH_OWNER, &publicTemplate, (byte*)gStorageKeyAuth, sizeof(gStorageKeyAuth)-1); @@ -775,7 +775,7 @@ int TPM2_Wrapper_Test(void* userCtx) rc = wolfTPM2_GetKeyTemplate_Symmetric(&publicTemplate, 128, TEST_AES_MODE, - YES, YES); + NO, YES); if (rc != 0) goto exit; rc = wolfTPM2_CreateAndLoadKey(&dev, &aesKey, &storageKey.handle, &publicTemplate, (byte*)gUsageAuth, sizeof(gUsageAuth)-1); diff --git a/src/tpm2.c b/src/tpm2.c index 73ba261..7c70ae6 100755 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -4604,7 +4604,7 @@ TPM_RC TPM2_NV_Certify(NV_Certify_In* in, NV_Certify_Out* out) /******************************************************************************/ /* --- BEGIN Manufacture Specific TPM API's -- */ /******************************************************************************/ -#ifdef WOLFTPM_ST33 +#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) int TPM2_SetCommandSet(SetCommandSet_In* in) { TPM_RC rc; @@ -5102,6 +5102,16 @@ int TPM2_ParseAttest(const TPM2B_ATTEST* in, TPMS_ATTEST* out) return TPM_RC_SUCCESS; } +UINT16 TPM2_GetVendorID(void) +{ + UINT16 vid = 0; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + if (ctx) { + vid = (UINT16)(ctx->did_vid & 0xFFFF); + } + return vid; +} + #ifdef DEBUG_WOLFTPM #define LINE_LEN 16 void TPM2_PrintBin(const byte* buffer, word32 length) diff --git a/src/tpm2_tis.c b/src/tpm2_tis.c index c7c97c7..fc55b02 100644 --- a/src/tpm2_tis.c +++ b/src/tpm2_tis.c @@ -376,36 +376,37 @@ int TPM2_TIS_Ready(TPM2_CTX* ctx) int TPM2_TIS_GetBurstCount(TPM2_CTX* ctx, word16* burstCount) { int rc = TPM_RC_SUCCESS; -#ifndef WOLFTPM_ST33 - int timeout = TPM_TIMEOUT_TRIES; -#endif if (burstCount == NULL) return BAD_FUNC_ARG; -#ifdef WOLFTPM_ST33 - *burstCount = 32; /* fixed value */ - (void)ctx; -#else - *burstCount = 0; - do { - rc = TPM2_TIS_Read(ctx, TPM_BURST_COUNT(ctx->locality), - (byte*)burstCount, sizeof(*burstCount)); - if (rc == TPM_RC_SUCCESS && *burstCount > 0) - break; - XTPM_WAIT(); - } while (rc == TPM_RC_SUCCESS && --timeout > 0); - -#ifdef WOLFTPM_DEBUG_TIMEOUT - printf("TIS_GetBurstCount: Timeout %d\n", TPM_TIMEOUT_TRIES - timeout); +#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) + if (TPM2_GetVendorID() == TPM_VENDOR_STM) { + *burstCount = 32; /* fixed value */ + } + else #endif + { + int timeout = TPM_TIMEOUT_TRIES; + *burstCount = 0; + do { + rc = TPM2_TIS_Read(ctx, TPM_BURST_COUNT(ctx->locality), + (byte*)burstCount, sizeof(*burstCount)); + if (rc == TPM_RC_SUCCESS && *burstCount > 0) + break; + XTPM_WAIT(); + } while (rc == TPM_RC_SUCCESS && --timeout > 0); - if (*burstCount > MAX_SPI_FRAMESIZE) - *burstCount = MAX_SPI_FRAMESIZE; + #ifdef WOLFTPM_DEBUG_TIMEOUT + printf("TIS_GetBurstCount: Timeout %d\n", TPM_TIMEOUT_TRIES - timeout); + #endif - if (timeout <= 0) - return TPM_RC_TIMEOUT; -#endif + if (*burstCount > MAX_SPI_FRAMESIZE) + *burstCount = MAX_SPI_FRAMESIZE; + + if (timeout <= 0) + return TPM_RC_TIMEOUT; + } return rc; } @@ -473,17 +474,20 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz) } } -#ifndef WOLFTPM_ST33 - /* Wait for TPM_STS_DATA_EXPECT = 0 and TPM_STS_VALID = 1 */ - rc = TPM2_TIS_WaitForStatus(ctx, TPM_STS_DATA_EXPECT | TPM_STS_VALID, - TPM_STS_VALID); - if (rc != TPM_RC_SUCCESS) { - #ifdef DEBUG_WOLFTPM - printf("TPM2_TIS_SendCommand status valid timeout!\n"); - #endif - goto exit; - } +#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) + if (TPM2_GetVendorID() != TPM_VENDOR_STM) #endif + { + /* Wait for TPM_STS_DATA_EXPECT = 0 and TPM_STS_VALID = 1 */ + rc = TPM2_TIS_WaitForStatus(ctx, TPM_STS_DATA_EXPECT | TPM_STS_VALID, + TPM_STS_VALID); + if (rc != TPM_RC_SUCCESS) { + #ifdef DEBUG_WOLFTPM + printf("TPM2_TIS_SendCommand status valid timeout!\n"); + #endif + goto exit; + } + } /* Execute Command */ access = TPM_STS_GO; diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 77ca7bf..e77c82d 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -2743,7 +2743,7 @@ int wolfTPM2_LoadSymmetricKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, int alg, /* Setup public key */ rc = wolfTPM2_GetKeyTemplate_Symmetric(&loadExtIn.inPublic.publicArea, - keySz * 8, alg, YES, YES); + keySz * 8, alg, NO, YES); if (rc != 0) goto exit; loadExtIn.inPublic.publicArea.nameAlg = hashAlg; @@ -2786,13 +2786,8 @@ int wolfTPM2_EncryptDecryptBlock(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, int isDecrypt) { int rc; -#ifdef WOLFTPM_MCHP - EncryptDecrypt_In encDecIn; - EncryptDecrypt_Out encDecOut; -#else EncryptDecrypt2_In encDecIn; EncryptDecrypt2_Out encDecOut; -#endif if (dev == NULL || key == NULL || in == NULL || out == NULL || inOutSz == 0) { return BAD_FUNC_ARG; @@ -2821,21 +2816,13 @@ int wolfTPM2_EncryptDecryptBlock(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, encDecIn.inData.size = (encDecIn.inData.size + MAX_AES_BLOCK_SIZE_BYTES - 1) & ~(MAX_AES_BLOCK_SIZE_BYTES - 1); -#ifdef WOLFTPM_MCHP - rc = TPM2_EncryptDecrypt(&encDecIn, &encDecOut); -#else rc = TPM2_EncryptDecrypt2(&encDecIn, &encDecOut); -#endif if (rc == TPM_RC_COMMAND_CODE) { /* some TPM's may not support command */ /* try to enable support */ rc = wolfTPM2_SetCommand(dev, TPM_CC_EncryptDecrypt2, YES); if (rc == TPM_RC_SUCCESS) { /* try command again */ - #ifdef WOLFTPM_MCHP - rc = TPM2_EncryptDecrypt(&encDecIn, &encDecOut); - #else rc = TPM2_EncryptDecrypt2(&encDecIn, &encDecOut); - #endif } } @@ -2897,26 +2884,27 @@ int wolfTPM2_EncryptDecrypt(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, int wolfTPM2_SetCommand(WOLFTPM2_DEV* dev, TPM_CC commandCode, int enableFlag) { - int rc; -#ifdef WOLFTPM_ST33 - SetCommandSet_In in; + int rc = TPM_RC_COMMAND_CODE; /* not supported */ +#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) + if (TPM2_GetVendorID() == TPM_VENDOR_STM) { + SetCommandSet_In in; - /* Enable commands (like TPM2_EncryptDecrypt2) */ - XMEMSET(&in, 0, sizeof(in)); - in.authHandle = TPM_RH_PLATFORM; - in.commandCode = commandCode; - in.enableFlag = enableFlag; - rc = TPM2_SetCommandSet(&in); - if (rc != TPM_RC_SUCCESS) { - #ifdef DEBUG_WOLFTPM - printf("TPM2_SetCommandSet failed 0x%x: %s\n", rc, - TPM2_GetRCString(rc)); - #endif + /* Enable commands (like TPM2_EncryptDecrypt2) */ + XMEMSET(&in, 0, sizeof(in)); + in.authHandle = TPM_RH_PLATFORM; + in.commandCode = commandCode; + in.enableFlag = enableFlag; + rc = TPM2_SetCommandSet(&in); + if (rc != TPM_RC_SUCCESS) { + #ifdef DEBUG_WOLFTPM + printf("TPM2_SetCommandSet failed 0x%x: %s\n", rc, + TPM2_GetRCString(rc)); + #endif + } } #else (void)commandCode; (void)enableFlag; - rc = TPM_RC_COMMAND_CODE; /* not supported */ #endif (void)dev; return rc; @@ -3239,13 +3227,6 @@ int wolfTPM2_GetKeyTemplate_Symmetric(TPMT_PUBLIC* publicTemplate, int keyBits, if (publicTemplate == NULL) return BAD_FUNC_ARG; -#ifdef WOLFTPM_MCHP - /* workaround for issue with both sign and decrypt being set */ - if (isSign && isDecrypt) { - isSign = NO; - } -#endif - XMEMSET(publicTemplate, 0, sizeof(TPMT_PUBLIC)); publicTemplate->type = TPM_ALG_SYMCIPHER; publicTemplate->nameAlg = WOLFTPM2_WRAP_DIGEST; diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index 13d9e1b..b29bc84 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -227,7 +227,7 @@ typedef enum { CC_VEND = 0x20000000, TPM_CC_Vendor_TCG_Test = CC_VEND + 0x0000, -#ifdef WOLFTPM_ST33 +#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) TPM_CC_SetMode = CC_VEND + 0x0307, TPM_CC_SetCommandSet = CC_VEND + 0x0309, TPM_CC_RestoreEK = CC_VEND + 0x030A, @@ -2704,7 +2704,7 @@ WOLFTPM_API TPM_RC TPM2_NV_Certify(NV_Certify_In* in, NV_Certify_Out* out); /* Vendor Specific API's */ -#ifdef WOLFTPM_ST33 +#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) typedef struct { TPMI_RH_HIERARCHY authHandle; TPM_CC commandCode; @@ -2732,7 +2732,7 @@ typedef struct { TPM_MODE_SET modeSet; } SetMode_In; WOLFTPM_API int TPM2_SetMode(SetMode_In* in); -#endif /* WOLFTPM_ST33 */ +#endif /* WOLFTPM_ST33 || WOLFTPM_AUTODETECT */ /* Non-standard API's */ #define _TPM_Init TPM2_Init @@ -2768,6 +2768,17 @@ WOLFTPM_API int TPM2_ParseAttest(const TPM2B_ATTEST* in, TPMS_ATTEST* out); WOLFTPM_API int TPM2_GetWolfRng(WC_RNG** rng); #endif +typedef enum { + TPM_VENDOR_UNKNOWN = 0, + TPM_VENDOR_INFINEON = 0x15d1, + TPM_VENDOR_STM = 0x104a, + TPM_VENDOR_MCHP = 0x1114, + TPM_VENDOR_NUVOTON = 0x1050, + TPM_VENDOR_NATIONTECH = 0x1B4E, +} TPM_Vendor_t; + +WOLFTPM_API UINT16 TPM2_GetVendorID(void); + #ifdef DEBUG_WOLFTPM WOLFTPM_API void TPM2_PrintBin(const byte* buffer, word32 length); #else diff --git a/wolftpm/tpm2_types.h b/wolftpm/tpm2_types.h index d187863..2d9208f 100644 --- a/wolftpm/tpm2_types.h +++ b/wolftpm/tpm2_types.h @@ -150,11 +150,12 @@ typedef int64_t INT64; /* ---------------------------------------------------------------------------*/ /* TPM HARDWARE TYPE */ /* ---------------------------------------------------------------------------*/ +/* Microchip ATTPM20 */ +/* #define WOLFTPM_MCHP */ + /* ST ST33TP TPM 2.0 */ /* #define WOLFTPM_ST33 */ -/* Microchip ATTPM20 */ -/* #define WOLFTPM_MCHP */ /* Nuvoton NPCT75x TPM 2.0 module */ /* #define WOLFTPM_NUVOTON */ @@ -211,6 +212,21 @@ typedef int64_t INT64; #endif #endif +/* Auto-chip detection requires SPI wait state support and safe SPI bus speed */ +#ifdef WOLFTPM_AUTODETECT + /* SPI wait state checking must be enabled */ + #undef WOLFTPM_CHECK_WAIT_STATE + #define WOLFTPM_CHECK_WAIT_STATE + + /* use a safe MHz (minimum of above) */ + #undef TPM2_SPI_MAX_HZ + #define TPM2_SPI_MAX_HZ 33000000 + + /* always perform self-test (some chips require) */ + #undef WOLFTPM_PERFORM_SELFTEST + #define WOLFTPM_PERFORM_SELFTEST +#endif + /* ---------------------------------------------------------------------------*/