mirror of https://github.com/wolfSSL/wolfTPM.git
1510 lines
58 KiB
C
1510 lines
58 KiB
C
/* native_test.c
|
|
*
|
|
* Copyright (C) 2006-2022 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 using the TPM2_ specification API's in TPM2_Native_Test() */
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <wolftpm/tpm2.h>
|
|
#include <wolftpm/tpm2_param_enc.h>
|
|
|
|
#include <examples/native/native_test.h>
|
|
#include <hal/tpm_io.h>
|
|
#include <examples/tpm_test.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
/******************************************************************************/
|
|
/* --- BEGIN TPM Native API Tests -- */
|
|
/******************************************************************************/
|
|
|
|
typedef struct tpmKey {
|
|
TPM_HANDLE handle;
|
|
TPM2B_AUTH auth;
|
|
TPMT_SYM_DEF_OBJECT symmetric; /* used for parameter encrypt/decrypt */
|
|
TPM2B_PRIVATE priv;
|
|
TPM2B_PUBLIC pub;
|
|
TPM2B_NAME name;
|
|
TPM2B_DIGEST creationHash;
|
|
TPMT_TK_CREATION creationTicket;
|
|
} TpmKey;
|
|
|
|
typedef TpmKey TpmRsaKey;
|
|
typedef TpmKey TpmEccKey;
|
|
typedef TpmKey TpmHmacKey;
|
|
typedef TpmKey TpmSymKey;
|
|
|
|
typedef struct tmpHandle {
|
|
TPM_HANDLE handle;
|
|
TPM2B_AUTH auth;
|
|
} TpmHandle;
|
|
|
|
|
|
int TPM2_Native_Test(void* userCtx)
|
|
{
|
|
return TPM2_Native_TestArgs(userCtx, 0, NULL);
|
|
}
|
|
int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[])
|
|
{
|
|
int rc;
|
|
TPM2_CTX tpm2Ctx;
|
|
|
|
union {
|
|
Startup_In startup;
|
|
Shutdown_In shutdown;
|
|
SelfTest_In selfTest;
|
|
GetRandom_In getRand;
|
|
StirRandom_In stirRand;
|
|
GetCapability_In cap;
|
|
IncrementalSelfTest_In incSelfTest;
|
|
PCR_Read_In pcrRead;
|
|
PCR_Extend_In pcrExtend;
|
|
PCR_Reset_In pcrReset;
|
|
CreatePrimary_In createPri;
|
|
Create_In create;
|
|
CreateLoaded_In createLoaded;
|
|
EvictControl_In evict;
|
|
ReadPublic_In readPub;
|
|
StartAuthSession_In authSes;
|
|
Load_In load;
|
|
LoadExternal_In loadExt;
|
|
FlushContext_In flushCtx;
|
|
Unseal_In unseal;
|
|
PolicyGetDigest_In policyGetDigest;
|
|
PolicyPCR_In policyPCR;
|
|
PolicyRestart_In policyRestart;
|
|
PolicyCommandCode_In policyCC;
|
|
Clear_In clear;
|
|
HashSequenceStart_In hashSeqStart;
|
|
SequenceUpdate_In seqUpdate;
|
|
SequenceComplete_In seqComp;
|
|
MakeCredential_In makeCred;
|
|
ObjectChangeAuth_In objChgAuth;
|
|
NV_ReadPublic_In nvReadPub;
|
|
NV_DefineSpace_In nvDefine;
|
|
NV_UndefineSpace_In nvUndefine;
|
|
RSA_Encrypt_In rsaEnc;
|
|
RSA_Decrypt_In rsaDec;
|
|
Sign_In sign;
|
|
VerifySignature_In verifySign;
|
|
ECC_Parameters_In eccParam;
|
|
ECDH_KeyGen_In ecdh;
|
|
ECDH_ZGen_In ecdhZ;
|
|
EncryptDecrypt2_In encDec;
|
|
CertifyCreation_In certifyCreationIn;
|
|
HMAC_In hmac;
|
|
HMAC_Start_In hmacStart;
|
|
#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)
|
|
SetCommandSet_In setCmdSet;
|
|
#endif
|
|
byte maxInput[MAX_COMMAND_SIZE];
|
|
} cmdIn;
|
|
union {
|
|
GetCapability_Out cap;
|
|
GetRandom_Out getRand;
|
|
#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)
|
|
GetRandom2_Out getRand2;
|
|
#endif
|
|
GetTestResult_Out tr;
|
|
IncrementalSelfTest_Out incSelfTest;
|
|
ReadClock_Out readClock;
|
|
PCR_Read_Out pcrRead;
|
|
CreatePrimary_Out createPri;
|
|
Create_Out create;
|
|
CreateLoaded_Out createLoaded;
|
|
ReadPublic_Out readPub;
|
|
StartAuthSession_Out authSes;
|
|
Load_Out load;
|
|
LoadExternal_Out loadExt;
|
|
Unseal_Out unseal;
|
|
PolicyGetDigest_Out policyGetDigest;
|
|
HashSequenceStart_Out hashSeqStart;
|
|
SequenceComplete_Out seqComp;
|
|
MakeCredential_Out makeCred;
|
|
ObjectChangeAuth_Out objChgAuth;
|
|
NV_ReadPublic_Out nvReadPub;
|
|
RSA_Encrypt_Out rsaEnc;
|
|
RSA_Decrypt_Out rsaDec;
|
|
Sign_Out sign;
|
|
VerifySignature_Out verifySign;
|
|
ECC_Parameters_Out eccParam;
|
|
ECDH_KeyGen_Out ecdh;
|
|
ECDH_ZGen_Out ecdhZ;
|
|
EncryptDecrypt2_Out encDec;
|
|
CertifyCreation_Out certifyCreationOut;
|
|
HMAC_Out hmac;
|
|
HMAC_Start_Out hmacStart;
|
|
byte maxOutput[MAX_RESPONSE_SIZE];
|
|
} cmdOut;
|
|
|
|
int pcrCount, pcrIndex, i;
|
|
TPML_TAGGED_TPM_PROPERTY* tpmProp;
|
|
TPM_HANDLE handle = TPM_RH_NULL;
|
|
TPM_HANDLE sessionHandle = TPM_RH_NULL;
|
|
#ifndef WOLFTPM_WINAPI
|
|
TPMI_RH_NV_INDEX nvIndex;
|
|
#endif
|
|
TPM2B_PUBLIC_KEY_RSA message;
|
|
|
|
TpmRsaKey endorse;
|
|
TpmRsaKey storage;
|
|
TpmHmacKey hmacKey;
|
|
TpmEccKey eccKey;
|
|
TpmRsaKey rsaKey;
|
|
TpmSymKey aesKey;
|
|
|
|
const char storagePwd[] = "WolfTPMPassword";
|
|
const char usageAuth[] = "ThisIsASecretUsageAuth";
|
|
const char userKey[] = "ThisIsMyKey";
|
|
const char label[] = "ThisIsMyLabel";
|
|
const char keyCreationNonce[] = "RandomServerPickedCreationNonce";
|
|
|
|
const char* hashTestData =
|
|
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
|
const char* hashTestDig =
|
|
"\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60"
|
|
"\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB"
|
|
"\x06\xC1";
|
|
|
|
int perform_EncryptDecrypt2 = 1;
|
|
|
|
TPM2_AUTH_SESSION session[MAX_SESSION_NUM];
|
|
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
|
TPM2B_AUTH sessionAuth;
|
|
#endif
|
|
|
|
(void)argc;
|
|
(void)argv;
|
|
|
|
printf("TPM2 Demo using Native API's\n");
|
|
|
|
endorse.handle = TPM_RH_NULL;
|
|
storage.handle = TPM_RH_NULL;
|
|
hmacKey.handle = TPM_RH_NULL;
|
|
eccKey.handle = TPM_RH_NULL;
|
|
rsaKey.handle = TPM_RH_NULL;
|
|
aesKey.handle = TPM_RH_NULL;
|
|
|
|
message.size = TPM_SHA256_DIGEST_SIZE;
|
|
XMEMSET(message.buffer, 0x11, message.size);
|
|
|
|
|
|
rc = TPM2_Init(&tpm2Ctx, TPM2_IoCb, userCtx);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Init failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
|
|
printf("TPM2: Caps 0x%08x, Did 0x%04x, Vid 0x%04x, Rid 0x%2x \n",
|
|
tpm2Ctx.caps,
|
|
tpm2Ctx.did_vid >> 16,
|
|
tpm2Ctx.did_vid & 0xFFFF,
|
|
tpm2Ctx.rid);
|
|
|
|
/* define the default session auth */
|
|
XMEMSET(session, 0, sizeof(session));
|
|
session[0].sessionHandle = TPM_RS_PW;
|
|
TPM2_SetSessionAuth(session);
|
|
|
|
#ifndef WOLFTPM_WINAPI
|
|
XMEMSET(&cmdIn.startup, 0, sizeof(cmdIn.startup));
|
|
cmdIn.startup.startupType = TPM_SU_CLEAR;
|
|
rc = TPM2_Startup(&cmdIn.startup);
|
|
if (rc != TPM_RC_SUCCESS &&
|
|
rc != TPM_RC_INITIALIZE /* TPM_RC_INITIALIZE = Already started */ ) {
|
|
printf("TPM2_Startup failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_Startup pass\n");
|
|
|
|
/* Full self test */
|
|
XMEMSET(&cmdIn.selfTest, 0, sizeof(cmdIn.selfTest));
|
|
cmdIn.selfTest.fullTest = YES;
|
|
rc = TPM2_SelfTest(&cmdIn.selfTest);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_SelfTest failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_SelfTest pass\n");
|
|
|
|
/* Get Test Result */
|
|
rc = TPM2_GetTestResult(&cmdOut.tr);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_GetTestResult failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_GetTestResult: Size %d, Rc 0x%x\n", cmdOut.tr.outData.size,
|
|
cmdOut.tr.testResult);
|
|
TPM2_PrintBin(cmdOut.tr.outData.buffer, cmdOut.tr.outData.size);
|
|
|
|
/* Incremental Test */
|
|
XMEMSET(&cmdIn.incSelfTest, 0, sizeof(cmdIn.incSelfTest));
|
|
cmdIn.incSelfTest.toTest.count = 1;
|
|
cmdIn.incSelfTest.toTest.algorithms[0] = TPM_ALG_RSA;
|
|
rc = TPM2_IncrementalSelfTest(&cmdIn.incSelfTest, &cmdOut.incSelfTest);
|
|
printf("TPM2_IncrementalSelfTest: Rc 0x%x, Alg 0x%x (Todo %d)\n",
|
|
rc, cmdIn.incSelfTest.toTest.algorithms[0],
|
|
(int)cmdOut.incSelfTest.toDoList.count);
|
|
#endif
|
|
|
|
|
|
/* Get Capability for Property */
|
|
XMEMSET(&cmdIn.cap, 0, sizeof(cmdIn.cap));
|
|
cmdIn.cap.capability = TPM_CAP_TPM_PROPERTIES;
|
|
cmdIn.cap.property = TPM_PT_FAMILY_INDICATOR;
|
|
cmdIn.cap.propertyCount = 1;
|
|
rc = TPM2_GetCapability(&cmdIn.cap, &cmdOut.cap);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_GetCapability failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
tpmProp = &cmdOut.cap.capabilityData.data.tpmProperties;
|
|
printf("TPM2_GetCapability: Property FamilyIndicator 0x%08x\n",
|
|
(unsigned int)tpmProp->tpmProperty[0].value);
|
|
|
|
cmdIn.cap.capability = TPM_CAP_TPM_PROPERTIES;
|
|
cmdIn.cap.property = TPM_PT_PCR_COUNT;
|
|
cmdIn.cap.propertyCount = 1;
|
|
rc = TPM2_GetCapability(&cmdIn.cap, &cmdOut.cap);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_GetCapability failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
tpmProp = &cmdOut.cap.capabilityData.data.tpmProperties;
|
|
pcrCount = tpmProp->tpmProperty[0].value;
|
|
printf("TPM2_GetCapability: Property PCR Count %d\n", pcrCount);
|
|
|
|
|
|
/* Get Capability for Firmware */
|
|
XMEMSET(&cmdIn.cap, 0, sizeof(cmdIn.cap));
|
|
cmdIn.cap.capability = TPM_CAP_TPM_PROPERTIES;
|
|
cmdIn.cap.property = TPM_PT_FIRMWARE_VERSION_1;
|
|
cmdIn.cap.propertyCount = 1;
|
|
rc = TPM2_GetCapability(&cmdIn.cap, &cmdOut.cap);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_GetCapability failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
tpmProp = &cmdOut.cap.capabilityData.data.tpmProperties;
|
|
printf("TPM2_GetCapability: Property FIRMWARE_VERSION_1 0x%08x\n",
|
|
(unsigned int)tpmProp->tpmProperty[0].value);
|
|
|
|
cmdIn.cap.capability = TPM_CAP_TPM_PROPERTIES;
|
|
cmdIn.cap.property = TPM_PT_FIRMWARE_VERSION_2;
|
|
cmdIn.cap.propertyCount = 1;
|
|
rc = TPM2_GetCapability(&cmdIn.cap, &cmdOut.cap);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_GetCapability failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
tpmProp = &cmdOut.cap.capabilityData.data.tpmProperties;
|
|
printf("TPM2_GetCapability: Property FIRMWARE_VERSION_2 0x%08x\n",
|
|
(unsigned int)tpmProp->tpmProperty[0].value);
|
|
|
|
|
|
/* Random */
|
|
#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)
|
|
if (TPM2_GetVendorID() == TPM_VENDOR_STM) {
|
|
XMEMSET(&cmdIn.getRand, 0, sizeof(cmdIn.getRand));
|
|
i = (int)sizeof(cmdOut.getRand2.randomBytes.buffer);
|
|
if (i > (MAX_RESPONSE_SIZE-(int)sizeof(UINT16))) {
|
|
i = (MAX_RESPONSE_SIZE-(int)sizeof(UINT16));
|
|
}
|
|
cmdIn.getRand.bytesRequested = (UINT16)i;
|
|
rc = TPM2_GetRandom2(&cmdIn.getRand, &cmdOut.getRand2);
|
|
if (rc == TPM_RC_COMMAND_CODE) {
|
|
printf("TPM2_GetRandom2: Command not supported on this hardware\n");
|
|
}
|
|
}
|
|
else {
|
|
rc = TPM_RC_COMMAND_CODE;
|
|
}
|
|
#else
|
|
rc = TPM_RC_COMMAND_CODE;
|
|
#endif
|
|
if (rc == TPM_RC_COMMAND_CODE) {
|
|
XMEMSET(&cmdIn.getRand, 0, sizeof(cmdIn.getRand));
|
|
i = MAX_RNG_REQ_SIZE;
|
|
cmdIn.getRand.bytesRequested = (UINT16)i;
|
|
rc = TPM2_GetRandom(&cmdIn.getRand, &cmdOut.getRand);
|
|
}
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_GetRandom failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
/* the getRand and getRand2 have same return size header in cmdOut union */
|
|
if (cmdOut.getRand.randomBytes.size != i) {
|
|
printf("TPM2_GetRandom length mismatch %d != %d\n",
|
|
cmdOut.getRand.randomBytes.size, i);
|
|
goto exit;
|
|
}
|
|
printf("TPM2_GetRandom: Got %d bytes\n", cmdOut.getRand.randomBytes.size);
|
|
TPM2_PrintBin(cmdOut.getRand.randomBytes.buffer,
|
|
cmdOut.getRand.randomBytes.size);
|
|
|
|
|
|
/* Stir Random */
|
|
XMEMSET(&cmdIn.stirRand, 0, sizeof(cmdIn.stirRand));
|
|
cmdIn.stirRand.inData.size = MAX_RNG_REQ_SIZE;
|
|
XMEMCPY(cmdIn.stirRand.inData.buffer,
|
|
cmdOut.getRand.randomBytes.buffer, cmdIn.stirRand.inData.size);
|
|
rc = TPM2_StirRandom(&cmdIn.stirRand);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_StirRandom failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_StirRandom: success\n");
|
|
|
|
|
|
/* ReadClock */
|
|
XMEMSET(&cmdOut.readClock, 0, sizeof(cmdOut.readClock));
|
|
rc = TPM2_ReadClock(&cmdOut.readClock);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_ReadClock failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_ReadClock: success\n");
|
|
|
|
|
|
/* PCR Read */
|
|
for (i=0; i<pcrCount; i++) {
|
|
pcrIndex = i;
|
|
XMEMSET(&cmdIn.pcrRead, 0, sizeof(cmdIn.pcrRead));
|
|
TPM2_SetupPCRSel(&cmdIn.pcrRead.pcrSelectionIn,
|
|
TEST_WRAP_DIGEST, pcrIndex);
|
|
rc = TPM2_PCR_Read(&cmdIn.pcrRead, &cmdOut.pcrRead);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_PCR_Read failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_PCR_Read: Index %d, Count %d\n",
|
|
pcrIndex, (int)cmdOut.pcrRead.pcrValues.count);
|
|
if (cmdOut.pcrRead.pcrValues.count > 0) {
|
|
printf("TPM2_PCR_Read: Index %d, Digest Sz %d, Update Counter %d\n",
|
|
pcrIndex,
|
|
(int)cmdOut.pcrRead.pcrValues.digests[0].size,
|
|
(int)cmdOut.pcrRead.pcrUpdateCounter);
|
|
TPM2_PrintBin(cmdOut.pcrRead.pcrValues.digests[0].buffer,
|
|
cmdOut.pcrRead.pcrValues.digests[0].size);
|
|
}
|
|
}
|
|
|
|
#ifndef WOLFTPM_WINAPI
|
|
/* PCR Extend and Verify */
|
|
/* Working with PCR16 because of next PCR Reset test */
|
|
pcrIndex = TPM2_TEST_PCR;
|
|
XMEMSET(&cmdIn.pcrExtend, 0, sizeof(cmdIn.pcrExtend));
|
|
cmdIn.pcrExtend.pcrHandle = pcrIndex;
|
|
cmdIn.pcrExtend.digests.count = 1;
|
|
cmdIn.pcrExtend.digests.digests[0].hashAlg = TEST_WRAP_DIGEST;
|
|
for (i=0; i<TPM_SHA256_DIGEST_SIZE; i++) {
|
|
cmdIn.pcrExtend.digests.digests[0].digest.H[i] = i;
|
|
}
|
|
rc = TPM2_PCR_Extend(&cmdIn.pcrExtend);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_PCR_Extend failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_PCR_Extend success\n");
|
|
|
|
XMEMSET(&cmdIn.pcrRead, 0, sizeof(cmdIn.pcrRead));
|
|
TPM2_SetupPCRSel(&cmdIn.pcrRead.pcrSelectionIn,
|
|
TEST_WRAP_DIGEST, pcrIndex);
|
|
rc = TPM2_PCR_Read(&cmdIn.pcrRead, &cmdOut.pcrRead);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_PCR_Read failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_PCR_Read: Index %d, Count %d\n",
|
|
pcrIndex, (int)cmdOut.pcrRead.pcrValues.count);
|
|
if (cmdOut.pcrRead.pcrValues.count > 0) {
|
|
printf("TPM2_PCR_Read: Index %d, Digest Sz %d, Update Counter %d\n",
|
|
pcrIndex,
|
|
(int)cmdOut.pcrRead.pcrValues.digests[0].size,
|
|
(int)cmdOut.pcrRead.pcrUpdateCounter);
|
|
TPM2_PrintBin(cmdOut.pcrRead.pcrValues.digests[0].buffer,
|
|
cmdOut.pcrRead.pcrValues.digests[0].size);
|
|
}
|
|
|
|
/* PCR Reset
|
|
Only PCR16(DEBUG) and PCR23(Application specific) can be reset
|
|
in locality 0. This is the only locality supported by wolfTPM.
|
|
*/
|
|
pcrIndex = TPM2_TEST_PCR;
|
|
XMEMSET(&cmdIn.pcrReset, 0, sizeof(cmdIn.pcrReset));
|
|
cmdIn.pcrReset.pcrHandle = pcrIndex;
|
|
rc = TPM2_PCR_Reset(&cmdIn.pcrReset);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_PCR_Reset failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_PCR_Reset command success\n");
|
|
|
|
/* Read out the PCR and show it is indeed cleared */
|
|
printf("PCR Reset: PCR%d value check after reset\n", pcrIndex);
|
|
XMEMSET(&cmdIn.pcrRead, 0, sizeof(cmdIn.pcrRead));
|
|
TPM2_SetupPCRSel(&cmdIn.pcrRead.pcrSelectionIn,
|
|
TEST_WRAP_DIGEST, pcrIndex);
|
|
rc = TPM2_PCR_Read(&cmdIn.pcrRead, &cmdOut.pcrRead);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("PCR Reset: Read failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("PCR Reset: PCR%d read successfully after reset\n", pcrIndex);
|
|
if (cmdOut.pcrRead.pcrValues.count > 0) {
|
|
TPM2_PrintBin(cmdOut.pcrRead.pcrValues.digests[0].buffer,
|
|
cmdOut.pcrRead.pcrValues.digests[0].size);
|
|
}
|
|
#endif /* !WOLFTPM_WINAPI */
|
|
|
|
/* Start Auth Session */
|
|
XMEMSET(&cmdIn.authSes, 0, sizeof(cmdIn.authSes));
|
|
cmdIn.authSes.tpmKey = TPM_RH_NULL;
|
|
cmdIn.authSes.bind = TPM_RH_NULL;
|
|
cmdIn.authSes.sessionType = TPM_SE_POLICY;
|
|
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
|
cmdIn.authSes.symmetric.algorithm = TPM_ALG_AES;
|
|
cmdIn.authSes.symmetric.keyBits.aes = 128;
|
|
cmdIn.authSes.symmetric.mode.aes = TPM_ALG_CFB;
|
|
#else
|
|
cmdIn.authSes.symmetric.algorithm = TPM_ALG_NULL;
|
|
#endif
|
|
cmdIn.authSes.authHash = TPM_ALG_SHA256;
|
|
cmdIn.authSes.nonceCaller.size = TPM_SHA256_DIGEST_SIZE;
|
|
rc = TPM2_GetNonce(cmdIn.authSes.nonceCaller.buffer,
|
|
cmdIn.authSes.nonceCaller.size);
|
|
if (rc < 0) {
|
|
printf("TPM2_GetNonce failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
rc = TPM2_StartAuthSession(&cmdIn.authSes, &cmdOut.authSes);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_StartAuthSession failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
sessionHandle = cmdOut.authSes.sessionHandle;
|
|
session[0].nonceTPM = cmdOut.authSes.nonceTPM;
|
|
|
|
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
|
/* calculate session key */
|
|
sessionAuth.size = TPM2_GetHashDigestSize(cmdIn.authSes.authHash);
|
|
rc = TPM2_KDFa(cmdIn.authSes.authHash, NULL, "ATH",
|
|
&cmdOut.authSes.nonceTPM, &cmdIn.authSes.nonceCaller,
|
|
sessionAuth.buffer, sessionAuth.size);
|
|
if (rc != sessionAuth.size) {
|
|
printf("KDFa ATH Gen Error %d\n", rc);
|
|
rc = TPM_RC_FAILURE;
|
|
goto exit;
|
|
}
|
|
#endif
|
|
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n", (word32)sessionHandle);
|
|
|
|
/* Policy Get Digest */
|
|
XMEMSET(&cmdIn.policyGetDigest, 0, sizeof(cmdIn.policyGetDigest));
|
|
cmdIn.policyGetDigest.policySession = sessionHandle;
|
|
rc = TPM2_PolicyGetDigest(&cmdIn.policyGetDigest, &cmdOut.policyGetDigest);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_PolicyGetDigest failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_PolicyGetDigest: size %d\n",
|
|
cmdOut.policyGetDigest.policyDigest.size);
|
|
TPM2_PrintBin(cmdOut.policyGetDigest.policyDigest.buffer,
|
|
cmdOut.policyGetDigest.policyDigest.size);
|
|
|
|
/* Read PCR[0] SHA1 */
|
|
pcrIndex = 0;
|
|
XMEMSET(&cmdIn.pcrRead, 0, sizeof(cmdIn.pcrRead));
|
|
TPM2_SetupPCRSel(&cmdIn.pcrRead.pcrSelectionIn, TPM_ALG_SHA1, pcrIndex);
|
|
rc = TPM2_PCR_Read(&cmdIn.pcrRead, &cmdOut.pcrRead);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_PCR_Read failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_PCR_Read: Index %d, Digest Sz %d, Update Counter %d\n",
|
|
pcrIndex,
|
|
(int)cmdOut.pcrRead.pcrValues.digests[0].size,
|
|
(int)cmdOut.pcrRead.pcrUpdateCounter);
|
|
TPM2_PrintBin(cmdOut.pcrRead.pcrValues.digests[0].buffer,
|
|
cmdOut.pcrRead.pcrValues.digests[0].size);
|
|
|
|
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
|
/* Set Auth Session index 0 */
|
|
session[0].sessionHandle = sessionHandle;
|
|
session[0].sessionAttributes = (TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
|
|
TPMA_SESSION_continueSession);
|
|
session[0].authHash = WOLFTPM2_WRAP_DIGEST;
|
|
session[0].symmetric.algorithm = TPM_ALG_AES;
|
|
session[0].symmetric.keyBits.aes = 128;
|
|
session[0].symmetric.mode.aes = TPM_ALG_CFB;
|
|
session[0].nonceCaller.size = TPM2_GetHashDigestSize(WOLFTPM2_WRAP_DIGEST);
|
|
session[0].auth = sessionAuth;
|
|
|
|
/* Policy PCR (Get) */
|
|
pcrIndex = 0;
|
|
XMEMSET(&cmdIn.policyPCR, 0, sizeof(cmdIn.policyPCR));
|
|
cmdIn.policyPCR.policySession = sessionHandle;
|
|
cmdIn.policyPCR.pcrDigest.size = 0;
|
|
TPM2_SetupPCRSel(&cmdIn.policyPCR.pcrs, TPM_ALG_SHA1, pcrIndex);
|
|
rc = TPM2_PolicyPCR(&cmdIn.policyPCR);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_PolicyPCR failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
else {
|
|
printf("TPM2_PolicyPCR: Updated\n");
|
|
}
|
|
XMEMSET(&session[0], 0, sizeof(TPM2_AUTH_SESSION));
|
|
session[0].sessionHandle = TPM_RS_PW;
|
|
#endif
|
|
|
|
/* Policy Restart (for session) */
|
|
XMEMSET(&cmdIn.policyRestart, 0, sizeof(cmdIn.policyRestart));
|
|
cmdIn.policyRestart.sessionHandle = sessionHandle;
|
|
rc = TPM2_PolicyRestart(&cmdIn.policyRestart);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_PolicyRestart failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_PolicyRestart: Done\n");
|
|
|
|
|
|
/* Hashing */
|
|
XMEMSET(&cmdIn.hashSeqStart, 0, sizeof(cmdIn.hashSeqStart));
|
|
cmdIn.hashSeqStart.auth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(cmdIn.hashSeqStart.auth.buffer, usageAuth,
|
|
cmdIn.hashSeqStart.auth.size);
|
|
cmdIn.hashSeqStart.hashAlg = TPM_ALG_SHA256;
|
|
rc = TPM2_HashSequenceStart(&cmdIn.hashSeqStart, &cmdOut.hashSeqStart);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_HashSequenceStart failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
handle = cmdOut.hashSeqStart.sequenceHandle;
|
|
printf("TPM2_HashSequenceStart: sequenceHandle 0x%x\n", (word32)handle);
|
|
|
|
/* set auth for hashing handle */
|
|
session[0].auth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(session[0].auth.buffer, usageAuth, session[0].auth.size);
|
|
|
|
XMEMSET(&cmdIn.seqUpdate, 0, sizeof(cmdIn.seqUpdate));
|
|
cmdIn.seqUpdate.sequenceHandle = handle;
|
|
cmdIn.seqUpdate.buffer.size = XSTRLEN(hashTestData);
|
|
XMEMCPY(cmdIn.seqUpdate.buffer.buffer, hashTestData,
|
|
cmdIn.seqUpdate.buffer.size);
|
|
rc = TPM2_SequenceUpdate(&cmdIn.seqUpdate);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_SequenceUpdate failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
|
|
XMEMSET(&cmdIn.seqComp, 0, sizeof(cmdIn.seqComp));
|
|
cmdIn.seqComp.sequenceHandle = handle;
|
|
cmdIn.seqComp.hierarchy = TPM_RH_NULL;
|
|
rc = TPM2_SequenceComplete(&cmdIn.seqComp, &cmdOut.seqComp);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_SequenceComplete failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
if (cmdOut.seqComp.result.size != TPM_SHA256_DIGEST_SIZE &&
|
|
XMEMCMP(cmdOut.seqComp.result.buffer, hashTestDig,
|
|
TPM_SHA256_DIGEST_SIZE) != 0) {
|
|
printf("Hash SHA256 test failed, result not as expected!\n");
|
|
goto exit;
|
|
}
|
|
printf("Hash SHA256 test success\n");
|
|
|
|
/* clear session auth */
|
|
session[0].auth.size = 0;
|
|
XMEMSET(session[0].auth.buffer, 0, sizeof(session[0].auth.buffer));
|
|
|
|
|
|
|
|
#if 0
|
|
/* Clear Owner */
|
|
cmdIn.clear.authHandle = TPM_RH_PLATFORM;
|
|
rc = TPM2_Clear(&cmdIn.clear);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Clear failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_Clear Owner\n");
|
|
#endif
|
|
|
|
|
|
/* Create Primary (Endorsement) */
|
|
XMEMSET(&cmdIn.createPri, 0, sizeof(cmdIn.createPri));
|
|
cmdIn.createPri.primaryHandle = TPM_RH_ENDORSEMENT;
|
|
cmdIn.createPri.inPublic.publicArea.authPolicy.size =
|
|
sizeof(TPM_20_EK_AUTH_POLICY);
|
|
XMEMCPY(cmdIn.createPri.inPublic.publicArea.authPolicy.buffer,
|
|
TPM_20_EK_AUTH_POLICY,
|
|
cmdIn.createPri.inPublic.publicArea.authPolicy.size);
|
|
cmdIn.createPri.inPublic.publicArea.type = TPM_ALG_RSA;
|
|
cmdIn.createPri.inPublic.publicArea.unique.rsa.size = MAX_RSA_KEY_BITS / 8;
|
|
cmdIn.createPri.inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
|
|
cmdIn.createPri.inPublic.publicArea.objectAttributes = (
|
|
TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent |
|
|
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_adminWithPolicy |
|
|
TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt);
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.keyBits = MAX_RSA_KEY_BITS;
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.exponent = 0;
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB;
|
|
rc = TPM2_CreatePrimary(&cmdIn.createPri, &cmdOut.createPri);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_CreatePrimary: Endorsement failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
endorse.handle = cmdOut.createPri.objectHandle;
|
|
endorse.auth = cmdIn.createPri.inPublic.publicArea.authPolicy;
|
|
endorse.pub = cmdOut.createPri.outPublic;
|
|
endorse.name = cmdOut.createPri.name;
|
|
endorse.symmetric = cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.symmetric;
|
|
printf("TPM2_CreatePrimary: Endorsement 0x%x (%d bytes)\n",
|
|
(word32)endorse.handle, endorse.pub.size);
|
|
|
|
|
|
/* Create Primary (Storage) */
|
|
XMEMSET(&cmdIn.createPri, 0, sizeof(cmdIn.createPri));
|
|
cmdIn.createPri.primaryHandle = TPM_RH_OWNER;
|
|
cmdIn.createPri.inSensitive.sensitive.userAuth.size = sizeof(storagePwd)-1;
|
|
XMEMCPY(cmdIn.createPri.inSensitive.sensitive.userAuth.buffer,
|
|
storagePwd, cmdIn.createPri.inSensitive.sensitive.userAuth.size);
|
|
cmdIn.createPri.inPublic.publicArea.type = TPM_ALG_RSA;
|
|
cmdIn.createPri.inPublic.publicArea.unique.rsa.size = MAX_RSA_KEY_BITS / 8;
|
|
cmdIn.createPri.inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
|
|
cmdIn.createPri.inPublic.publicArea.objectAttributes = (
|
|
TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent |
|
|
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
|
|
TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA);
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.keyBits = MAX_RSA_KEY_BITS;
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.exponent = 0;
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
|
|
cmdIn.createPri.inPublic.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB;
|
|
rc = TPM2_CreatePrimary(&cmdIn.createPri, &cmdOut.createPri);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_CreatePrimary: Storage failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
storage.handle = cmdOut.createPri.objectHandle;
|
|
storage.pub = cmdOut.createPri.outPublic;
|
|
storage.name = cmdOut.createPri.name;
|
|
printf("TPM2_CreatePrimary: Storage 0x%x (%d bytes)\n",
|
|
(word32)storage.handle, storage.pub.size);
|
|
|
|
#if 0
|
|
/* Move new primary key into NV to persist */
|
|
cmdIn.evict.auth = endorse.handle;
|
|
cmdIn.evict.objectHandle = storage.handle;
|
|
cmdIn.evict.persistentHandle;
|
|
rc = TPM2_EvictControl(&cmdIn.evict);
|
|
#endif
|
|
|
|
|
|
/* set session auth for storage key */
|
|
session[0].auth.size = sizeof(storagePwd)-1;
|
|
XMEMCPY(session[0].auth.buffer, storagePwd, session[0].auth.size);
|
|
|
|
/* Create a loaded new TPM 2.0 key and then unload it */
|
|
XMEMSET(&cmdIn.createLoaded, 0, sizeof(cmdIn.createLoaded));
|
|
cmdIn.createLoaded.parentHandle = storage.handle;
|
|
cmdIn.createLoaded.inSensitive.sensitive.userAuth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(cmdIn.createLoaded.inSensitive.sensitive.userAuth.buffer, usageAuth,
|
|
cmdIn.createLoaded.inSensitive.sensitive.userAuth.size);
|
|
cmdIn.createLoaded.inSensitive.sensitive.data.size = sizeof(userKey)-1;
|
|
XMEMCPY(cmdIn.createLoaded.inSensitive.sensitive.data.buffer, userKey,
|
|
cmdIn.createLoaded.inSensitive.sensitive.data.size);
|
|
cmdIn.createLoaded.inPublic.publicArea.type = TPM_ALG_KEYEDHASH;
|
|
cmdIn.createLoaded.inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
|
|
cmdIn.createLoaded.inPublic.publicArea.objectAttributes = (
|
|
TPMA_OBJECT_userWithAuth | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
|
|
cmdIn.createLoaded.inPublic.publicArea.parameters.keyedHashDetail.scheme.scheme = TPM_ALG_HMAC;
|
|
cmdIn.createLoaded.inPublic.publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = TPM_ALG_SHA256;
|
|
rc = TPM2_CreateLoaded(&cmdIn.createLoaded, &cmdOut.createLoaded);
|
|
if (rc == TPM_RC_SUCCESS) {
|
|
printf("TPM2_CreateLoaded: handle 0x%x pub %d, priv %d\n",
|
|
cmdOut.createLoaded.objectHandle, cmdOut.createLoaded.outPublic.size,
|
|
cmdOut.createLoaded.outPrivate.size);
|
|
cmdIn.flushCtx.flushHandle = cmdOut.createLoaded.objectHandle;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
}
|
|
else if (WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) {
|
|
printf("TPM2_CreateLoaded: Command is not supported on this hardware\n");
|
|
}
|
|
else {
|
|
printf("TPM2_CreateLoaded failed %d: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
|
|
/* Load public key */
|
|
XMEMSET(&cmdIn.loadExt, 0, sizeof(cmdIn.loadExt));
|
|
cmdIn.loadExt.inPublic = endorse.pub;
|
|
cmdIn.loadExt.hierarchy = TPM_RH_NULL;
|
|
rc = TPM2_LoadExternal(&cmdIn.loadExt, &cmdOut.loadExt);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_LoadExternal: failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
handle = cmdOut.loadExt.objectHandle;
|
|
printf("TPM2_LoadExternal: 0x%x\n", (word32)handle);
|
|
|
|
/* Make a credential */
|
|
XMEMSET(&cmdIn.makeCred, 0, sizeof(cmdIn.makeCred));
|
|
cmdIn.makeCred.handle = handle;
|
|
cmdIn.makeCred.credential.size = TPM_SHA256_DIGEST_SIZE;
|
|
XMEMSET(cmdIn.makeCred.credential.buffer, 0x11,
|
|
cmdIn.makeCred.credential.size);
|
|
cmdIn.makeCred.objectName = endorse.name;
|
|
rc = TPM2_MakeCredential(&cmdIn.makeCred, &cmdOut.makeCred);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_MakeCredential: failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_MakeCredential: credentialBlob %d, secret %d\n",
|
|
cmdOut.makeCred.credentialBlob.size,
|
|
cmdOut.makeCred.secret.size);
|
|
|
|
|
|
/* Read public key */
|
|
XMEMSET(&cmdIn.readPub, 0, sizeof(cmdIn.readPub));
|
|
cmdIn.readPub.objectHandle = handle;
|
|
rc = TPM2_ReadPublic(&cmdIn.readPub, &cmdOut.readPub);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_ReadPublic failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_ReadPublic Handle 0x%x: pub %d, name %d, qualifiedName %d\n",
|
|
(word32)cmdIn.readPub.objectHandle,
|
|
cmdOut.readPub.outPublic.size, cmdOut.readPub.name.size,
|
|
cmdOut.readPub.qualifiedName.size);
|
|
|
|
cmdIn.flushCtx.flushHandle = handle;
|
|
handle = TPM_RH_NULL;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
|
|
|
|
/* HMAC Example */
|
|
/* set session auth for storage key */
|
|
session[0].auth.size = sizeof(storagePwd)-1;
|
|
XMEMCPY(session[0].auth.buffer, storagePwd, session[0].auth.size);
|
|
|
|
/* Create an HMAC-SHA256 Key */
|
|
XMEMSET(&cmdIn.create, 0, sizeof(cmdIn.create));
|
|
cmdIn.create.parentHandle = storage.handle;
|
|
cmdIn.create.inSensitive.sensitive.userAuth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(cmdIn.create.inSensitive.sensitive.userAuth.buffer, usageAuth,
|
|
cmdIn.create.inSensitive.sensitive.userAuth.size);
|
|
cmdIn.create.inSensitive.sensitive.data.size = sizeof(userKey)-1;
|
|
XMEMCPY(cmdIn.create.inSensitive.sensitive.data.buffer, userKey,
|
|
cmdIn.create.inSensitive.sensitive.data.size);
|
|
cmdIn.create.inPublic.publicArea.type = TPM_ALG_KEYEDHASH;
|
|
cmdIn.create.inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
|
|
cmdIn.create.inPublic.publicArea.objectAttributes = (
|
|
TPMA_OBJECT_userWithAuth | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
|
|
cmdIn.create.inPublic.publicArea.parameters.keyedHashDetail.scheme.scheme = TPM_ALG_HMAC;
|
|
cmdIn.create.inPublic.publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = TPM_ALG_SHA256;
|
|
rc = TPM2_Create(&cmdIn.create, &cmdOut.create);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Create HMAC failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
hmacKey.pub = cmdOut.create.outPublic;
|
|
hmacKey.priv = cmdOut.create.outPrivate;
|
|
printf("Create HMAC-SHA256 Key success, public %d, Private %d\n",
|
|
hmacKey.pub.size, hmacKey.priv.size);
|
|
|
|
XMEMSET(&cmdIn.load, 0, sizeof(cmdIn.load));
|
|
cmdIn.load.parentHandle = storage.handle;
|
|
cmdIn.load.inPrivate = hmacKey.priv;
|
|
cmdIn.load.inPublic = hmacKey.pub;
|
|
rc = TPM2_Load(&cmdIn.load, &cmdOut.load);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Load failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
hmacKey.handle = cmdOut.load.objectHandle;
|
|
printf("TPM2_Load New HMAC Key Handle 0x%x\n", (word32)hmacKey.handle);
|
|
|
|
/* set auth for HMAC handle */
|
|
session[0].auth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(session[0].auth.buffer, usageAuth, session[0].auth.size);
|
|
|
|
/* TODO: Add simple HMAC test */
|
|
#if 0
|
|
rc = TPM2_HMAC(&cmdIn.hmac, &cmdOut.hmac);
|
|
rc = TPM2_HMAC_Start(&cmdIn.hmacStart, &cmdOut.hmacStart);
|
|
#endif
|
|
|
|
|
|
/* Allow object change auth */
|
|
XMEMSET(&cmdIn.policyCC, 0, sizeof(cmdIn.policyCC));
|
|
cmdIn.policyCC.policySession = sessionHandle;
|
|
cmdIn.policyCC.code = TPM_CC_ObjectChangeAuth;
|
|
rc = TPM2_PolicyCommandCode(&cmdIn.policyCC);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_PolicyCommandCode failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_PolicyCommandCode: success\n");
|
|
|
|
/* Change Object Auth */
|
|
XMEMSET(&cmdIn.objChgAuth, 0, sizeof(cmdIn.objChgAuth));
|
|
cmdIn.objChgAuth.objectHandle = hmacKey.handle;
|
|
cmdIn.objChgAuth.parentHandle = storage.handle;
|
|
cmdIn.objChgAuth.newAuth.size = TPM_SHA256_DIGEST_SIZE;
|
|
rc = TPM2_GetNonce(cmdIn.objChgAuth.newAuth.buffer,
|
|
cmdIn.objChgAuth.newAuth.size);
|
|
if (rc < 0) {
|
|
printf("TPM2_GetNonce failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
rc = TPM2_ObjectChangeAuth(&cmdIn.objChgAuth, &cmdOut.objChgAuth);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_ObjectChangeAuth failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
//goto exit;
|
|
}
|
|
hmacKey.priv = cmdOut.objChgAuth.outPrivate;
|
|
printf("TPM2_ObjectChangeAuth: private %d\n", hmacKey.priv.size);
|
|
|
|
/* done with hmac handle */
|
|
cmdIn.flushCtx.flushHandle = hmacKey.handle;
|
|
hmacKey.handle = TPM_RH_NULL;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
|
|
|
|
|
|
/* set session auth for storage key */
|
|
session[0].auth.size = sizeof(storagePwd)-1;
|
|
XMEMCPY(session[0].auth.buffer, storagePwd, session[0].auth.size);
|
|
|
|
|
|
/* Get a curve's parameters */
|
|
XMEMSET(&cmdIn.eccParam, 0, sizeof(cmdIn.eccParam));
|
|
cmdIn.eccParam.curveID = TPM_ECC_NIST_P256;
|
|
rc = TPM2_ECC_Parameters(&cmdIn.eccParam, &cmdOut.eccParam);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_ECC_Parameters failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_ECC_Parameters: CurveID %d, sz %d, p %d, a %d, b %d, "
|
|
"gX %d, gY %d, n %d, h %d\n",
|
|
cmdOut.eccParam.parameters.curveID,
|
|
cmdOut.eccParam.parameters.keySize,
|
|
cmdOut.eccParam.parameters.p.size,
|
|
cmdOut.eccParam.parameters.a.size,
|
|
cmdOut.eccParam.parameters.b.size,
|
|
cmdOut.eccParam.parameters.gX.size,
|
|
cmdOut.eccParam.parameters.gY.size,
|
|
cmdOut.eccParam.parameters.n.size,
|
|
cmdOut.eccParam.parameters.h.size);
|
|
|
|
|
|
/* Create an ECDSA key */
|
|
XMEMSET(&cmdIn.create, 0, sizeof(cmdIn.create));
|
|
cmdIn.create.parentHandle = storage.handle;
|
|
cmdIn.create.inSensitive.sensitive.userAuth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(cmdIn.create.inSensitive.sensitive.userAuth.buffer, usageAuth,
|
|
cmdIn.create.inSensitive.sensitive.userAuth.size);
|
|
cmdIn.create.inPublic.publicArea.type = TPM_ALG_ECC;
|
|
cmdIn.create.inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
|
|
cmdIn.create.inPublic.publicArea.objectAttributes = (
|
|
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
|
|
TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
|
|
cmdIn.create.inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_NULL;
|
|
cmdIn.create.inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_ECDSA;
|
|
cmdIn.create.inPublic.publicArea.parameters.eccDetail.scheme.details.ecdsa.hashAlg = TPM_ALG_SHA256;
|
|
cmdIn.create.inPublic.publicArea.parameters.eccDetail.curveID = TPM_ECC_NIST_P256;
|
|
cmdIn.create.inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL;
|
|
rc = TPM2_Create(&cmdIn.create, &cmdOut.create);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Create ECDSA failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_Create: New ECDSA Key: pub %d, priv %d\n",
|
|
cmdOut.create.outPublic.size,
|
|
cmdOut.create.outPrivate.size);
|
|
eccKey.pub = cmdOut.create.outPublic;
|
|
eccKey.priv = cmdOut.create.outPrivate;
|
|
|
|
/* Load new key */
|
|
XMEMSET(&cmdIn.load, 0, sizeof(cmdIn.load));
|
|
cmdIn.load.parentHandle = storage.handle;
|
|
cmdIn.load.inPrivate = eccKey.priv;
|
|
cmdIn.load.inPublic = eccKey.pub;
|
|
rc = TPM2_Load(&cmdIn.load, &cmdOut.load);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Load ECDSA failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
eccKey.handle = cmdOut.load.objectHandle;
|
|
printf("TPM2_Load ECDSA Key Handle 0x%x\n", (word32)eccKey.handle);
|
|
|
|
/* set session auth for ecc key */
|
|
session[0].auth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(session[0].auth.buffer, usageAuth, session[0].auth.size);
|
|
|
|
/* Sign with ECC key */
|
|
XMEMSET(&cmdIn.sign, 0, sizeof(cmdIn.sign));
|
|
cmdIn.sign.keyHandle = eccKey.handle;
|
|
cmdIn.sign.digest.size = message.size;
|
|
XMEMCPY(cmdIn.sign.digest.buffer, message.buffer, message.size);
|
|
cmdIn.sign.inScheme.scheme = TPM_ALG_ECDSA;
|
|
cmdIn.sign.inScheme.details.ecdsa.hashAlg = TPM_ALG_SHA256;
|
|
cmdIn.sign.validation.tag = TPM_ST_HASHCHECK;
|
|
cmdIn.sign.validation.hierarchy = TPM_RH_NULL;
|
|
rc = TPM2_Sign(&cmdIn.sign, &cmdOut.sign);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Sign failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_Sign: ECC S %d, R %d\n",
|
|
cmdOut.sign.signature.signature.ecdsa.signatureS.size,
|
|
cmdOut.sign.signature.signature.ecdsa.signatureR.size);
|
|
|
|
/* Verify with ECC key */
|
|
XMEMSET(&cmdIn.verifySign, 0, sizeof(cmdIn.verifySign));
|
|
cmdIn.verifySign.keyHandle = eccKey.handle;
|
|
cmdIn.verifySign.digest.size = message.size;
|
|
XMEMCPY(cmdIn.verifySign.digest.buffer, message.buffer, message.size);
|
|
cmdIn.verifySign.signature = cmdOut.sign.signature;
|
|
rc = TPM2_VerifySignature(&cmdIn.verifySign, &cmdOut.verifySign);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_VerifySignature failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_VerifySignature: Tag %d\n", cmdOut.verifySign.validation.tag);
|
|
|
|
cmdIn.flushCtx.flushHandle = eccKey.handle;
|
|
eccKey.handle = TPM_RH_NULL;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
|
|
|
|
/* set session auth for storage key */
|
|
session[0].auth.size = sizeof(storagePwd)-1;
|
|
XMEMCPY(session[0].auth.buffer, storagePwd, session[0].auth.size);
|
|
|
|
/* Create an ECC key for ECDH */
|
|
XMEMSET(&cmdIn.create, 0, sizeof(cmdIn.create));
|
|
cmdIn.create.parentHandle = storage.handle;
|
|
cmdIn.create.inSensitive.sensitive.userAuth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(cmdIn.create.inSensitive.sensitive.userAuth.buffer, usageAuth,
|
|
cmdIn.create.inSensitive.sensitive.userAuth.size);
|
|
cmdIn.create.inPublic.publicArea.type = TPM_ALG_ECC;
|
|
cmdIn.create.inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
|
|
cmdIn.create.inPublic.publicArea.objectAttributes = (
|
|
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
|
|
TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA);
|
|
cmdIn.create.inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_NULL;
|
|
cmdIn.create.inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_ECDH;
|
|
cmdIn.create.inPublic.publicArea.parameters.eccDetail.scheme.details.ecdsa.hashAlg = TPM_ALG_SHA256;
|
|
cmdIn.create.inPublic.publicArea.parameters.eccDetail.curveID = TPM_ECC_NIST_P256;
|
|
cmdIn.create.inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL;
|
|
rc = TPM2_Create(&cmdIn.create, &cmdOut.create);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Create ECDH failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_Create: New ECDH Key: pub %d, priv %d\n",
|
|
cmdOut.create.outPublic.size,
|
|
cmdOut.create.outPrivate.size);
|
|
eccKey.pub = cmdOut.create.outPublic;
|
|
eccKey.priv = cmdOut.create.outPrivate;
|
|
|
|
/* Load new key */
|
|
XMEMSET(&cmdIn.load, 0, sizeof(cmdIn.load));
|
|
cmdIn.load.parentHandle = storage.handle;
|
|
cmdIn.load.inPrivate = eccKey.priv;
|
|
cmdIn.load.inPublic = eccKey.pub;
|
|
rc = TPM2_Load(&cmdIn.load, &cmdOut.load);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Load ECDH key failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
eccKey.handle = cmdOut.load.objectHandle;
|
|
printf("TPM2_Load ECDH Key Handle 0x%x\n", (word32)eccKey.handle);
|
|
|
|
/* set session auth for ecc key */
|
|
session[0].auth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(session[0].auth.buffer, usageAuth, session[0].auth.size);
|
|
|
|
/* ECDH Key Gen (gen public point and shared secret) */
|
|
XMEMSET(&cmdIn.ecdh, 0, sizeof(cmdIn.ecdh));
|
|
cmdIn.ecdh.keyHandle = eccKey.handle;
|
|
rc = TPM2_ECDH_KeyGen(&cmdIn.ecdh, &cmdOut.ecdh);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_ECDH_KeyGen failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_ECDH_KeyGen: zPt %d, pubPt %d\n",
|
|
cmdOut.ecdh.zPoint.size,
|
|
cmdOut.ecdh.pubPoint.size);
|
|
message.size = cmdOut.ecdh.zPoint.size;
|
|
XMEMCPY(message.buffer, &cmdOut.ecdh.zPoint.point, message.size);
|
|
|
|
/* ECDH ZGen (compute shared secret) */
|
|
XMEMSET(&cmdIn.ecdhZ, 0, sizeof(cmdIn.ecdhZ));
|
|
cmdIn.ecdhZ.keyHandle = eccKey.handle;
|
|
cmdIn.ecdhZ.inPoint = cmdOut.ecdh.pubPoint;
|
|
rc = TPM2_ECDH_ZGen(&cmdIn.ecdhZ, &cmdOut.ecdhZ);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_ECDH_KeyGen failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_ECDH_ZGen: zPt %d\n",
|
|
cmdOut.ecdhZ.outPoint.size);
|
|
|
|
/* verify shared secret is the same */
|
|
if (message.size != cmdOut.ecdhZ.outPoint.size ||
|
|
XMEMCMP(message.buffer, &cmdOut.ecdhZ.outPoint.point, message.size) != 0) {
|
|
rc = -1; /* fail */
|
|
}
|
|
printf("TPM2 ECC Shared Secret %s\n", rc == 0 ? "Pass" : "Fail");
|
|
|
|
cmdIn.flushCtx.flushHandle = eccKey.handle;
|
|
eccKey.handle = TPM_RH_NULL;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
|
|
|
|
/* set session auth for storage key */
|
|
session[0].auth.size = sizeof(storagePwd)-1;
|
|
XMEMCPY(session[0].auth.buffer, storagePwd, session[0].auth.size);
|
|
|
|
/* Create an RSA key for encrypt/decrypt */
|
|
XMEMSET(&cmdIn.create, 0, sizeof(cmdIn.create));
|
|
cmdIn.create.parentHandle = storage.handle;
|
|
cmdIn.create.inSensitive.sensitive.userAuth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(cmdIn.create.inSensitive.sensitive.userAuth.buffer, usageAuth,
|
|
cmdIn.create.inSensitive.sensitive.userAuth.size);
|
|
cmdIn.create.inPublic.publicArea.type = TPM_ALG_RSA;
|
|
cmdIn.create.inPublic.publicArea.unique.rsa.size = MAX_RSA_KEY_BITS / 8;
|
|
cmdIn.create.inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
|
|
cmdIn.create.inPublic.publicArea.objectAttributes = (
|
|
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
|
|
TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
|
|
cmdIn.create.inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL;
|
|
cmdIn.create.inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
|
|
cmdIn.create.inPublic.publicArea.parameters.rsaDetail.keyBits = MAX_RSA_KEY_BITS;
|
|
cmdIn.create.outsideInfo.size = sizeof(keyCreationNonce)-1;
|
|
XMEMCPY(cmdIn.create.outsideInfo.buffer, keyCreationNonce,
|
|
cmdIn.create.outsideInfo.size);
|
|
rc = TPM2_Create(&cmdIn.create, &cmdOut.create);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Create RSA failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_Create: New RSA Key: pub %d, priv %d\n",
|
|
cmdOut.create.outPublic.size,
|
|
cmdOut.create.outPrivate.size);
|
|
rsaKey.pub = cmdOut.create.outPublic;
|
|
rsaKey.priv = cmdOut.create.outPrivate;
|
|
/* Keep creation Hash for certifyCreation unit test below */
|
|
rsaKey.creationHash.size = cmdOut.create.creationHash.size;
|
|
XMEMCPY(rsaKey.creationHash.buffer, cmdOut.create.creationHash.buffer, rsaKey.creationHash.size);
|
|
/* Keep creation Ticket for certifyCreation unit test below */
|
|
XMEMCPY(&rsaKey.creationTicket, &cmdOut.create.creationTicket, sizeof(rsaKey.creationTicket));
|
|
|
|
/* Load new key */
|
|
XMEMSET(&cmdIn.load, 0, sizeof(cmdIn.load));
|
|
cmdIn.load.parentHandle = storage.handle;
|
|
cmdIn.load.inPrivate = rsaKey.priv;
|
|
cmdIn.load.inPublic = rsaKey.pub;
|
|
rc = TPM2_Load(&cmdIn.load, &cmdOut.load);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Load RSA key failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
rsaKey.handle = cmdOut.load.objectHandle;
|
|
printf("TPM2_Load RSA Key Handle 0x%x\n", (word32)rsaKey.handle);
|
|
|
|
/* set session auth for RSA key */
|
|
session[0].auth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(session[0].auth.buffer, usageAuth, session[0].auth.size);
|
|
|
|
|
|
/* RSA Encrypt */
|
|
XMEMSET(&cmdIn.rsaEnc, 0, sizeof(cmdIn.rsaEnc));
|
|
cmdIn.rsaEnc.keyHandle = rsaKey.handle;
|
|
cmdIn.rsaEnc.message = message;
|
|
cmdIn.rsaEnc.inScheme.scheme = TPM_ALG_OAEP;
|
|
cmdIn.rsaEnc.inScheme.details.oaep.hashAlg = TPM_ALG_SHA256;
|
|
cmdIn.rsaEnc.label.size = sizeof(label); /* Null term required */
|
|
XMEMCPY(cmdIn.rsaEnc.label.buffer, label, cmdIn.rsaEnc.label.size);
|
|
rc = TPM2_RSA_Encrypt(&cmdIn.rsaEnc, &cmdOut.rsaEnc);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_RSA_Encrypt failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_RSA_Encrypt: %d\n", cmdOut.rsaEnc.outData.size);
|
|
|
|
/* RSA Decrypt */
|
|
XMEMSET(&cmdIn.rsaDec, 0, sizeof(cmdIn.rsaDec));
|
|
cmdIn.rsaDec.keyHandle = rsaKey.handle;
|
|
cmdIn.rsaDec.cipherText = cmdOut.rsaEnc.outData;
|
|
cmdIn.rsaDec.inScheme.scheme = TPM_ALG_OAEP;
|
|
cmdIn.rsaDec.inScheme.details.oaep.hashAlg = TPM_ALG_SHA256;
|
|
cmdIn.rsaDec.label.size = sizeof(label); /* Null term required */
|
|
XMEMCPY(cmdIn.rsaDec.label.buffer, label, cmdIn.rsaEnc.label.size);
|
|
rc = TPM2_RSA_Decrypt(&cmdIn.rsaDec, &cmdOut.rsaDec);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_RSA_Decrypt failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_RSA_Decrypt: %d\n", cmdOut.rsaDec.message.size);
|
|
|
|
if (cmdOut.rsaDec.message.size != message.size ||
|
|
XMEMCMP(cmdOut.rsaDec.message.buffer, message.buffer,
|
|
cmdOut.rsaDec.message.size)) {
|
|
printf("RSA Test failed!\n");
|
|
}
|
|
else {
|
|
printf("RSA Encrypt/Decrypt test passed\n");
|
|
}
|
|
|
|
/* 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);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_CertifyCreation RSA key failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
else {
|
|
printf("TPM2_CertifyCreation test passed\n");
|
|
}
|
|
|
|
cmdIn.flushCtx.flushHandle = rsaKey.handle;
|
|
rsaKey.handle = TPM_RH_NULL;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
|
|
#ifndef WOLFTPM_WINAPI
|
|
|
|
/* NVRAM Access */
|
|
|
|
/* Clear auth buffer */
|
|
session[0].auth.size = 0;
|
|
XMEMSET(session[0].auth.buffer, 0, sizeof(session[0].auth.buffer));
|
|
|
|
/* Define new NV */
|
|
nvIndex = TPM_20_OWNER_NV_SPACE + 0x003FFFFF; /* Last owner Index */
|
|
XMEMSET(&cmdIn.nvDefine, 0, sizeof(cmdIn.nvDefine));
|
|
cmdIn.nvDefine.authHandle = TPM_RH_OWNER;
|
|
cmdIn.nvDefine.auth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(cmdIn.nvDefine.auth.buffer, usageAuth, cmdIn.nvDefine.auth.size);
|
|
cmdIn.nvDefine.publicInfo.nvPublic.nvIndex = nvIndex;
|
|
cmdIn.nvDefine.publicInfo.nvPublic.nameAlg = TPM_ALG_SHA256;
|
|
cmdIn.nvDefine.publicInfo.nvPublic.attributes = (
|
|
TPMA_NV_OWNERWRITE | TPMA_NV_OWNERREAD | TPMA_NV_NO_DA);
|
|
cmdIn.nvDefine.publicInfo.nvPublic.dataSize = TPM_SHA256_DIGEST_SIZE;
|
|
rc = TPM2_NV_DefineSpace(&cmdIn.nvDefine);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_NV_DefineSpace failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_NV_DefineSpace: 0x%x\n", (word32)nvIndex);
|
|
|
|
/* Read NV */
|
|
XMEMSET(&cmdIn.nvReadPub, 0, sizeof(cmdIn.nvReadPub));
|
|
cmdIn.nvReadPub.nvIndex = nvIndex;
|
|
rc = TPM2_NV_ReadPublic(&cmdIn.nvReadPub, &cmdOut.nvReadPub);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_NV_ReadPublic failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
printf("TPM2_NV_ReadPublic: Sz %d, Idx 0x%x, nameAlg %d, Attr 0x%x, "
|
|
"authPol %d, dataSz %d, name %d\n",
|
|
cmdOut.nvReadPub.nvPublic.size,
|
|
(word32)cmdOut.nvReadPub.nvPublic.nvPublic.nvIndex,
|
|
cmdOut.nvReadPub.nvPublic.nvPublic.nameAlg,
|
|
(word32)cmdOut.nvReadPub.nvPublic.nvPublic.attributes,
|
|
cmdOut.nvReadPub.nvPublic.nvPublic.authPolicy.size,
|
|
cmdOut.nvReadPub.nvPublic.nvPublic.dataSize,
|
|
cmdOut.nvReadPub.nvName.size);
|
|
|
|
/* Undefine NV */
|
|
XMEMSET(&cmdIn.nvUndefine, 0, sizeof(cmdIn.nvUndefine));
|
|
cmdIn.nvUndefine.authHandle = TPM_RH_OWNER;
|
|
cmdIn.nvUndefine.nvIndex = nvIndex;
|
|
rc = TPM2_NV_UndefineSpace(&cmdIn.nvUndefine);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_NV_UndefineSpace failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
#endif
|
|
|
|
|
|
/* Example for Encrypt/Decrypt */
|
|
|
|
/* Clear auth buffer */
|
|
session[0].auth.size = 0;
|
|
XMEMSET(session[0].auth.buffer, 0, sizeof(session[0].auth.buffer));
|
|
|
|
#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)
|
|
if (TPM2_GetVendorID() == TPM_VENDOR_STM) {
|
|
/* Enable TPM2_EncryptDecrypt2 command */
|
|
XMEMSET(&cmdIn.setCmdSet, 0, sizeof(cmdIn.setCmdSet));
|
|
cmdIn.setCmdSet.authHandle = TPM_RH_PLATFORM;
|
|
cmdIn.setCmdSet.commandCode = TPM_CC_EncryptDecrypt2;
|
|
cmdIn.setCmdSet.enableFlag = 1;
|
|
rc = TPM2_SetCommandSet(&cmdIn.setCmdSet);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_SetCommandSet failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* set session auth for storage key */
|
|
session[0].auth.size = sizeof(storagePwd)-1;
|
|
XMEMCPY(session[0].auth.buffer, storagePwd, session[0].auth.size);
|
|
|
|
/* Create a symmetric key */
|
|
XMEMSET(&cmdIn.create, 0, sizeof(cmdIn.create));
|
|
cmdIn.create.parentHandle = storage.handle;
|
|
cmdIn.create.inSensitive.sensitive.userAuth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(cmdIn.create.inSensitive.sensitive.userAuth.buffer, usageAuth,
|
|
cmdIn.create.inSensitive.sensitive.userAuth.size);
|
|
cmdIn.create.inPublic.publicArea.type = TPM_ALG_SYMCIPHER;
|
|
cmdIn.create.inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
|
|
cmdIn.create.inPublic.publicArea.objectAttributes = (
|
|
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
|
|
TPMA_OBJECT_noDA | TPMA_OBJECT_decrypt | TPMA_OBJECT_sign);
|
|
cmdIn.create.inPublic.publicArea.parameters.symDetail.sym.algorithm = TPM_ALG_AES;
|
|
cmdIn.create.inPublic.publicArea.parameters.symDetail.sym.keyBits.aes = MAX_AES_KEY_BITS;
|
|
cmdIn.create.inPublic.publicArea.parameters.symDetail.sym.mode.aes = TEST_AES_MODE;
|
|
|
|
rc = TPM2_Create(&cmdIn.create, &cmdOut.create);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Create symmetric failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
aesKey.pub = cmdOut.create.outPublic;
|
|
aesKey.priv = cmdOut.create.outPrivate;
|
|
printf("Create AES%d CFB Key success, public %d, Private %d\n",
|
|
MAX_AES_KEY_BITS, aesKey.pub.size, aesKey.priv.size);
|
|
|
|
XMEMSET(&cmdIn.load, 0, sizeof(cmdIn.load));
|
|
cmdIn.load.parentHandle = storage.handle;
|
|
cmdIn.load.inPrivate = aesKey.priv;
|
|
cmdIn.load.inPublic = aesKey.pub;
|
|
rc = TPM2_Load(&cmdIn.load, &cmdOut.load);
|
|
if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Load failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
aesKey.handle = cmdOut.load.objectHandle;
|
|
printf("TPM2_Load New AES Key Handle 0x%x\n", (word32)aesKey.handle);
|
|
|
|
/* set auth for AES handle */
|
|
session[0].auth.size = sizeof(usageAuth)-1;
|
|
XMEMCPY(session[0].auth.buffer, usageAuth, session[0].auth.size);
|
|
|
|
/* Test data */
|
|
message.size = MAX_AES_BLOCK_SIZE_BYTES;
|
|
for (i=0; i<message.size; i++)
|
|
message.buffer[i] = (byte)(i & 0xff);
|
|
|
|
/* Perform encrypt of data */
|
|
/* Note: TPM2_EncryptDecrypt2 is used to allow parameter encryption for data */
|
|
XMEMSET(&cmdIn.encDec, 0, sizeof(cmdIn.encDec));
|
|
cmdIn.encDec.keyHandle = aesKey.handle;
|
|
cmdIn.encDec.ivIn.size = MAX_AES_BLOCK_SIZE_BYTES; /* zeros */
|
|
cmdIn.encDec.inData.size = message.size;
|
|
XMEMCPY(cmdIn.encDec.inData.buffer, message.buffer, cmdIn.encDec.inData.size);
|
|
cmdIn.encDec.decrypt = NO;
|
|
cmdIn.encDec.mode = TEST_AES_MODE;
|
|
rc = TPM2_EncryptDecrypt2(&cmdIn.encDec, &cmdOut.encDec);
|
|
if (WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) { /* some TPM's may not support command */
|
|
printf("TPM2_EncryptDecrypt2: Is not a supported feature without enabling due to export controls\n");
|
|
perform_EncryptDecrypt2 = 0;
|
|
rc = 0;
|
|
}
|
|
else if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_EncryptDecrypt2 failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
|
|
if(perform_EncryptDecrypt2) {
|
|
/* Perform decrypt of data */
|
|
XMEMSET(&cmdIn.encDec, 0, sizeof(cmdIn.encDec));
|
|
cmdIn.encDec.keyHandle = aesKey.handle;
|
|
cmdIn.encDec.ivIn.size = MAX_AES_BLOCK_SIZE_BYTES; /* zeros */
|
|
cmdIn.encDec.inData.size = cmdOut.encDec.outData.size;
|
|
XMEMCPY(cmdIn.encDec.inData.buffer, cmdOut.encDec.outData.buffer,
|
|
cmdOut.encDec.outData.size);
|
|
cmdIn.encDec.decrypt = YES;
|
|
cmdIn.encDec.mode = TEST_AES_MODE;
|
|
rc = TPM2_EncryptDecrypt2(&cmdIn.encDec, &cmdOut.encDec);
|
|
if (rc == TPM_RC_COMMAND_CODE) { /* some TPM's may not support command */
|
|
printf("TPM2_EncryptDecrypt2: Is not a supported feature without enabling due to export controls\n");
|
|
}
|
|
else if (rc != TPM_RC_SUCCESS) {
|
|
printf("TPM2_EncryptDecrypt2 failed 0x%x: %s\n", rc,
|
|
TPM2_GetRCString(rc));
|
|
goto exit;
|
|
}
|
|
|
|
/* Verify plain and decrypted data are the same */
|
|
if (rc == TPM_RC_SUCCESS &&
|
|
cmdOut.encDec.outData.size == MAX_AES_BLOCK_SIZE_BYTES &&
|
|
XMEMCMP(cmdOut.encDec.outData.buffer, message.buffer,
|
|
cmdOut.encDec.outData.size) == 0) {
|
|
printf("Encrypt/Decrypt test success\n");
|
|
}
|
|
else if (WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) {
|
|
printf("Encrypt/Decrypt test result allowed as pass since hardware doesn't support.\n");
|
|
rc = TPM_RC_SUCCESS;
|
|
}
|
|
else {
|
|
printf("Encrypt/Decrypt test failed, result not as expected!\n");
|
|
goto exit;
|
|
}
|
|
}
|
|
exit:
|
|
|
|
/* Close session */
|
|
if (sessionHandle != TPM_RH_NULL) {
|
|
cmdIn.flushCtx.flushHandle = sessionHandle;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
}
|
|
|
|
/* Close object handle */
|
|
if (handle != TPM_RH_NULL) {
|
|
cmdIn.flushCtx.flushHandle = handle;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
}
|
|
if (eccKey.handle != TPM_RH_NULL) {
|
|
cmdIn.flushCtx.flushHandle = eccKey.handle;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
}
|
|
if (hmacKey.handle != TPM_RH_NULL) {
|
|
cmdIn.flushCtx.flushHandle = hmacKey.handle;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
}
|
|
if (aesKey.handle != TPM_RH_NULL) {
|
|
cmdIn.flushCtx.flushHandle = aesKey.handle;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
}
|
|
if (rsaKey.handle != TPM_RH_NULL) {
|
|
cmdIn.flushCtx.flushHandle = rsaKey.handle;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
}
|
|
|
|
/* Cleanup key handles */
|
|
if (endorse.handle != TPM_RH_NULL) {
|
|
cmdIn.flushCtx.flushHandle = endorse.handle;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
}
|
|
if (storage.handle != TPM_RH_NULL) {
|
|
cmdIn.flushCtx.flushHandle = storage.handle;
|
|
TPM2_FlushContext(&cmdIn.flushCtx);
|
|
}
|
|
|
|
/* Shutdown */
|
|
cmdIn.shutdown.shutdownType = TPM_SU_CLEAR;
|
|
if (TPM2_Shutdown(&cmdIn.shutdown) != TPM_RC_SUCCESS) {
|
|
printf("TPM2_Shutdown failed\n");
|
|
}
|
|
|
|
TPM2_Cleanup(&tpm2Ctx);
|
|
|
|
#ifdef TPM2_SPI_DEV
|
|
/* close handle */
|
|
if (gSpiDev >= 0)
|
|
close(gSpiDev);
|
|
#endif
|
|
|
|
return rc;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/* --- BEGIN TPM Native API Tests -- */
|
|
/******************************************************************************/
|
|
|
|
|
|
#ifndef NO_MAIN_DRIVER
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int rc;
|
|
|
|
rc = TPM2_Native_TestArgs(NULL, argc, argv);
|
|
|
|
return rc;
|
|
}
|
|
#endif
|