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..b74c7e1f --- /dev/null +++ b/examples/attestation/certify.c @@ -0,0 +1,240 @@ +/* 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 [-eh] [-rsa/-ecc]\n"); + printf("* -ecc/-rsa: SRK is RSA or ECC (default is RSA)\n"); + printf("* -eh: Create keys under the Endorsement Hierarchy (EK) " + "(default is Owner)\n"); +} + +int TPM2_Certify_Example(void* userCtx, int argc, char *argv[]) +{ + int rc = -1; + int endorseKey = 0; + WOLFTPM2_DEV dev; + WOLFTPM2_KEY storage; + WOLFTPM2_KEYBLOB akKey; + WOLFTPM2_KEY devidKey; + WOLFTPM2_SESSION tpmSession; + TPM_ALG_ID alg = TPM_ALG_RSA; + TPMA_OBJECT objectAttributes; + TPMT_PUBLIC publicTemplate; + TPM_ALG_ID hashAlg = TPM_ALG_SHA256; + word32 digestSz = 0; + 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 (XSTRCMP(argv[argc-1], "-eh") == 0) { + endorseKey = 1; + } + else { + printf("Warning: Unrecognized option: %s\n", argv[argc-1]); + } + argc--; + } + + (void)endorseKey; /* TODO: Add endorsement */ + + XMEMSET(&storage, 0, sizeof(storage)); + XMEMSET(&akKey, 0, sizeof(akKey)); + XMEMSET(&devidKey, 0, sizeof(devidKey)); + XMEMSET(&tpmSession, 0, sizeof(tpmSession)); + + printf("Certify IDevID with IAK to generate TPM-signed attestation info\n"); + 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"); + + /* Get SRK */ + rc = getPrimaryStoragekey(&dev, &storage, alg); + if (rc != 0) goto exit; + + /* Create an IAK */ + objectAttributes = ( + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_noDA | + TPMA_OBJECT_userWithAuth | TPMA_OBJECT_adminWithPolicy | + TPMA_OBJECT_decrypt | TPMA_OBJECT_sign); + XMEMSET(&publicTemplate, 0, sizeof(publicTemplate)); + if (alg == TPM_ALG_RSA) { + rc = GetKeyTemplateRSA(&publicTemplate, TPM_ALG_SHA256, + objectAttributes, 2048, 0, TPM_ALG_NULL, TPM_ALG_NULL); + } + else { /* TPM_ALG_ECC */ + rc = GetKeyTemplateECC(&publicTemplate, TPM_ALG_SHA256, + objectAttributes, TPM_ECC_NIST_P256, TPM_ALG_NULL, TPM_ALG_NULL); + } + if (rc == 0) { + word32 val; + + /* Setup admin policy */ + publicTemplate.objectAttributes |= TPMA_OBJECT_adminWithPolicy; + + XMEMSET(publicTemplate.authPolicy.buffer, 0, + sizeof(publicTemplate.authPolicy.buffer)); + digestSz = TPM2_GetHashDigestSize(hashAlg); + + val = TPM_CC_Certify; + #ifndef BIG_ENDIAN_ORDER + val = ByteReverseWord32(val); + #endif + rc = wolfTPM2_PolicyHash1(hashAlg, publicTemplate.authPolicy.buffer, + &digestSz, TPM_CC_PolicyCommandCode, (byte*)&val, sizeof(val)); + TPM2_PrintBin(publicTemplate.authPolicy.buffer, digestSz); + } + if (rc == 0) { + publicTemplate.authPolicy.size = (UINT16)digestSz; + rc = wolfTPM2_CreateKey(&dev, &akKey, &storage.handle, &publicTemplate, + (const byte*)gAiKeyAuth, sizeof(gAiKeyAuth)-1); + } + if (rc == 0) { + wolfTPM2_LoadKey(&dev, &akKey, &storage.handle); + } + if (rc != 0) { + printf("Failed to create IAK!\n"); + goto exit; + } + printf("IAK Created and Loaded: 0x%x (%d bytes)\n", + (word32)akKey.handle.hndl, akKey.pub.size); + + /* Start a policy session for admin policy authentication */ + rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL, + TPM_SE_POLICY, TPM_ALG_NULL); + if (rc == 0) { + printf("TPM2_StartAuthSession: sessionHandle 0x%x\n", + (word32)tpmSession.handle.hndl); + + /* set session for authorization of the storage key */ + rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession, + TPMA_SESSION_continueSession); + } + if (rc != 0) { + printf("Failed to start policy session!\n"); + goto exit; + } + + /* Perform admin policy authorizations */ + rc = wolfTPM2_PolicyCommandCode(&dev, &tpmSession, TPM_CC_Certify); + if (rc != 0) { + goto exit; + } + + wolfTPM2_SetAuthHandle(&dev, 1, &akKey.handle); + + /* Create signed certify structure */ + XMEMSET(&certifyIn, 0, sizeof(certifyIn)); + certifyIn.objectHandle = storage.handle.hndl; + certifyIn.signHandle = akKey.handle.hndl; + certifyIn.inScheme.scheme = TPM_ALG_RSASSA; + certifyIn.inScheme.details.any.hashAlg = TPM_ALG_SHA256; + /* 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; + } + else { + printf("TPM2_Certify test passed\n"); + } + +exit: + + if (rc != 0) { + printf("\nFailure 0x%x: %s\n\n", rc, wolfTPM2_GetRCString(rc)); + } + + wolfTPM2_UnloadHandle(&dev, &storage.handle); + wolfTPM2_UnloadHandle(&dev, &akKey.handle); + 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/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/src/tpm2_wrap.c b/src/tpm2_wrap.c index 852b35fa..ba838c99 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -7131,6 +7131,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 +7240,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 +7254,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 +7276,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 +7296,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 +7363,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 +7380,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 */ + rc = wolfTPM2_ComputeName(pub, &name); 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_PolicyHash1(pcrAlg, digest, digestSz, + TPM_CC_PolicyAuthorize, name.name, name.size); } - if (rc == 0) { - rc = wc_HashFinal(&hash_ctx, hashType, digest); - } - wc_HashFree(&hash_ctx, hashType); - if (rc == 0) { rc = wolfTPM2_PolicyRefMake(pcrAlg, digest, digestSz, policyRef, policyRefSz); @@ -7427,6 +7410,7 @@ int wolfTPM2_PolicyAuthorizeMake(TPM_ALG_ID pcrAlg, #endif return rc; } + #endif /* !WOLFTPM2_NO_WOLFCRYPT */ /******************************************************************************/ @@ -7524,20 +7508,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 +7547,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_wrap.h b/wolftpm/tpm2_wrap.h index 84bbc28a..0ab4f7e1 100644 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -3694,6 +3694,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 +3742,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 +3763,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 +3782,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 */