diff --git a/.gitignore b/.gitignore index 4179de0..b5db98e 100644 --- a/.gitignore +++ b/.gitignore @@ -87,6 +87,8 @@ ak.name cred.blob ek.pub srk.pub +ak.pem +ek.pem # Generated Documentation docs/html diff --git a/ChangeLog.md b/ChangeLog.md index af7f904..ddbf60d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,44 @@ # Release Notes +## wolfTPM Release 2.2 (07/13/2021) + +**Summary** + +Added new examples for remote attestation, make credential and GPIO support. Added Endorsement hierarchy support to many examples. Refactored the reference HAL IO code into separate files. + +**Detail** + +* Fixed total auth area size when multiple auth sessions are used (PR #174) +* Fixed `TPM2_SetupPCRSel` to only allow valid pcrIndex values (PR #165 and PR #167) +* Fixed `TPM2_MakeCredential` to work without auth as TCG spec defines (PR #174) +* Fixed `TPM2_MakeCredential` to support using EK pub to encrypt challenge (PR #174) +* Fixed `TPM2_ActivateCredential` to work with EK pub to decrypt challenge (PR #174) +* Fix to only enable `printf` in library proper if `DEBUG_WOLFTPM` is set (PR #154) +* Added support for QNX with wolfTPM (PR #156) +* Added credential examples for remote attestation (PR #161) +* Added new example for sealing a secret using TPM key (PR #157) +* Added GPIO config, read and set examples (PR #155 and #172) +* Added GPIO support and examples for ST33 (PR #155) +* Added GPIO support and examples for Nuvoton NPCT75x (PR #172) +* Added Endorsement support for keygen and attestation examples using `-eh` (PR #174) +* Added missing `TPM2_CreateLoaded` command and added wrapper `wolfTPM2_CreateLoadedKey` (PR #174) +* Added new wrappers for public PEM support `wolfTPM2_RsaKey_TpmToPemPub` and `wolfTPM2_RsaKey_PemPubToTpm` (PR #174) +* Added keygen option to output PEM files for TPM public keys (PR #174) +* Added saving of EK's TPM2B_PUBLIC for attestation purposes (PR #174) +* Added new wrapper for satisfying EK policy (PR #174) +* Added unit test for `TPM2_CertifyCreation` (PR #169) +* Added support for `--with-wolfcrypt=/dir/` (PR #166) +* Added documentation for using QEMU with `--enable-devtpm` for testing (PR #146) +* Modified keygen to use new `wolfTPM2_CreateLoaded` wrapper to acquire correct AK name (PR #174) +* Modified keyload to be able to load keys created under the EK/EH (PR #174) +* Cleanup the ECC point code to appease some coverity warnings (PR #168) +* Cleanup obsolete `txBuf[4] = 0x00;` because handled with SPI check wait state logic (PR #162) +* Improved API documentation using Doxygen for wolfTPM wrappers and proprietary API's (PR #164) +* Improved the Windows TBS documentation (PR #163) +* Refactor the assignment of structs to use memcpy (PR #176) +* Refactor of the TPM IO code to separate files (PR #171) + + ## wolfTPM Release 2.1 (03/17/2021) * Fixed possible KDFa buffer overrun (PR #147) diff --git a/configure.ac b/configure.ac index fe3eebc..f646a25 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ # All right reserved. AC_COPYRIGHT([Copyright (C) 2014-2021 wolfSSL Inc.]) -AC_INIT([wolftpm],[2.1.0],[https://github.com/wolfssl/wolfTPM/issues],[wolftpm],[http://www.wolfssl.com]) +AC_INIT([wolftpm],[2.2.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=11:0:0 +WOLFTPM_LIBRARY_VERSION=12:0:0 # | | | # +------+ | +---+ # | | | diff --git a/examples/README.md b/examples/README.md index aeba6e8..3d5cf9a 100644 --- a/examples/README.md +++ b/examples/README.md @@ -401,7 +401,6 @@ Using the `seal` example we store securely our data in a newly generated TPM 2.0 Please find example output from sealing and unsealing a secret message: ``` - $ ./examples/seal/seal keyblob.bin mySecretMessage TPM2.0 Simple Seal example Key Blob: keyblob.bin @@ -431,7 +430,6 @@ Stored unsealed data to file = message.raw $ cat message.raw mySecretMessage - ``` After a successful unsealing, the data is stored into a new file. If no filename is provided, the `unseal` tool stores the data in `unseal.bin`. @@ -497,7 +495,7 @@ NV Index for GPIO access created ### GPIO Config (NPCT75xx) -NPCT75x supports 3 output modes, information from `gpio/gpio_nuvoton` below: +NPCT75x supports 3 output modes (no input modes), information from `gpio/gpio_nuvoton` below: ``` $ ./examples/gpio/gpio_nuvoton -h diff --git a/examples/attestation/activate_credential.c b/examples/attestation/activate_credential.c index 0dd7cb1..c314274 100644 --- a/examples/attestation/activate_credential.c +++ b/examples/attestation/activate_credential.c @@ -148,6 +148,7 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[]) printf("AK loaded at 0x%x\n", (word32)akKey.handle.hndl); rc = wolfTPM2_UnsetAuth(&dev, 0); + if (rc != 0) goto exit; if (endorseKey) { /* Fresh policy session for EK auth */ @@ -178,8 +179,10 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[]) if (fp != XBADFILE) { dataSize = (int)XFREAD((BYTE*)&cmdIn.activCred.credentialBlob, 1, sizeof(cmdIn.activCred.credentialBlob), fp); - dataSize = (int)XFREAD((BYTE*)&cmdIn.activCred.secret, 1, - sizeof(cmdIn.activCred.secret), fp); + if (dataSize > 0) { + dataSize += (int)XFREAD((BYTE*)&cmdIn.activCred.secret, 1, + sizeof(cmdIn.activCred.secret), fp); + } XFCLOSE(fp); } printf("Read credential blob and secret from %s, %d bytes\n", diff --git a/examples/attestation/make_credential.c b/examples/attestation/make_credential.c index 3238c89..7a9b7e1 100644 --- a/examples/attestation/make_credential.c +++ b/examples/attestation/make_credential.c @@ -141,6 +141,7 @@ int TPM2_MakeCredential_Example(void* userCtx, int argc, char *argv[]) printf("Public key for encryption loaded\n"); handle.hndl = cmdOut.loadExtOut.objectHandle; +#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM) /* Load AK Name digest */ fp = XFOPEN("ak.name", "rb"); if (fp != XBADFILE) { @@ -148,6 +149,7 @@ int TPM2_MakeCredential_Example(void* userCtx, int argc, char *argv[]) printf("Read AK Name digest\n"); XFCLOSE(fp); } +#endif /* Create secret for the attestation server */ cmdIn.makeCred.credential.size = CRED_SECRET_SIZE; @@ -172,8 +174,10 @@ int TPM2_MakeCredential_Example(void* userCtx, int argc, char *argv[]) if (fp != XBADFILE) { dataSize = (int)XFWRITE((BYTE*)&cmdOut.makeCred.credentialBlob, 1, sizeof(cmdOut.makeCred.credentialBlob), fp); - dataSize = (int)XFWRITE((BYTE*)&cmdOut.makeCred.secret, 1, - sizeof(cmdOut.makeCred.secret), fp); + if (dataSize > 0) { + dataSize += (int)XFWRITE((BYTE*)&cmdOut.makeCred.secret, 1, + sizeof(cmdOut.makeCred.secret), fp); + } XFCLOSE(fp); } printf("Wrote credential blob and secret to %s, %d bytes\n", diff --git a/examples/gpio/gpio_config.c b/examples/gpio/gpio_config.c index 4373f5c..2d62142 100644 --- a/examples/gpio/gpio_config.c +++ b/examples/gpio/gpio_config.c @@ -23,7 +23,8 @@ #include -#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) +#if !defined(WOLFTPM2_NO_WRAPPER) && \ + (defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)) #include #include @@ -245,14 +246,15 @@ exit_badargs: /******************************************************************************/ /* --- END TPM2.0 GPIO Configuration example -- */ /******************************************************************************/ -#endif /* WOLFTPM_ST33 || WOLFTPM_AUTODETECT */ +#endif /* !WOLFTPM2_NO_WRAPPER && (WOLFTPM_ST33 || WOLFTPM_AUTODETECT) */ #ifndef NO_MAIN_DRIVER int main(int argc, char *argv[]) { int rc = -1; -#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) +#if !defined(WOLFTPM2_NO_WRAPPER) && \ + (defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)) rc = TPM2_GPIO_Config_Example(NULL, argc, argv); #else printf("GPIO configuration requires an ST33 TPM 2.0 module built with WOLFTPM_ST33 or --enable-st33\n"); diff --git a/examples/keygen/keygen.c b/examples/keygen/keygen.c index 00ac8d0..509a951 100644 --- a/examples/keygen/keygen.c +++ b/examples/keygen/keygen.c @@ -129,14 +129,16 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[]) int bAIK = 1; int keyBits = 256; const char *outputFile = "keyblob.bin"; - const char *nameFile = "ak.name"; /* Name Digest for attestation purposes */ const char *ekPubFile = "ek.pub"; const char *srkPubFile = "srk.pub"; const char *pubFilename = NULL; +#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM) + const char *nameFile = "ak.name"; /* Name Digest for attestation purposes */ const char *pemFilename = NULL; + FILE *fp; +#endif size_t len = 0; char symMode[] = "aesctr"; - FILE *fp; if (argc >= 2) { if (XSTRNCMP(argv[1], "-?", 2) == 0 || @@ -348,6 +350,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[]) if (rc == 0) { rc = writeKeyPubPem(pemFilename, pem, pemSz); } + if (rc != 0) goto exit; pemFilename = (bAIK) ? pemFileAk : pemFileKey; pemSz = (word32)sizeof(pem); diff --git a/examples/keygen/keyload.c b/examples/keygen/keyload.c index ef503cf..a44d2eb 100644 --- a/examples/keygen/keyload.c +++ b/examples/keygen/keyload.c @@ -119,7 +119,7 @@ int TPM2_Keyload_Example(void* userCtx, int argc, char *argv[]) primary = &endorse; } else { /* SRK */ - rc = getPrimaryStoragekey(&dev, primary, TPM_ALG_RSA); + rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA); if (rc != 0) goto exit; primary = &storage; } diff --git a/examples/tls/tls_server.c b/examples/tls/tls_server.c index a8e5e9c..75628bb 100644 --- a/examples/tls/tls_server.c +++ b/examples/tls/tls_server.c @@ -513,6 +513,9 @@ exit: #ifdef HAVE_ECC wc_ecc_free(&wolfEccKey); wolfTPM2_UnloadHandle(&dev, &eccKey.handle); + #ifndef WOLFTPM2_USE_SW_ECDHE + wolfTPM2_UnloadHandle(&dev, &ecdhKey.handle); + #endif #endif wolfTPM2_UnloadHandle(&dev, &tpmSession.handle); diff --git a/examples/tpm_test_keys.c b/examples/tpm_test_keys.c index 400c5de..4f224fb 100644 --- a/examples/tpm_test_keys.c +++ b/examples/tpm_test_keys.c @@ -39,13 +39,13 @@ int writeKeyPubPem(const char* filename, byte *buf, int bufSz) { int rc = TPM_RC_FAILURE; + if (filename == NULL || buf == NULL) + return BAD_FUNC_ARG; + #if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM) XFILE fp = NULL; size_t fileSz = 0; - if (filename == NULL || buf == NULL) - return BAD_FUNC_ARG; - fp = XFOPEN(filename, "wt"); if (fp != XBADFILE) { fileSz = XFWRITE(buf, 1, bufSz, fp); @@ -59,6 +59,8 @@ int writeKeyPubPem(const char* filename, byte *buf, int bufSz) #endif XFCLOSE(fp); } +#else + (void)bufSz; #endif return rc; } diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 71e0aeb..709f650 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -1788,7 +1788,8 @@ int wolfTPM2_RsaKey_TpmToPemPub(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey, byte* pem, word32* pemSz) { int rc = TPM_RC_FAILURE; -#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_DER_TO_PEM) +#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_DER_TO_PEM) && \ + (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) RsaKey rsaKey; byte* derBuf = NULL; int derSz = 0; @@ -1797,7 +1798,9 @@ int wolfTPM2_RsaKey_TpmToPemPub(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey, if (dev == NULL || tpmKey == NULL || pem == NULL || pemSz == NULL) return BAD_FUNC_ARG; -#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_DER_TO_PEM) +#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_DER_TO_PEM) && \ + (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) + /* Prepare wolfCrypt key structure */ rc = wc_InitRsaKey(&rsaKey, NULL); if (rc == 0) { diff --git a/wolftpm/version.h b/wolftpm/version.h index a5d9985..5210d1d 100644 --- a/wolftpm/version.h +++ b/wolftpm/version.h @@ -34,8 +34,8 @@ extern "C" { #endif -#define LIBWOLFTPM_VERSION_STRING "2.1.0" -#define LIBWOLFTPM_VERSION_HEX 0x02001000 +#define LIBWOLFTPM_VERSION_STRING "2.2.0" +#define LIBWOLFTPM_VERSION_HEX 0x02002000 #ifdef __cplusplus }