Added example for `TPM2_Certify`:

* Added new build option for TPM provisioning (`--enable-provisioning` on by default).
* Added new `wolfTPM2_CreatePrimaryKey_ex` and `WOLFTPM2_PKEY` that supports returning creation ticket/hash.
* Added key templates for initial device (IDevID) and attestation keys (IAK).
* Extended `create_primary` example to support creation or IDevID and IAK.
* Added new policy hash helper API `wolfTPM2_PolicyHash`
* Switch handle/nvIndex string parsing to use `strtoul`.

ZD 18347
pull/369/head
David Garske 2024-08-22 10:38:01 -07:00
parent fc683a1cc0
commit a6d7ed8695
24 changed files with 938 additions and 195 deletions

View File

@ -140,6 +140,12 @@ jobs:
- name: make pedantic
run: make
# build not provisioning
- name: configure not provisioning
run: ./configure --disable-provisioning
- name: make not provisioning
run: make
# test without ECC
- name: wolfssl no ECC
working-directory: ./wolfssl

1
.gitignore vendored
View File

@ -74,6 +74,7 @@ examples/seal/seal
examples/seal/unseal
examples/attestation/make_credential
examples/attestation/activate_credential
examples/attestation/certify
examples/boot/secure_rot
examples/boot/secret_seal
examples/boot/secret_unseal

View File

@ -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

View File

@ -10,7 +10,8 @@ Complete list of the required examples is shown below:
* `./examples/attestation/make_credential`: Used by a server to create a remote attestation challenge
* `./examples/attestation/activate_credential`: Used by a client to decrypt the challenge and respond
* `./examples/keygen/keygen`: Used to create a primary key(PK) and attestation key(AK)
* `./examples/attestation/certify`: Used to certify (attest) or prove an object with name is loaded in the TPM.
* `./examples/keygen/create_primary`: Used to create a primary key(PK) and attestation key(AK)
Note: All of these example allow the use of the Endorsement Key and Attestation Key under the Endorsement Hierarchy. This is done by adding the `-eh` option when executing any of the three examples above. The advantage of using EK/EH is that the private key material of the EK never leaves the TPM. Anything encrypted using the public part of the EK can be encrypted only internally by the TPM owner of the EK, and EK is unique for every TPM chip. Therefore, creating challenges for Remote Attestation using the EK/EH has greater value in some scenarios. One drawback is that by using the EK the identity of the host under attestation is always known, because the EK private-public key pair identifies the TPM and in some scenarios this might rise privacy concerns. Our remote attestation examples support both AK under SRK and AK under EK. It is up to the developer to decide which one to use.
@ -99,6 +100,58 @@ TPM2_ActivateCredential success
The transfer of the challenge response containing the secret in plain (or used as a symmetric key seed) is not part of the `activate_credential` example, because the exchange is also implementation specific.
### Certify Example
The certify example shows how to use the `TPM2_Certify` API to sign the attestation info for another key. This can be used to prove that an object with a specific name is loaded into the TPM. A common example of this is using the restricted IAK to sign the attestation information for the IDevID.
The create_primary example support creating RSA or ECC initial device identity (IDevID) and attestation identity (IAK) keys. These are created under the endorsement hierarchy and follow the "TPM 2.0 Keys for Device Identity and Attestation" TCG specification for setting up the primary key policies. Figures 10 and 11 fom this specification shows the IAK/IDevID policy.
![Figure 10: Example IDevID Key Delegation Policy](tpm_idevid_policy.png)
![Figure 11: Example IAK Key Delegation Policy](tpm_iak_policy.png)
The IDevID key can be used for external non-restrictive signing.
The IAK is used for internal attestation.
Here we use the IAK to certify the attestation information for the IDevID key.
```sh
% ./examples/keygen/create_primary -rsa -eh -iak -keep
TPM2.0 Primary Key generation example
Algorithm: RSA
Unique: IAK
Store Handle: 0x00000000
Use Parameter Encryption: NULL
Creating new RSA primary key...
Create Primary Handle: 0x80000000
% ./examples/keygen/create_primary -rsa -eh -idevid -keep
TPM2.0 Primary Key generation example
Algorithm: RSA
Unique: IDEVID
Store Handle: 0x00000000
Use Parameter Encryption: NULL
Creating new RSA primary key...
Create Primary Handle: 0x80000001
% ./examples/attestation/certify -rsa -certify=0x80000001 -signer=0x80000000
Certify 0x80000001 with 0x80000000 to generate TPM-signed attestation info
EK Policy Session: Handle 0x3000000
TPM2_Certify complete
Certify Info 172
RSA Signature: 256
% ./examples/management/flush 0x80000001
Preparing to free TPM2.0 Resources
Freeing 80000001 object
% ./examples/management/flush 0x80000000
Preparing to free TPM2.0 Resources
Freeing 80000000 object
```
For ECC use the same steps as above, but replace `-rsa` with `-ecc`.
## More information
Please contact us at facts@wolfssl.com if you are interested in more information about Remote Attestation using wolfTPM.

View File

@ -33,7 +33,7 @@
#ifndef WOLFTPM2_NO_WRAPPER
#include <examples/attestation/credential.h>
#include <examples/attestation/attestation.h>
#include <hal/tpm_io.h>
#include <examples/tpm_test.h>
#include <examples/tpm_test_keys.h>

View File

@ -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_ */

View File

@ -0,0 +1,277 @@
/* 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 <config.h>
#endif
#include <wolftpm/tpm2_wrap.h>
#include <stdio.h>
#ifndef WOLFTPM2_NO_WRAPPER
#include <examples/attestation/attestation.h>
#include <hal/tpm_io.h>
#include <examples/tpm_test.h>
#include <examples/tpm_test_keys.h>
/******************************************************************************/
/* --- 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", 0x80000001U);
printf("\t* -signer=[handle] Key to sign with (default 0x%x)\n", 0x80000000U);
printf("\nExample Usage:\n");
printf("./examples/keygen/create_primary -rsa -eh -iak -keep\n");
printf("./examples/keygen/create_primary -rsa -eh -idevid -keep\n");
printf("./examples/attestation/certify -rsa -certify=0x80000001 "
"-signer=0x80000000\n");
printf("./examples/management/flush 0x80000001\n");
printf("./examples/management/flush 0x80000000\n");
}
/* Policies for IDevID/IAK from:
* "TPM 2.0 Keys for Device Identity and Attestation" */
static const byte PA_User_Policy[] = {
0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xB3, 0xF8,
0x1A, 0x90, 0xCC, 0x8D, 0x46, 0xA5, 0xD7, 0x24,
0xFD, 0x52, 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64,
0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14, 0x69, 0xAA
};
static const byte Certify[] = {
0xB2, 0xA6, 0x9E, 0x63, 0x91, 0xE2, 0x68, 0x4A,
0x0F, 0xE7, 0x52, 0xD3, 0x9E, 0x14, 0xAC, 0xD2,
0xE5, 0xCB, 0x92, 0x2E, 0x4B, 0xD0, 0x35, 0x83,
0x0E, 0xEA, 0x31, 0xF2, 0xAA, 0xBE, 0x98, 0x70
};
static const byte Activate_CredentialPolicy[] = {
0xCD, 0x99, 0x17, 0xCF, 0x18, 0xC3, 0x84, 0x8C,
0x3A, 0x2E, 0x60, 0x69, 0x86, 0xA0, 0x66, 0xC6,
0x81, 0x42, 0xF9, 0xBC, 0x27, 0x10, 0xA2, 0x78,
0x28, 0x7A, 0x65, 0x0C, 0xA3, 0xBB, 0xF2, 0x45};
static const byte Policy_Authorize_NV_IDevID[] = {
0x62, 0x9C, 0x50, 0xB0, 0x5F, 0x1A, 0xDB, 0x5B,
0x42, 0x97, 0xFE, 0xB2, 0x41, 0x54, 0x9D, 0x42,
0x17, 0xA1, 0xC7, 0x92, 0xC1, 0x62, 0xFE, 0xB8,
0x61, 0x02, 0x2D, 0xEF, 0x88, 0xFA, 0x95, 0x01
};
#if 0
static const byte Policy_Authorize_NV_IAK[] = {
0x10, 0x1E, 0x68, 0x9D, 0xAD, 0xF1, 0x45, 0x22,
0x24, 0x12, 0xC0, 0x5B, 0x76, 0xE1, 0x45, 0x32,
0xAF, 0x1E, 0x5C, 0x74, 0x20, 0x8E, 0x0A, 0xE7,
0xCD, 0xB0, 0xCF, 0xF1, 0x90, 0x6C, 0x8A, 0x09
};
#endif
int TPM2_Certify_Example(void* userCtx, int argc, char *argv[])
{
int rc = -1;
WOLFTPM2_DEV dev;
WOLFTPM2_SESSION tpmSession;
TPM_HANDLE certifyHandle = 0x80000001;
TPM_HANDLE signerHandle = 0x80000000;
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;
PolicyOR_In policyOR;
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)XSTRTOUL(certifyStr, NULL, 0);
}
else if (XSTRNCMP(argv[argc-1], "-signer=", XSTRLEN("-signer=")) == 0) {
const char* signerStr = argv[argc-1] + XSTRLEN("-signer=");
signerHandle = (word32)XSTRTOUL(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;
/* Set the created Policy Session for use in next operation */
rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession, 0);
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;
/* satisfy the TPM2_PolicyOR for SHA2-256 for IDevID/IAK admin policy */
XMEMSET(&policyOR, 0, sizeof(policyOR));
policyOR.policySession = tpmSession.handle.hndl;
policyOR.pHashList.count = 4;
policyOR.pHashList.digests[0].size = sizeof(PA_User_Policy);
XMEMCPY(policyOR.pHashList.digests[0].buffer, PA_User_Policy,
sizeof(PA_User_Policy));
policyOR.pHashList.digests[1].size = sizeof(Certify);
XMEMCPY(policyOR.pHashList.digests[1].buffer, Certify, sizeof(Certify));
policyOR.pHashList.digests[2].size = sizeof(Activate_CredentialPolicy);
XMEMCPY(policyOR.pHashList.digests[2].buffer, Activate_CredentialPolicy,
sizeof(Activate_CredentialPolicy));
policyOR.pHashList.digests[3].size = sizeof(Policy_Authorize_NV_IDevID);
XMEMCPY(policyOR.pHashList.digests[3].buffer, Policy_Authorize_NV_IDevID,
sizeof(Policy_Authorize_NV_IDevID));
rc = TPM2_PolicyOR(&policyOR);
if (rc != TPM_RC_SUCCESS) {
printf("TPM2_PolicyOR failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
goto exit;
}
/* Setup the session object names used for policy HMAC */
(void)wolfTPM2_SetAuthHandleName(&dev, 0, &certify.handle);
(void)wolfTPM2_SetAuthHandle(&dev, 1, &signer.handle);
/* Create signed certify structure */
XMEMSET(&certifyIn, 0, sizeof(certifyIn));
/* the first handle (objectHandle) requires ADMIN role */
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);
}
/* the policy session is automatically closed */
tpmSession.handle.hndl = TPM_RH_NULL;
/* 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 */
#ifndef NO_MAIN_DRIVER
int main(int argc, char *argv[])
{
int rc = -1;
#ifndef WOLFTPM2_NO_WRAPPER
rc = TPM2_Certify_Example(NULL, argc, argv);
#else
printf("Wrapper code not compiled in\n");
(void)argc;
(void)argv;
#endif /* !WOLFTPM2_NO_WRAPPER */
return rc;
}
#endif

View File

@ -3,27 +3,36 @@
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
EXTRA_DIST+= examples/attestation/README.md \
examples/attestation/tpm_idevid_policy.png \
examples/attestation/tpm_iak_policy.png

View File

@ -29,7 +29,7 @@
#ifndef WOLFTPM2_NO_WRAPPER
#include <examples/attestation/credential.h>
#include <examples/attestation/attestation.h>
#include <hal/tpm_io.h>
#include <examples/tpm_test.h>
#include <examples/tpm_test_keys.h>

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -103,7 +103,7 @@ int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[])
while (argc > 1) {
if (XSTRNCMP(argv[argc-1], "-nvindex=", XSTRLEN("-nvindex=")) == 0) {
const char* nvIndexStr = argv[argc-1] + XSTRLEN("-nvindex=");
nvIndex = (word32)XSTRTOL(nvIndexStr, NULL, 0);
nvIndex = (word32)XSTRTOUL(nvIndexStr, NULL, 0);
if (!(authHandle == TPM_RH_PLATFORM && (
nvIndex > TPM_20_PLATFORM_MFG_NV_SPACE &&
nvIndex < TPM_20_OWNER_NV_SPACE)) &&

View File

@ -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");
@ -75,7 +83,8 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[])
{
int rc;
WOLFTPM2_DEV dev;
WOLFTPM2_KEY primary;
WOLFTPM2_PKEY root; /* primary key with ticket */
WOLFTPM2_KEY* primary = (WOLFTPM2_KEY*)&root; /* cast to public key only */
TPMT_PUBLIC publicTemplate;
TPMI_ALG_PUBLIC alg = TPM_ALG_RSA;
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
@ -84,6 +93,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 +129,17 @@ 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;
}
else if (XSTRCMP(argv[argc-1], "-idevid") == 0) {
useIDevIDTemplate = 1;
}
#endif
else if (XSTRNCMP(argv[argc-1], "-unique=", XSTRLEN("-unique=")) == 0) {
uniqueStr = argv[argc-1] + XSTRLEN("-unique=");
}
@ -122,13 +147,16 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[])
authStr = argv[argc-1] + XSTRLEN("-auth=");
}
else if (XSTRNCMP(argv[argc-1], "-store=", XSTRLEN("-store=")) == 0) {
persistHandle = (word32)XSTRTOL(argv[argc-1] + XSTRLEN("-store="),
persistHandle = (word32)XSTRTOUL(argv[argc-1] + XSTRLEN("-store="),
NULL, 0);
if (persistHandle < 0x81000000 && persistHandle > 0x810FFFF) {
printf("Invalid storage handle %s\n", argv[argc-1] + 7);
persistHandle = 0;
}
}
else if (XSTRCMP(argv[argc-1], "-keep") == 0) {
keepHandleOpen = 1;
}
else {
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
}
@ -136,7 +164,7 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[])
argc--;
}
XMEMSET(&primary, 0, sizeof(primary));
XMEMSET(&root, 0, sizeof(root));
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
printf("TPM2.0 Primary Key generation example\n");
@ -158,7 +186,7 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[])
/* See if handle already exists */
if (persistHandle > 0) {
if (wolfTPM2_ReadPublicKey(&dev, &primary, persistHandle) == 0) {
if (wolfTPM2_ReadPublicKey(&dev, primary, persistHandle) == 0) {
printf("Primary Handle 0x%08x already exists\n", persistHandle);
goto exit;
}
@ -166,10 +194,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;
@ -199,23 +249,35 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[])
printf("Creating new %s primary key...\n", TPM2_GetAlgName(alg));
rc = wolfTPM2_CreatePrimaryKey(&dev, &primary, hierarchy, &publicTemplate,
rc = wolfTPM2_CreatePrimaryKey_ex(&dev, &root, hierarchy,
&publicTemplate,
(const byte*)authStr, authStr ? (int)XSTRLEN(authStr) : 0);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_CreatePrimaryKey failed\n");
goto exit;
}
printf("Create Primary Handle: 0x%x\n", (word32)root.handle.hndl);
#ifdef DEBUG_WOLFTPM
printf("Primary Key Public (%d bytes)\n", primary.pub.size);
TPM2_PrintBin((const byte*)&primary.pub.publicArea, primary.pub.size);
printf("Primary Key Public (%d bytes)\n", primary->pub.size);
TPM2_PrintBin((const byte*)&primary->pub.publicArea, primary->pub.size);
printf("Creation Hash: %d\n", root.creationHash.size);
TPM2_PrintBin(root.creationHash.buffer, root.creationHash.size);
printf("Creation Ticket: Tag 0x%x, hierarchy 0x%x, Ticket %d\n",
root.creationTicket.tag, root.creationTicket.hierarchy,
root.creationTicket.digest.size);
TPM2_PrintBin(root.creationTicket.digest.buffer,
root.creationTicket.digest.size);
#endif
if (persistHandle > 0) {
#ifndef WOLFTPM_WINAPI
/* Move storage key into persistent NV */
printf("Storing Primary key to handle 0x%08x\n", persistHandle);
rc = wolfTPM2_NVStoreKey(&dev, hierarchy, &primary,
rc = wolfTPM2_NVStoreKey(&dev, hierarchy, primary,
persistHandle);
if (rc != TPM_RC_SUCCESS) goto exit;
#else
@ -231,7 +293,8 @@ exit:
}
/* Close handles */
wolfTPM2_UnloadHandle(&dev, &primary.handle);
if (!keepHandleOpen)
wolfTPM2_UnloadHandle(&dev, &primary->handle);
if (paramEncAlg != TPM_ALG_NULL) {
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
}

View File

@ -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)XSTRTOUL(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);

View File

@ -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));

View File

@ -81,7 +81,7 @@ int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[])
while (argc > 1) {
if (XSTRNCMP(argv[argc-1], "-nvindex=", XSTRLEN("-nvindex=")) == 0) {
const char* nvIndexStr = argv[argc-1] + XSTRLEN("-nvindex=");
nvIndex = (word32)XSTRTOL(nvIndexStr, NULL, 0);
nvIndex = (word32)XSTRTOUL(nvIndexStr, NULL, 0);
if (!(authHandle == TPM_RH_PLATFORM && (
nvIndex > TPM_20_PLATFORM_MFG_NV_SPACE &&
nvIndex < TPM_20_OWNER_NV_SPACE)) &&

View File

@ -93,7 +93,7 @@ int TPM2_NVRAM_PolicyNV_Example(void* userCtx, int argc, char *argv[])
while (argc > 1) {
if (XSTRNCMP(argv[argc-1], "-nvindex=", XSTRLEN("-nvindex=")) == 0) {
const char* nvIndexStr = argv[argc-1] + XSTRLEN("-nvindex=");
nvIndex = (word32)XSTRTOL(nvIndexStr, NULL, 0);
nvIndex = (word32)XSTRTOUL(nvIndexStr, NULL, 0);
if (!(authHandle == TPM_RH_PLATFORM && (
nvIndex > TPM_20_PLATFORM_MFG_NV_SPACE &&
nvIndex < TPM_20_OWNER_NV_SPACE)) &&

View File

@ -89,7 +89,7 @@ int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[])
while (argc > 1) {
if (XSTRNCMP(argv[argc-1], "-nvindex=", XSTRLEN("-nvindex=")) == 0) {
const char* nvIndexStr = argv[argc-1] + XSTRLEN("-nvindex=");
nvIndex = (word32)XSTRTOL(nvIndexStr, NULL, 0);
nvIndex = (word32)XSTRTOUL(nvIndexStr, NULL, 0);
if (nvIndex < NV_INDEX_FIRST || nvIndex > NV_INDEX_LAST) {
fprintf(stderr, "Invalid NV Index %s\n", nvIndexStr);
fprintf(stderr, "\tPlatform Range: 0x%x -> 0x%x\n",

View File

@ -95,7 +95,7 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[])
while (argc > 1) {
if (XSTRNCMP(argv[argc-1], "-nvindex=", XSTRLEN("-nvindex=")) == 0) {
const char* nvIndexStr = argv[argc-1] + XSTRLEN("-nvindex=");
nvIndex = (word32)XSTRTOL(nvIndexStr, NULL, 0);
nvIndex = (word32)XSTRTOUL(nvIndexStr, NULL, 0);
if (!(authHandle == TPM_RH_PLATFORM && (
nvIndex > TPM_20_PLATFORM_MFG_NV_SPACE &&
nvIndex < TPM_20_OWNER_NV_SPACE)) &&

View File

@ -51,6 +51,37 @@ RESULT=$?
RESULT=$?
[ $RESULT -ne 0 ] && echo -e "create primary owner rsa key stored failed! $RESULT" && exit 1
if [ $WOLFCRYPT_ENABLE -eq 1 ]; then
# 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 -rsa -certify=0x80000001 -signer=0x80000000 >> run.out 2>&1
RESULT=$?
[ $RESULT -ne 0 ] && echo -e "certify RSA IDevID with IAK failed! $RESULT" && exit 1
./examples/management/flush 0x80000000 >> run.out 2>&1
./examples/management/flush 0x80000001 >> run.out 2>&1
./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 -ecc -certify=0x80000001 -signer=0x80000000 >> run.out 2>&1
RESULT=$?
[ $RESULT -ne 0 ] && echo -e "certify ECC IDevID with IAK failed! $RESULT" && exit 1
./examples/management/flush 0x80000000 >> run.out 2>&1
./examples/management/flush 0x80000001 >> run.out 2>&1
fi
if [ $WOLFCRYPT_ENABLE -eq 1 ]; then
./examples/keygen/create_primary -rsa -oh -aes >> run.out 2>&1
RESULT=$?

View File

@ -1690,7 +1690,7 @@ int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
}
int wolfTPM2_CreatePrimaryKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
int wolfTPM2_CreatePrimaryKey_ex(WOLFTPM2_DEV* dev, WOLFTPM2_PKEY* pkey,
TPM_HANDLE primaryHandle, TPMT_PUBLIC* publicTemplate,
const byte* auth, int authSz)
{
@ -1698,14 +1698,14 @@ int wolfTPM2_CreatePrimaryKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
CreatePrimary_In createPriIn;
CreatePrimary_Out createPriOut;
if (dev == NULL || key == NULL || publicTemplate == NULL)
if (dev == NULL || pkey == NULL || publicTemplate == NULL)
return BAD_FUNC_ARG;
/* set session auth to blank */
wolfTPM2_SetAuthPassword(dev, 0, NULL);
/* clear output key buffer */
XMEMSET(key, 0, sizeof(WOLFTPM2_KEY));
XMEMSET(pkey, 0, sizeof(*pkey));
/* setup create primary command */
XMEMSET(&createPriIn, 0, sizeof(createPriIn));
@ -1732,22 +1732,51 @@ int wolfTPM2_CreatePrimaryKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
#endif
return rc;
}
key->handle.hndl = createPriOut.objectHandle;
wolfTPM2_CopyAuth(&key->handle.auth,
pkey->handle.hndl = createPriOut.objectHandle;
wolfTPM2_CopyAuth(&pkey->handle.auth,
&createPriIn.inSensitive.sensitive.userAuth);
wolfTPM2_CopyName(&key->handle.name, &createPriOut.name);
wolfTPM2_CopySymmetric(&key->handle.symmetric,
wolfTPM2_CopyName(&pkey->handle.name, &createPriOut.name);
wolfTPM2_CopySymmetric(&pkey->handle.symmetric,
&createPriOut.outPublic.publicArea.parameters.asymDetail.symmetric);
wolfTPM2_CopyPub(&key->pub, &createPriOut.outPublic);
wolfTPM2_CopyPub(&pkey->pub, &createPriOut.outPublic);
pkey->creationHash.size = createPriOut.creationHash.size;
XMEMCPY(pkey->creationHash.buffer, createPriOut.creationHash.buffer,
createPriOut.creationHash.size);
pkey->creationTicket.tag = createPriOut.creationTicket.tag;
pkey->creationTicket.hierarchy = createPriOut.creationTicket.hierarchy;
pkey->creationTicket.digest.size = createPriOut.creationTicket.digest.size;
XMEMCPY(pkey->creationTicket.digest.buffer,
createPriOut.creationTicket.digest.buffer,
createPriOut.creationTicket.digest.size);
#ifdef DEBUG_WOLFTPM
printf("TPM2_CreatePrimary: 0x%x (%d bytes)\n",
(word32)key->handle.hndl, key->pub.size);
(word32)pkey->handle.hndl, pkey->pub.size);
#endif
return rc;
}
int wolfTPM2_CreatePrimaryKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
TPM_HANDLE primaryHandle, TPMT_PUBLIC* publicTemplate,
const byte* auth, int authSz)
{
int rc;
WOLFTPM2_PKEY pKey;
if (dev == NULL || key == NULL || publicTemplate == NULL)
return BAD_FUNC_ARG;
rc = wolfTPM2_CreatePrimaryKey_ex(dev, &pKey, primaryHandle, publicTemplate,
auth, authSz);
if (rc == 0) {
/* return only the handle and public information */
XMEMCPY(&key->handle, &pKey.handle, sizeof(WOLFTPM2_HANDLE));
XMEMCPY(&key->pub, &pKey.pub, sizeof(TPM2B_PUBLIC));
}
return rc;
}
int wolfTPM2_ChangeAuthKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
WOLFTPM2_HANDLE* parent, const byte* auth, int authSz)
{
@ -6091,6 +6120,147 @@ 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_adminWithPolicy | 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_adminWithPolicy | TPMA_OBJECT_restricted |
TPMA_OBJECT_sign);
ret = GetKeyTemplateECC(publicTemplate, hashAlg,
objectAttributes, curveID, TPM_ALG_ECDSA, hashAlg);
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_adminWithPolicy | 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_adminWithPolicy | TPMA_OBJECT_sign);
ret = GetKeyTemplateECC(publicTemplate, hashAlg,
objectAttributes, curveID, TPM_ALG_ECDSA, hashAlg);
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)
{
@ -6168,7 +6338,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;
@ -7145,6 +7316,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,
@ -7239,11 +7425,12 @@ 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]) */
int wolfTPM2_PolicyHash(TPM_ALG_ID hashAlg,
byte* digest, word32* digestSz, TPM_CC cc,
const byte* input, word32 inputSz)
{
int rc;
word32 val;
@ -7251,18 +7438,18 @@ 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)) {
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)
@ -7272,34 +7459,68 @@ 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);
}
/* Hash of PCR(s) */
if (rc == 0) {
rc = wc_HashUpdate(&hash_ctx, hashType, pcrDigest, pcrDigestSz);
/* Input (optional) */
if (rc == 0 && input != NULL && inputSz > 0) {
rc = wc_HashUpdate(&hash_ctx, hashType, input, inputSz);
}
if (rc == 0) {
rc = wc_HashFinal(&hash_ctx, hashType, digest);
}
wc_HashFree(&hash_ctx, hashType);
#ifdef DEBUG_WOLFTPM
if (rc != 0) {
printf("wolfTPM2_PolicyHash failed %d: %s\n",
rc, wolfTPM2_GetRCString(rc));
}
#ifdef WOLFTPM_DEBUG_VERBOSE
else {
printf("wolfTPM2_PolicyHash: %d\n", *digestSz);
TPM2_PrintBin(digest, *digestSz);
}
#endif
#endif
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)
{
int rc;
TPM2_Packet packet;
byte buf[sizeof(TPML_PCR_SELECTION)+WC_MAX_DIGEST_SIZE];
TPML_PCR_SELECTION pcr;
if (digest == NULL || digestSz == NULL || pcrArray == NULL ||
pcrArraySz == 0) {
return BAD_FUNC_ARG;
}
/* 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);
/* Copy the pcrDigest to the end of buffer */
if (pcrDigestSz + packet.pos > sizeof(buf))
return BUFFER_E;
XMEMCPY(buf + packet.pos, pcrDigest, pcrDigestSz);
packet.pos += pcrDigestSz;
rc = wolfTPM2_PolicyHash(pcrAlg, digest, digestSz, TPM_CC_PolicyPCR,
buf, packet.pos);
#ifdef DEBUG_WOLFTPM
if (rc != 0) {
printf("wolfTPM2_PolicyPCRMake failed %d: %s\n",
@ -7320,55 +7541,8 @@ int wolfTPM2_PolicyPCRMake(TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz,
int wolfTPM2_PolicyRefMake(TPM_ALG_ID pcrAlg, byte* digest, word32* digestSz,
const byte* policyRef, word32 policyRefSz)
{
int rc;
enum wc_HashType hashType;
wc_HashAlg hash_ctx;
word32 inSz;
if (digest == NULL || digestSz == NULL ||
(policyRef == NULL && policyRefSz > 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);
}
wc_HashFree(&hash_ctx, hashType);
#ifdef DEBUG_WOLFTPM
if (rc != 0) {
printf("wolfTPM_PolicyRefMake failed %d: %s\n",
rc, wolfTPM2_GetRCString(rc));
}
#ifdef WOLFTPM_DEBUG_VERBOSE
else {
printf("wolfTPM_PolicyRefMake: %d\n", *digestSz);
TPM2_PrintBin(digest, *digestSz);
}
#endif
#endif
return rc;
return wolfTPM2_PolicyHash(pcrAlg, digest, digestSz, 0,
policyRef, policyRefSz);
}
/* Assemble a PCR Authorization for a public key */
@ -7379,49 +7553,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 */
rc = wolfTPM2_ComputeName(pub, &name);
if (rc == 0) {
val = TPM2_Packet_SwapU32(TPM_CC_PolicyAuthorize);
rc = wc_HashUpdate(&hash_ctx, hashType, (byte*)&val, sizeof(val));
rc = wolfTPM2_PolicyHash(pcrAlg, digest, digestSz,
TPM_CC_PolicyAuthorize, name.name, name.size);
}
/* 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);
}
}
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);
@ -7441,6 +7583,7 @@ int wolfTPM2_PolicyAuthorizeMake(TPM_ALG_ID pcrAlg,
#endif
return rc;
}
#endif /* !WOLFTPM2_NO_WOLFCRYPT */
/******************************************************************************/
@ -7538,20 +7681,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,
@ -7580,17 +7720,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;

View File

@ -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;

View File

@ -226,9 +226,8 @@ typedef int64_t INT64;
#ifndef WOLFTPM_CUSTOM_TYPES
#include <stdlib.h>
#define XSTRTOL(s,e,b) strtol((s),(e),(b))
#define XSTRTOUL(s,e,b) strtoul((s),(e),(b))
#define XATOI(s) atoi((s))
#endif
/* make sure file IO macros are available for examples */

View File

@ -58,13 +58,27 @@ typedef struct WOLFTPM2_DEV {
TPM2_AUTH_SESSION session[MAX_SESSION_NUM];
} WOLFTPM2_DEV;
/* WOLFTPM2_KEYBLOB can be cast to WOLFTPM2_KEY.
* Both structures must have "handle" and "pub" as first members */
/* Public Key with Handle.
* Must have "handle" and "pub" as first members */
typedef struct WOLFTPM2_KEY {
WOLFTPM2_HANDLE handle;
TPM2B_PUBLIC pub;
} WOLFTPM2_KEY;
/* Primary Key - From TPM2_CreatePrimary that include creation hash and ticket.
* WOLFTPM2_PKEY can be cast to WOLFTPM2_KEY.
* Must have "handle" and "pub" as first members */
typedef struct WOLFTPM2_PKEY {
WOLFTPM2_HANDLE handle;
TPM2B_PUBLIC pub;
TPM2B_DIGEST creationHash;
TPMT_TK_CREATION creationTicket;
} WOLFTPM2_PKEY;
/* Private/Public Key:
* WOLFTPM2_KEYBLOB can be cast to WOLFTPM2_KEY
* Must have "handle" and "pub" as first members */
typedef struct WOLFTPM2_KEYBLOB {
WOLFTPM2_HANDLE handle;
TPM2B_PUBLIC pub;
@ -595,6 +609,7 @@ WOLFTPM_API int wolfTPM2_CreateAuthSession_EkPolicy(WOLFTPM2_DEV* dev,
\param authSz integer value, specifying the size of the password authorization, in bytes
\sa wolfTPM2_CreateKey
\sa wolfTPM2_CreatePrimaryKey_ex
\sa wolfTPM2_GetKeyTemplate_RSA
\sa wolfTPM2_GetKeyTemplate_ECC
*/
@ -602,6 +617,33 @@ WOLFTPM_API int wolfTPM2_CreatePrimaryKey(WOLFTPM2_DEV* dev,
WOLFTPM2_KEY* key, TPM_HANDLE primaryHandle, TPMT_PUBLIC* publicTemplate,
const byte* auth, int authSz);
/*!
\ingroup wolfTPM2_Wrappers
\brief Single function to prepare and create a TPM 2.0 Primary Key
\note TPM 2.0 allows only asymmetric RSA or ECC primary keys. Afterwards, both symmetric and asymmetric keys can be created under a TPM 2.0 Primary Key
Typically, Primary Keys are used to create Hierarchies of TPM 2.0 Keys.
The TPM uses a Primary Key to wrap the other keys, signing or decrypting.
\return TPM_RC_SUCCESS: successful
\return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code)
\return BAD_FUNC_ARG: check the provided arguments
\param dev pointer to a TPM2_DEV struct
\param pkey pointer to an empty struct of WOLFTPM2_PKEY type including the creation hash and ticket.
\param primaryHandle integer value, specifying one of four TPM 2.0 Primary Seeds: TPM_RH_OWNER, TPM_RH_ENDORSEMENT, TPM_RH_PLATFORM or TPM_RH_NULL
\param publicTemplate pointer to a TPMT_PUBLIC structure populated manually or using one of the wolfTPM2_GetKeyTemplate_... wrappers
\param auth pointer to a string constant, specifying the password authorization for the Primary Key
\param authSz integer value, specifying the size of the password authorization, in bytes
\sa wolfTPM2_CreateKey
\sa wolfTPM2_CreatePrimaryKey
\sa wolfTPM2_GetKeyTemplate_RSA
\sa wolfTPM2_GetKeyTemplate_ECC
*/
WOLFTPM_API int wolfTPM2_CreatePrimaryKey_ex(WOLFTPM2_DEV* dev, WOLFTPM2_PKEY* pkey,
TPM_HANDLE primaryHandle, TPMT_PUBLIC* publicTemplate,
const byte* auth, int authSz);
/*!
\ingroup wolfTPM2_Wrappers
\brief Change the authorization secret of a TPM 2.0 key
@ -2801,6 +2843,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.
@ -3691,6 +3745,29 @@ 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])
\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
\sa wolfTPM2_PolicyPCRMake
*/
WOLFTPM_API int wolfTPM2_PolicyHash(TPM_ALG_ID hashAlg,
byte* digest, word32* digestSz, TPM_CC cc,
const byte* input, word32 inputSz);
/*!
\ingroup wolfTPM2_Wrappers
@ -3708,7 +3785,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,
@ -3729,6 +3806,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);
@ -3747,10 +3825,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 */