From 5c275008c8fb74e6a2cec4e2b1c9aa24fa404185 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 14 Aug 2024 16:56:47 -0700 Subject: [PATCH] Added example for TPM2_Certify. Extended create_primary example to support creation of initial device and attestation keys. Added new build option for TPM provisioning. --- .github/workflows/make-test-swtpm.yml | 6 + configure.ac | 11 + examples/attestation/activate_credential.c | 2 +- .../{credential.h => attestation.h} | 9 +- examples/attestation/certify.c | 203 +++++++++++ examples/attestation/include.am | 19 +- examples/attestation/make_credential.c | 2 +- examples/keygen/create_primary.c | 58 ++- examples/management/flush.c | 23 +- examples/native/native_test.c | 25 +- examples/run_examples.sh | 30 ++ src/tpm2_wrap.c | 344 ++++++++++++------ wolftpm/tpm2.h | 61 ++++ wolftpm/tpm2_wrap.h | 64 +++- 14 files changed, 703 insertions(+), 154 deletions(-) rename examples/attestation/{credential.h => attestation.h} (87%) create mode 100644 examples/attestation/certify.c diff --git a/.github/workflows/make-test-swtpm.yml b/.github/workflows/make-test-swtpm.yml index e61e8528..8650023a 100644 --- a/.github/workflows/make-test-swtpm.yml +++ b/.github/workflows/make-test-swtpm.yml @@ -138,6 +138,12 @@ jobs: - name: make pedantic run: make +# build not provisioning + - name: configure not provisioning + run: ./configure --disable-provisioning + - name: make not provisioning + run: make + # capture logs on failure - name: Upload failure logs if: failure() diff --git a/configure.ac b/configure.ac index 803c1d2d..fd7b2013 100644 --- a/configure.ac +++ b/configure.ac @@ -418,6 +418,17 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_FIRMWARE_UPGRADE" fi +# Enable support for provisioning identity keys for device and attestation +AC_ARG_ENABLE([provisioning], + [AS_HELP_STRING([--enable-provisioning],[Enable support for Provisioning Initial Device Identity (IDevID) and Attestation Identity Keys (default: enabled)])], + [ ENABLED_PROVISIONING=$enableval ], + [ ENABLED_PROVISIONING=yes ] + ) +if test "x$ENABLED_PROVISIONING" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_PROVISIONING" +fi + # HARDEN FLAGS AX_HARDEN_CC_COMPILER_FLAGS diff --git a/examples/attestation/activate_credential.c b/examples/attestation/activate_credential.c index d58b1a6a..32294710 100644 --- a/examples/attestation/activate_credential.c +++ b/examples/attestation/activate_credential.c @@ -33,7 +33,7 @@ #ifndef WOLFTPM2_NO_WRAPPER -#include +#include #include #include #include diff --git a/examples/attestation/credential.h b/examples/attestation/attestation.h similarity index 87% rename from examples/attestation/credential.h rename to examples/attestation/attestation.h index 68266e7b..540995d2 100644 --- a/examples/attestation/credential.h +++ b/examples/attestation/attestation.h @@ -1,4 +1,4 @@ -/* credential.h +/* attestation.h * * Copyright (C) 2006-2024 wolfSSL Inc. * @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifndef _CREDENTIAL_H_ -#define _CREDENTIAL_H_ +#ifndef _ATTESTATION_H_ +#define _ATTESTATION_H_ #ifdef __cplusplus extern "C" { @@ -30,9 +30,10 @@ int TPM2_MakeCredential_Example(void* userCtx, int argc, char *argv[]); int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[]); +int TPM2_Certify_Example(void* userCtx, int argc, char *argv[]); #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* _CREDENTIAL_H_ */ +#endif /* _ATTESTATION_H_ */ diff --git a/examples/attestation/certify.c b/examples/attestation/certify.c new file mode 100644 index 00000000..7e47acee --- /dev/null +++ b/examples/attestation/certify.c @@ -0,0 +1,203 @@ +/* certify.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfTPM. + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* This example shows how to create a attestation for a key (like IAK) + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#include + +#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) + +#include +#include +#include +#include + + +/******************************************************************************/ +/* --- BEGIN TPM2.0 Certify example tool -- */ +/******************************************************************************/ + +static void usage(void) +{ + printf("Expected usage:\n"); + printf("./examples/attestation/certify [-rsa/-ecc] [-certify=] [-signer=]\n"); + printf("\t* -ecc/-rsa: RSA or ECC (default is RSA)\n"); + printf("\t* -certify=[handle] Key to certify (default 0x%x)\n", 0x80000000U); + printf("\t* -signer=[handle] Key to sign with (default 0x%x)\n", 0x80000001U); +} + +int TPM2_Certify_Example(void* userCtx, int argc, char *argv[]) +{ + int rc = -1; + WOLFTPM2_DEV dev; + WOLFTPM2_SESSION tpmSession; + TPM_HANDLE certifyHandle = 0x80000000; + TPM_HANDLE signerHandle = 0x80000001; + WOLFTPM2_KEY certify; + WOLFTPM2_KEY signer; + TPM_ALG_ID hashAlg = TPM_ALG_SHA256; + TPM_ALG_ID alg = TPM_ALG_RSA; + Certify_In certifyIn; + Certify_Out certifyOut; + const char keyCreationNonce[] = "RandomServerPickedCreationNonce"; + + if (argc >= 2) { + if (XSTRCMP(argv[1], "-?") == 0 || + XSTRCMP(argv[1], "-h") == 0 || + XSTRCMP(argv[1], "--help") == 0) { + usage(); + return 0; + } + } + while (argc > 1) { + if (XSTRCMP(argv[argc-1], "-ecc") == 0) { + alg = TPM_ALG_ECC; + } + else if (XSTRCMP(argv[argc-1], "-rsa") == 0) { + alg = TPM_ALG_RSA; + } + else if (XSTRNCMP(argv[argc-1], "-certify=", XSTRLEN("-certify=")) == 0) { + const char* certifyStr = argv[argc-1] + XSTRLEN("-certify="); + certifyHandle = (word32)XSTRTOL(certifyStr, NULL, 0); + } + else if (XSTRNCMP(argv[argc-1], "-signer=", XSTRLEN("-signer=")) == 0) { + const char* signerStr = argv[argc-1] + XSTRLEN("-signer="); + signerHandle = (word32)XSTRTOL(signerStr, NULL, 0); + } + else { + printf("Warning: Unrecognized option: %s\n", argv[argc-1]); + } + argc--; + } + + XMEMSET(&tpmSession, 0, sizeof(tpmSession)); + XMEMSET(&certify, 0, sizeof(certify)); + XMEMSET(&signer, 0, sizeof(signer)); + + printf("Certify 0x%x with 0x%x to generate TPM-signed attestation info\n", + certifyHandle, signerHandle); + + rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); + if (rc != TPM_RC_SUCCESS) { + printf("wolfTPM2_Init failed 0x%x: %s\n", rc, TPM2_GetRCString(rc)); + goto exit; + } + printf("wolfTPM2_Init: success\n"); + + /* Read public information for each handle */ + rc = wolfTPM2_ReadPublicKey(&dev, &certify, certifyHandle); + if (rc != 0) goto exit; + rc = wolfTPM2_ReadPublicKey(&dev, &signer, signerHandle); + if (rc != 0) goto exit; + + /* Start a policy session for using endorsement */ + rc = wolfTPM2_CreateAuthSession_EkPolicy(&dev, &tpmSession); + if (rc != 0) goto exit; + printf("EK Policy Session: Handle 0x%x\n", (word32)tpmSession.handle.hndl); + + /* satisfy policy for using certify command */ + rc = wolfTPM2_PolicyCommandCode(&dev, &tpmSession, TPM_CC_Certify); + if (rc != 0) goto exit; + + rc = wolfTPM2_SetAuthPassword(&dev, 1, NULL); + + /* Create signed certify structure */ + XMEMSET(&certifyIn, 0, sizeof(certifyIn)); + certifyIn.objectHandle = certifyHandle; + certifyIn.signHandle = signerHandle; + certifyIn.inScheme.scheme = + (alg == TPM_ALG_ECC) ? TPM_ALG_ECDSA : TPM_ALG_RSASSA;; + certifyIn.inScheme.details.any.hashAlg = hashAlg; + /* provide a random nonce from remote server (optional) */ + certifyIn.qualifyingData.size = sizeof(keyCreationNonce)-1; + XMEMCPY(certifyIn.qualifyingData.buffer, keyCreationNonce, + certifyIn.qualifyingData.size); + rc = TPM2_Certify(&certifyIn, &certifyOut); + if (rc != TPM_RC_SUCCESS) { + printf("TPM2_Certify RSA key failed 0x%x: %s\n", rc, + TPM2_GetRCString(rc)); + goto exit; + } + printf("TPM2_Certify complete\n"); + + printf("Certify Info %d\n", certifyOut.certifyInfo.size); + TPM2_PrintBin(certifyOut.certifyInfo.attestationData, + certifyOut.certifyInfo.size); + + if (certifyOut.signature.sigAlg == TPM_ALG_RSASSA) { + printf("RSA Signature: %d\n", + certifyOut.signature.signature.rsassa.sig.size); + TPM2_PrintBin(certifyOut.signature.signature.rsassa.sig.buffer, + certifyOut.signature.signature.rsassa.sig.size); + } + else if (certifyOut.signature.sigAlg == TPM_ALG_ECDSA) { + printf("ECDSA Signature R %d / S %d\n", + certifyOut.signature.signature.ecdsa.signatureR.size, + certifyOut.signature.signature.ecdsa.signatureS.size); + TPM2_PrintBin(certifyOut.signature.signature.ecdsa.signatureR.buffer, + certifyOut.signature.signature.ecdsa.signatureR.size); + TPM2_PrintBin(certifyOut.signature.signature.ecdsa.signatureS.buffer, + certifyOut.signature.signature.ecdsa.signatureS.size); + } + + /* Perform software verification of signature by hashing the attestation + * information and use the signer public key to verify the signature */ + +exit: + + if (rc != 0) { + printf("\nFailure 0x%x: %s\n\n", rc, wolfTPM2_GetRCString(rc)); + } + + wolfTPM2_UnloadHandle(&dev, &tpmSession.handle); + wolfTPM2_Cleanup(&dev); + + return rc; +} + +/******************************************************************************/ +/* --- END TPM2.0 Certify example tool -- */ +/******************************************************************************/ +#endif /* !WOLFTPM2_NO_WRAPPER && !WOLFTPM2_NO_WOLFCRYPT */ + +#ifndef NO_MAIN_DRIVER +int main(int argc, char *argv[]) +{ + int rc = -1; + +#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) + rc = TPM2_Certify_Example(NULL, argc, argv); +#else + printf("Wrapper or wolfCrypt code not compiled in\n"); + (void)argc; + (void)argv; +#endif /* !WOLFTPM2_NO_WRAPPER && !WOLFTPM2_NO_WOLFCRYPT */ + + return rc; +} +#endif diff --git a/examples/attestation/include.am b/examples/attestation/include.am index ba7484f7..19e4360e 100644 --- a/examples/attestation/include.am +++ b/examples/attestation/include.am @@ -3,27 +3,34 @@ if BUILD_EXAMPLES noinst_PROGRAMS += examples/attestation/make_credential \ - examples/attestation/activate_credential + examples/attestation/activate_credential \ + examples/attestation/certify -noinst_HEADERS += examples/attestation/credential.h +noinst_HEADERS += examples/attestation/attestation.h examples_attestation_make_credential_SOURCES = examples/attestation/make_credential.c \ examples/tpm_test_keys.c examples_attestation_make_credential_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD) examples_attestation_make_credential_DEPENDENCIES = src/libwolftpm.la -examples_attestation_activate_credential_SOURCES = examples/attestation/activate_credential.c \ - examples/tpm_test_keys.c +examples_attestation_activate_credential_SOURCES = examples/attestation/activate_credential.c \ + examples/tpm_test_keys.c examples_attestation_activate_credential_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD) examples_attestation_activate_credential_DEPENDENCIES = src/libwolftpm.la +examples_attestation_certify_SOURCES = examples/attestation/certify.c \ + examples/tpm_test_keys.c +examples_attestation_certify_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD) +examples_attestation_certify_DEPENDENCIES = src/libwolftpm.la endif example_attestationdir = $(exampledir)/attestation dist_example_attestation_DATA = \ examples/attestation/make_credential.c \ - examples/attestation/activate_credential.c + examples/attestation/activate_credential.c \ + examples/attestation/certify.c DISTCLEANFILES+= examples/attestation/.libs/make_credential \ - examples/attestation/.libs/activate_credential + examples/attestation/.libs/activate_credential \ + examples/attestation/.libs/certify EXTRA_DIST+= examples/attestation/README.md diff --git a/examples/attestation/make_credential.c b/examples/attestation/make_credential.c index 530d0784..1b4ea64a 100644 --- a/examples/attestation/make_credential.c +++ b/examples/attestation/make_credential.c @@ -29,7 +29,7 @@ #ifndef WOLFTPM2_NO_WRAPPER -#include +#include #include #include #include diff --git a/examples/keygen/create_primary.c b/examples/keygen/create_primary.c index 18c52e15..eef00726 100644 --- a/examples/keygen/create_primary.c +++ b/examples/keygen/create_primary.c @@ -51,6 +51,13 @@ static void usage(void) printf("\t-oh: Create keys under the Owner Hierarchy (DEFAULT)\n"); printf("\t-eh: Create keys under the Endorsement Hierarchy\n"); printf("\t-ph: Create keys under the Platform Hierarchy\n"); + printf("Public Template:\n"); + printf("\t-srk: Storage Root Key (default)\n"); + printf("\t-aik: Attestation Identity Key, a TPM 1.2 key type\n"); +#ifdef WOLFTPM_PROVISIONING + printf("\t-iak: Initial Attestation Template\n"); + printf("\t-idevid: Initial Device IDentity Template\n"); +#endif printf("Unique Template:\n"); printf("\t-unique=[value]\n"); printf("\t\tOptional unique value for the KDF of the create\n"); @@ -64,6 +71,7 @@ static void usage(void) printf("\t-store=[handle]\n"); printf("\t\tPersistent primary key handle range: 0x81000000 - 0x810FFFF\n"); printf("\t\tUse leading 0x for hex\n"); + printf("\t-keep: Keep handle open (don't flush)\n"); printf("Example usage:\n"); printf("\t* Create SRK used by wolfTPM:\n"); @@ -84,6 +92,11 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[]) const char* uniqueStr = NULL; const char* authStr = NULL; word32 persistHandle = 0; + int keepHandleOpen = 0; + int useAIKTemplate = 0; +#ifdef WOLFTPM_PROVISIONING + int useIAKTemplate = 0, useIDevIDTemplate = 0; +#endif if (argc >= 2) { if (XSTRCMP(argv[1], "-?") == 0 || @@ -115,6 +128,19 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[]) else if (XSTRCMP(argv[argc-1], "-oh") == 0) { hierarchy = TPM_RH_OWNER; } + else if (XSTRCMP(argv[argc-1], "-aik") == 0) { + useAIKTemplate = 1; + } +#ifdef WOLFTPM_PROVISIONING + else if (XSTRCMP(argv[argc-1], "-iak") == 0) { + useIAKTemplate = 1; + uniqueStr = "IAK"; + } + else if (XSTRCMP(argv[argc-1], "-idevid") == 0) { + useIDevIDTemplate = 1; + uniqueStr = "IDEVID"; + } +#endif else if (XSTRNCMP(argv[argc-1], "-unique=", XSTRLEN("-unique=")) == 0) { uniqueStr = argv[argc-1] + XSTRLEN("-unique="); } @@ -129,6 +155,9 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[]) persistHandle = 0; } } + else if (XSTRCMP(argv[argc-1], "-keep") == 0) { + keepHandleOpen = 1; + } else { printf("Warning: Unrecognized option: %s\n", argv[argc-1]); } @@ -166,10 +195,32 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[]) /* Supported algorithms for primary key are only RSA 2048-bit & ECC P256 */ if (alg == TPM_ALG_RSA) { - rc = wolfTPM2_GetKeyTemplate_RSA_SRK(&publicTemplate); + if (useAIKTemplate) + rc = wolfTPM2_GetKeyTemplate_RSA_AIK(&publicTemplate); +#ifdef WOLFTPM_PROVISIONING + else if (useIAKTemplate) + rc = wolfTPM2_GetKeyTemplate_RSA_IAK(&publicTemplate, + 2048, TPM_ALG_SHA256); + else if (useIDevIDTemplate) + rc = wolfTPM2_GetKeyTemplate_RSA_IDevID(&publicTemplate, + 2048, TPM_ALG_SHA256); +#endif + else + rc = wolfTPM2_GetKeyTemplate_RSA_SRK(&publicTemplate); } else if (alg == TPM_ALG_ECC) { - rc = wolfTPM2_GetKeyTemplate_ECC_SRK(&publicTemplate); + if (useAIKTemplate) + rc = wolfTPM2_GetKeyTemplate_ECC_AIK(&publicTemplate); +#ifdef WOLFTPM_PROVISIONING + else if (useIAKTemplate) + rc = wolfTPM2_GetKeyTemplate_ECC_IAK(&publicTemplate, + TPM_ECC_NIST_P256, TPM_ALG_SHA256); + else if (useIDevIDTemplate) + rc = wolfTPM2_GetKeyTemplate_ECC_IDevID(&publicTemplate, + TPM_ECC_NIST_P256, TPM_ALG_SHA256); +#endif + else + rc = wolfTPM2_GetKeyTemplate_ECC_SRK(&publicTemplate); } else { rc = BAD_FUNC_ARG; @@ -231,7 +282,8 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[]) } /* Close handles */ - wolfTPM2_UnloadHandle(&dev, &primary.handle); + if (!keepHandleOpen) + wolfTPM2_UnloadHandle(&dev, &primary.handle); if (paramEncAlg != TPM_ALG_NULL) { wolfTPM2_UnloadHandle(&dev, &tpmSession.handle); } diff --git a/examples/management/flush.c b/examples/management/flush.c index ee26c5d4..2632db36 100644 --- a/examples/management/flush.c +++ b/examples/management/flush.c @@ -41,8 +41,8 @@ static void usage(void) { printf("Expected usage:\n"); - printf("./tool/management/flush [handle]\n"); - printf("* handle is a valid TPM2.0 handle index\n"); + printf("./examples/management/flush [handle]\n"); + printf("* handle is a valid TPM2.0 handle (example 0x80000000)\n"); printf("Note: Default behavior, without parameters, the tool flushes\n" "\tcommon transient TPM2.0 objects, including:\n" "- Transient Key handles 0x8000000\n" @@ -53,18 +53,13 @@ static void usage(void) int TPM2_Flush_Tool(void* userCtx, int argc, char *argv[]) { int rc = TPM_RC_FAILURE; - int allTransientObjects = 0, handle = 0; + int allTransientObjects = 0; + TPM_HANDLE handle = 0; WOLFTPM2_DEV dev; FlushContext_In flushCtx; if (argc == 2) { - /* TODO: Parse input parameter as 8 digit hex value */ - (void)argv; - if(1) { - printf("Input value does not look like a TPM handle\n"); - usage(); - return 0; - } + handle = (word32)XSTRTOL(argv[1], NULL, 0); } else if (argc == 1) { allTransientObjects = 1; @@ -83,21 +78,21 @@ int TPM2_Flush_Tool(void* userCtx, int argc, char *argv[]) } printf("wolfTPM2_Init: success\n"); - if (allTransientObjects) { + if (allTransientObjects || handle == 0) { /* Flush key objects */ - for (handle=0x80000000; handle < (int)0x8000000A; handle++) { + for (handle=0x80000000; handle < 0x8000000A; handle++) { flushCtx.flushHandle = handle; printf("Freeing %X object\n", handle); TPM2_FlushContext(&flushCtx); } /* Flush policy sessions */ - for (handle=0x3000000; handle < (int)0x3000004; handle++) { + for (handle=0x3000000; handle < 0x3000004; handle++) { flushCtx.flushHandle = handle; printf("Freeing %X object\n", handle); TPM2_FlushContext(&flushCtx); } /* Flush hmac sessions */ - for (handle=0x3000000; handle < (int)0x3000004; handle++) { + for (handle=0x3000000; handle < 0x3000004; handle++) { flushCtx.flushHandle = handle; printf("Freeing %X object\n", handle); TPM2_FlushContext(&flushCtx); diff --git a/examples/native/native_test.c b/examples/native/native_test.c index 04296053..0d89bd9c 100644 --- a/examples/native/native_test.c +++ b/examples/native/native_test.c @@ -111,7 +111,7 @@ int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[]) ECDH_KeyGen_In ecdh; ECDH_ZGen_In ecdhZ; EncryptDecrypt2_In encDec; - CertifyCreation_In certifyCreationIn; + CertifyCreation_In certifyCreation; HMAC_In hmac; HMAC_Start_In hmacStart; #if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT) @@ -151,7 +151,7 @@ int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[]) ECDH_KeyGen_Out ecdh; ECDH_ZGen_Out ecdhZ; EncryptDecrypt2_Out encDec; - CertifyCreation_Out certifyCreationOut; + CertifyCreation_Out certifyCreation; HMAC_Out hmac; HMAC_Start_Out hmacStart; byte maxOutput[MAX_RESPONSE_SIZE]; @@ -1226,15 +1226,18 @@ int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[]) } /* Use the RSA key for Encrypt/Decrypt to unit test certifyCreation */ - cmdIn.certifyCreationIn.signHandle = rsaKey.handle; - cmdIn.certifyCreationIn.objectHandle = rsaKey.handle; - cmdIn.certifyCreationIn.creationHash.size = rsaKey.creationHash.size; - XMEMCPY(cmdIn.certifyCreationIn.creationHash.buffer, rsaKey.creationHash.buffer, cmdIn.certifyCreationIn.creationHash.size); - XMEMCPY(&cmdIn.certifyCreationIn.creationTicket, &rsaKey.creationTicket, sizeof(rsaKey.creationTicket)); - cmdIn.certifyCreationIn.inScheme.scheme = TPM_ALG_RSASSA; - cmdIn.certifyCreationIn.inScheme.details.any.hashAlg = TPM_ALG_SHA256; - cmdIn.certifyCreationIn.qualifyingData.size = 0; /* optional */ - rc = TPM2_CertifyCreation(&cmdIn.certifyCreationIn, &cmdOut.certifyCreationOut); + cmdIn.certifyCreation.signHandle = rsaKey.handle; + cmdIn.certifyCreation.objectHandle = rsaKey.handle; + cmdIn.certifyCreation.creationHash.size = rsaKey.creationHash.size; + XMEMCPY(cmdIn.certifyCreation.creationHash.buffer, rsaKey.creationHash.buffer, cmdIn.certifyCreation.creationHash.size); + XMEMCPY(&cmdIn.certifyCreation.creationTicket, &rsaKey.creationTicket, sizeof(rsaKey.creationTicket)); + cmdIn.certifyCreation.inScheme.scheme = TPM_ALG_RSASSA; + cmdIn.certifyCreation.inScheme.details.any.hashAlg = TPM_ALG_SHA256; + /* provide a random nonce from remote server (optional) */ + cmdIn.certifyCreation.qualifyingData.size = sizeof(keyCreationNonce)-1; + XMEMCPY(cmdIn.certifyCreation.qualifyingData.buffer, keyCreationNonce, + cmdIn.certifyCreation.qualifyingData.size); + rc = TPM2_CertifyCreation(&cmdIn.certifyCreation, &cmdOut.certifyCreation); if (rc != TPM_RC_SUCCESS) { printf("TPM2_CertifyCreation RSA key failed 0x%x: %s\n", rc, TPM2_GetRCString(rc)); diff --git a/examples/run_examples.sh b/examples/run_examples.sh index e6d037c4..a3b13cf9 100755 --- a/examples/run_examples.sh +++ b/examples/run_examples.sh @@ -42,6 +42,36 @@ RESULT=$? RESULT=$? [ $RESULT -ne 0 ] && echo -e "create primary owner rsa key stored failed! $RESULT" && exit 1 +# Provisioning examples (required --enable-provisioning) +./examples/keygen/create_primary -rsa -eh -iak -keep >> run.out 2>&1 +RESULT=$? +[ $RESULT -ne 0 ] && echo -e "create primary endosement rsa IAK key failed! $RESULT" && exit 1 +./examples/keygen/create_primary -rsa -eh -idevid -keep >> run.out 2>&1 +RESULT=$? +[ $RESULT -ne 0 ] && echo -e "create primary endosement rsa IDevID key failed! $RESULT" && exit 1 + +./examples/attestation/certify -certify=0x80000000 -signer=0x80000001 +RESULT=$? +[ $RESULT -ne 0 ] && echo -e "certify RSA IDevID with IAK failed! $RESULT" && exit 1 + +./examples/management/flush 0x80000000 +./examples/management/flush 0x80000001 + +./examples/keygen/create_primary -ecc -eh -iak -keep >> run.out 2>&1 +RESULT=$? +[ $RESULT -ne 0 ] && echo -e "create primary endosement ecc IAK key failed! $RESULT" && exit 1 +./examples/keygen/create_primary -ecc -eh -idevid -keep >> run.out 2>&1 +RESULT=$? +[ $RESULT -ne 0 ] && echo -e "create primary endosement ecc IDevID key failed! $RESULT" && exit 1 + +./examples/attestation/certify -certify=0x80000000 -signer=0x80000001 +RESULT=$? +[ $RESULT -ne 0 ] && echo -e "certify ECC IDevID with IAK failed! $RESULT" && exit 1 + +./examples/management/flush 0x80000000 +./examples/management/flush 0x80000001 + + if [ $WOLFCRYPT_ENABLE -eq 1 ]; then ./examples/keygen/create_primary -rsa -oh -aes >> run.out 2>&1 RESULT=$? diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 852b35fa..c088ca8d 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -6076,6 +6076,145 @@ int wolfTPM2_GetKeyTemplate_ECC_AIK(TPMT_PUBLIC* publicTemplate) return ret; } +#ifdef WOLFTPM_PROVISIONING +static int wolfTPM2_SetKeyTemplate_IAK(TPMT_PUBLIC* publicTemplate, + TPM_ALG_ID hashAlg) +{ + int ret = 0; + if (hashAlg == TPM_ALG_SHA256) { + publicTemplate->authPolicy.size = sizeof(TPM_20_IAK_POLICY); + XMEMCPY(publicTemplate->authPolicy.buffer, + TPM_20_IAK_POLICY, publicTemplate->authPolicy.size); + } +#ifdef WOLFSSL_SHA384 + else if (hashAlg == TPM_ALG_SHA384) { + publicTemplate->authPolicy.size = sizeof(TPM_20_IAK_POLICY_SHA384); + XMEMCPY(publicTemplate->authPolicy.buffer, + TPM_20_IAK_POLICY_SHA384, publicTemplate->authPolicy.size); + } +#endif +#ifdef WOLFSSL_SHA512 + else if (hashAlg == TPM_ALG_SHA512) { + publicTemplate->authPolicy.size = sizeof(TPM_20_IAK_POLICY_SHA512); + XMEMCPY(publicTemplate->authPolicy.buffer, + TPM_20_IAK_POLICY_SHA512, publicTemplate->authPolicy.size); + } +#endif + else { + ret = BAD_FUNC_ARG; + } + if (ret == 0) { + const char* IAKStr = "IAK"; + ret = wolfTPM2_SetKeyTemplate_Unique(publicTemplate, + (const byte*)IAKStr, (int)XSTRLEN(IAKStr)); + } + return ret; +} + +int wolfTPM2_GetKeyTemplate_RSA_IAK(TPMT_PUBLIC* publicTemplate, int keyBits, + TPM_ALG_ID hashAlg) +{ + int ret; + TPMA_OBJECT objectAttributes = ( + TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent | + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_restricted | TPMA_OBJECT_sign); + + ret = GetKeyTemplateRSA(publicTemplate, hashAlg, + objectAttributes, keyBits, 0, TPM_ALG_RSASSA, hashAlg); + if (ret == 0) { + publicTemplate->parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL; + ret = wolfTPM2_SetKeyTemplate_IAK(publicTemplate, hashAlg); + } + return ret; +} +int wolfTPM2_GetKeyTemplate_ECC_IAK(TPMT_PUBLIC* publicTemplate, + TPM_ECC_CURVE curveID, TPM_ALG_ID hashAlg) +{ + int ret; + TPMA_OBJECT objectAttributes = ( + TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent | + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_restricted | TPMA_OBJECT_sign); + + ret = GetKeyTemplateECC(publicTemplate, hashAlg, + objectAttributes, curveID, TPM_ALG_ECDSA, TPM_ALG_NULL); + if (ret == 0) { + publicTemplate->parameters.eccDetail.symmetric.algorithm = TPM_ALG_NULL; + ret = wolfTPM2_SetKeyTemplate_IAK(publicTemplate, hashAlg); + } + return ret; +} + +static int wolfTPM2_SetKeyTemplate_IDevID(TPMT_PUBLIC* publicTemplate, + TPM_ALG_ID hashAlg) +{ + int ret = 0; + if (hashAlg == TPM_ALG_SHA256) { + publicTemplate->authPolicy.size = sizeof(TPM_20_IDEVID_POLICY); + XMEMCPY(publicTemplate->authPolicy.buffer, + TPM_20_IDEVID_POLICY, publicTemplate->authPolicy.size); + } +#ifdef WOLFSSL_SHA384 + else if (hashAlg == TPM_ALG_SHA384) { + publicTemplate->authPolicy.size = sizeof(TPM_20_IDEVID_POLICY_SHA384); + XMEMCPY(publicTemplate->authPolicy.buffer, + TPM_20_IDEVID_POLICY_SHA384, publicTemplate->authPolicy.size); + } +#endif +#ifdef WOLFSSL_SHA512 + else if (hashAlg == TPM_ALG_SHA512) { + publicTemplate->authPolicy.size = sizeof(TPM_20_IDEVID_POLICY_SHA512); + XMEMCPY(publicTemplate->authPolicy.buffer, + TPM_20_IDEVID_POLICY_SHA512, publicTemplate->authPolicy.size); + } +#endif + else { + ret = BAD_FUNC_ARG; + } + if (ret == 0) { + const char* IDevIDStr = "IDEVID"; + ret = wolfTPM2_SetKeyTemplate_Unique(publicTemplate, + (const byte*)IDevIDStr, (int)XSTRLEN(IDevIDStr)); + } + return ret; +} +int wolfTPM2_GetKeyTemplate_RSA_IDevID(TPMT_PUBLIC* publicTemplate, int keyBits, + TPM_ALG_ID hashAlg) +{ + int ret; + TPMA_OBJECT objectAttributes = ( + TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent | + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_sign); + + ret = GetKeyTemplateRSA(publicTemplate, hashAlg, + objectAttributes, keyBits, 0, TPM_ALG_NULL, TPM_ALG_NULL); + if (ret == 0) { + publicTemplate->parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL; + ret = wolfTPM2_SetKeyTemplate_IDevID(publicTemplate, hashAlg); + } + return ret; +} +int wolfTPM2_GetKeyTemplate_ECC_IDevID(TPMT_PUBLIC* publicTemplate, + TPM_ECC_CURVE curveID, TPM_ALG_ID hashAlg) +{ + int ret; + TPMA_OBJECT objectAttributes = ( + TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent | + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_sign); + + ret = GetKeyTemplateECC(publicTemplate, hashAlg, + objectAttributes, curveID, TPM_ALG_ECDSA, TPM_ALG_NULL); + if (ret == 0) { + publicTemplate->parameters.eccDetail.symmetric.algorithm = TPM_ALG_NULL; + ret = wolfTPM2_SetKeyTemplate_IDevID(publicTemplate, hashAlg); + } + return ret; +} +#endif /* WOLFTPM_PROVISIONING */ + /* Returns key size (in bytes) for the public template */ static int GetKeyTemplateSize(TPMT_PUBLIC* publicTemplate) { @@ -6153,7 +6292,8 @@ int wolfTPM2_SetKeyTemplate_Unique(TPMT_PUBLIC* publicTemplate, } else { XMEMCPY(publicTemplate->unique.ecc.x.buffer, unique, uniqueSz); - XMEMCPY(publicTemplate->unique.ecc.y.buffer, unique + uniqueSz, uniqueSz); + XMEMCPY(publicTemplate->unique.ecc.y.buffer, unique + uniqueSz, + uniqueSz); } publicTemplate->unique.ecc.x.size = uniqueSz; publicTemplate->unique.ecc.y.size = uniqueSz; @@ -7131,6 +7271,21 @@ int wolfTPM2_PolicyAuthValue(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* tpmSession, return TPM2_PolicyAuthValue(&policyAuthValueIn); } +int wolfTPM2_PolicyCommandCode(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* tpmSession, + TPM_CC cc) +{ + PolicyCommandCode_In policyCC; + + if (dev == NULL || tpmSession == NULL) { + return BAD_FUNC_ARG; + } + + XMEMSET(&policyCC, 0, sizeof(policyCC)); + policyCC.policySession = tpmSession->handle.hndl; + policyCC.code = cc; + return TPM2_PolicyCommandCode(&policyCC); +} + #ifndef WOLFTPM2_NO_WOLFCRYPT /* Authorize a policy based on external key for a verified policy digiest signature */ int wolfTPM2_PolicyAuthorize(WOLFTPM2_DEV* dev, TPM_HANDLE sessionHandle, @@ -7225,11 +7380,13 @@ int wolfTPM2_PCRGetDigest(WOLFTPM2_DEV* dev, TPM_ALG_ID pcrAlg, return rc; } -/* Assemble a PCR policy */ -/* policyDigestnew = hash(policyDigestOld || TPM_CC_PolicyPCR || PCRS || - * pcrDigest) */ -int wolfTPM2_PolicyPCRMake(TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz, - const byte* pcrDigest, word32 pcrDigestSz, byte* digest, word32* digestSz) +/* Generic Policy Hashing Function */ +/* digest is in/out (input "old" / output "new") */ +/* policyDigestnew = hash(policyDigestOld || [cc] || [Input] || [Input2]) */ +int wolfTPM2_PolicyHash2(TPM_ALG_ID hashAlg, + byte* digest, word32* digestSz, TPM_CC cc, + const byte* input, word32 inputSz, + const byte* input2, word32 input2Sz) { int rc; word32 val; @@ -7237,18 +7394,19 @@ int wolfTPM2_PolicyPCRMake(TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz, wc_HashAlg hash_ctx; word32 inSz; - if (pcrArray == NULL || pcrArraySz == 0 || digest == NULL || - digestSz == NULL) { + if (digest == NULL || digestSz == NULL || + (input == NULL && inputSz > 0) || + (input2 == NULL && input2Sz > 0)) { return BAD_FUNC_ARG; } inSz = *digestSz; /* capture input digest size (for policyDigestOld) */ - rc = TPM2_GetHashType(pcrAlg); + rc = TPM2_GetHashType(hashAlg); hashType = (enum wc_HashType)rc; rc = wc_HashGetDigestSize(hashType); if (rc < 0) return rc; - *digestSz = rc; /* set actual size */ + *digestSz = rc; rc = wc_HashInit(&hash_ctx, hashType); if (rc != 0) @@ -7258,28 +7416,18 @@ int wolfTPM2_PolicyPCRMake(TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz, if (rc == 0 && inSz > 0) { rc = wc_HashUpdate(&hash_ctx, hashType, digest, inSz); } - /* Command Code */ - if (rc == 0) { - val = TPM2_Packet_SwapU32(TPM_CC_PolicyPCR); + /* Command Code (optional) */ + if (rc == 0 && cc > TPM_CC_FIRST) { + val = TPM2_Packet_SwapU32(cc); rc = wc_HashUpdate(&hash_ctx, hashType, (byte*)&val, sizeof(val)); } - /* PCR Count and PCR Selection */ - if (rc == 0) { - TPM2_Packet packet; - byte buf[sizeof(TPML_PCR_SELECTION)]; - TPML_PCR_SELECTION pcr; - XMEMSET(&pcr, 0, sizeof(pcr)); - XMEMSET(&packet, 0, sizeof(packet)); - - TPM2_SetupPCRSelArray(&pcr, pcrAlg, pcrArray, pcrArraySz); - packet.buf = buf; - packet.size = sizeof(buf); - TPM2_Packet_AppendPCR(&packet, &pcr); - rc = wc_HashUpdate(&hash_ctx, hashType, buf, packet.pos); + /* Input (optional) */ + if (rc == 0 && input != NULL && inputSz > 0) { + rc = wc_HashUpdate(&hash_ctx, hashType, input, inputSz); } - /* Hash of PCR(s) */ - if (rc == 0) { - rc = wc_HashUpdate(&hash_ctx, hashType, pcrDigest, pcrDigestSz); + /* Input2 (optional) */ + if (rc == 0 && input2 != NULL && input2Sz > 0) { + rc = wc_HashUpdate(&hash_ctx, hashType, input2, input2Sz); } if (rc == 0) { rc = wc_HashFinal(&hash_ctx, hashType, digest); @@ -7288,68 +7436,66 @@ int wolfTPM2_PolicyPCRMake(TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz, #ifdef DEBUG_WOLFTPM if (rc != 0) { - printf("wolfTPM2_PolicyPCRMake failed %d: %s\n", + printf("wolfTPM2_PolicyHash failed %d: %s\n", rc, wolfTPM2_GetRCString(rc)); } #ifdef WOLFTPM_DEBUG_VERBOSE else { - printf("wolfTPM2_PolicyPCRMake: %d\n", *digestSz); + printf("wolfTPM2_PolicyHash: %d\n", *digestSz); TPM2_PrintBin(digest, *digestSz); } #endif #endif return rc; } +int wolfTPM2_PolicyHash(TPM_ALG_ID hashAlg, byte* digest, word32* digestSz, + TPM_CC cc) +{ + return wolfTPM2_PolicyHash2(hashAlg, digest, digestSz, + cc, NULL, 0, NULL, 0); +} +int wolfTPM2_PolicyHash1(TPM_ALG_ID hashAlg, byte* digest, word32* digestSz, + TPM_CC cc, const byte* input, word32 inputSz) +{ + return wolfTPM2_PolicyHash2(hashAlg, digest, digestSz, + cc, input, inputSz, NULL, 0); +} -/* Assemble a PCR policy ref - optional */ -/* aHash = hash(approvedPolicy || policyRef) */ -int wolfTPM2_PolicyRefMake(TPM_ALG_ID pcrAlg, byte* digest, word32* digestSz, - const byte* policyRef, word32 policyRefSz) +/* Assemble a PCR policy */ +/* policyDigestnew = hash(policyDigestOld || TPM_CC_PolicyPCR || PCRS || + * pcrDigest) */ +int wolfTPM2_PolicyPCRMake(TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz, + const byte* pcrDigest, word32 pcrDigestSz, byte* digest, word32* digestSz) { int rc; - enum wc_HashType hashType; - wc_HashAlg hash_ctx; - word32 inSz; + TPM2_Packet packet; + byte buf[sizeof(TPML_PCR_SELECTION)]; + TPML_PCR_SELECTION pcr; - if (digest == NULL || digestSz == NULL || - (policyRef == NULL && policyRefSz > 0)) { + if (digest == NULL || digestSz == NULL || pcrArray == NULL || + pcrArraySz == 0) { return BAD_FUNC_ARG; } - inSz = *digestSz; /* capture input digest size (for approvedPolicy) */ - rc = TPM2_GetHashType(pcrAlg); - hashType = (enum wc_HashType)rc; - rc = wc_HashGetDigestSize(hashType); - if (rc < 0) - return rc; - *digestSz = rc; /* set actual size */ - - rc = wc_HashInit(&hash_ctx, hashType); - if (rc != 0) - return rc; - - /* approvedPolicy */ - if (rc == 0 && inSz > 0) { - rc = wc_HashUpdate(&hash_ctx, hashType, digest, inSz); - } - /* policyRef */ - if (rc == 0 && policyRefSz > 0) { - rc = wc_HashUpdate(&hash_ctx, hashType, policyRef, policyRefSz); - } - if (rc == 0) { - rc = wc_HashFinal(&hash_ctx, hashType, digest); - } + /* Build PCRS (PCR Count and PCR Selection) */ + XMEMSET(&pcr, 0, sizeof(pcr)); + XMEMSET(&packet, 0, sizeof(packet)); + TPM2_SetupPCRSelArray(&pcr, pcrAlg, pcrArray, pcrArraySz); + packet.buf = buf; + packet.size = (int)sizeof(buf); + TPM2_Packet_AppendPCR(&packet, &pcr); - wc_HashFree(&hash_ctx, hashType); + rc = wolfTPM2_PolicyHash2(pcrAlg, digest, digestSz, TPM_CC_PolicyPCR, + buf, packet.pos, pcrDigest, pcrDigestSz); #ifdef DEBUG_WOLFTPM if (rc != 0) { - printf("wolfTPM_PolicyRefMake failed %d: %s\n", + printf("wolfTPM2_PolicyPCRMake failed %d: %s\n", rc, wolfTPM2_GetRCString(rc)); } #ifdef WOLFTPM_DEBUG_VERBOSE else { - printf("wolfTPM_PolicyRefMake: %d\n", *digestSz); + printf("wolfTPM2_PolicyPCRMake: %d\n", *digestSz); TPM2_PrintBin(digest, *digestSz); } #endif @@ -7357,6 +7503,15 @@ int wolfTPM2_PolicyRefMake(TPM_ALG_ID pcrAlg, byte* digest, word32* digestSz, return rc; } +/* Assemble a PCR policy ref - optional */ +/* aHash = hash(approvedPolicy || policyRef) */ +int wolfTPM2_PolicyRefMake(TPM_ALG_ID pcrAlg, byte* digest, word32* digestSz, + const byte* policyRef, word32 policyRefSz) +{ + return wolfTPM2_PolicyHash1(pcrAlg, digest, digestSz, 0, + policyRef, policyRefSz); +} + /* Assemble a PCR Authorization for a public key */ /* policyDigestnew = hash(policyDigestOld || TPM_CC_PolicyAuthorize || * Public.Name || PolicyRef) */ @@ -7365,49 +7520,17 @@ int wolfTPM2_PolicyAuthorizeMake(TPM_ALG_ID pcrAlg, const byte* policyRef, word32 policyRefSz) { int rc; - word32 val; - enum wc_HashType hashType; - wc_HashAlg hash_ctx; - word32 inSz; + TPM2B_NAME name; - if (pub == NULL || digest == NULL || digestSz == NULL) { + if (digest == NULL || digestSz == NULL || pub == NULL) { return BAD_FUNC_ARG; } - inSz = *digestSz; /* capture input digest size (for policyDigestOld) */ - rc = TPM2_GetHashType(pcrAlg); - hashType = (enum wc_HashType)rc; - rc = wc_HashGetDigestSize(hashType); - if (rc < 0) - return rc; - *digestSz = rc; - - rc = wc_HashInit(&hash_ctx, hashType); - if (rc != 0) - return rc; - - /* policyDigestOld */ - if (rc == 0 && inSz > 0) { - rc = wc_HashUpdate(&hash_ctx, hashType, digest, inSz); - } - /* Command Code */ - if (rc == 0) { - val = TPM2_Packet_SwapU32(TPM_CC_PolicyAuthorize); - rc = wc_HashUpdate(&hash_ctx, hashType, (byte*)&val, sizeof(val)); - } - /* Public Name Compute */ - if (rc == 0) { - TPM2B_NAME name; - rc = wolfTPM2_ComputeName(pub, &name); - if (rc == 0) { - rc = wc_HashUpdate(&hash_ctx, hashType, name.name, name.size); - } - } + rc = wolfTPM2_ComputeName(pub, &name); if (rc == 0) { - rc = wc_HashFinal(&hash_ctx, hashType, digest); + rc = wolfTPM2_PolicyHash1(pcrAlg, digest, digestSz, + TPM_CC_PolicyAuthorize, name.name, name.size); } - wc_HashFree(&hash_ctx, hashType); - if (rc == 0) { rc = wolfTPM2_PolicyRefMake(pcrAlg, digest, digestSz, policyRef, policyRefSz); @@ -7427,6 +7550,7 @@ int wolfTPM2_PolicyAuthorizeMake(TPM_ALG_ID pcrAlg, #endif return rc; } + #endif /* !WOLFTPM2_NO_WOLFCRYPT */ /******************************************************************************/ @@ -7524,20 +7648,17 @@ int wolfTPM2_SetIdentityAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* handle, static int tpm2_ifx_firmware_enable_policy(WOLFTPM2_DEV* dev) { int rc; - PolicyCommandCode_In policyCC; SetPrimaryPolicy_In policy; WOLFTPM2_SESSION tpmSession; XMEMSET(&tpmSession, 0, sizeof(tpmSession)); - XMEMSET(&policyCC, 0, sizeof(policyCC)); XMEMSET(&policy, 0, sizeof(policy)); rc = wolfTPM2_StartSession(dev, &tpmSession, NULL, NULL, TPM_SE_POLICY, TPM_ALG_NULL); if (rc == TPM_RC_SUCCESS) { - policyCC.policySession = tpmSession.handle.hndl; - policyCC.code = TPM_CC_FieldUpgradeStartVendor; - rc = TPM2_PolicyCommandCode(&policyCC); + rc = wolfTPM2_PolicyCommandCode(dev, &tpmSession, + TPM_CC_FieldUpgradeStartVendor); if (rc == TPM_RC_SUCCESS) { word32 policySz = (word32)sizeof(policy.authPolicy.buffer); rc = wolfTPM2_GetPolicyDigest(dev, tpmSession.handle.hndl, @@ -7566,17 +7687,14 @@ static int tpm2_ifx_firmware_start(WOLFTPM2_DEV* dev, TPM_ALG_ID hashAlg, { int rc; WOLFTPM2_SESSION tpmSession; - PolicyCommandCode_In policyCC; XMEMSET(&tpmSession, 0, sizeof(tpmSession)); - XMEMSET(&policyCC, 0, sizeof(policyCC)); rc = wolfTPM2_StartSession(dev, &tpmSession, NULL, NULL, TPM_SE_POLICY, TPM_ALG_NULL); if (rc == TPM_RC_SUCCESS) { - policyCC.policySession = tpmSession.handle.hndl; - policyCC.code = TPM_CC_FieldUpgradeStartVendor; - rc = TPM2_PolicyCommandCode(&policyCC); + rc = wolfTPM2_PolicyCommandCode(dev, &tpmSession, + TPM_CC_FieldUpgradeStartVendor); if (rc == TPM_RC_SUCCESS) { /* build command for manifest header */ uint16_t val16; diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index 474f1b9d..0e64bfe5 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -1711,6 +1711,67 @@ static const BYTE TPM_20_EK_AUTH_POLICY_SHA512[] = { }; #endif +#ifdef WOLFTPM_PROVISIONING +/* Precalcualted IDevID/IAK Policies */ +/* PolicyOR: + * 1: PolicyUser (section 7.3.6.1) + * 2: PolicyCertify (section 7.3.6.2) + * 3: PolicyActivateCredential (section 7.3.6.3) + * 4: PolicyDelegationNV (section 7.3.6.4)*/ +static const BYTE TPM_20_IDEVID_POLICY[] = { + 0xAD, 0x6B, 0x3A, 0x22, 0x84, 0xFD, 0x69, 0x8A, + 0x07, 0x10, 0xBF, 0x5C, 0xC1, 0xB9, 0xBD, 0xF1, + 0x5E, 0x25, 0x32, 0xE3, 0xF6, 0x01, 0xFA, 0x4B, + 0x93, 0xA6, 0xA8, 0xFA, 0x8D, 0xE5, 0x79, 0xEA +}; +static const BYTE TPM_20_IAK_POLICY[] = { + 0x54, 0x37, 0x18, 0x23, 0x26, 0xE4, 0x14, 0xFC, + 0xA7, 0x97, 0xD5, 0xF1, 0x74, 0x61, 0x5A, 0x16, + 0x41, 0xF6, 0x12, 0x55, 0x79, 0x7C, 0x3A, 0x2B, + 0x22, 0xC2, 0x1D, 0x12, 0x0B, 0x2D, 0x1E, 0x07 +}; +#ifdef WOLFSSL_SHA384 +static const BYTE TPM_20_IDEVID_POLICY_SHA384[] = { + 0x4D, 0xB1, 0xAA, 0x83, 0x6D, 0x0B, 0x56, 0x15, + 0xDF, 0x6E, 0xE5, 0x3A, 0x40, 0xEF, 0x70, 0xC6, + 0x1C, 0x21, 0x7F, 0x43, 0x03, 0xD4, 0x46, 0x95, + 0x92, 0x59, 0x72, 0xBC, 0x92, 0x70, 0x06, 0xCF, + 0xA5, 0xCB, 0xDF, 0x6D, 0xC1, 0x8C, 0x4D, 0xBE, + 0x32, 0x9B, 0x2F, 0x15, 0x42, 0xC3, 0xDD, 0x33 +}; +static const BYTE TPM_20_IAK_POLICY_SHA384[] = { + 0x12, 0x9D, 0x94, 0xEB, 0xF8, 0x45, 0x56, 0x65, + 0x2C, 0x6E, 0xEF, 0x43, 0xBB, 0xB7, 0x57, 0x51, + 0x2A, 0xC8, 0x7E, 0x52, 0xBE, 0x7B, 0x34, 0x9C, + 0xA6, 0xCE, 0x4D, 0x82, 0x6F, 0x74, 0x9F, 0xCF, + 0x67, 0x2F, 0x51, 0x71, 0x6C, 0x5C, 0xBB, 0x60, + 0x5F, 0x31, 0x3B, 0xF3, 0x45, 0xAA, 0xB3, 0x12 +}; +#endif +#ifdef WOLFSSL_SHA512 +static const BYTE TPM_20_IDEVID_POLICY_SHA512[] = { + 0x7D, 0xD7, 0x50, 0x0F, 0xD6, 0xC1, 0xB9, 0x4F, + 0x97, 0xA6, 0xAF, 0x91, 0x0D, 0xA1, 0x47, 0x30, + 0x1E, 0xF2, 0x8F, 0x66, 0x2F, 0xEE, 0x06, 0xF2, + 0x25, 0xA4, 0xCC, 0xAD, 0xDA, 0x3B, 0x4E, 0x6B, + 0x38, 0xE6, 0x6B, 0x2F, 0x3A, 0xD5, 0xDE, 0xE1, + 0xA0, 0x50, 0x3C, 0xD2, 0xDA, 0xED, 0xB1, 0xE6, + 0x8C, 0xFE, 0x4F, 0x84, 0xB0, 0x3A, 0x8C, 0xD2, + 0x2B, 0xB6, 0xA9, 0x76, 0xF0, 0x71, 0xA7, 0x2F +}; +static const BYTE TPM_20_IAK_POLICY_SHA512[] = { + 0x80, 0x60, 0xD1, 0xFB, 0x31, 0x71, 0x6A, 0x29, + 0xE4, 0x8A, 0x6E, 0x5F, 0xEC, 0xE0, 0x88, 0xBC, + 0xFC, 0x1B, 0x27, 0x8F, 0xC1, 0x62, 0x25, 0x5E, + 0x81, 0xC3, 0xEC, 0xA3, 0x54, 0x4C, 0xD4, 0x4A, + 0xF9, 0x44, 0x10, 0xC3, 0x71, 0x5D, 0x56, 0x1C, + 0xCC, 0xD9, 0xE3, 0x9A, 0x6C, 0xB2, 0x64, 0x6D, + 0x43, 0x53, 0x5B, 0xB5, 0x4E, 0xA8, 0x87, 0x10, + 0xDE, 0xB5, 0xF7, 0x83, 0x6B, 0xD9, 0xB5, 0x86 +}; +#endif +#endif /* WOLFTPM_PROVISIONING */ + /* HAL IO Callbacks */ struct TPM2_CTX; diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index 84bbc28a..5b2e7ddf 100644 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -2804,6 +2804,18 @@ WOLFTPM_API int wolfTPM2_GetKeyTemplate_RSA_AIK(TPMT_PUBLIC* publicTemplate); */ WOLFTPM_API int wolfTPM2_GetKeyTemplate_ECC_AIK(TPMT_PUBLIC* publicTemplate); +#ifdef WOLFTPM_PROVISIONING +WOLFTPM_API int wolfTPM2_GetKeyTemplate_RSA_IAK(TPMT_PUBLIC* publicTemplate, int keyBits, + TPM_ALG_ID hashAlg); +WOLFTPM_API int wolfTPM2_GetKeyTemplate_ECC_IAK(TPMT_PUBLIC* publicTemplate, + TPM_ECC_CURVE curveID, TPM_ALG_ID hashAlg); + +WOLFTPM_API int wolfTPM2_GetKeyTemplate_ECC_IDevID(TPMT_PUBLIC* publicTemplate, + TPM_ECC_CURVE curveID, TPM_ALG_ID hashAlg); +WOLFTPM_API int wolfTPM2_GetKeyTemplate_RSA_IDevID(TPMT_PUBLIC* publicTemplate, int keyBits, + TPM_ALG_ID hashAlg); +#endif /* WOLFTPM_PROVISIONING */ + /*! \ingroup wolfTPM2_Wrappers \brief Sets the unique area of a public template used by Create or CreatePrimary. @@ -3694,6 +3706,37 @@ WOLFTPM_API int wolfTPM2_PolicyPCRMake(TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz, const byte* pcrDigest, word32 pcrDigestSz, byte* digest, word32* digestSz); +/*! + \ingroup wolfTPM2_Wrappers + + \brief Utility for creating a policy hash. + Generic helper that takes command code and input array. + policyDigestnew = hash(policyDigestOld || [cc] || [Input] || [Input2]) + + \return TPM_RC_SUCCESS: successful + \return INPUT_SIZE_E: policyDigestSz is too small to hold the returned digest + \return BAD_FUNC_ARG: check the provided arguments + + \param pcrAlg the hash algorithm to use with pcr policy + \param digest input/out digest (input "old" / output "new") + \param digestSz input/out digest size + \param input pointer to a array to use (optional) + \param inputSz size of input + \param input2 pointer to a array to use (optional) + \param input2Sz size of input + + \sa wolfTPM2_PolicyPCRMake +*/ +WOLFTPM_API int wolfTPM2_PolicyHash(TPM_ALG_ID hashAlg, + byte* digest, word32* digestSz, TPM_CC cc); +WOLFTPM_API int wolfTPM2_PolicyHash1(TPM_ALG_ID hashAlg, + byte* digest, word32* digestSz, TPM_CC cc, + const byte* input, word32 inputSz); +WOLFTPM_API int wolfTPM2_PolicyHash2(TPM_ALG_ID hashAlg, + byte* digest, word32* digestSz, TPM_CC cc, + const byte* input, word32 inputSz, + const byte* input2, word32 input2Sz); + /*! \ingroup wolfTPM2_Wrappers @@ -3711,7 +3754,7 @@ WOLFTPM_API int wolfTPM2_PolicyPCRMake(TPM_ALG_ID pcrAlg, \param policyRefSz optional nonce size \sa wolfTPM2_PolicyPCRMake - \sa wolfTPM2_PolicyPCRMake + \sa wolfTPM2_PolicyHash */ WOLFTPM_API int wolfTPM2_PolicyAuthorizeMake(TPM_ALG_ID pcrAlg, const TPM2B_PUBLIC* pub, byte* digest, word32* digestSz, @@ -3732,6 +3775,7 @@ WOLFTPM_API int wolfTPM2_PolicyAuthorizeMake(TPM_ALG_ID pcrAlg, \param authSz integer value, specifying the size of the password authorization, in bytes \sa wolfTPM2_PolicyAuthValue + \sa wolfTPM2_PolicyCommandCode */ WOLFTPM_API int wolfTPM2_PolicyPassword(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* tpmSession, const byte* auth, int authSz); @@ -3750,10 +3794,28 @@ WOLFTPM_API int wolfTPM2_PolicyPassword(WOLFTPM2_DEV* dev, \param authSz integer value, specifying the size of the password authorization, in bytes \sa wolfTPM2_PolicyPassword + \sa wolfTPM2_PolicyCommandCode */ WOLFTPM_API int wolfTPM2_PolicyAuthValue(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* tpmSession, const byte* auth, int authSz); +/*! + \ingroup wolfTPM2_Wrappers + + \brief Wrapper for setting a policy command code + + \return TPM_RC_SUCCESS: successful + \return BAD_FUNC_ARG: check the provided arguments + + \param dev pointer to a TPM2_DEV struct + \param tpmSession pointer to a WOLFTPM2_SESSION struct used with wolfTPM2_StartSession and wolfTPM2_SetAuthSession + \param cc TPM_CC command code + + \sa wolfTPM2_PolicyPassword + \sa wolfTPM2_PolicyAuthValue +*/ +WOLFTPM_API int wolfTPM2_PolicyCommandCode(WOLFTPM2_DEV* dev, + WOLFTPM2_SESSION* tpmSession, TPM_CC cc); /* Pre-provisioned IAK and IDevID key/cert from TPM vendor */