0.97 version of SAPI code. First version open sourced.
diff --git a/systemApi/Test/tpmclient/tpmclient.cpp b/systemApi/Test/tpmclient/tpmclient.cpp
new file mode 100644
index 0000000..1f3a32a
--- /dev/null
+++ b/systemApi/Test/tpmclient/tpmclient.cpp
@@ -0,0 +1,6081 @@
+//**********************************************************************;
+// Copyright (c) 2015, Intel Corporation
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//**********************************************************************;
+
+//
+// tpmclient.cpp : Defines the entry point for the console test application.
+//
+
+#ifdef _WIN32
+#include "stdafx.h"
+#else
+#include <stdarg.h>
+#endif
+
+#ifndef UNICODE
+#define UNICODE 1
+#endif
+
+#ifdef _WIN32
+// link with Ws2_32.lib
+#pragma comment(lib,"Ws2_32.lib")
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#define sprintf_s snprintf
+#define sscanf_s sscanf
+#endif
+
+#include <stdio.h>
+#include <stdlib.h> // Needed for _wtoi
+#include <string.h>
+
+#include "tpm20.h"
+#include "sample.h"
+#include "resourcemgr.h"
+#include "tpmclient.h"
+#include "tss2_sysapi_util.h"
+#include "tpmsockets.h"
+#include "syscontext.h"
+
+//
+// TPM indices and sizes
+//
+#define NV_AUX_INDEX_SIZE 96
+#define NV_PS_INDEX_SIZE 34
+#define NV_PO_INDEX_SIZE 34
+
+#define INDEX_AUX 0x01800003 // NV Storage
+#define INDEX_LCP_OWN 0x01400001 // Launch Policy Owner
+#define INDEX_LCP_SUP 0x01800001 // Launch Policy Default (Supplier)
+#define TPM20_INDEX_TEST1 0x01500015
+#define TPM20_INDEX_TEST2 0x01500016
+#define TPM20_INDEX_PASSWORD_TEST 0x01500020
+
+
+#define SET_PCR_SELECT_BIT( pcrSelection, pcr ) \
+ (pcrSelection).pcrSelect[( (pcr)/8 )] |= ( 1 << ( (pcr) % 8) );
+
+#define CLEAR_PCR_SELECT_BITS( pcrSelection ) \
+ (pcrSelection).pcrSelect[0] = 0; \
+ (pcrSelection).pcrSelect[1] = 0; \
+ (pcrSelection).pcrSelect[2] = 0;
+
+#define SET_PCR_SELECT_SIZE( pcrSelection, size ) \
+ (pcrSelection).sizeofSelect = size;
+
+char outFileName[200] = "";
+
+TPM_CC currentCommandCode;
+TPM_CC *currentCommandCodePtr = ¤tCommandCode;
+
+#define errorStringSize 200
+char errorString[errorStringSize];
+
+UINT32 tpmMaxResponseLen = TPMBUF_LEN;
+
+UINT8 pcrAfterExtend[20];
+TPM_HANDLE loadedRsaKeyHandle;
+TPM_HANDLE loadedSha1KeyHandle;
+
+TPM2B_AUTH loadedSha1KeyAuth;
+
+TPM_HANDLE handle1024, handle2048sha1, handle2048rsa;
+
+UINT32 passCount = 1;
+UINT32 demoDelay = 0;
+int debugLevel = 0;
+int startAuthSessionTestOnly = 0;
+UINT8 indent = 0;
+
+TSS2_SYS_CONTEXT *sysContext;
+
+#define rmInterfaceConfigSize 250
+char rmInterfaceConfig[rmInterfaceConfigSize];
+
+TSS2_TCTI_DRIVER_INFO resMgrInterfaceInfo = { "resMgr", "", InitTcti, TeardownTcti };
+
+TSS2_TCTI_CONTEXT *resMgrTctiContext = 0;
+TSS2_ABI_VERSION abiVersion = { TSSWG_INTEROP, TSS_SAPI_FIRST_FAMILY, TSS_SAPI_FIRST_LEVEL, TSS_SAPI_FIRST_VERSION };
+
+UINT32 tpmSpecVersion = 0;
+
+//
+// These are helper functions that are called through function pointers so that
+// they could be swapped easily to point to different functions.
+//
+// Currently they are set to functions that use the TPM to perform the function, but SW-only
+// implementations could be substituted as well.
+//
+UINT32 ( *ComputeSessionHmacPtr )(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPMS_AUTH_COMMAND *cmdAuth, // Pointer to session input struct
+ TPM_HANDLE entityHandle, // Used to determine if we're accessing a different
+ // resource than the bound resoure.
+ TPM_RC responseCode, // Response code for the command, 0xffff for "none" is
+ // used to indicate that no response code is present
+ // (used for calculating command HMACs vs response HMACs).
+ TPM_HANDLE handle1, // First handle == 0xff000000 indicates no handle
+ TPM_HANDLE handle2, // Second handle == 0xff000000 indicates no handle
+ TPMA_SESSION sessionAttributes, // Current session attributes
+ TPM2B_DIGEST *result, // Where the result hash is saved.
+ TPM_RC sessionCmdRval
+ ) = TpmComputeSessionHmac;
+
+TPM_RC ( *GetSessionAlgIdPtr )( TPMI_SH_AUTH_SESSION authHandle, TPMI_ALG_HASH *sessionAlgId ) = GetSessionAlgId;
+
+TPM_RC ( *CalcPHash )( TSS2_SYS_CONTEXT *sysContext,TPM_HANDLE handle1, TPM_HANDLE handle2, TPMI_ALG_HASH authHash,
+ TPM_RC responseCode, TPM2B_DIGEST *pHash ) = TpmCalcPHash;
+
+UINT32 (*HmacFunctionPtr)( TPM_ALG_ID hashAlg, TPM2B *key,TPM2B **bufferList, TPM2B_DIGEST *result ) = TpmHmac;
+
+UINT32 (*HashFunctionPtr)( TPMI_ALG_HASH hashAlg, UINT16 size, BYTE *data, TPM2B_DIGEST *result ) = TpmHash;
+
+UINT32 (*HandleToNameFunctionPtr)( TPM_HANDLE handle, TPM2B_NAME *name ) = TpmHandleToName;
+
+TPMI_SH_AUTH_SESSION StartPolicySession();
+
+TPMI_SH_AUTH_SESSION InitNvAuxPolicySession();
+
+FILE *outFp;
+
+//
+// Used by some high level sample routines to copy the results.
+//
+void copyData( UINT8 *to, UINT8 *from, UINT32 length )
+{
+ if( to != 0 && from != 0 )
+ memcpy( to, from, length );
+}
+
+int TpmClientPrintf( UINT8 type, const char *format, ...)
+{
+ va_list args;
+ int rval = 0;
+
+ OpenOutFile( &outFp );
+
+ if( outFp )
+ {
+ if( type == RM_PREFIX )
+ {
+ PrintRMDebugPrefix();
+ }
+
+ va_start( args, format );
+ rval = vfprintf( outFp, format, args );
+ va_end (args);
+
+ CloseOutFile( &outFp );
+ }
+ else
+ {
+ printf( "TpmClientPrintf failed\n" );
+ }
+
+ return rval;
+}
+
+TPM_RC CompareTPM2B( TPM2B *buffer1, TPM2B *buffer2 )
+{
+ if( buffer1->size != buffer2->size )
+ return TPM_RC_FAILURE;
+ for( int i = 0; i < buffer1->size; i++ )
+ {
+ if( buffer1->buffer[0] != buffer2->buffer[0] )
+ return TPM_RC_FAILURE;
+ }
+ return TPM_RC_SUCCESS;
+}
+
+void PrintSizedBufferOpen( TPM2B *sizedBuffer )
+{
+ int i;
+
+
+ OpenOutFile( &outFp );
+
+ if( outFp )
+ {
+ for( i = 0; i < sizedBuffer->size; i++ )
+ {
+ TpmClientPrintf( 0, "%2.2x ", sizedBuffer->buffer[i] );
+
+ if( ( (i+1) % 16 ) == 0 )
+ {
+ TpmClientPrintf( 0, "\n" );
+ }
+ }
+ TpmClientPrintf( 0, "\n" );
+
+ CloseOutFile( &outFp );
+ }
+ else
+ {
+ printf( "PrintSizedBufferOpen failed\n" );
+ }
+
+}
+
+void PrintSizedBuffer( TPM2B *sizedBuffer )
+{
+ int i;
+
+ for( i = 0; i < sizedBuffer->size; i++ )
+ {
+ TpmClientPrintf( 0, "%2.2x ", sizedBuffer->buffer[i] );
+
+ if( ( (i+1) % 16 ) == 0 )
+ {
+ TpmClientPrintf( 0, "\n" );
+ }
+ }
+ TpmClientPrintf( 0, "\n" );
+}
+
+#define LEVEL_STRING_SIZE 50
+
+void ErrorHandler( UINT32 rval )
+{
+ UINT32 errorLevel = rval & TSS2_ERROR_LEVEL_MASK;
+ char levelString[LEVEL_STRING_SIZE + 1];
+
+ switch( errorLevel )
+ {
+ case TSS2_TPM_ERROR_LEVEL:
+ strncpy( levelString, "TPM", LEVEL_STRING_SIZE );
+ break;
+ case TSS2_APP_ERROR_LEVEL:
+ strncpy( levelString, "Application", LEVEL_STRING_SIZE );
+ break;
+ case TSS2_SYS_ERROR_LEVEL:
+ strncpy( levelString, "System API", LEVEL_STRING_SIZE );
+ break;
+ case TSS2_SYS_PART2_ERROR_LEVEL:
+ strncpy( levelString, "System API TPM encoded", LEVEL_STRING_SIZE );
+ break;
+ case TSS2_TCTI_ERROR_LEVEL:
+ strncpy( levelString, "TCTI", LEVEL_STRING_SIZE );
+ break;
+ case TSS2_RESMGRTPM_ERROR_LEVEL:
+ strncpy( levelString, "Resource Mgr TPM encoded", LEVEL_STRING_SIZE );
+ break;
+ case TSS2_RESMGR_ERROR_LEVEL:
+ strncpy( levelString, "Resource Mgr", LEVEL_STRING_SIZE );
+ break;
+ case TSS2_DRIVER_ERROR_LEVEL:
+ strncpy( levelString, "Driver", LEVEL_STRING_SIZE );
+ break;
+ default:
+ strncpy( levelString, "Unknown Level", LEVEL_STRING_SIZE );
+ break;
+ }
+
+ sprintf_s( errorString, errorStringSize, "%s Error: 0x%x\n", levelString, rval );
+}
+
+char resMgrInterfaceName[] = "Resource Manager";
+
+TSS2_RC InitTctiResMgrContext( char *rmInterfaceConfig, TSS2_TCTI_CONTEXT **tctiContext, char *name )
+{
+ size_t size;
+
+ TSS2_RC rval;
+
+ rval = resMgrInterfaceInfo.initialize(NULL, &size, rmInterfaceConfig, 0, 0, &resMgrInterfaceName[0], 0 );
+ if( rval != TSS2_RC_SUCCESS )
+ return rval;
+
+ *tctiContext = (TSS2_TCTI_CONTEXT *)malloc(size);
+
+ if( *tctiContext )
+ {
+ rval = resMgrInterfaceInfo.initialize(*tctiContext, &size, rmInterfaceConfig, 0, 0, resMgrInterfaceName, 0 );
+ }
+ else
+ {
+ rval = TSS2_TCTI_RC_BAD_CONTEXT;
+ }
+ return rval;
+}
+
+TSS2_RC TeardownTctiResMgrContext( char *interfaceConfig, TSS2_TCTI_CONTEXT *tctiContext, char *name )
+{
+ return resMgrInterfaceInfo.teardown( tctiContext, interfaceConfig, name );
+}
+
+void Cleanup()
+{
+ fflush( stdout );
+
+ PlatformCommand( resMgrTctiContext, MS_SIM_POWER_OFF );
+
+ TeardownTctiResMgrContext( rmInterfaceConfig, resMgrTctiContext, &resMgrInterfaceName[0] );
+
+#ifdef _WIN32
+ WSACleanup();
+#endif
+ exit(1);
+}
+
+void InitSysContextFailure()
+{
+ TpmClientPrintf( 0, "InitSysContext failed, exiting...\n" );
+ Cleanup();
+}
+
+void Delay( UINT16 delay)
+{
+ volatile UINT32 i, j;
+
+ for( j = 0; j < delay; j++ )
+ {
+ for( i = 0; i < 10000000; i++ )
+ ;
+ }
+}
+
+void CheckPassed( UINT32 rval )
+{
+ OpenOutFile( &outFp );
+ TpmClientPrintf( 0, "\tpassing case: " );
+ if ( rval != TPM_RC_SUCCESS) {
+ ErrorHandler( rval);
+ TpmClientPrintf( 0, "\tFAILED! %s\n", errorString );
+ Cleanup();
+ }
+ else
+ {
+ TpmClientPrintf( 0, "\tPASSED!\n" );
+ }
+
+ CloseOutFile( &outFp );
+ Delay(demoDelay);
+}
+
+TPMS_AUTH_COMMAND nullSessionData;
+TPMS_AUTH_RESPONSE nullSessionDataOut;
+TPMS_AUTH_COMMAND *nullSessionDataArray[1] = { &nullSessionData };
+TPMS_AUTH_RESPONSE *nullSessionDataOutArray[1] = { &nullSessionDataOut };
+TSS2_SYS_CMD_AUTHS nullSessionsData = { 1, &nullSessionDataArray[0] };
+TSS2_SYS_RSP_AUTHS nullSessionsDataOut = { 1, &nullSessionDataOutArray[0] };
+TPM2B_NONCE nullSessionNonce, nullSessionNonceOut;
+TPM2B_AUTH nullSessionHmac;
+
+void CheckFailed( UINT32 rval, UINT32 expectedTpmErrorCode )
+{
+ OpenOutFile( &outFp );
+ TpmClientPrintf( 0, "\tfailing case: " );
+ if ( rval != expectedTpmErrorCode) {
+ ErrorHandler( rval);
+ TpmClientPrintf( 0, "\tFAILED! Ret code s/b: %x, but was: %x\n", expectedTpmErrorCode, rval );
+ Cleanup();
+ }
+ else
+ {
+ TpmClientPrintf( 0, "\tPASSED!\n" );
+ }
+ fflush( stdout );
+ CloseOutFile( &outFp );
+ Delay(demoDelay);
+}
+
+TSS2_RC TpmReset()
+{
+ TSS2_RC rval = TSS2_RC_SUCCESS;
+
+ rval = (TSS2_RC)PlatformCommand( resMgrTctiContext, MS_SIM_POWER_OFF );
+ if( rval == TSS2_RC_SUCCESS )
+ {
+ rval = (TSS2_RC)PlatformCommand( resMgrTctiContext, MS_SIM_POWER_ON );
+ }
+ return rval;
+}
+
+void GetTpmVersion()
+{
+ TSS2_RC rval = TSS2_RC_SUCCESS;
+ TPMS_CAPABILITY_DATA capabilityData;
+
+ rval = Tss2_Sys_GetCapability( sysContext, 0,
+ TPM_CAP_TPM_PROPERTIES, TPM_PT_REVISION,
+ 1, 0, &capabilityData, 0 );
+ CheckPassed( rval );
+
+ if( capabilityData.data.tpmProperties.count == 1 &&
+ (capabilityData.data.tpmProperties.tpmProperty[0].property == TPM_PT_REVISION) )
+ {
+ tpmSpecVersion = capabilityData.data.tpmProperties.tpmProperty[0].value;
+ }
+ else
+ {
+ TpmClientPrintf( 0, "Failed to get TPM spec version!!\n" );
+ Cleanup();
+ }
+}
+
+
+void TestDictionaryAttackLockReset()
+{
+ UINT32 rval;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nDICTIONARY ATTACK LOCK RESET TEST :\n" );
+
+ // Init authHandle
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ rval = Tss2_Sys_DictionaryAttackLockReset ( sysContext, TPM_RH_LOCKOUT, &sessionsData, &sessionsDataOut );
+ CheckPassed( rval );
+}
+
+TSS2_RC StartPolicySession( TPMI_SH_AUTH_SESSION *sessionHandle )
+{
+ UINT8 i;
+ TPM2B_NONCE nonceCaller, nonceTpm;
+ TPM2B_ENCRYPTED_SECRET salt;
+ TPMT_SYM_DEF symmetric;
+ UINT16 digestSize;
+ UINT32 rval;
+
+ digestSize = GetDigestSize( TPM_ALG_SHA1 );
+ nonceCaller.t.size = digestSize;
+ for( i = 0; i < nonceCaller.t.size; i++ )
+ nonceCaller.t.buffer[i] = 0;
+
+ salt.t.size = 0;
+ symmetric.algorithm = TPM_ALG_NULL;
+
+ // Create policy session
+ rval = Tss2_Sys_StartAuthSession ( sysContext, TPM_RH_NULL, TPM_RH_NULL, 0, &nonceCaller, &salt,
+ TPM_SE_POLICY, &symmetric, TPM_ALG_SHA1, sessionHandle, &nonceTpm, 0 );
+ return( rval );
+}
+
+void TestTpmStartup()
+{
+ UINT32 rval;
+
+ TpmClientPrintf( 0, "\nSTARTUP TESTS:\n" );
+
+ //
+ // First test the one-call interface.
+ //
+
+ // First must do TPM reset.
+ rval = TpmReset();
+ CheckPassed(rval);
+
+ // This one should pass.
+ rval = Tss2_Sys_Startup( sysContext, TPM_SU_CLEAR );
+ CheckPassed(rval);
+
+ // This one should fail.
+ rval = Tss2_Sys_Startup( sysContext, TPM_SU_CLEAR );
+ CheckFailed( rval, TPM_RC_INITIALIZE );
+
+
+ // Cycle power using simulator interface.
+ rval = PlatformCommand( resMgrTctiContext, MS_SIM_POWER_OFF );
+ CheckPassed( rval );
+ rval = PlatformCommand( resMgrTctiContext, MS_SIM_POWER_ON );
+ CheckPassed( rval );
+
+
+ //
+ // Now test the syncronous, non-one-call interface.
+ //
+ rval = Tss2_Sys_Startup_Prepare( sysContext, TPM_SU_CLEAR );
+ CheckPassed(rval);
+
+ // Execute the command syncronously.
+ rval = Tss2_Sys_Execute( sysContext );
+
+ // Cycle power using simulator interface.
+ rval = PlatformCommand( resMgrTctiContext, MS_SIM_POWER_OFF );
+ CheckPassed( rval );
+ rval = PlatformCommand( resMgrTctiContext, MS_SIM_POWER_ON );
+ CheckPassed( rval );
+
+
+ //
+ // Now test the asyncronous, non-one-call interface.
+ //
+ rval = Tss2_Sys_Startup_Prepare( sysContext, TPM_SU_CLEAR );
+ CheckPassed(rval);
+
+ // Execute the command asyncronously.
+ rval = Tss2_Sys_ExecuteAsync( sysContext );
+ CheckPassed(rval);
+
+ // Get the command response. Wait a maximum of 20ms
+ // for response.
+ rval = Tss2_Sys_ExecuteFinish( sysContext, TSS2_TCTI_TIMEOUT_BLOCK );
+ CheckPassed(rval);
+}
+
+void TestSapiApis()
+{
+ UINT32 rval;
+ TPM2B_MAX_BUFFER outData = { { MAX_DIGEST_BUFFER, } };
+ TPM_RC testResult;
+
+ TpmClientPrintf( 0, "\nGET TEST RESULT TESTS:\n" );
+
+ //
+ // First test the one-call interface.
+ //
+ rval = Tss2_Sys_GetTestResult( sysContext, 0, &outData, &testResult, 0 );
+ CheckPassed(rval);
+
+ //
+ // Now test the syncronous, non-one-call interface.
+ //
+ rval = Tss2_Sys_GetTestResult_Prepare( sysContext );
+ CheckPassed(rval);
+
+ // Execute the command syncronously.
+ rval = Tss2_Sys_Execute( sysContext );
+ CheckPassed(rval);
+
+ // Get the command results
+ rval = Tss2_Sys_GetTestResult_Complete( sysContext, &outData, &testResult );
+ CheckPassed(rval);
+
+ //
+ // Now test the asyncronous, non-one-call interface.
+ //
+ rval = Tss2_Sys_GetTestResult_Prepare( sysContext );
+ CheckPassed(rval);
+
+ // Execute the command asyncronously.
+ rval = Tss2_Sys_ExecuteAsync( sysContext );
+ CheckPassed(rval);
+
+ // Get the command response. Wait a maximum of 20ms
+ // for response.
+ rval = Tss2_Sys_ExecuteFinish( sysContext, TSS2_TCTI_TIMEOUT_BLOCK );
+ CheckPassed(rval);
+
+ // Get the command results
+ rval = Tss2_Sys_GetTestResult_Complete( sysContext, &outData, &testResult );
+ CheckPassed(rval);
+
+ // Check case of ExecuteFinish receving TPM error code.
+ // Subsequent _Complete call should fail with SEQUENCE error.
+ rval = TpmReset();
+ CheckPassed(rval);
+
+ rval = Tss2_Sys_GetCapability_Prepare( sysContext,
+ TPM_CAP_TPM_PROPERTIES, TPM_PT_ACTIVE_SESSIONS_MAX,
+ 1 );
+ CheckPassed(rval);
+
+ // Execute the command asyncronously.
+ rval = Tss2_Sys_ExecuteAsync( sysContext );
+ CheckPassed(rval);
+
+ // Get the command response. Wait a maximum of 20ms
+ // for response.
+ rval = Tss2_Sys_ExecuteFinish( sysContext, TSS2_TCTI_TIMEOUT_BLOCK );
+ CheckFailed( rval, TPM_RC_INITIALIZE );
+
+ // Get the command results
+ rval = Tss2_Sys_GetCapability_Complete( sysContext, 0, 0 );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_SEQUENCE );
+
+ rval = Tss2_Sys_Startup( sysContext, TPM_SU_CLEAR );
+ CheckPassed(rval);
+}
+
+
+void TestTpmSelftest()
+{
+ UINT32 rval;
+
+ TpmClientPrintf( 0, "\nSELFTEST TESTS:\n" );
+
+ rval = Tss2_Sys_SelfTest( sysContext, 0, YES, 0);
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_SelfTest( sysContext, 0, NO, 0);
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_SelfTest( sysContext, 0, YES, 0);
+ CheckPassed( rval );
+
+}
+
+void TestTpmGetCapability()
+{
+ UINT32 rval;
+
+ char manuID[5] = " ";
+ char *manuIDPtr = &manuID[0];
+ TPMI_YES_NO moreData;
+ TPMS_CAPABILITY_DATA capabilityData;
+
+ TpmClientPrintf( 0, "\nGET_CAPABILITY TESTS:\n" );
+
+ rval = Tss2_Sys_GetCapability( sysContext, 0, TPM_CAP_TPM_PROPERTIES, TPM_PT_MANUFACTURER, 1, &moreData, &capabilityData, 0 );
+ CheckPassed( rval );
+
+ *( (UINT32 *)manuIDPtr ) = CHANGE_ENDIAN_DWORD( capabilityData.data.tpmProperties.tpmProperty[0].value );
+ TpmClientPrintf( 0, "\t\tcount: %d, property: %x, manuId: %s\n",
+ capabilityData.data.tpmProperties.count,
+ capabilityData.data.tpmProperties.tpmProperty[0].property,
+ manuID );
+
+ rval = Tss2_Sys_GetCapability( sysContext, 0, TPM_CAP_TPM_PROPERTIES, TPM_PT_MAX_COMMAND_SIZE, 1, &moreData, &capabilityData, 0 );
+ CheckPassed( rval );
+ TpmClientPrintf( 0, "\t\tcount: %d, property: %x, max cmd size: %d\n",
+ capabilityData.data.tpmProperties.count,
+ capabilityData.data.tpmProperties.tpmProperty[0].property,
+ capabilityData.data.tpmProperties.tpmProperty[0].value );
+
+
+ rval = Tss2_Sys_GetCapability( sysContext, 0, TPM_CAP_TPM_PROPERTIES, TPM_PT_MAX_COMMAND_SIZE, 40, &moreData, &capabilityData, 0 );
+ CheckPassed( rval );
+ TpmClientPrintf( 0, "\t\tcount: %d, property: %x, max cmd size: %d\n",
+ capabilityData.data.tpmProperties.count,
+ capabilityData.data.tpmProperties.tpmProperty[0].property,
+ capabilityData.data.tpmProperties.tpmProperty[0].value );
+
+
+ rval = Tss2_Sys_GetCapability( sysContext, 0, TPM_CAP_TPM_PROPERTIES, TPM_PT_MAX_RESPONSE_SIZE, 1, &moreData, &capabilityData, 0 );
+ CheckPassed( rval );
+ TpmClientPrintf( 0, "\t count: %d, property: %x, max response size: %d\n",
+ capabilityData.data.tpmProperties.count,
+ capabilityData.data.tpmProperties.tpmProperty[0].property,
+ capabilityData.data.tpmProperties.tpmProperty[0].value );
+
+ rval = Tss2_Sys_GetCapability( sysContext, 0, 0xff, TPM_PT_MANUFACTURER, 1, &moreData, &capabilityData, 0 );
+
+ if( tpmSpecVersion == 115 || tpmSpecVersion == 119 )
+ {
+ CheckFailed( rval, TPM_RC_VALUE );
+ }
+ else
+ {
+ CheckFailed( rval, TPM_RC_VALUE+TPM_RC_1+TPM_RC_P );
+ }
+}
+
+void TestTpmClear()
+{
+ UINT32 rval;
+ TPM2B_AUTH hmac;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TPM2B_NONCE nonce;
+ TSS2_SYS_CMD_AUTHS sessionsDataIn;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsDataIn.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+ sessionsDataOut.rspAuths[0] = &sessionDataOut;
+
+ TpmClientPrintf( 0, "\nCLEAR and CLEAR CONTROL TESTS:\n" );
+
+ // Init sessionHandle
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ nonce.t.size = 0;
+ sessionData.nonce = nonce;
+
+ // init hmac
+ hmac.t.size = 0;
+ sessionData.hmac = hmac;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ sessionsDataIn.cmdAuthsCount = 1;
+ sessionsDataIn.cmdAuths[0] = &sessionData;
+
+ rval = Tss2_Sys_Clear ( sysContext, TPM_RH_PLATFORM, &sessionsDataIn, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_ClearControl ( sysContext, TPM_RH_PLATFORM, &sessionsDataIn, YES, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_Clear ( sysContext, TPM_RH_PLATFORM, &sessionsDataIn, 0 );
+ CheckFailed( rval, TPM_RC_DISABLED );
+
+ rval = Tss2_Sys_ClearControl ( sysContext, TPM_RH_PLATFORM, &sessionsDataIn, NO, &sessionsDataOut );
+ CheckPassed( rval );
+
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0xff;
+ sessionsDataIn.cmdAuths[0] = &sessionData;
+ rval = Tss2_Sys_Clear ( sysContext, TPM_RH_PLATFORM, &sessionsDataIn, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_9 + TPM_RC_RESERVED_BITS );
+
+ rval = Tss2_Sys_ClearControl ( sysContext, TPM_RH_PLATFORM, &sessionsDataIn, NO, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_9 + TPM_RC_RESERVED_BITS );
+
+ hmac.t.size = 0;
+
+
+}
+
+#ifdef DEBUG_GAP_HANDLING
+
+#define SESSIONS_ABOVE_MAX_ACTIVE 1
+// SESSION sessions[DEBUG_GAP_MAX*3];
+ SESSION *sessions[300];
+#else
+
+#define SESSIONS_ABOVE_MAX_ACTIVE 0
+#define DEBUG_MAX_ACTIVE_SESSIONS 8
+#define DEBUG_GAP_MAX 2*DEBUG_MAX_ACTIVE_SESSIONS
+ SESSION *sessions[5];
+
+#endif
+
+void TestStartAuthSession()
+{
+ UINT32 rval;
+ TPM2B_ENCRYPTED_SECRET encryptedSalt;
+ TPMT_SYM_DEF symmetric;
+ SESSION *authSession;
+ TPM2B_NONCE nonceCaller;
+ UINT16 i, debugGapMax = DEBUG_GAP_MAX, debugMaxActiveSessions = DEBUG_MAX_ACTIVE_SESSIONS;
+ TPMA_LOCALITY locality;
+ TPM_HANDLE badSessionHandle = 0x03010000;
+
+ TPMS_AUTH_COMMAND sessionData;
+ TPM2B_NONCE nonce;
+ TSS2_SYS_CMD_AUTHS sessionsDataIn;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+
+ TPM2B_AUTH hmac;
+
+ TPMS_CONTEXT evictedSessionContext;
+ TPM_HANDLE evictedHandle;
+
+ sessionDataArray[0] = &sessionData;
+
+ sessionsDataIn.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataIn.cmdAuthsCount = 1;
+
+ // Init sessionHandle
+ sessionData.sessionHandle = badSessionHandle;
+
+ // Init nonce.
+ nonce.t.size = 0;
+ sessionData.nonce = nonce;
+
+ // init hmac
+ hmac.t.size = 0;
+ sessionData.hmac = hmac;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ encryptedSalt.t.size = 0;
+
+ TpmClientPrintf( 0, "\nSTART_AUTH_SESSION TESTS:\n" );
+
+ symmetric.algorithm = TPM_ALG_NULL;
+ symmetric.keyBits.sym = 0;
+ symmetric.mode.sym = 0;
+
+ nonceCaller.t.size = 0;
+
+ encryptedSalt.t.size = 0;
+
+ // Init session
+ rval = StartAuthSessionWithParams( &authSession, TPM_RH_NULL, 0, TPM_RH_PLATFORM, 0, &nonceCaller, &encryptedSalt, TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_FlushContext( sysContext, authSession->sessionHandle );
+ CheckPassed( rval );
+ EndAuthSession( authSession );
+
+ // Init session
+ rval = StartAuthSessionWithParams( &authSession, TPM_RH_NULL, 0, TPM_RH_PLATFORM, 0, &nonceCaller, &encryptedSalt, 0xff, &symmetric, TPM_ALG_SHA256 );
+ CheckFailed( rval, TPM_RC_VALUE + TPM_RC_P + TPM_RC_3 );
+
+ // Try starting a bunch to see if resource manager handles this correctly.
+
+#ifdef DEBUG_GAP_HANDLING
+ for( i = 0; i < debugMaxActiveSessions*3; i++ )
+#else
+ for( i = 0; i < ( sizeof(sessions) / sizeof (SESSION *) ); i++ )
+#endif
+ {
+// TpmClientPrintf( 0, "i = 0x%4.4x\n", i );
+
+ // Init session struct
+ rval = StartAuthSessionWithParams( &sessions[i], TPM_RH_NULL, 0, TPM_RH_PLATFORM, 0, &nonceCaller, &encryptedSalt, TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+ TpmClientPrintf( 0, "Number of sessions created: %d\n\n", i );
+
+#ifdef DEBUG_GAP_HANDLING
+ if( i == 0 )
+ {
+ // Save evicted session's context so we can use it for a test.
+ rval = Tss2_Sys_ContextSave( sysContext, sessions[i]->sessionHandle, &evictedSessionContext );
+ CheckPassed( rval );
+ }
+#endif
+ }
+
+#ifdef DEBUG_GAP_HANDLING
+ TpmClientPrintf( 0, "loading evicted session's context\n" );
+ // Now try loading an evicted session's context.
+ // NOTE: simulator versions 01.19 and earlier this test will fail due to a
+ // simulator bug (unless patches have been applied).
+ rval = Tss2_Sys_ContextLoad( sysContext, &evictedSessionContext, &evictedHandle );
+ CheckFailed( rval, TPM_RC_HANDLE + TPM_RC_P + ( 1 << 8 ));
+#endif
+
+ // Now try two ways of using a bad session handle. Both should fail.
+
+ // first way is to use as command parameter.
+ *(UINT8 *)( (void *)&locality ) = 0;
+ locality.TPM_LOC_THREE = 1;
+ rval = Tss2_Sys_PolicyLocality( sysContext, badSessionHandle, 0, locality, 0 );
+ CheckFailed( rval, TSS2_RESMGRTPM_ERROR_LEVEL + TPM_RC_HANDLE + ( 1 << 8 ) );
+
+ // Second way is to use as handle in session area.
+ rval = Tss2_Sys_PolicyLocality( sysContext, sessions[0]->sessionHandle, &sessionsDataIn, locality, 0 );
+ CheckFailed( rval, TSS2_RESMGRTPM_ERROR_LEVEL + TPM_RC_VALUE + TPM_RC_S + ( 1 << 8 ) );
+
+ // clean up the sessions that I don't want here.
+#ifdef DEBUG_GAP_HANDLING
+ for( i = 0; i < ( debugMaxActiveSessions*3); i++ )
+#else
+ for( i = 0; i < ( sizeof(sessions) / sizeof (SESSION *)); i++ )
+#endif
+ {
+// TpmClientPrintf( 0, "i(2) = 0x%4.4x\n", i );
+ rval = Tss2_Sys_FlushContext( sysContext, sessions[i]->sessionHandle );
+
+ rval = EndAuthSession( sessions[i] );
+ }
+
+ // Now do some gap tests.
+ rval = StartAuthSessionWithParams( &sessions[0], TPM_RH_NULL, 0, TPM_RH_PLATFORM, 0, &nonceCaller, &encryptedSalt, TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+
+#ifdef DEBUG_GAP_HANDLING
+// for( i = 1; i < debugGapMax/2; i++ )
+ for( i = 1; i < 300; i++ )
+#else
+ for( i = 1; i < ( sizeof(sessions) / sizeof (SESSION *) ); i++ )
+#endif
+ {
+// TpmClientPrintf( 0, "i(3) = 0x%4.4x\n", i );
+
+ rval = StartAuthSessionWithParams( &sessions[i], TPM_RH_NULL, 0, TPM_RH_PLATFORM, 0, &nonceCaller, &encryptedSalt, TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_FlushContext( sysContext, sessions[i]->sessionHandle );
+ CheckPassed( rval );
+
+ rval = EndAuthSession( sessions[i] );
+ CheckPassed( rval );
+ }
+
+#ifdef DEBUG_GAP_HANDLING
+ // Now do some gap tests.
+ rval = StartAuthSessionWithParams( &sessions[8], TPM_RH_NULL, 0, TPM_RH_PLATFORM, 0, &nonceCaller, &encryptedSalt, TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+#endif
+
+#ifdef DEBUG_GAP_HANDLING
+ for( i = 9; i < debugGapMax; i++ )
+#else
+ for( i = 0; i < ( sizeof(sessions) / sizeof (SESSION *) ); i++ )
+#endif
+ {
+// TpmClientPrintf( 0, "i(4) = 0x%4.4x\n", i );
+ rval = StartAuthSessionWithParams( &sessions[i], TPM_RH_NULL, 0, TPM_RH_PLATFORM, 0, &nonceCaller, &encryptedSalt, TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_FlushContext( sysContext, sessions[i]->sessionHandle );
+ CheckPassed( rval );
+
+ rval = EndAuthSession( sessions[i] );
+ CheckPassed( rval );
+
+ }
+
+#ifdef DEBUG_GAP_HANDLING
+ for( i = 0; i < 5; i++ )
+ {
+// TpmClientPrintf( 0, "i(5) = 0x%4.4x\n", i );
+ rval = StartAuthSessionWithParams( &sessions[i+16], TPM_RH_NULL, 0, TPM_RH_PLATFORM, 0, &nonceCaller, &encryptedSalt, TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+ }
+
+ for( i = 0; i < 5; i++ )
+ {
+// TpmClientPrintf( 0, "i(6) = 0x%4.4x\n", i );
+ rval = Tss2_Sys_FlushContext( sysContext, sessions[i+16]->sessionHandle );
+ CheckPassed( rval );
+
+ rval = EndAuthSession( sessions[i+16] );
+ CheckPassed( rval );
+ }
+
+ rval = Tss2_Sys_FlushContext( sysContext, sessions[0]->sessionHandle );
+ CheckPassed( rval );
+
+ rval = EndAuthSession( sessions[0] );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_FlushContext( sysContext, sessions[8]->sessionHandle );
+ CheckPassed( rval );
+
+ rval = EndAuthSession( sessions[8] );
+ CheckPassed( rval );
+#endif
+
+}
+
+void TestChangeEps()
+{
+ UINT32 rval;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nCHANGE_EPS TESTS:\n" );
+
+ sessionsData.cmdAuthsCount = 1;
+
+ // Init authHandle
+ sessionsData.cmdAuths[0]->sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionsData.cmdAuths[0]->nonce.t.size = 0;
+
+ // init hmac
+ sessionsData.cmdAuths[0]->hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionsData.cmdAuths[0]->sessionAttributes ) ) = 0;
+
+ rval = Tss2_Sys_ChangeEPS( sysContext, TPM_RH_PLATFORM, &sessionsData, &sessionsDataOut );
+ CheckPassed( rval );
+
+ sessionsData.cmdAuths[0]->hmac.t.size = 0x10;
+
+ rval = Tss2_Sys_ChangeEPS( sysContext, TPM_RH_PLATFORM, &sessionsData, 0 );
+ CheckFailed( rval, TPM_RC_1 + TPM_RC_S + TPM_RC_BAD_AUTH );
+}
+
+void TestChangePps()
+{
+ UINT32 rval;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nCHANGE_PPS TESTS:\n" );
+
+ sessionsData.cmdAuthsCount = 1;
+
+ // Init authHandle
+ sessionsData.cmdAuths[0]->sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionsData.cmdAuths[0]->nonce.t.size = 0;
+
+ // init hmac
+ sessionsData.cmdAuths[0]->hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionsData.cmdAuths[0]->sessionAttributes ) ) = 0;
+
+ rval = Tss2_Sys_ChangePPS( sysContext, TPM_RH_PLATFORM, &sessionsData, &sessionsDataOut );
+ CheckPassed( rval );
+
+ sessionsData.cmdAuths[0]->hmac.t.size = 0x10;
+
+ rval = Tss2_Sys_ChangePPS( sysContext, TPM_RH_PLATFORM, &sessionsData, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_1 + TPM_RC_S + TPM_RC_BAD_AUTH );
+}
+
+void TestHierarchyChangeAuth()
+{
+ UINT32 rval;
+ TPM2B_AUTH newAuth;
+ TPMS_AUTH_COMMAND sessionData;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ int i;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+
+ sessionDataArray[0] = &sessionData;
+
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ TpmClientPrintf( 0, "\nHIERARCHY_CHANGE_AUTH TESTS:\n" );
+
+ // Init authHandle
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ newAuth.t.size = 0;
+ rval = Tss2_Sys_HierarchyChangeAuth( sysContext, TPM_RH_PLATFORM, &sessionsData, &newAuth, 0 );
+ CheckPassed( rval );
+
+ // Init new auth
+ newAuth.t.size = 20;
+ for( i = 0; i < newAuth.t.size; i++ )
+ newAuth.t.buffer[i] = i;
+
+ rval = Tss2_Sys_HierarchyChangeAuth( sysContext, TPM_RH_PLATFORM, &sessionsData, &newAuth, 0 );
+ CheckPassed( rval );
+
+ sessionData.hmac = newAuth;
+ rval = Tss2_Sys_HierarchyChangeAuth( sysContext, TPM_RH_PLATFORM, &sessionsData, &newAuth, 0 );
+ CheckPassed( rval );
+
+ // Init new auth
+ newAuth.t.size = 0;
+
+ rval = Tss2_Sys_HierarchyChangeAuth( sysContext, TPM_RH_PLATFORM, &sessionsData, &newAuth, 0 );
+ CheckPassed( rval );
+
+ sessionsData.cmdAuths[0] = &sessionData;
+ rval = Tss2_Sys_HierarchyChangeAuth( sysContext, TPM_RH_PLATFORM, &sessionsData, &newAuth, 0 );
+ CheckFailed( rval, TPM_RC_1 + TPM_RC_S + TPM_RC_BAD_AUTH );
+
+ rval = Tss2_Sys_HierarchyChangeAuth( sysContext, 0, &sessionsData, &newAuth, 0 );
+ CheckFailed( rval, TPM_RC_1 + TPM_RC_VALUE );
+}
+
+#define PCR_0 0
+#define PCR_1 1
+#define PCR_2 2
+#define PCR_3 3
+#define PCR_4 4
+#define PCR_5 5
+#define PCR_6 6
+#define PCR_7 7
+#define PCR_8 8
+#define PCR_9 9
+#define PCR_10 10
+#define PCR_11 11
+#define PCR_12 12
+#define PCR_13 13
+#define PCR_14 14
+#define PCR_15 15
+#define PCR_16 16
+#define PCR_17 17
+#define PCR_18 18
+
+#define PCR_SIZE 20
+
+void TestPcrExtend()
+{
+ UINT32 rval;
+ TPMS_AUTH_COMMAND sessionData;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ UINT16 i, digestSize;
+ TPML_PCR_SELECTION pcrSelection;
+ UINT32 pcrUpdateCounterBeforeExtend;
+ UINT32 pcrUpdateCounterAfterExtend;
+ UINT8 pcrBeforeExtend[PCR_SIZE];
+ TPM2B_EVENT eventData;
+ TPML_DIGEST pcrValues;
+ TPML_DIGEST_VALUES digests;
+ TPML_PCR_SELECTION pcrSelectionOut;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ TpmClientPrintf( 0, "\nPCR_EXTEND, PCR_EVENT, PCR_ALLOCATE, and PCR_READ TESTS:\n" );
+
+ // Init authHandle
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ // Init digests
+ digests.count = 1;
+ digests.digests[0].hashAlg = TPM_ALG_SHA1;
+ digestSize = GetDigestSize( digests.digests[0].hashAlg );
+
+ for( i = 0; i < digestSize; i++ )
+ {
+ digests.digests[0].digest.sha1[i] = (UINT8)(i % 256);
+ }
+
+ pcrSelection.count = 1;
+ pcrSelection.pcrSelections[0].hash = TPM_ALG_SHA1;
+ pcrSelection.pcrSelections[0].sizeofSelect = 3;
+
+ // Clear out PCR select bit field
+ pcrSelection.pcrSelections[0].pcrSelect[0] = 0;
+ pcrSelection.pcrSelections[0].pcrSelect[1] = 0;
+ pcrSelection.pcrSelections[0].pcrSelect[2] = 0;
+
+ // Now set the PCR you want to read
+ SET_PCR_SELECT_BIT( pcrSelection.pcrSelections[0], PCR_17 );
+
+ rval = Tss2_Sys_PCR_Read( sysContext, 0, &pcrSelection, &pcrUpdateCounterBeforeExtend, &pcrSelectionOut, &pcrValues, 0 );
+ CheckPassed( rval );
+
+ if( pcrValues.digests[0].t.size <= PCR_SIZE &&
+ pcrValues.digests[0].t.size <= sizeof( pcrValues.digests[0].t.buffer ) )
+ memcpy( &( pcrBeforeExtend[0] ), &( pcrValues.digests[0].t.buffer[0] ), pcrValues.digests[0].t.size );
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ rval = Tss2_Sys_PCR_Extend( sysContext, PCR_17, &sessionsData, &digests, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_PCR_Read( sysContext, 0, &pcrSelection, &pcrUpdateCounterAfterExtend, &pcrSelectionOut, &pcrValues, 0 );
+ CheckPassed( rval );
+
+ memcpy( &( pcrAfterExtend[0] ), &( pcrValues.digests[0].t.buffer[0] ), pcrValues.digests[0].t.size );
+
+ if( pcrUpdateCounterBeforeExtend == pcrUpdateCounterAfterExtend )
+ {
+ TpmClientPrintf( 0, "ERROR!! pcrUpdateCounter didn't change value\n" );
+ Cleanup();
+ }
+
+ if( 0 == memcmp( &( pcrBeforeExtend[0] ), &( pcrAfterExtend[0] ), 20 ) )
+ {
+ TpmClientPrintf( 0, "ERROR!! PCR didn't change value\n" );
+ Cleanup();
+ }
+
+ pcrSelection.pcrSelections[0].sizeofSelect = 4;
+
+ rval = Tss2_Sys_PCR_Read( sysContext, 0, &pcrSelection, &pcrUpdateCounterAfterExtend, 0, 0, 0 );
+ CheckFailed( rval, TPM_RC_1 + TPM_RC_P + TPM_RC_VALUE );
+
+ eventData.t.size = 4;
+ eventData.t.buffer[0] = 0;
+ eventData.t.buffer[1] = 0xff;
+ eventData.t.buffer[2] = 0x55;
+ eventData.t.buffer[3] = 0xaa;
+
+ rval = Tss2_Sys_PCR_Event( sysContext, PCR_18, &sessionsData, &eventData, &digests, 0 );
+ CheckPassed( rval );
+}
+
+void TestGetRandom()
+{
+ UINT32 rval;
+ TPM2B_DIGEST randomBytes1, randomBytes2;
+
+ TpmClientPrintf( 0, "\nGET_RANDOM TESTS:\n" );
+
+ rval = Tss2_Sys_GetRandom( sysContext, 0, 20, &randomBytes1, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetRandom( sysContext, 0, 20, &randomBytes2, 0 );
+ CheckPassed( rval );
+
+ if( 0 == memcmp( &randomBytes1, &randomBytes2, 20 ) )
+ {
+ TpmClientPrintf( 0, "ERROR!! Random value is the same\n" );
+ Cleanup();
+ }
+}
+
+void TestShutdown()
+{
+ UINT32 rval;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+ TPMS_AUTH_RESPONSE sessionDataOut;
+
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nSHUTDOWN TESTS:\n" );
+
+ rval = Tss2_Sys_Shutdown( sysContext, 0, TPM_SU_STATE, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_Shutdown( sysContext, 0, TPM_SU_CLEAR, &sessionsDataOut );
+ CheckPassed( rval );
+
+ if( !( tpmSpecVersion == 115 || tpmSpecVersion == 119 ) )
+ {
+ rval = Tss2_Sys_Shutdown( sysContext, 0, 0xff, 0 );
+ CheckFailed( rval, TPM_RC_VALUE+TPM_RC_1+TPM_RC_P );
+ }
+}
+
+void TestNV()
+{
+ UINT32 rval;
+ TPM2B_NV_PUBLIC publicInfo;
+ TPM2B_AUTH nvAuth;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+ int i;
+ TPM2B_MAX_NV_BUFFER nvWriteData;
+ TPM2B_MAX_NV_BUFFER nvData;
+
+ TPM2B_NV_PUBLIC nvPublic;
+ TPM2B_NAME nvName;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nNV INDEX TESTS:\n" );
+
+ nvAuth.t.size = 20;
+ for( i = 0; i < nvAuth.t.size; i++ )
+ nvAuth.t.buffer[i] = (UINT8)i;
+
+ publicInfo.t.size = sizeof( TPMI_RH_NV_INDEX ) +
+ sizeof( TPMI_ALG_HASH ) + sizeof( TPMA_NV ) + sizeof( UINT16) +
+ sizeof( UINT16 );
+ publicInfo.t.nvPublic.nvIndex = TPM20_INDEX_TEST1;
+ publicInfo.t.nvPublic.nameAlg = TPM_ALG_SHA1;
+
+ // First zero out attributes.
+ *(UINT32 *)&( publicInfo.t.nvPublic.attributes ) = 0;
+
+ // Now set the attributes.
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PPREAD = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PPWRITE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_WRITE_STCLEAR = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_ORDERLY = 1;
+ publicInfo.t.nvPublic.authPolicy.t.size = 0;
+ publicInfo.t.nvPublic.dataSize = 32;
+
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ rval = Tss2_Sys_NV_Read( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, 32, 0, &nvData, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_2 + TPM_RC_HANDLE );
+
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_PLATFORM, &sessionsData, &nvAuth, &publicInfo, &sessionsDataOut );
+ CheckPassed( rval );
+
+ nvPublic.t.size = 0;
+ rval = Tss2_Sys_NV_ReadPublic( sysContext, TPM20_INDEX_TEST1, 0, &nvPublic, &nvName, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Read( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, 32, 0, &nvData, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_NV_UNINITIALIZED );
+
+ // Should fail since index is already defined.
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_PLATFORM, &sessionsData, &nvAuth, &publicInfo, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_NV_DEFINED );
+
+ nvWriteData.t.size = 4;
+ for( i = 0; i < nvWriteData.t.size; i++ )
+ nvWriteData.t.buffer[i] = 0xff - i;
+
+#if 1
+ //
+ // Following, at one point, was commented out so that NVDefine will work on successive
+ // invocations of client app.
+ //
+ // Noticed on 12/13/12, this doesn't seem to be necessary anymore. Maybe something else
+ // I did fixed it.
+ //
+ // Seems to be a bug in TPM 2.0 simulator that if:
+ // First pass of tpmclient.exe after restarting TPM 2.0 simulator will work fine.
+ // If NVWrite is done, subsequent invocations of tpmclient.exe will ALWAYS fail on
+ // first call to Tpm2NVDefineSpace with 0x2cb error. Removing NVWrite removes this.
+ // And restarting TPM 2.0 simulator will make it work the first time and fail
+ // subsequent times.
+ // Removing NVWrite works around this problem.
+ //
+ rval = Tss2_Sys_NV_Write( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, &nvWriteData, 0, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Read( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, 32, 0, &nvData, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_WriteLock( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Write( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, &nvWriteData, 0, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_NV_LOCKED );
+#endif
+
+ // Now undefine the index.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_PLATFORM, &sessionsData, &nvAuth, &publicInfo, 0 );
+ CheckPassed( rval );
+
+ // Now undefine the index so that next run will work correctly.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, 0 );
+ CheckPassed( rval );
+
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PPREAD = 0;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PPWRITE = 0;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_OWNERREAD = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_OWNERWRITE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE = 0;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_ORDERLY = 1;
+ publicInfo.t.nvPublic.nvIndex = TPM20_INDEX_TEST2;
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_OWNER, &sessionsData, &nvAuth, &publicInfo, 0 );
+ CheckPassed( rval );
+
+ nvPublic.t.size = 0;
+ rval = Tss2_Sys_NV_ReadPublic( sysContext, TPM20_INDEX_TEST2, 0, &nvPublic, &nvName, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Read( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST2, &sessionsData, 32, 0, &nvData, 0 );
+ CheckFailed( rval, TPM_RC_NV_AUTHORIZATION );
+
+ // Now undefine the index.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_OWNER, TPM20_INDEX_TEST2, &sessionsData, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_OWNER, &sessionsData, &nvAuth, &publicInfo, 0 );
+ CheckPassed( rval );
+
+ // Now undefine the index so that next run will work correctly.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_OWNER, TPM20_INDEX_TEST2, &sessionsData, 0 );
+ CheckPassed( rval );
+
+#if 0
+ TpmClientPrintf( 0, "\nStart of NVUndefineSpaceSpecial test\n" );
+
+ // Init nonceNewer
+ digestSize = GetDigestSize( TPM_ALG_SHA1 );
+ nonceNewer.t.size = digestSize;
+ for( i = 0; i < nonceNewer.t.size; i++ )
+ nonceNewer.t.buffer[i] = 0;
+
+ // Init salt
+ salt.t.size = 0;
+
+ // Init symmetric.
+ symmetric.algorithm = TPM_ALG_NULL;
+ symmetric.keyBits.sym = 0;
+ symmetric.mode.sym = 0;
+ rval = Tss2_Sys_StartAuthSession ( sysContext, TPM_RH_NULL, TPM_RH_PLATFORM, 0, &nonceNewer, &salt,
+ TPM_SE_TRIAL, &symmetric, TPM_ALG_SHA1, &nvSessionHandle, &nvSessionNonce );
+ CheckPassed( rval );
+
+ nvSessionHandle = ( ( TPM20_StartAuthSession_Out *)(TpmOutBuff) )->sessionHandle;
+
+ rval = Tss2_Sys_PolicyCommandCode ( sysContext, nvSessionHandle, 0, TPM_CC_NV_UndefineSpaceSpecial, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_PolicyGetDigest( sysContext, nvSessionHandle, 0, &nvAuth1, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_FlushContext( sysContext, nvSessionHandle );
+
+ nvAuth1 = (TPM2B_AUTH *)&( ( ( TPM20_PolicyGetDigest_Out *)(TpmOutBuff) )->otherData );
+ publicInfo.t.nvPublic.authPolicy.t.size = nvAuth1->t.size;
+ memcpy( &( publicInfo.t.nvPublic.authPolicy.t.buffer[0] ),c
+ &( nvAuth1->t.buffer[0] ),
+ publicInfo.t.nvPublic.authPolicy.t.size );
+
+ publicInfo.t.nvPublic.attributes.TPMA_NV_POLICY_DELETE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PPREAD = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PPWRITE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_OWNERREAD = 0;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_OWNERWRITE = 0;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_ORDERLY = 1;
+
+ InitNullSession( &nvSession );
+
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_PLATFORM, &sessionsData, &nvAuth, &publicInfo, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_StartAuthSession ( sysContext, TPM_RH_NULL, TPM_RH_PLATFORM, 0, &nonceCaller, &salt,
+ TPM_SE_POLICY, &symmetric, TPM_ALG_SHA1, &nvSessionHandle, &nvSessionNonce );
+ CheckPassed( rval );
+
+ nvSession.sessionHandle = nvSessionHandle = ( ( TPM20_StartAuthSession_Out *)(TpmOutBuff) )->sessionHandle;
+
+ rval = Tss2_Sys_PolicyCommandCode ( sysContext, nvSessionHandle, 0, TPM_CC_NV_UndefineSpaceSpecial, 0 );
+ CheckPassed( rval );
+
+ nvSession->hmac = publicInfo.t.nvPublic.authPolicy;
+
+ nvSessions.cmdAuthsCount = 2;
+ nvSessions.session[0] = nvSession;
+
+ rval = Tss2_Sys_NVUndefineSpaceSpecial( sysContext, TPM20_INDEX_TEST2, TPM_RH_PLATFORM, &nvSessions, &sessionsData );
+ CheckPassed( rval );
+#endif
+}
+
+void TestHierarchyControl()
+{
+ UINT32 rval;
+ TPM2B_NV_PUBLIC publicInfo;
+ TPM2B_AUTH nvAuth;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+ int i;
+ TPM2B_NAME nvName;
+ TPM2B_NV_PUBLIC nvPublic;
+ TPM2B_MAX_NV_BUFFER nvData;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nHIERARCHY CONTROL TESTS:\n" );
+
+ nvAuth.t.size = 20;
+ for( i = 0; i < nvAuth.t.size; i++ )
+ nvAuth.t.buffer[i] = i;
+
+ publicInfo.t.size = sizeof( TPMI_RH_NV_INDEX ) +
+ sizeof( TPMI_ALG_HASH ) + sizeof( TPMA_NV ) + sizeof( UINT16) +
+ sizeof( UINT16 );
+ publicInfo.t.nvPublic.nvIndex = TPM20_INDEX_TEST1;
+ publicInfo.t.nvPublic.nameAlg = TPM_ALG_SHA1;
+
+ // First zero out attributes.
+ *(UINT32 *)&( publicInfo.t.nvPublic.attributes ) = 0;
+
+ // Now set the attributes.
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PPREAD = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PPWRITE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PPWRITE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_WRITE_STCLEAR = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_ORDERLY = 1;
+ publicInfo.t.nvPublic.authPolicy.t.size = 0;
+ publicInfo.t.nvPublic.dataSize = 32;
+
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_PLATFORM, &sessionsData, &nvAuth, &publicInfo, 0 );
+ CheckPassed( rval );
+
+ // Test SAPI for case where nvPublic.t.size != 0
+ nvPublic.t.size = 0xff;
+ rval = Tss2_Sys_NV_ReadPublic( sysContext, TPM20_INDEX_TEST1, 0, &nvPublic, &nvName, 0 );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_VALUE );
+
+ nvPublic.t.size = 0;
+ rval = Tss2_Sys_NV_ReadPublic( sysContext, TPM20_INDEX_TEST1, 0, &nvPublic, &nvName, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Read( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, 32, 0, &nvData, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_NV_UNINITIALIZED );
+
+ rval = Tss2_Sys_HierarchyControl( sysContext, TPM_RH_PLATFORM, &sessionsData, TPM_RH_PLATFORM, NO, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Read( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, 32, 0, &nvData, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_1 + TPM_RC_HIERARCHY );
+
+ rval = Tss2_Sys_HierarchyControl( sysContext, TPM_RH_PLATFORM, &sessionsData, TPM_RH_PLATFORM, YES, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_1 + TPM_RC_HIERARCHY );
+
+ // Need to do TPM reset and Startup to re-enable platform hierarchy.
+ rval = TpmReset();
+ CheckPassed(rval);
+
+ rval = Tss2_Sys_Startup ( sysContext, TPM_SU_CLEAR );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_HierarchyControl( sysContext, TPM_RH_PLATFORM, &sessionsData, TPM_RH_PLATFORM, YES, &sessionsDataOut );
+ CheckPassed( rval );
+
+ // Now undefine the index so that next run will work correctly.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &sessionsData, 0 );
+ CheckPassed( rval );
+}
+
+TPM2B_PUBLIC inPublic = { { sizeof( TPM2B_PUBLIC ) - 2, } };
+
+void TestCreate(){
+ UINT32 rval;
+ TPM2B_SENSITIVE_CREATE inSensitive = { { sizeof( TPM2B_SENSITIVE_CREATE ) - 2, } };
+ TPM2B_DATA outsideInfo = { { sizeof( TPM2B_DATA ) - 2, } };
+ TPML_PCR_SELECTION creationPCR;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+ TPM2B_NAME name = { { sizeof( TPM2B_NAME ) - 2, } };
+ TPM2B_NAME name1 = { { sizeof( TPM2B_NAME ) - 2, } };
+ TPM2B_PRIVATE outPrivate = { { sizeof( TPM2B_PRIVATE ) - 2, } };
+ TPM2B_PUBLIC outPublic = { { sizeof( TPM2B_PUBLIC ) - 2, } };
+ TPM2B_CREATION_DATA creationData = { { sizeof( TPM2B_CREATION_DATA ) - 2, } };
+ TPM2B_DIGEST creationHash = { { sizeof( TPM2B_DIGEST ) - 2, } };
+ TPMT_TK_CREATION creationTicket = { 0, 0, { { sizeof( TPM2B_DIGEST ) - 2, } } };
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nCREATE, CREATE PRIMARY, and LOAD TESTS:\n" );
+
+ inSensitive.t.sensitive.userAuth = loadedSha1KeyAuth;
+ inSensitive.t.sensitive.userAuth = loadedSha1KeyAuth;
+ inSensitive.t.sensitive.data.t.size = 0;
+ inSensitive.t.size = loadedSha1KeyAuth.b.size + 2;
+
+ inPublic.t.publicArea.type = TPM_ALG_RSA;
+ inPublic.t.publicArea.nameAlg = TPM_ALG_SHA1;
+
+ // First clear attributes bit field.
+ *(UINT32 *)&( inPublic.t.publicArea.objectAttributes) = 0;
+ inPublic.t.publicArea.objectAttributes.restricted = 1;
+ inPublic.t.publicArea.objectAttributes.userWithAuth = 1;
+ inPublic.t.publicArea.objectAttributes.decrypt = 1;
+ inPublic.t.publicArea.objectAttributes.fixedTPM = 1;
+ inPublic.t.publicArea.objectAttributes.fixedParent = 1;
+ inPublic.t.publicArea.objectAttributes.sensitiveDataOrigin = 1;
+
+ inPublic.t.publicArea.authPolicy.t.size = 0;
+
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_ECB;
+ inPublic.t.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
+ inPublic.t.publicArea.parameters.rsaDetail.keyBits = 1024;
+ inPublic.t.publicArea.parameters.rsaDetail.exponent = 0;
+
+ inPublic.t.publicArea.unique.rsa.t.size = 0;
+
+ outsideInfo.t.size = 0;
+ creationPCR.count = 0;
+
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ inPublic.t.publicArea.parameters.rsaDetail.keyBits = 2048;
+
+ // Do SAPI test for non-zero sized outPublic
+ outPublic.t.size = 0xff;
+ creationData.t.size = 0;
+ rval = Tss2_Sys_CreatePrimary( sysContext, TPM_RH_PLATFORM, &sessionsData, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR, &handle2048rsa, &outPublic, &creationData, &creationHash,
+ &creationTicket, &name, &sessionsDataOut );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_VALUE );
+
+ rval = Tss2_Sys_FlushContext( sysContext, handle2048rsa );
+ CheckPassed( rval );
+#if 0
+ // Do SAPI test for non-zero sized creationData
+ outPublic.t.size = 0;
+ creationData.t.size = 0x10;
+ rval = Tss2_Sys_CreatePrimary( sysContext, TPM_RH_PLATFORM, &sessionsData, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR, &handle2048rsa, &outPublic, &creationData, &creationHash,
+ &creationTicket, &name, &sessionsDataOut );
+ CheckFailed( rval, TSS2_SYS_RC_INSUFFICIENT_BUFFER );
+#endif
+
+ outPublic.t.size = 0;
+ creationData.t.size = sizeof( TPM2B_CREATION_DATA ) - 2;
+ outPublic.t.publicArea.authPolicy.t.size = sizeof( TPM2B_DIGEST ) - 2;
+ outPublic.t.publicArea.unique.keyedHash.t.size = sizeof( TPM2B_DIGEST ) - 2;
+ rval = Tss2_Sys_CreatePrimary( sysContext, TPM_RH_PLATFORM, &sessionsData, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR, &handle2048rsa, &outPublic, &creationData, &creationHash,
+ &creationTicket, &name, &sessionsDataOut );
+ CheckPassed( rval );
+
+ TpmClientPrintf( 0, "\nNew key successfully created in platform hierarchy (RSA 2048). Handle: 0x%8.8x\n",
+ handle2048rsa );
+
+ sessionData.hmac.t.size = 2;
+ sessionData.hmac.t.buffer[0] = 0x00;
+ sessionData.hmac.t.buffer[1] = 0xff;
+
+ inPublic.t.publicArea.type = TPM_ALG_KEYEDHASH;
+ inPublic.t.publicArea.objectAttributes.decrypt = 0;
+ inPublic.t.publicArea.objectAttributes.sign = 1;
+
+ inPublic.t.publicArea.parameters.keyedHashDetail.scheme.scheme = TPM_ALG_HMAC;
+ inPublic.t.publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = TPM_ALG_SHA1;
+
+ inPublic.t.publicArea.unique.keyedHash.t.size = 0;
+
+ outsideInfo.t.size = 0;
+ outPublic.t.size = 0;
+ creationData.t.size = 0;
+ rval = Tss2_Sys_Create( sysContext, handle2048rsa, &sessionsData, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR,
+ &outPrivate, &outPublic, &creationData,
+ &creationHash, &creationTicket, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_Load ( sysContext, handle2048rsa, &sessionsData, &outPrivate, &outPublic,
+ &loadedSha1KeyHandle, &name, &sessionsDataOut);
+ CheckPassed( rval );
+
+ rval = (*HandleToNameFunctionPtr)( loadedSha1KeyHandle, &name1 );
+ CheckPassed( rval );
+ OpenOutFile( &outFp );
+ TpmClientPrintf( 0, "Name of loaded key: " );
+ PrintSizedBuffer( (TPM2B *)&name1 );
+ CloseOutFile( &outFp );
+
+ rval = CompareTPM2B( &name.b, &name1.b );
+ CheckPassed( rval );
+
+ TpmClientPrintf( 0, "\nLoaded key handle: %8.8x\n", loadedSha1KeyHandle );
+}
+
+void TestEvict()
+{
+ TPM_RC rval = TPM_RC_SUCCESS;
+ TPM2B_SENSITIVE_CREATE inSensitive = { { sizeof( TPM2B_SENSITIVE_CREATE ) - 2, } };
+ TPM2B_DATA outsideInfo = { { sizeof( TPM2B_DATA ) - 2, } };
+ TPML_PCR_SELECTION creationPCR;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+
+ TPM2B_PRIVATE outPrivate = { { sizeof( TPM2B_PRIVATE ) - 2, } };
+ TPM2B_PUBLIC outPublic = { { sizeof( TPM2B_PUBLIC ) - 2, } };
+ TPM2B_CREATION_DATA creationData = { { sizeof( TPM2B_CREATION_DATA ) - 2, } };
+ TPM2B_DIGEST creationHash = { { sizeof( TPM2B_DIGEST ) - 2, } };
+ TPMT_TK_CREATION creationTicket = { 0, 0, { { sizeof( TPM2B_DIGEST ) - 2, } } };
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ TSS2_TCTI_CONTEXT *otherResMgrTctiContext = 0;
+ TSS2_SYS_CONTEXT *otherSysContext;
+ char otherResMgrInterfaceName[] = "Other Resource Manager";
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+ sessionsData.cmdAuthsCount = 1;
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ outsideInfo.t.size = 0;
+ creationPCR.count = 0;
+
+ TpmClientPrintf( 0, "\nEVICT CONTROL TESTS:\n" );
+
+ // Make transient key persistent.
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ rval = Tss2_Sys_EvictControl( sysContext, TPM_RH_PLATFORM, handle2048rsa, &sessionsData, 0x81800000, &sessionsDataOut );
+ CheckPassed( rval );
+
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ // Create new key under persistent one.
+ sessionData.hmac.t.size = 2;
+ sessionData.hmac.t.buffer[0] = 0x00;
+ sessionData.hmac.t.buffer[1] = 0xff;
+
+ inPublic.t.publicArea.nameAlg = TPM_ALG_SHA1;
+ inPublic.t.publicArea.type = TPM_ALG_KEYEDHASH;
+ inPublic.t.publicArea.objectAttributes.decrypt = 0;
+ inPublic.t.publicArea.objectAttributes.sign = 1;
+
+ inPublic.t.publicArea.parameters.keyedHashDetail.scheme.scheme = TPM_ALG_HMAC;
+ inPublic.t.publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = TPM_ALG_SHA1;
+
+ inPublic.t.publicArea.unique.keyedHash.t.size = 0;
+
+ inSensitive.t.sensitive.userAuth = loadedSha1KeyAuth;
+ inSensitive.t.sensitive.userAuth = loadedSha1KeyAuth;
+ inSensitive.t.sensitive.data.t.size = 0;
+ inSensitive.t.size = loadedSha1KeyAuth.b.size + 2;
+
+ outsideInfo.t.size = 0;
+ outPublic.t.size = 0;
+ creationData.t.size = 0;
+
+ // Try creating a key under the persistent key using a different context.
+
+ rval = InitTctiResMgrContext( rmInterfaceConfig, &otherResMgrTctiContext, &otherResMgrInterfaceName[0] );
+ if( rval != TSS2_RC_SUCCESS )
+ {
+ TpmClientPrintf( 0, "Resource Mgr, %s, failed initialization: 0x%x. Exiting...\n", resMgrInterfaceInfo.shortName, rval );
+ Cleanup();
+ return;
+ }
+ else
+ {
+ (( TSS2_TCTI_CONTEXT_INTEL *)otherResMgrTctiContext )->status.debugMsgLevel = debugLevel;
+ }
+
+ otherSysContext = InitSysContext( 0, otherResMgrTctiContext, &abiVersion );
+ if( otherSysContext == 0 )
+ {
+ InitSysContextFailure();
+ }
+
+ rval = Tss2_Sys_Create( otherSysContext, 0x81800000, &sessionsData, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR,
+ &outPrivate, &outPublic, &creationData,
+ &creationHash, &creationTicket, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = TeardownTctiResMgrContext( rmInterfaceConfig, otherResMgrTctiContext, &otherResMgrInterfaceName[0] );
+ CheckPassed( rval );
+
+ TeardownSysContext( &otherSysContext );
+
+ outsideInfo.t.size = 0;
+ outPublic.t.size = 0;
+ creationData.t.size = 0;
+
+ // Try creating a key under the transient key. This should work, too.
+ rval = Tss2_Sys_Create( sysContext, handle2048rsa, &sessionsData, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR,
+ &outPrivate, &outPublic, &creationData,
+ &creationHash, &creationTicket, &sessionsDataOut );
+ CheckPassed( rval );
+
+ // Reset persistent key to be transitent.
+ sessionData.hmac.t.size = 0;
+ rval = Tss2_Sys_EvictControl( sysContext, TPM_RH_PLATFORM, 0x81800000, &sessionsData, 0x81800000, &sessionsDataOut );
+ CheckPassed( rval );
+}
+
+TPM_RC DefineNvIndex( TPMI_RH_PROVISION authHandle, TPMI_SH_AUTH_SESSION sessionAuthHandle, TPM2B_AUTH *auth, TPM2B_DIGEST *authPolicy,
+ TPMI_RH_NV_INDEX nvIndex, TPMI_ALG_HASH nameAlg, TPMA_NV attributes, UINT16 size )
+{
+ TPM_RC rval = TPM_RC_SUCCESS;
+ TPM2B_NV_PUBLIC publicInfo;
+
+ // Command and response session data structures.
+ TPMS_AUTH_COMMAND sessionData = { sessionAuthHandle, };
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TPMS_AUTH_COMMAND *sessionDataArray[1] = { &sessionData };
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1] = { &sessionDataOut };
+ TSS2_SYS_CMD_AUTHS sessionsData = { 1, &sessionDataArray[0] };
+ TSS2_SYS_RSP_AUTHS sessionsDataOut = { 1, &sessionDataOutArray[0] };
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+ // init hmac
+ sessionData.hmac.t.size = 0;
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ attributes.TPMA_NV_ORDERLY = 1;
+
+ // Init public info structure.
+ publicInfo.t.nvPublic.attributes = attributes;
+ CopySizedByteBuffer( &publicInfo.t.nvPublic.authPolicy.b, &authPolicy->b );
+ publicInfo.t.nvPublic.dataSize = size;
+ publicInfo.t.size = sizeof( TPMI_RH_NV_INDEX ) +
+ sizeof( TPMI_ALG_HASH ) + sizeof( TPMA_NV ) + sizeof( UINT16) +
+ sizeof( UINT16 );
+ publicInfo.t.nvPublic.nvIndex = nvIndex;
+ publicInfo.t.nvPublic.nameAlg = nameAlg;
+
+ // Create the index
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, authHandle, &sessionsData, auth, &publicInfo, &sessionsDataOut );
+
+ return rval;
+}
+
+typedef struct {
+ char name[50];
+ TPM_RC (*buildPolicyFn )( TSS2_SYS_CONTEXT *sysContext, SESSION *trialPolicySession, TPM2B_DIGEST *policyDigest );
+ TPM_RC (*createObjectFn )( TSS2_SYS_CONTEXT *sysContext, SESSION **policySession, TPM2B_DIGEST *policyDigest );
+ TPM_RC (*testPolicyFn )( TSS2_SYS_CONTEXT *sysContext, SESSION *policySession );
+} POLICY_TEST_SETUP;
+
+TPM_RC BuildPolicy( TSS2_SYS_CONTEXT *sysContext, SESSION **policySession,
+ TPM_RC (*buildPolicyFn )( TSS2_SYS_CONTEXT *sysContext, SESSION *policySession, TPM2B_DIGEST *policyDigest ),
+ TPM2B_DIGEST *policyDigest, bool trialSession )
+{
+ // NOTE: this policySession will be either a trial or normal policy session
+ // depending on the value of the passed in trialSession parameter.
+ TPM2B_ENCRYPTED_SECRET encryptedSalt = { {0}, };
+ TPMT_SYM_DEF symmetric;
+ TPM_RC rval;
+ TPM2B_NONCE nonceCaller;
+
+ nonceCaller.t.size = 0;
+
+ // Start policy session.
+ symmetric.algorithm = TPM_ALG_NULL;
+ rval = StartAuthSessionWithParams( policySession, TPM_RH_NULL, 0, TPM_RH_NULL, 0, &nonceCaller, &encryptedSalt, trialSession ? TPM_SE_TRIAL : TPM_SE_POLICY , &symmetric, TPM_ALG_SHA256 );
+ if( rval != TPM_RC_SUCCESS )
+ return rval;
+
+ // Send policy command.
+ rval = ( *buildPolicyFn )( sysContext, *policySession, policyDigest );
+ CheckPassed( rval );
+
+ // Get policy hash.
+ rval = Tss2_Sys_PolicyGetDigest( sysContext, (*policySession)->sessionHandle,
+ 0, policyDigest, 0 );
+ CheckPassed( rval );
+
+ if( trialSession )
+ {
+ // Need to flush the session here.
+ rval = Tss2_Sys_FlushContext( sysContext, (*policySession)->sessionHandle );
+ CheckPassed( rval );
+
+ // And remove the session from sessions table.
+ rval = EndAuthSession( *policySession );
+ CheckPassed( rval );
+ }
+
+ return rval;
+}
+
+TPM_RC CreateNVIndex( TSS2_SYS_CONTEXT *sysContext, SESSION **policySession, TPM2B_DIGEST *policyDigest )
+{
+ TPM_RC rval = TPM_RC_SUCCESS;
+ TPMA_LOCALITY locality;
+ TPM2B_ENCRYPTED_SECRET encryptedSalt = { {0}, };
+ TPMT_SYM_DEF symmetric;
+ TPMA_NV nvAttributes;
+ TPM2B_AUTH nvAuth;
+ TPM2B_NONCE nonceCaller;
+
+ nonceCaller.t.size = 0;
+
+ // Since locality is a fairly simple command and we can guarantee
+ // its correctness, we don't need a trial session for this.
+
+ // Start real policy session
+ symmetric.algorithm = TPM_ALG_NULL;
+ rval = StartAuthSessionWithParams( policySession, TPM_RH_NULL,
+ 0, TPM_RH_NULL, 0, &nonceCaller, &encryptedSalt, TPM_SE_POLICY,
+ &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+
+ // Send PolicyLocality command
+ *(UINT8 *)( (void *)&locality ) = 0;
+ locality.TPM_LOC_THREE = 1;
+ rval = Tss2_Sys_PolicyLocality( sysContext, (*policySession)->sessionHandle,
+ 0, locality, 0 );
+ CheckPassed( rval );
+
+ // Read policyHash
+ rval = Tss2_Sys_PolicyGetDigest( sysContext,
+ (*policySession)->sessionHandle, 0, policyDigest, 0 );
+ CheckPassed( rval );
+
+ nvAuth.t.size = 0;
+
+ // Now set the attributes.
+ *(UINT32 *)( (void *)&nvAttributes ) = 0;
+ nvAttributes.TPMA_NV_POLICYREAD = 1;
+ nvAttributes.TPMA_NV_POLICYWRITE = 1;
+ nvAttributes.TPMA_NV_PLATFORMCREATE = 1;
+
+ rval = DefineNvIndex( TPM_RH_PLATFORM, TPM_RS_PW, &nvAuth, policyDigest,
+ TPM20_INDEX_PASSWORD_TEST, TPM_ALG_SHA256, nvAttributes, 32 );
+ CheckPassed( rval );
+
+ AddEntity( TPM20_INDEX_PASSWORD_TEST, &nvAuth );
+ CheckPassed( rval );
+
+ return rval;
+}
+
+
+TPM_RC TestLocality( TSS2_SYS_CONTEXT *sysContext, SESSION *policySession )
+{
+ TSS2_RC rval = TPM_RC_SUCCESS;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ TPM2B_MAX_NV_BUFFER nvWriteData;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut = { 1, };
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ // Init write data.
+ nvWriteData.t.size = 0;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0]->sessionHandle = policySession->sessionHandle;
+ sessionsData.cmdAuths[0]->nonce.t.size = 0;
+ sessionsData.cmdAuths[0]->hmac.t.size = 0;
+
+ *(UINT8 *)( (void *)&( sessionsData.cmdAuths[0]->sessionAttributes ) ) = 0;
+ sessionsData.cmdAuths[0]->sessionAttributes.continueSession = 1;
+
+ rval = SetLocality( sysContext, 2 );
+ CheckPassed( rval );
+
+ // Do NV write using open session's policy.
+ rval = Tss2_Sys_NV_Write( sysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &sessionsData, &nvWriteData, 0, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_LOCALITY );
+
+ rval = SetLocality( sysContext, 3 );
+ CheckPassed( rval );
+
+ // Do NV write using open session's policy.
+ rval = Tss2_Sys_NV_Write( sysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &sessionsData, &nvWriteData, 0, &sessionsDataOut );
+ CheckPassed( rval );
+
+ // Do another NV write using open session's policy.
+ rval = Tss2_Sys_NV_Write( sysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &sessionsData, &nvWriteData, 0, &sessionsDataOut );
+ CheckFailed( rval, TPM_RC_POLICY_FAIL + TPM_RC_S + TPM_RC_1 );
+
+ // Delete NV index
+ sessionsData.cmdAuths[0]->sessionHandle = TPM_RS_PW;
+ sessionsData.cmdAuths[0]->nonce.t.size = 0;
+ sessionsData.cmdAuths[0]->nonce.t.buffer[0] = 0xa5;
+ sessionData.hmac.t.size = 0;
+
+ // Now undefine the index.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_PLATFORM,
+ TPM20_INDEX_PASSWORD_TEST, &sessionsData, 0 );
+ CheckPassed( rval );
+
+ rval = DeleteEntity( TPM20_INDEX_PASSWORD_TEST );
+ CheckPassed( rval );
+
+ return rval;
+}
+
+UINT8 passwordPCRTestPassword[] = "password PCR";
+UINT8 dataBlob[] = "some data";
+TPM_HANDLE blobHandle;
+TPM2B_AUTH blobAuth;
+
+TPM_RC BuildPasswordPolicy( TSS2_SYS_CONTEXT *sysContext, SESSION *policySession, TPM2B_DIGEST *policyDigest )
+{
+ TPM_RC rval = TPM_RC_SUCCESS;
+
+ rval = Tss2_Sys_PolicyPassword( sysContext, policySession->sessionHandle, 0, 0 );
+ CheckPassed( rval );
+
+ return rval;
+}
+
+TPM_RC BuildAuthValuePolicy( TSS2_SYS_CONTEXT *sysContext, SESSION *policySession, TPM2B_DIGEST *policyDigest )
+{
+ TPM_RC rval = TPM_RC_SUCCESS;
+
+ rval = Tss2_Sys_PolicyAuthValue( sysContext, policySession->sessionHandle, 0, 0 );
+ CheckPassed( rval );
+
+ return rval;
+}
+
+
+TPM_RC BuildPasswordPcrPolicy( TSS2_SYS_CONTEXT *sysContext, SESSION *policySession, TPM2B_DIGEST *policyDigest )
+{
+ TPM_RC rval = TPM_RC_SUCCESS;
+ TPM2B_DIGEST pcrDigest;
+ TPML_PCR_SELECTION pcrs;
+ TPML_DIGEST pcrValues;
+ UINT32 pcrUpdateCounter;
+ TPML_PCR_SELECTION pcrSelectionOut;
+
+ pcrDigest.t.size = 0;
+ rval = Tss2_Sys_PolicyPassword( sysContext, policySession->sessionHandle, 0, 0 );
+ CheckPassed( rval );
+
+ pcrs.count = 1;
+ pcrs.pcrSelections[0].hash = TPM_ALG_SHA1;
+ pcrs.pcrSelections[0].sizeofSelect = 3;
+ pcrs.pcrSelections[0].pcrSelect[0] = 0;
+ pcrs.pcrSelections[0].pcrSelect[1] = 0;
+ pcrs.pcrSelections[0].pcrSelect[2] = 0;
+ SET_PCR_SELECT_BIT( pcrs.pcrSelections[0], PCR_0 );
+ SET_PCR_SELECT_BIT( pcrs.pcrSelections[0], PCR_3 );
+
+ //
+ // Compute pcrDigest
+ //
+ // Read PCRs
+ rval = Tss2_Sys_PCR_Read( sysContext, 0, &pcrs, &pcrUpdateCounter, &pcrSelectionOut, &pcrValues, 0 );
+ CheckPassed( rval );
+ // Hash them together
+ rval = TpmHashSequence( policySession->authHash, pcrValues.count, &pcrValues.digests[0], &pcrDigest );
+
+ rval = Tss2_Sys_PolicyPCR( sysContext, policySession->sessionHandle, 0, &pcrDigest, &pcrs, 0 );
+ CheckPassed( rval );
+
+ return rval;
+}
+
+
+TPM_RC CreateDataBlob( TSS2_SYS_CONTEXT *sysContext, SESSION **policySession, TPM2B_DIGEST *policyDigest )
+{
+ TPM_RC rval = TPM_RC_SUCCESS;
+ TPMS_AUTH_COMMAND cmdAuth;
+ TPMS_AUTH_COMMAND *cmdSessionArray[1] = { &cmdAuth };
+ TSS2_SYS_CMD_AUTHS cmdAuthArray = { 1, &cmdSessionArray[0] };
+ TPM2B_SENSITIVE_CREATE inSensitive;
+ TPM2B_PUBLIC inPublic;
+ TPM2B_DATA outsideInfo = { { 0, } };
+ TPML_PCR_SELECTION creationPcr = { 0 };
+ TPM2B_PUBLIC outPublic;
+ TPM2B_CREATION_DATA creationData;
+ TPM_HANDLE srkHandle;
+ TPM2B_DIGEST creationHash;
+ TPMT_TK_CREATION creationTicket;
+ TPM2B_NAME srkName, blobName;
+ TPM2B_DIGEST data;
+ TPM2B_PRIVATE outPrivate;
+
+ cmdAuth.sessionHandle = TPM_RS_PW;
+ cmdAuth.nonce.t.size = 0;
+ *( (UINT8 *)((void *)&cmdAuth.sessionAttributes ) ) = 0;
+ cmdAuth.hmac.t.size = 0;
+
+ inSensitive.t.sensitive.userAuth.t.size = 0;
+ inSensitive.t.sensitive.data.t.size = 0;
+
+ inPublic.t.publicArea.type = TPM_ALG_RSA;
+ inPublic.t.publicArea.nameAlg = TPM_ALG_SHA1;
+ *(UINT32 *)&( inPublic.t.publicArea.objectAttributes) = 0;
+ inPublic.t.publicArea.objectAttributes.restricted = 1;
+ inPublic.t.publicArea.objectAttributes.userWithAuth = 1;
+ inPublic.t.publicArea.objectAttributes.decrypt = 1;
+ inPublic.t.publicArea.objectAttributes.fixedTPM = 1;
+ inPublic.t.publicArea.objectAttributes.fixedParent = 1;
+ inPublic.t.publicArea.objectAttributes.sensitiveDataOrigin = 1;
+ inPublic.t.publicArea.authPolicy.t.size = 0;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CBC;
+ inPublic.t.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
+ inPublic.t.publicArea.parameters.rsaDetail.keyBits = 2048;
+ inPublic.t.publicArea.parameters.rsaDetail.exponent = 0;
+ inPublic.t.publicArea.unique.rsa.t.size = 0;
+
+ outPublic.t.size = 0;
+ creationData.t.size = 0;
+ rval = Tss2_Sys_CreatePrimary( sysContext, TPM_RH_PLATFORM, &cmdAuthArray,
+ &inSensitive, &inPublic, &outsideInfo, &creationPcr,
+ &srkHandle, &outPublic, &creationData, &creationHash,
+ &creationTicket, &srkName, 0 );
+ CheckPassed( rval );
+
+ cmdAuth.sessionHandle = TPM_RS_PW;
+
+ inSensitive.t.sensitive.userAuth.t.size = 0;
+ blobAuth.t.size = sizeof( passwordPCRTestPassword );
+ memcpy( &blobAuth.t.buffer, passwordPCRTestPassword, sizeof( passwordPCRTestPassword ) );
+ CopySizedByteBuffer( &(inSensitive.t.sensitive.userAuth.b ), &blobAuth.b );
+ data.t.size = sizeof( dataBlob );
+ memcpy( &data.t.buffer, dataBlob, sizeof( dataBlob ) );
+ CopySizedByteBuffer( &(inSensitive.t.sensitive.data.b ), &data.b );
+
+ inPublic.t.publicArea.type = TPM_ALG_KEYEDHASH;
+ inPublic.t.publicArea.nameAlg = TPM_ALG_SHA256;
+ inPublic.t.publicArea.objectAttributes.restricted = 0;
+ inPublic.t.publicArea.objectAttributes.decrypt = 0;
+ inPublic.t.publicArea.objectAttributes.sensitiveDataOrigin = 0;
+ CopySizedByteBuffer( &( inPublic.t.publicArea.authPolicy.b), &( policyDigest->b ) );
+ inPublic.t.publicArea.parameters.keyedHashDetail.scheme.scheme = TPM_ALG_NULL;
+ inPublic.t.publicArea.unique.keyedHash.t.size = 0;
+
+ outPublic.t.size = 0;
+ creationData.t.size = 0;
+ rval = Tss2_Sys_Create( sysContext, srkHandle, &cmdAuthArray,
+ &inSensitive, &inPublic, &outsideInfo, &creationPcr,
+ &outPrivate, &outPublic, &creationData, &creationHash,
+ &creationTicket, 0 );
+ CheckPassed( rval );
+
+ // Now we need to load the object.
+ rval = Tss2_Sys_Load( sysContext, srkHandle, &cmdAuthArray, &outPrivate, &outPublic, &blobHandle, &blobName, 0 );
+ CheckPassed( rval );
+
+ return rval;
+}
+
+TPM_RC AuthValueUnseal( TSS2_SYS_CONTEXT *sysContext, SESSION *policySession )
+{
+ TPM_RC rval = TPM_RC_SUCCESS;
+ TPM2B_SENSITIVE_DATA outData;
+ TPMS_AUTH_COMMAND cmdAuth;
+ TPMS_AUTH_COMMAND *cmdSessionArray[1] = { &cmdAuth };
+ TSS2_SYS_CMD_AUTHS cmdAuthArray = { 1, &cmdSessionArray[0] };
+
+ cmdAuth.sessionHandle = policySession->sessionHandle;
+ cmdAuth.nonce.t.size = 0;
+ *( (UINT8 *)((void *)&cmdAuth.sessionAttributes ) ) = 0;
+ cmdAuth.sessionAttributes.continueSession = 1;
+ cmdAuth.hmac.t.size = 0;
+
+ // Now try to unseal the blob without setting the HMAC.
+ // This test should fail.
+ rval = Tss2_Sys_Unseal( sysContext, blobHandle, &cmdAuthArray, &outData, 0 );
+ CheckFailed( rval, TPM_RC_S + TPM_RC_1 + TPM_RC_AUTH_FAIL );
+
+ // Clear DA lockout.
+ TestDictionaryAttackLockReset();
+
+ //
+ // Now try to unseal the blob after setting the HMAC.
+ // This test should pass.
+ //
+
+ // First, call Prepare.
+ rval = Tss2_Sys_Unseal_Prepare( sysContext, blobHandle );
+ CheckPassed( rval );
+
+ rval = AddEntity( blobHandle, &blobAuth );
+ CheckPassed( rval );
+
+ // Roll nonces for command.
+ RollNonces( policySession, &cmdAuth.nonce );
+
+ // Now generate the HMAC.
+ rval = ComputeCommandHmacs( sysContext,
+ blobHandle,
+ TPM_HT_NO_HANDLE, &cmdAuthArray, 1 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_Unseal( sysContext, blobHandle, &cmdAuthArray, &outData, 0 );
+ CheckPassed( rval );
+
+ rval = DeleteEntity( blobHandle );
+ CheckPassed( rval );
+
+ // Add test to make sure we unsealed correctly.
+
+ // Now we'll want to flush the data blob and remove it
+ // from resource manager tables.
+ rval = Tss2_Sys_FlushContext( sysContext, blobHandle );
+ CheckPassed( rval );
+
+ return rval;
+}
+
+TPM_RC PasswordUnseal( TSS2_SYS_CONTEXT *sysContext, SESSION *policySession )
+{
+ TPM_RC rval = TPM_RC_SUCCESS;
+ TPM2B_SENSITIVE_DATA outData;
+ TPMS_AUTH_COMMAND cmdAuth;
+ TPMS_AUTH_COMMAND *cmdSessionArray[1] = { &cmdAuth };
+ TSS2_SYS_CMD_AUTHS cmdAuthArray = { 1, &cmdSessionArray[0] };
+
+ cmdAuth.sessionHandle = policySession->sessionHandle;
+ cmdAuth.nonce.t.size = 0;
+ *( (UINT8 *)((void *)&cmdAuth.sessionAttributes ) ) = 0;
+ cmdAuth.sessionAttributes.continueSession = 1;
+ cmdAuth.hmac.t.size = 0;
+
+ // Now try to unseal the blob without setting the password.
+ // This test should fail.
+ rval = Tss2_Sys_Unseal( sysContext, blobHandle, &cmdAuthArray, &outData, 0 );
+ CheckFailed( rval, TPM_RC_S + TPM_RC_1 + TPM_RC_AUTH_FAIL );
+
+ // Clear DA lockout.
+ TestDictionaryAttackLockReset();
+
+ // Now try to unseal the blob after setting the password.
+ // This test should pass.
+ cmdAuth.hmac.t.size = sizeof( passwordPCRTestPassword );
+ memcpy( &cmdAuth.hmac.t.buffer, passwordPCRTestPassword, sizeof( passwordPCRTestPassword ) );
+ rval = Tss2_Sys_Unseal( sysContext, blobHandle, &cmdAuthArray, &outData, 0 );
+ CheckPassed( rval );
+
+ // Add test to make sure we unsealed correctly.
+
+ // Now we'll want to flush the data blob and remove it
+ // from resource manager tables.
+ rval = Tss2_Sys_FlushContext( sysContext, blobHandle );
+ CheckPassed( rval );
+
+ return rval;
+}
+
+POLICY_TEST_SETUP policyTestSetups[] =
+{
+ // NOTE: Since locality is a fairly simple command and we
+ // can guarantee its correctness, we don't need a trial
+ // session for this. buildPolicyFn pointer can be 0 in
+ // this case.
+ { "LOCALITY", 0, CreateNVIndex, TestLocality },
+ { "PASSWORD", BuildPasswordPolicy, CreateDataBlob, PasswordUnseal },
+ { "PASSWORD/PCR", BuildPasswordPcrPolicy, CreateDataBlob, PasswordUnseal },
+ { "AUTHVALUE", BuildAuthValuePolicy, CreateDataBlob, AuthValueUnseal },
+ // TBD...
+};
+
+void TestPolicy()
+{
+ UINT32 rval;
+ unsigned int i;
+ SESSION *policySession = 0;
+
+ TpmClientPrintf( 0, "\nPOLICY TESTS:\n" );
+
+ for( i = 0; i < ( sizeof( policyTestSetups ) / sizeof( POLICY_TEST_SETUP ) ); i++ )
+ {
+ TPM2B_DIGEST policyDigest;
+
+ rval = TPM_RC_SUCCESS;
+
+ TpmClientPrintf( 0, "Policy Test: %s\n", policyTestSetups[i].name );
+
+ // Create trial policy session and run policy commands, in order to create policyDigest.
+ if( policyTestSetups[i].buildPolicyFn != 0)
+ {
+ rval = BuildPolicy( sysContext, &policySession, policyTestSetups[i].buildPolicyFn, &policyDigest, true );
+ CheckPassed( rval );
+ }
+
+ // Create entity that will use that policyDigest as authPolicy.
+ if( policyTestSetups[i].createObjectFn != 0 )
+ {
+ rval = ( *policyTestSetups[i].createObjectFn )( sysContext, &policySession, &policyDigest);
+ CheckPassed( rval );
+ }
+
+ // Create real policy session and run policy commands; after this we're ready
+ // to authorize actions on the entity.
+ if( policyTestSetups[i].buildPolicyFn != 0)
+ {
+ rval = BuildPolicy( sysContext, &policySession, policyTestSetups[i].buildPolicyFn, &policyDigest, false );
+ CheckPassed( rval );
+ }
+
+ if( policySession )
+ {
+ // Now do tests by authorizing actions on the entity.
+ rval = ( *policyTestSetups[i].testPolicyFn)( sysContext, policySession );
+ CheckPassed( rval );
+
+ // Need to flush the session here.
+ rval = Tss2_Sys_FlushContext( sysContext, policySession->sessionHandle );
+ CheckPassed( rval );
+
+ // And remove the session from test app session table.
+ rval = EndAuthSession( policySession );
+ }
+ else
+ {
+ CheckFailed( rval, 0xffffffff );
+ }
+
+ CheckPassed( rval );
+ }
+}
+
+#define MAX_TEST_SEQUENCES 10
+void TestHash()
+{
+ UINT32 rval;
+ TPM2B_AUTH auth;
+ TPMI_DH_OBJECT sequenceHandle[MAX_TEST_SEQUENCES];
+ TPMS_AUTH_COMMAND sessionData, sessionData1;
+ TPMS_AUTH_RESPONSE sessionDataOut, sessionDataOut1;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ int i;
+ TPM2B_MAX_BUFFER dataToHash;
+
+ UINT8 memoryToHash[] =
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0xde, 0xad, 0xbe, 0xef
+ };
+
+ // Known good hash of above memory.
+ UINT8 goodHashValue[] =
+ { 0xB3, 0xFD, 0x6A, 0xD2, 0x9F, 0xD0, 0x13, 0x52, 0xBA, 0xFC,
+ 0x8B, 0x22, 0xC9, 0x6D, 0x88, 0x42, 0xA3, 0x3C, 0xB0, 0xC9 };
+
+ // Hash to be calculated by TPM.
+ TPM2B_DIGEST result;
+ TPMT_TK_HASHCHECK validation;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[2];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[2];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+ sessionDataArray[1] = &sessionData1;
+ sessionDataOutArray[1] = &sessionDataOut1;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nHASH TESTS:\n" );
+
+ auth.t.size = 2;
+ auth.t.buffer[0] = 0;
+ auth.t.buffer[1] = 0xff;
+ rval = Tss2_Sys_HashSequenceStart ( sysContext, 0, &auth, TPM_ALG_SHA1, &sequenceHandle[0], 0 );
+ CheckPassed( rval );
+
+ // Init authHandle
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac = auth;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ dataToHash.t.size = MAX_DIGEST_BUFFER;
+ memcpy( &dataToHash.t.buffer[0], &memoryToHash[0], dataToHash.t.size );
+
+ rval = Tss2_Sys_SequenceUpdate ( sysContext, sequenceHandle[0], &sessionsData, &dataToHash, &sessionsDataOut );
+ CheckPassed( rval );
+
+ // Now try starting a bunch of sequences to see what happens.
+ // This checks that the resource manager properly saves and restores the context
+ // of the interrupted original sequence.
+ for( i = 1; i < 5; i++ )
+ {
+ rval = Tss2_Sys_HashSequenceStart ( sysContext, 0, &auth, TPM_ALG_SHA1, &sequenceHandle[i], 0 );
+ CheckPassed( rval );
+ }
+
+ // Now end the created sequences.
+ dataToHash.t.size = 0;
+ for( i = 1; i < 5; i++ )
+ {
+ rval = Tss2_Sys_SequenceComplete ( sysContext, sequenceHandle[i], &sessionsData, &dataToHash,
+ TPM_RH_PLATFORM, &result, &validation, &sessionsDataOut );
+ CheckPassed( rval );
+ }
+
+ // Now try to finish the interrupted sequence.
+ rval = Tss2_Sys_SequenceUpdate ( sysContext, sequenceHandle[0], &sessionsData, &dataToHash, &sessionsDataOut );
+ CheckPassed( rval );
+
+ dataToHash.t.size = sizeof( memoryToHash ) - MAX_DIGEST_BUFFER;
+ memcpy( &dataToHash.t.buffer[0], &memoryToHash[MAX_DIGEST_BUFFER], dataToHash.t.size );
+ rval = Tss2_Sys_SequenceComplete ( sysContext, sequenceHandle[0], &sessionsData, &dataToHash,
+ TPM_RH_PLATFORM, &result, &validation, &sessionsDataOut );
+ CheckPassed( rval );
+
+ // Test the resulting hash.
+ if( memcmp( (void *)&( result.t.buffer[0] ), (void *)&( goodHashValue[0] ), result.t.size ) )
+ {
+ TpmClientPrintf( 0, "ERROR!! resulting hash is incorrect.\n" );
+ Cleanup();
+ }
+
+ // Now try starting a bunch of sequences to see what happens.
+ // This stresses the resource manager.
+ for( i = 0; i < MAX_TEST_SEQUENCES; i++ )
+ {
+ rval = Tss2_Sys_HashSequenceStart ( sysContext, 0, &auth, TPM_ALG_SHA1, &sequenceHandle[i], 0 );
+ CheckPassed( rval );
+ }
+
+ // Now end them all
+ dataToHash.t.size = 0;
+ for( i = (MAX_TEST_SEQUENCES - 1); i >= 0; i-- )
+// for( i = 0; i < MAX_TEST_SEQUENCES; i++ )
+ {
+ rval = Tss2_Sys_SequenceComplete ( sysContext, sequenceHandle[i], &sessionsData, &dataToHash,
+ TPM_RH_PLATFORM, &result, &validation, &sessionsDataOut );
+ CheckPassed( rval );
+ }
+}
+
+void TestQuote()
+{
+ UINT32 rval;
+ TPM2B_DATA qualifyingData;
+ UINT8 qualDataString[] = { 0x00, 0xff, 0x55, 0xaa };
+ TPMT_SIG_SCHEME inScheme;
+ TPML_PCR_SELECTION pcrSelection;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+ TPM2B_ATTEST quoted;
+ TPMT_SIGNATURE signature;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nQUOTE CONTROL TESTS:\n" );
+
+ // Init authHandle
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 2;
+ sessionData.hmac.t.buffer[0] = 0x00;
+ sessionData.hmac.t.buffer[1] = 0xff;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ qualifyingData.t.size = sizeof( qualDataString );
+ memcpy( &( qualifyingData.t.buffer[0] ), qualDataString, sizeof( qualDataString ) );
+
+ inScheme.scheme = TPM_ALG_NULL;
+
+ pcrSelection.count = 1;
+ pcrSelection.pcrSelections[0].hash = TPM_ALG_SHA1;
+ pcrSelection.pcrSelections[0].sizeofSelect = 3;
+
+ // Clear out PCR select bit field
+ pcrSelection.pcrSelections[0].pcrSelect[0] = 0;
+ pcrSelection.pcrSelections[0].pcrSelect[1] = 0;
+ pcrSelection.pcrSelections[0].pcrSelect[2] = 0;
+
+ // Now set the PCR you want
+ pcrSelection.pcrSelections[0].pcrSelect[( PCR_17/8 )] = ( 1 << ( PCR_18 % 8) );
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ // Test with wrong type of key.
+ rval = Tss2_Sys_Quote ( sysContext, loadedSha1KeyHandle, &sessionsData, &qualifyingData, &inScheme,
+ &pcrSelection, "ed, &signature, &sessionsDataOut );
+ CheckPassed( rval );
+
+ // Create signing key
+
+
+ // Now test quote operation
+// Tpm20Quote ( ??TPMI_DH_OBJECT signHandle, TPM2B_DATA *qualifyingData,
+// TPMT_SIG_SCHEME *inScheme, TPML_PCR_SELECTION *pcrSelect,
+// TPMS_AUTH_COMMAND *sessionsData)
+
+}
+
+void ProvisionOtherIndices()
+{
+ UINT32 rval;
+ TPMI_SH_AUTH_SESSION otherIndicesPolicyAuthHandle;
+ TPM2B_DIGEST nvPolicyHash;
+ TPM2B_AUTH nvAuth;
+ TPMS_AUTH_COMMAND otherIndicesSessionData;
+ TPMS_AUTH_RESPONSE otherIndicesSessionDataOut;
+ TSS2_SYS_CMD_AUTHS otherIndicesSessionsData;
+ TSS2_SYS_RSP_AUTHS otherIndicesSessionsDataOut;
+ TPM2B_NV_PUBLIC publicInfo;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &otherIndicesSessionData;
+ sessionDataOutArray[0] = &otherIndicesSessionDataOut;
+
+ otherIndicesSessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ otherIndicesSessionsData.cmdAuths = &sessionDataArray[0];
+
+ otherIndicesSessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nPROVISION OTHER NV INDICES:\n" );
+
+ //
+ // AUX index: Write is controlled by TPM2_PolicyLocality; Read is controlled by authValue and is unrestricted since authValue is set to emptyBuffer
+ // Do this by setting up two policies and ORing them together when creating AuxIndex:
+ // 1. PolicyLocality(3) && PolicyCommand(NVWrite)
+ // 2. EmptyAuth policy && PolicyCommand(NVRead)
+ // Page 126 of Part 1 describes how to do this.
+ //
+
+ // Steps:
+ rval = StartPolicySession( &otherIndicesPolicyAuthHandle );
+ CheckPassed( rval );
+
+ // 3. GetPolicyDigest and save it
+ rval = Tss2_Sys_PolicyGetDigest( sysContext, otherIndicesPolicyAuthHandle, 0, &nvPolicyHash, 0 );
+ CheckPassed( rval );
+
+ // Now save the policy digest from the first OR branch.
+ DEBUG_PRINT_BUFFER( &( nvPolicyHash.t.buffer[0] ), nvPolicyHash.t.size );
+
+ // 4. CreateNvIndex
+ otherIndicesSessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ otherIndicesSessionData.nonce.t.size = 0;
+
+ // init hmac
+ otherIndicesSessionData.hmac.t.size = 0;
+
+ // init nvAuth
+ nvAuth.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&otherIndicesSessionData.sessionAttributes ) ) = 0;
+
+ publicInfo.t.size = sizeof( TPMI_RH_NV_INDEX ) +
+ sizeof( TPMI_ALG_HASH ) + sizeof( TPMA_NV ) + sizeof( UINT16) +
+ sizeof( UINT16 );
+ publicInfo.t.nvPublic.nvIndex = INDEX_LCP_SUP;
+ publicInfo.t.nvPublic.nameAlg = TPM_ALG_SHA1;
+
+ // First zero out attributes.
+ *(UINT32 *)&( publicInfo.t.nvPublic.attributes ) = 0;
+
+ // Now set the attributes.
+ publicInfo.t.nvPublic.attributes.TPMA_NV_AUTHREAD = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_AUTHWRITE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE = 1;
+ // Following commented out for convenience during development.
+ // publicInfo.t.nvPublic.attributes.TPMA_NV_POLICY_DELETE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_WRITEDEFINE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_ORDERLY = 1;
+
+ publicInfo.t.nvPublic.authPolicy.t.size = 0;
+ publicInfo.t.nvPublic.dataSize = NV_PS_INDEX_SIZE;
+
+ otherIndicesSessionsData.cmdAuthsCount = 1;
+ otherIndicesSessionsData.cmdAuths[0] = &otherIndicesSessionData;
+
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_PLATFORM, &otherIndicesSessionsData,
+ &nvAuth, &publicInfo, &otherIndicesSessionsDataOut );
+ CheckPassed( rval );
+
+ publicInfo.t.nvPublic.nvIndex = INDEX_LCP_OWN;
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_PLATFORM, &otherIndicesSessionsData,
+ &nvAuth, &publicInfo, &otherIndicesSessionsDataOut );
+ CheckPassed( rval );
+
+ // Now teardown session
+ rval = Tss2_Sys_FlushContext( sysContext, otherIndicesPolicyAuthHandle );
+ CheckPassed( rval );
+}
+
+
+TSS2_RC InitNvAuxPolicySession( TPMI_SH_AUTH_SESSION *nvAuxPolicySessionHandle )
+{
+ TPMA_LOCALITY locality;
+ TPM_RC rval;
+
+ rval = StartPolicySession( nvAuxPolicySessionHandle );
+ CheckPassed( rval );
+
+ // 2. PolicyLocality(3)
+ *(UINT8 *)((void *)&locality) = 0;
+ locality.TPM_LOC_THREE = 1;
+ locality.TPM_LOC_FOUR = 1;
+ rval = Tss2_Sys_PolicyLocality( sysContext, *nvAuxPolicySessionHandle, 0, locality, 0 );
+
+ return( rval );
+}
+
+void ProvisionNvAux()
+{
+ UINT32 rval;
+ TPMI_SH_AUTH_SESSION nvAuxPolicyAuthHandle;
+ TPM2B_DIGEST nvPolicyHash;
+ TPM2B_AUTH nvAuth;
+ TPMS_AUTH_COMMAND nvAuxSessionData;
+ TPMS_AUTH_RESPONSE nvAuxSessionDataOut;
+ TSS2_SYS_CMD_AUTHS nvAuxSessionsData;
+ TSS2_SYS_RSP_AUTHS nvAuxSessionsDataOut;
+ TPM2B_NV_PUBLIC publicInfo;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &nvAuxSessionData;
+ sessionDataOutArray[0] = &nvAuxSessionDataOut;
+
+ nvAuxSessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ nvAuxSessionsData.cmdAuths = &sessionDataArray[0];
+
+ nvAuxSessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nPROVISION NV AUX:\n" );
+
+ //
+ // AUX index: Write is controlled by TPM2_PolicyLocality; Read is controlled by authValue and is unrestricted since authValue is set to emptyBuffer
+ // Do this by setting up two policies and ORing them together when creating AuxIndex:
+ // 1. PolicyLocality(3) && PolicyCommand(NVWrite)
+ // 2. EmptyAuth policy && PolicyCommand(NVRead)
+ // Page 126 of Part 1 describes how to do this.
+ //
+
+ // Steps:
+ rval = InitNvAuxPolicySession( &nvAuxPolicyAuthHandle );
+ CheckPassed( rval );
+
+ // 3. GetPolicyDigest and save it
+ rval = Tss2_Sys_PolicyGetDigest( sysContext, nvAuxPolicyAuthHandle, 0, &nvPolicyHash, 0 );
+ CheckPassed( rval );
+
+ // Now save the policy digest.
+ DEBUG_PRINT_BUFFER( &( nvPolicyHash.t.buffer[0] ), nvPolicyHash.t.size );
+
+ // 4. CreateNvIndex
+ nvAuxSessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ nvAuxSessionData.nonce.t.size = 0;
+
+ // init hmac
+ nvAuxSessionData.hmac.t.size = 0;
+
+ // init nvAuth
+ nvAuth.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&nvAuxSessionData.sessionAttributes ) ) = 0;
+
+ nvAuxSessionsData.cmdAuthsCount = 1;
+ nvAuxSessionsData.cmdAuths[0] = &nvAuxSessionData;
+
+ publicInfo.t.size = sizeof( TPMI_RH_NV_INDEX ) +
+ sizeof( TPMI_ALG_HASH ) + sizeof( TPMA_NV ) + sizeof( UINT16) +
+ sizeof( UINT16 );
+ publicInfo.t.nvPublic.nvIndex = INDEX_AUX;
+ publicInfo.t.nvPublic.nameAlg = TPM_ALG_SHA1;
+
+ // First zero out attributes.
+ *(UINT32 *)&( publicInfo.t.nvPublic.attributes ) = 0;
+
+ // Now set the attributes.
+ publicInfo.t.nvPublic.attributes.TPMA_NV_AUTHREAD = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_POLICYWRITE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE = 1;
+ // Following commented out for convenience during development.
+ // publicInfo.t.nvPublic.attributes.TPMA_NV_POLICY_DELETE = 1;
+
+ publicInfo.t.nvPublic.authPolicy.t.size = GetDigestSize( TPM_ALG_SHA1 );
+ memcpy( (UINT8 *)&( publicInfo.t.nvPublic.authPolicy.t.buffer ), (UINT8 *)&(nvPolicyHash.t.buffer[0]),
+ nvPolicyHash.t.size );
+
+ publicInfo.t.nvPublic.dataSize = NV_AUX_INDEX_SIZE;
+
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_PLATFORM, &nvAuxSessionsData,
+ &nvAuth, &publicInfo, &nvAuxSessionsDataOut );
+ CheckPassed( rval );
+
+ // Now teardown session
+ rval = Tss2_Sys_FlushContext( sysContext, nvAuxPolicyAuthHandle );
+ CheckPassed( rval );
+}
+
+void TpmAuxWrite( int locality)
+{
+ TSS2_RC rval;
+ int i;
+ TPMI_SH_AUTH_SESSION nvAuxPolicyAuthHandle;
+ TPM2B_MAX_NV_BUFFER nvWriteData;
+
+ rval = InitNvAuxPolicySession( &nvAuxPolicyAuthHandle );
+ CheckPassed( rval );
+
+ // Now we're going to test it.
+ nvWriteData.t.size = 4;
+ for( i = 0; i < nvWriteData.t.size; i++ )
+ nvWriteData.t.buffer[i] = 0xff - i;
+
+ nullSessionData.sessionHandle = nvAuxPolicyAuthHandle;
+
+ // Make sure that session terminates after NVWrite completes.
+ nullSessionData.sessionAttributes.continueSession = 0;
+
+ rval = SetLocality( sysContext, locality );
+ CheckPassed( rval );
+
+ nullSessionsData.cmdAuthsCount = 1;
+ nullSessionsData.cmdAuths[0] = &nullSessionData;
+
+ rval = Tss2_Sys_NV_Write( sysContext, INDEX_AUX, INDEX_AUX, &nullSessionsData, &nvWriteData, 0, &nullSessionsDataOut );
+
+ {
+ TSS2_RC setLocalityRval;
+ setLocalityRval = SetLocality( sysContext, 3 );
+ CheckPassed( setLocalityRval );
+ }
+
+ if( locality == 3 || locality == 4 )
+ {
+ CheckPassed( rval );
+
+ // No teardown of session needed, since the authorization was
+ // successful.
+ }
+ else
+ {
+ CheckFailed( rval, TPM_RC_LOCALITY );
+
+ // Now teardown session
+ rval = Tss2_Sys_FlushContext( sysContext, nvAuxPolicyAuthHandle );
+ CheckPassed( rval );
+ }
+}
+
+void TpmAuxReadWriteTest()
+{
+ UINT32 rval;
+ int testLocality;
+ TPM2B_MAX_NV_BUFFER nvData;
+
+ TpmClientPrintf( 0, "TPM AUX READ/WRITE TEST\n" );
+
+ nullSessionData.sessionAttributes.continueSession = 0;
+
+ // Try writing it from all localities. Only locality 3 should work.
+ for( testLocality = 0; testLocality < 5; testLocality++ )
+ {
+ TpmAuxWrite( testLocality );
+ }
+
+ nullSessionData.sessionHandle = TPM_RS_PW;
+
+ nullSessionsData.cmdAuths[0] = &nullSessionData;
+
+ // Try reading it from all localities. They all should work.
+ for( testLocality = 0; testLocality < 5; testLocality++ )
+ {
+ rval = SetLocality( sysContext, testLocality );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Read( sysContext, INDEX_AUX, INDEX_AUX, &nullSessionsData, 4, 0, &nvData, &nullSessionsDataOut );
+ CheckPassed( rval );
+
+ rval = SetLocality( sysContext, 3 );
+ CheckPassed( rval );
+ }
+}
+
+void TpmOtherIndicesReadWriteTest()
+{
+ UINT32 rval;
+ TPM2B_MAX_NV_BUFFER nvWriteData;
+ int i;
+ TPM2B_MAX_NV_BUFFER nvData;
+
+ nullSessionData.sessionHandle = TPM_RS_PW;
+
+ TpmClientPrintf( 0, "TPM OTHER READ/WRITE TEST\n" );
+
+ nvWriteData.t.size = 4;
+ for( i = 0; i < nvWriteData.t.size; i++ )
+ nvWriteData.t.buffer[i] = 0xff - i;
+
+ nullSessionsData.cmdAuthsCount = 1;
+ nullSessionsData.cmdAuths[0] = &nullSessionData;
+
+ rval = Tss2_Sys_NV_Write( sysContext, INDEX_LCP_SUP, INDEX_LCP_SUP, &nullSessionsData, &nvWriteData, 0, &nullSessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Write( sysContext, INDEX_LCP_OWN, INDEX_LCP_OWN, &nullSessionsData, &nvWriteData, 0, &nullSessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Read( sysContext, INDEX_LCP_SUP, INDEX_LCP_SUP, &nullSessionsData, 4, 0, &nvData, &nullSessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Read( sysContext, INDEX_LCP_OWN, INDEX_LCP_OWN, &nullSessionsData, 4, 0, &nvData, &nullSessionsDataOut );
+ CheckPassed( rval );
+}
+
+void NvIndexProto()
+{
+ UINT32 rval;
+
+ TpmClientPrintf( 0, "\nNV INDEX PROTOTYPE TESTS:\n" );
+
+
+ // AUX index: Write is controlled by TPM2_PolicyLocality; Read is controlled by authValue and is unrestricted since authValue is set to emptyBuffer
+ // PS index: Write and read are unrestricted until TPM2_WriteLock. After that content is write protected
+ // PO index: Write is restricted by ownerAuth; Read is controlled by authValue and is unrestricted since authValue is set to emptyBuffer
+
+ // Now we need to configure NV indices
+ ProvisionNvAux();
+
+ ProvisionOtherIndices();
+
+ TpmAuxReadWriteTest();
+
+ TpmOtherIndicesReadWriteTest();
+
+ // Now undefine the aux index, so that subsequent test passes will work.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_PLATFORM, INDEX_AUX, &nullSessionsData, &nullSessionsDataOut );
+ CheckPassed( rval );
+
+ // Now undefine the other indices, so that subsequent test passes will work.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_PLATFORM, INDEX_LCP_SUP, &nullSessionsData, &nullSessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_PLATFORM, INDEX_LCP_OWN, &nullSessionsData, &nullSessionsDataOut );
+ CheckPassed( rval );
+}
+
+void TestPcrAllocate()
+{
+ UINT32 rval;
+ TPML_PCR_SELECTION pcrSelection;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+ TPMI_YES_NO allocationSuccess;
+ UINT32 maxPcr;
+ UINT32 sizeNeeded;
+ UINT32 sizeAvailable;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TpmClientPrintf( 0, "\nPCR ALLOCATE TEST :\n" );
+
+ // Init authHandle
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ pcrSelection.count = 0;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ rval = Tss2_Sys_PCR_Allocate( sysContext, TPM_RH_PLATFORM, &sessionsData, &pcrSelection,
+ &allocationSuccess, &maxPcr, &sizeNeeded, &sizeAvailable, &sessionsDataOut);
+ CheckPassed( rval );
+
+ pcrSelection.count = 3;
+ pcrSelection.pcrSelections[0].hash = TPM_ALG_SHA256;
+ CLEAR_PCR_SELECT_BITS( pcrSelection.pcrSelections[0] );
+ SET_PCR_SELECT_SIZE( pcrSelection.pcrSelections[0], 3 );
+ SET_PCR_SELECT_BIT( pcrSelection.pcrSelections[0], PCR_5 );
+ SET_PCR_SELECT_BIT( pcrSelection.pcrSelections[0], PCR_7 );
+ pcrSelection.pcrSelections[1].hash = TPM_ALG_SHA384;
+ CLEAR_PCR_SELECT_BITS( pcrSelection.pcrSelections[1] );
+ SET_PCR_SELECT_SIZE( pcrSelection.pcrSelections[1], 3 );
+ SET_PCR_SELECT_BIT( pcrSelection.pcrSelections[1], PCR_5 );
+ SET_PCR_SELECT_BIT( pcrSelection.pcrSelections[1], PCR_8 );
+ pcrSelection.pcrSelections[2].hash = TPM_ALG_SHA256;
+ CLEAR_PCR_SELECT_BITS( pcrSelection.pcrSelections[2] );
+ SET_PCR_SELECT_SIZE( pcrSelection.pcrSelections[2], 3 );
+ SET_PCR_SELECT_BIT( pcrSelection.pcrSelections[2], PCR_6 );
+
+ rval = Tss2_Sys_PCR_Allocate( sysContext, TPM_RH_PLATFORM, &sessionsData, &pcrSelection,
+ &allocationSuccess, &maxPcr, &sizeNeeded, &sizeAvailable, &sessionsDataOut);
+ CheckPassed( rval );
+}
+
+void TestUnseal()
+{
+ UINT32 rval;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+ TPM2B_SENSITIVE_CREATE inSensitive;
+ TPML_PCR_SELECTION creationPCR;
+ TPM2B_DATA outsideInfo;
+ TPM2B_PUBLIC inPublic;
+ TPM_HANDLE loadedObjectHandle;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ TPM2B_PRIVATE outPrivate;
+ TPM2B_PUBLIC outPublic;
+ TPM2B_CREATION_DATA creationData;
+ TPM2B_DIGEST creationHash;
+ TPMT_TK_CREATION creationTicket;
+ TPM2B_NAME name;
+ TPM2B_SENSITIVE_DATA outData;
+
+
+ const char authStr[] = "test";
+ const char sensitiveData[] = "this is sensitive";
+
+ TpmClientPrintf( 0, "\nUNSEAL TEST :\n" );
+
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ sessionData.hmac.t.size = 2;
+ sessionData.hmac.t.buffer[0] = 0x00;
+ sessionData.hmac.t.buffer[1] = 0xff;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ inSensitive.t.sensitive.userAuth.t.size = sizeof( authStr ) - 1;
+ memcpy( &( inSensitive.t.sensitive.userAuth.t.buffer[0] ), authStr, sizeof( authStr ) - 1 );
+ inSensitive.t.sensitive.data.t.size = sizeof( sensitiveData ) - 1;
+ memcpy( &( inSensitive.t.sensitive.data.t.buffer[0] ), sensitiveData, sizeof( sensitiveData ) - 1 );
+
+ inPublic.t.publicArea.authPolicy.t.size = 0;
+
+ inPublic.t.publicArea.unique.keyedHash.t.size = 0;
+
+ outsideInfo.t.size = 0;
+ creationPCR.count = 0;
+
+ inPublic.t.publicArea.type = TPM_ALG_KEYEDHASH;
+ inPublic.t.publicArea.nameAlg = TPM_ALG_SHA1;
+
+ *(UINT32 *)&( inPublic.t.publicArea.objectAttributes) = 0;
+ inPublic.t.publicArea.objectAttributes.userWithAuth = 1;
+
+ inPublic.t.publicArea.parameters.keyedHashDetail.scheme.scheme = TPM_ALG_NULL;
+
+ inPublic.t.publicArea.unique.keyedHash.t.size = 0;
+
+ outsideInfo.t.size = 0;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ outPublic.t.size = 0;
+ creationData.t.size = 0;
+ rval = Tss2_Sys_Create( sysContext, handle2048rsa, &sessionsData, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR,
+ &outPrivate, &outPublic, &creationData,
+ &creationHash, &creationTicket, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_LoadExternal ( sysContext, 0, 0, &outPublic,
+ TPM_RH_PLATFORM, &loadedObjectHandle, &name, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_FlushContext( sysContext, loadedObjectHandle );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_Load ( sysContext, handle2048rsa, &sessionsData, &outPrivate, &outPublic,
+ &loadedObjectHandle, &name, &sessionsDataOut);
+ CheckPassed( rval );
+
+ sessionData.hmac.t.size = sizeof( authStr ) - 1;
+ memcpy( &( sessionData.hmac.t.buffer[0] ), authStr, sizeof( authStr ) - 1 );
+
+ rval = Tss2_Sys_Unseal( sysContext, loadedObjectHandle, &sessionsData, &outData, &sessionsDataOut );
+
+ rval = Tss2_Sys_FlushContext( sysContext, loadedObjectHandle );
+ CheckPassed( rval );
+
+ CheckPassed( rval );
+}
+
+
+void CreatePasswordTestNV( TPMI_RH_NV_INDEX nvIndex, char * password )
+{
+ UINT32 rval;
+ int i;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+ TPM2B_NV_PUBLIC publicInfo;
+ TPM2B_AUTH nvAuth;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ sessionsDataOut.rspAuthsCount = 1;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ nvAuth.t.size = strlen( password );
+ for( i = 0; i < nvAuth.t.size; i++ )
+ nvAuth.t.buffer[i] = password[i];
+
+ publicInfo.t.size = sizeof( TPMI_RH_NV_INDEX ) +
+ sizeof( TPMI_ALG_HASH ) + sizeof( TPMA_NV ) + sizeof( UINT16) +
+ sizeof( UINT16 );
+ publicInfo.t.nvPublic.nvIndex = nvIndex;
+ publicInfo.t.nvPublic.nameAlg = TPM_ALG_SHA1;
+
+ // First zero out attributes.
+ *(UINT32 *)&( publicInfo.t.nvPublic.attributes ) = 0;
+
+ // Now set the attributes.
+ publicInfo.t.nvPublic.attributes.TPMA_NV_AUTHREAD = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_AUTHWRITE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE = 1;
+ publicInfo.t.nvPublic.attributes.TPMA_NV_ORDERLY = 1;
+ publicInfo.t.nvPublic.authPolicy.t.size = 0;
+ publicInfo.t.nvPublic.dataSize = 32;
+
+ rval = Tss2_Sys_NV_DefineSpace( sysContext, TPM_RH_PLATFORM,
+ &sessionsData, &nvAuth, &publicInfo, &sessionsDataOut );
+ CheckPassed( rval );
+}
+
+// Password used to authorize access to the NV index.
+char password[] = "test password";
+
+void PasswordTest()
+{
+ UINT32 rval;
+ int i;
+
+ // Authorization structure for command.
+ TPMS_AUTH_COMMAND sessionData;
+
+ // Authorization structure for response.
+ TPMS_AUTH_RESPONSE sessionDataOut;
+
+ // Create and init authorization area for command:
+ // only 1 authorization area.
+ TPMS_AUTH_COMMAND *sessionDataArray[1] = { &sessionData };
+
+ // Create authorization area for response:
+ // only 1 authorization area.
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1] = { &sessionDataOut };
+
+ // Authorization array for command (only has one auth structure).
+ TSS2_SYS_CMD_AUTHS sessionsData = { 1, &sessionDataArray[0] };
+
+ // Authorization array for response (only has one auth structure).
+ TSS2_SYS_RSP_AUTHS sessionsDataOut = { 1, &sessionDataOutArray[0] };
+ TPM2B_MAX_NV_BUFFER nvWriteData;
+
+ TpmClientPrintf( 0, "\nPASSWORD TESTS:\n" );
+
+ // Create an NV index that will use password
+ // authorizations the password will be
+ // "test password".
+ CreatePasswordTestNV( TPM20_INDEX_PASSWORD_TEST, password );
+
+ //
+ // Initialize the command authorization area.
+ //
+
+ // Init sessionHandle, nonce, session
+ // attributes, and hmac (password).
+ sessionData.sessionHandle = TPM_RS_PW;
+ // Set zero sized nonce.
+ sessionData.nonce.t.size = 0;
+ // sessionAttributes is a bit field. To initialize
+ // it to 0, cast to a pointer to UINT8 and
+ // write 0 to that pointer.
+ *( (UINT8 *)&sessionData.sessionAttributes ) = 0;
+
+ // Init password (HMAC field in authorization structure).
+ sessionData.hmac.t.size = strlen( password );
+ memcpy( &( sessionData.hmac.t.buffer[0] ),
+ &( password[0] ), sessionData.hmac.t.size );
+
+ // Initialize write data.
+ nvWriteData.t.size = 4;
+ for( i = 0; i < nvWriteData.t.size; i++ )
+ nvWriteData.t.buffer[i] = 0xff - i;
+
+ // Attempt write with the correct password.
+ // It should pass.
+ rval = Tss2_Sys_NV_Write( sysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &sessionsData, &nvWriteData, 0,
+ &sessionsDataOut );
+ // Check that the function passed as
+ // expected. Otherwise, exit.
+ CheckPassed( rval );
+
+ // Alter the password so it's incorrect.
+ sessionData.hmac.t.buffer[4] = 0xff;
+ rval = Tss2_Sys_NV_Write( sysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &sessionsData, &nvWriteData, 0,
+ &sessionsDataOut );
+ // Check that the function failed as expected,
+ // since password was incorrect. If wrong
+ // response code received, exit.
+ CheckFailed( rval,
+ TPM_RC_S + TPM_RC_1 + TPM_RC_AUTH_FAIL );
+
+ // Change hmac to null one, since null auth is
+ // used to undefine the index.
+ sessionData.hmac.t.size = 0;
+
+ // Now undefine the index.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_PLATFORM,
+ TPM20_INDEX_PASSWORD_TEST, &sessionsData, 0 );
+ CheckPassed( rval );
+}
+
+
+void SimplePolicyTest()
+{
+ UINT32 rval, sessionCmdRval;
+ TPM2B_AUTH nvAuth;
+ SESSION *nvSession, *trialPolicySession;
+ TPMA_NV nvAttributes;
+ TPM2B_DIGEST authPolicy;
+ TPM2B_NAME nvName;
+ TPM2B_MAX_NV_BUFFER nvWriteData, nvReadData;
+ UINT8 dataToWrite[] = { 0x00, 0xff, 0x55, 0xaa };
+ int i;
+ TPM2B_ENCRYPTED_SECRET encryptedSalt;
+ TPMT_SYM_DEF symmetric;
+ TPMA_SESSION sessionAttributes;
+
+ // Command authorization area: one password session.
+ TPMS_AUTH_COMMAND nvCmdAuth = { TPM_RS_PW, };
+ TPMS_AUTH_COMMAND *nvCmdAuthArray[1] = { &nvCmdAuth };
+ TSS2_SYS_CMD_AUTHS nvCmdAuths = { 1, &nvCmdAuthArray[0] };
+
+ // Response authorization area.
+ TPMS_AUTH_RESPONSE nvRspAuth;
+ TPMS_AUTH_RESPONSE *nvRspAuthArray[1] = { &nvRspAuth };
+ TSS2_SYS_RSP_AUTHS nvRspAuths = { 1, &nvRspAuthArray[0] };
+ TPM_ALG_ID sessionAlg = TPM_ALG_SHA256;
+ TPM2B_NONCE nonceCaller;
+
+ nonceCaller.t.size = 0;
+
+ TpmClientPrintf( 0, "\nSIMPLE POLICY TEST:\n" );
+
+ //
+ // Create NV index.
+ //
+
+ // Setup the NV index's authorization value.
+ nvAuth.t.size = 0;
+
+ // Zero sized encrypted salt, since the session
+ // is unsalted.
+ encryptedSalt.t.size = 0;
+
+ // No symmetric algorithm.
+ symmetric.algorithm = TPM_ALG_NULL;
+
+ //
+ // Create the NV index's authorization policy
+ // using a trial policy session.
+ //
+ rval = StartAuthSessionWithParams( &trialPolicySession, TPM_RH_NULL,
+ 0, TPM_RH_NULL, 0, &nonceCaller, &encryptedSalt, TPM_SE_TRIAL,
+ &symmetric, sessionAlg );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_PolicyAuthValue( sysContext, trialPolicySession->sessionHandle, 0, 0 );
+ CheckPassed( rval );
+
+ // Get policy digest.
+ rval = Tss2_Sys_PolicyGetDigest( sysContext, trialPolicySession->sessionHandle,
+ 0, &authPolicy, 0 );
+ CheckPassed( rval );
+
+ // End the trial session by flushing it.
+ rval = Tss2_Sys_FlushContext( sysContext, trialPolicySession->sessionHandle );
+ CheckPassed( rval );
+
+ // And remove the trial policy session from sessions table.
+ rval = EndAuthSession( trialPolicySession );
+ CheckPassed( rval );
+
+ // Now set the NV index's attributes:
+ // policyRead, authWrite, and platormCreate.
+ *(UINT32 *)( (void *)&nvAttributes ) = 0;
+ nvAttributes.TPMA_NV_POLICYREAD = 1;
+ nvAttributes.TPMA_NV_POLICYWRITE = 1;
+ nvAttributes.TPMA_NV_PLATFORMCREATE = 1;
+
+ // Create the NV index.
+ rval = DefineNvIndex( TPM_RH_PLATFORM, TPM_RS_PW,
+ &nvAuth, &authPolicy, TPM20_INDEX_PASSWORD_TEST,
+ sessionAlg, nvAttributes, 32 );
+ CheckPassed( rval );
+
+ // Add index and associated authorization value to
+ // entity table. This helps when we need
+ // to calculate HMACs.
+ AddEntity( TPM20_INDEX_PASSWORD_TEST, &nvAuth );
+ CheckPassed( rval );
+
+ // Get the name of the NV index.
+ rval = (*HandleToNameFunctionPtr)( TPM20_INDEX_PASSWORD_TEST,
+ &nvName );
+ CheckPassed( rval );
+
+ //
+ // Start real (non-trial) policy authorization session:
+ // it's an unbound and unsalted session, no symmetric
+ // encryption algorithm, and SHA256 is the session's
+ // hash algorithm.
+ //
+
+ // Zero sized encrypted salt, since the session
+ // is unsalted.
+ encryptedSalt.t.size = 0;
+
+ // No symmetric algorithm.
+ symmetric.algorithm = TPM_ALG_NULL;
+
+ // Create the session.
+ // Session state (session handle, nonces, etc.) gets
+ // saved into nvSession structure for later use.
+ rval = StartAuthSessionWithParams( &nvSession, TPM_RH_NULL,
+ 0, TPM_RH_NULL, 0, &nonceCaller, &encryptedSalt, TPM_SE_POLICY,
+ &symmetric, sessionAlg );
+ CheckPassed( rval );
+
+ // Get the name of the session and save it in
+ // the nvSession structure.
+ rval = (*HandleToNameFunctionPtr)( nvSession->sessionHandle,
+ &nvSession->name );
+ CheckPassed( rval );
+
+ // Initialize NV write data.
+ nvWriteData.t.size = sizeof( dataToWrite );
+ for( i = 0; i < nvWriteData.t.size; i++ )
+ {
+ nvWriteData.t.buffer[i] = dataToWrite[i];
+ }
+
+ //
+ // Now setup for writing the NV index.
+ //
+
+ rval = Tss2_Sys_PolicyAuthValue( sysContext, nvSession->sessionHandle, 0, 0 );
+ CheckPassed( rval );
+
+ // Get policy digest.
+ rval = Tss2_Sys_PolicyGetDigest( sysContext, trialPolicySession->sessionHandle,
+ 0, &authPolicy, 0 );
+ CheckPassed( rval );
+
+ // First call prepare in order to create cpBuffer.
+ rval = Tss2_Sys_NV_Write_Prepare( sysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvWriteData, 0 );
+ CheckPassed( rval );
+
+ // Configure command authorization area, except for HMAC.
+ nvCmdAuths.cmdAuths[0]->sessionHandle = nvSession->sessionHandle;
+ nvCmdAuths.cmdAuths[0]->nonce.t.size = 1;
+ nvCmdAuths.cmdAuths[0]->nonce.t.buffer[0] = 0xa5;
+ *( (UINT8 *)((void *)&sessionAttributes ) ) = 0;
+ nvCmdAuths.cmdAuths[0]->sessionAttributes = sessionAttributes;
+ nvCmdAuths.cmdAuths[0]->sessionAttributes.continueSession = 1;
+
+ // Roll nonces for command
+ RollNonces( nvSession, &nvCmdAuths.cmdAuths[0]->nonce );
+
+ // Complete command authorization area, by computing
+ // HMAC and setting it in nvCmdAuths.
+ rval = ComputeCommandHmacs( sysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvCmdAuths,
+ TPM_RC_FAILURE );
+ CheckPassed( rval );
+
+ // Finally!! Write the data to the NV index.
+ // If the command is successful, the command
+ // HMAC was correct.
+ sessionCmdRval = Tss2_Sys_NV_Write( sysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &nvCmdAuths, &nvWriteData, 0, &nvRspAuths );
+ CheckPassed( sessionCmdRval );
+
+ // Roll nonces for response
+ RollNonces( nvSession, &nvRspAuths.rspAuths[0]->nonce );
+
+ if( sessionCmdRval == TPM_RC_SUCCESS )
+ {
+ // If the command was successful, check the
+ // response HMAC to make sure that the
+ // response was received correctly.
+ rval = CheckResponseHMACs( sysContext, sessionCmdRval,
+ &nvCmdAuths, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvRspAuths );
+ CheckPassed( rval );
+ }
+
+ rval = Tss2_Sys_PolicyAuthValue( sysContext, nvSession->sessionHandle, 0, 0 );
+ CheckPassed( rval );
+
+ // First call prepare in order to create cpBuffer.
+ rval = Tss2_Sys_NV_Read_Prepare( sysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, sizeof( dataToWrite ), 0 );
+ CheckPassed( rval );
+
+ // Roll nonces for command
+ RollNonces( nvSession, &nvCmdAuths.cmdAuths[0]->nonce );
+
+ // End the session after next command.
+ nvCmdAuths.cmdAuths[0]->sessionAttributes.continueSession = 0;
+
+ // Complete command authorization area, by computing
+ // HMAC and setting it in nvCmdAuths.
+ rval = ComputeCommandHmacs( sysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvCmdAuths,
+ TPM_RC_FAILURE );
+ CheckPassed( rval );
+
+ // And now read the data back.
+ // If the command is successful, the command
+ // HMAC was correct.
+ sessionCmdRval = Tss2_Sys_NV_Read( sysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &nvCmdAuths, sizeof( dataToWrite ), 0,
+ &nvReadData, &nvRspAuths );
+ CheckPassed( sessionCmdRval );
+
+ // Roll nonces for response
+ RollNonces( nvSession, &nvRspAuths.rspAuths[0]->nonce );
+
+ if( sessionCmdRval == TPM_RC_SUCCESS )
+ {
+ // If the command was successful, check the
+ // response HMAC to make sure that the
+ // response was received correctly.
+ rval = CheckResponseHMACs( sysContext, sessionCmdRval,
+ &nvCmdAuths, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvRspAuths );
+ CheckPassed( rval );
+ }
+
+ // Check that write and read data are equal.
+ if( memcmp( (void *)&nvReadData.t.buffer[0],
+ (void *)&nvWriteData.t.buffer[0], nvReadData.t.size ) )
+ {
+ TpmClientPrintf( 0, "ERROR!! read data not equal to written data\n" );
+ Cleanup();
+ }
+
+ //
+ // Now cleanup: undefine the NV index and delete
+ // the NV index's entity table entry.
+ //
+
+ // Setup authorization for undefining the NV index.
+ nvCmdAuths.cmdAuths[0]->sessionHandle = TPM_RS_PW;
+ nvCmdAuths.cmdAuths[0]->nonce.t.size = 0;
+ nvCmdAuths.cmdAuths[0]->hmac.t.size = 0;
+
+ // Undefine the NV index.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext,
+ TPM_RH_PLATFORM, TPM20_INDEX_PASSWORD_TEST,
+ &nvCmdAuths, 0 );
+ CheckPassed( rval );
+
+ // Delete the NV index's entry in the entity table.
+ rval = DeleteEntity( TPM20_INDEX_PASSWORD_TEST );
+ CheckPassed( rval );
+}
+
+void SimpleHmacTest()
+{
+ UINT32 rval, sessionCmdRval;
+ TPM2B_AUTH nvAuth;
+ SESSION *nvSession;
+ TPMA_NV nvAttributes;
+ TPM2B_DIGEST authPolicy;
+ TPM2B_NAME nvName;
+ TPM2B_MAX_NV_BUFFER nvWriteData, nvReadData;
+ UINT8 dataToWrite[] = { 0x00, 0xff, 0x55, 0xaa };
+ char sharedSecret[] = "shared secret";
+ int i;
+ TPM2B_ENCRYPTED_SECRET encryptedSalt;
+ TPMT_SYM_DEF symmetric;
+ TPMA_SESSION sessionAttributes;
+
+ // Command authorization area: one password session.
+ TPMS_AUTH_COMMAND nvCmdAuth = { TPM_RS_PW, };
+ TPMS_AUTH_COMMAND *nvCmdAuthArray[1] = { &nvCmdAuth };
+ TSS2_SYS_CMD_AUTHS nvCmdAuths = { 1, &nvCmdAuthArray[0] };
+
+ // Response authorization area.
+ TPMS_AUTH_RESPONSE nvRspAuth;
+ TPMS_AUTH_RESPONSE *nvRspAuthArray[1] = { &nvRspAuth };
+ TSS2_SYS_RSP_AUTHS nvRspAuths = { 1, &nvRspAuthArray[0] };
+ TPM2B_NONCE nonceCaller;
+
+ nonceCaller.t.size = 0;
+
+ TpmClientPrintf( 0, "\nSIMPLE HMAC SESSION TEST:\n" );
+
+ //
+ // Create NV index.
+ //
+
+ // Setup the NV index's authorization value.
+ nvAuth.t.size = strlen( sharedSecret );
+ for( i = 0; i < nvAuth.t.size; i++ )
+ nvAuth.t.buffer[i] = sharedSecret[i];
+
+ // Set NV index's authorization policy
+ // to zero sized policy since we won't be
+ // using policy to authorize.
+ authPolicy.t.size = 0;
+
+ // Now set the NV index's attributes:
+ // policyRead, authWrite, and platormCreate.
+ *(UINT32 *)( (void *)&nvAttributes ) = 0;
+ nvAttributes.TPMA_NV_AUTHREAD = 1;
+ nvAttributes.TPMA_NV_AUTHWRITE = 1;
+ nvAttributes.TPMA_NV_PLATFORMCREATE = 1;
+
+ // Create the NV index.
+ rval = DefineNvIndex( TPM_RH_PLATFORM, TPM_RS_PW,
+ &nvAuth, &authPolicy, TPM20_INDEX_PASSWORD_TEST,
+ TPM_ALG_SHA256, nvAttributes, 32 );
+ CheckPassed( rval );
+
+ // Add index and associated authorization value to
+ // entity table. This helps when we need
+ // to calculate HMACs.
+ AddEntity( TPM20_INDEX_PASSWORD_TEST, &nvAuth );
+ CheckPassed( rval );
+
+ // Get the name of the NV index.
+ rval = (*HandleToNameFunctionPtr)( TPM20_INDEX_PASSWORD_TEST,
+ &nvName );
+ CheckPassed( rval );
+
+ //
+ // Start HMAC authorization session: it's an
+ // unbound and unsalted session, no symmetric
+ // encryption algorithm, and SHA256 is the session's
+ // hash algorithm.
+ //
+
+ // Zero sized encrypted salt, since the session
+ // is unsalted.
+ encryptedSalt.t.size = 0;
+
+ // No symmetric algorithm.
+ symmetric.algorithm = TPM_ALG_NULL;
+
+ // Create the session.
+ // Session state (session handle, nonces, etc.) gets
+ // saved into nvSession structure for later use.
+ rval = StartAuthSessionWithParams( &nvSession, TPM_RH_NULL,
+ 0, TPM_RH_NULL, 0, &nonceCaller, &encryptedSalt, TPM_SE_HMAC,
+ &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+
+ // Get the name of the session and save it in
+ // the nvSession structure.
+ rval = (*HandleToNameFunctionPtr)( nvSession->sessionHandle,
+ &nvSession->name );
+ CheckPassed( rval );
+
+ // Initialize NV write data.
+ nvWriteData.t.size = sizeof( dataToWrite );
+ for( i = 0; i < nvWriteData.t.size; i++ )
+ {
+ nvWriteData.t.buffer[i] = dataToWrite[i];
+ }
+
+ //
+ // Now setup for writing the NV index.
+ //
+
+ // First call prepare in order to create cpBuffer.
+ rval = Tss2_Sys_NV_Write_Prepare( sysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvWriteData, 0 );
+ CheckPassed( rval );
+
+ // Configure command authorization area, except for HMAC.
+ nvCmdAuths.cmdAuths[0]->sessionHandle = nvSession->sessionHandle;
+ nvCmdAuths.cmdAuths[0]->nonce.t.size = 1;
+ nvCmdAuths.cmdAuths[0]->nonce.t.buffer[0] = 0xa5;
+ *( (UINT8 *)(&sessionAttributes ) ) = 0;
+ nvCmdAuths.cmdAuths[0]->sessionAttributes = sessionAttributes;
+ nvCmdAuths.cmdAuths[0]->sessionAttributes.continueSession = 1;
+
+ // Roll nonces for command
+ RollNonces( nvSession, &nvCmdAuths.cmdAuths[0]->nonce );
+
+ // Complete command authorization area, by computing
+ // HMAC and setting it in nvCmdAuths.
+ rval = ComputeCommandHmacs( sysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvCmdAuths,
+ TPM_RC_FAILURE );
+ CheckPassed( rval );
+
+ // Finally!! Write the data to the NV index.
+ // If the command is successful, the command
+ // HMAC was correct.
+ sessionCmdRval = Tss2_Sys_NV_Write( sysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &nvCmdAuths, &nvWriteData, 0, &nvRspAuths );
+ CheckPassed( sessionCmdRval );
+
+ // Roll nonces for response
+ RollNonces( nvSession, &nvRspAuths.rspAuths[0]->nonce );
+
+ if( sessionCmdRval == TPM_RC_SUCCESS )
+ {
+ // If the command was successful, check the
+ // response HMAC to make sure that the
+ // response was received correctly.
+ rval = CheckResponseHMACs( sysContext, sessionCmdRval,
+ &nvCmdAuths, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvRspAuths );
+ CheckPassed( rval );
+ }
+
+ // First call prepare in order to create cpBuffer.
+ rval = Tss2_Sys_NV_Read_Prepare( sysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, sizeof( dataToWrite ), 0 );
+ CheckPassed( rval );
+
+ // Roll nonces for command
+ RollNonces( nvSession, &nvCmdAuths.cmdAuths[0]->nonce );
+
+ // End the session after next command.
+ nvCmdAuths.cmdAuths[0]->sessionAttributes.continueSession = 0;
+
+ // Complete command authorization area, by computing
+ // HMAC and setting it in nvCmdAuths.
+ rval = ComputeCommandHmacs( sysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvCmdAuths,
+ TPM_RC_FAILURE );
+ CheckPassed( rval );
+
+ // And now read the data back.
+ // If the command is successful, the command
+ // HMAC was correct.
+ sessionCmdRval = Tss2_Sys_NV_Read( sysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &nvCmdAuths, sizeof( dataToWrite ), 0,
+ &nvReadData, &nvRspAuths );
+ CheckPassed( sessionCmdRval );
+
+ // Roll nonces for response
+ RollNonces( nvSession, &nvRspAuths.rspAuths[0]->nonce );
+
+ if( sessionCmdRval == TPM_RC_SUCCESS )
+ {
+ // If the command was successful, check the
+ // response HMAC to make sure that the
+ // response was received correctly.
+ rval = CheckResponseHMACs( sysContext, sessionCmdRval,
+ &nvCmdAuths, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvRspAuths );
+ CheckPassed( rval );
+ }
+
+ // Check that write and read data are equal.
+ if( memcmp( (void *)&nvReadData.t.buffer[0],
+ (void *)&nvWriteData.t.buffer[0], nvReadData.t.size ) )
+ {
+ TpmClientPrintf( 0, "ERROR!! read data not equal to written data\n" );
+ Cleanup();
+ }
+
+ //
+ // Now cleanup: undefine the NV index and delete
+ // the NV index's entity table entry.
+ //
+
+ // Setup authorization for undefining the NV index.
+ nvCmdAuths.cmdAuths[0]->sessionHandle = TPM_RS_PW;
+ nvCmdAuths.cmdAuths[0]->nonce.t.size = 0;
+ nvCmdAuths.cmdAuths[0]->hmac.t.size = 0;
+
+ // Undefine the NV index.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext,
+ TPM_RH_PLATFORM, TPM20_INDEX_PASSWORD_TEST,
+ &nvCmdAuths, 0 );
+ CheckPassed( rval );
+
+ // Delete the NV index's entry in the entity table.
+ rval = DeleteEntity( TPM20_INDEX_PASSWORD_TEST );
+ CheckPassed( rval );
+
+ rval = EndAuthSession( nvSession );
+
+ CheckPassed( rval );
+}
+
+
+void SimpleHmacOrPolicyTest( bool hmacTest )
+{
+ UINT32 rval, sessionCmdRval;
+ TPM2B_AUTH nvAuth;
+ SESSION *nvSession, *trialPolicySession;
+ TPMA_NV nvAttributes;
+ TPM2B_DIGEST authPolicy;
+ TPM2B_NAME nvName;
+ TPM2B_MAX_NV_BUFFER nvWriteData, nvReadData;
+ UINT8 dataToWrite[] = { 0x00, 0xff, 0x55, 0xaa };
+ char sharedSecret[] = "shared secret";
+ int i;
+ TPM2B_ENCRYPTED_SECRET encryptedSalt;
+ TPMT_SYM_DEF symmetric;
+ TPMA_SESSION sessionAttributes;
+ TPM_SE tpmSe;
+ char *testString;
+ char testStringHmac[] = "HMAC";
+ char testStringPolicy[] = "POLICY";
+
+ // Command authorization area: one password session.
+ TPMS_AUTH_COMMAND nvCmdAuth = { TPM_RS_PW, };
+ TPMS_AUTH_COMMAND *nvCmdAuthArray[1] = { &nvCmdAuth };
+ TSS2_SYS_CMD_AUTHS nvCmdAuths = { 1, &nvCmdAuthArray[0] };
+
+ // Response authorization area.
+ TPMS_AUTH_RESPONSE nvRspAuth;
+ TPMS_AUTH_RESPONSE *nvRspAuthArray[1] = { &nvRspAuth };
+ TSS2_SYS_RSP_AUTHS nvRspAuths = { 1, &nvRspAuthArray[0] };
+
+ TSS2_SYS_CONTEXT *simpleTestContext;
+ TPM2B_NONCE nonceCaller;
+
+ nonceCaller.t.size = 0;
+
+ if( hmacTest )
+ testString = testStringHmac;
+ else
+ testString = testStringPolicy;
+
+ TpmClientPrintf( 0, "\nSIMPLE %s SESSION TEST:\n", testString );
+
+ // Create sysContext structure.
+ simpleTestContext = InitSysContext( 1000, resMgrTctiContext, &abiVersion );
+ if( simpleTestContext == 0 )
+ {
+ InitSysContextFailure();
+ }
+
+ // Setup the NV index's authorization value.
+ nvAuth.t.size = strlen( sharedSecret );
+ for( i = 0; i < nvAuth.t.size; i++ )
+ nvAuth.t.buffer[i] = sharedSecret[i];
+
+ //
+ // Create NV index.
+ //
+ if( hmacTest )
+ {
+ // Setup the NV index's authorization value.
+ nvAuth.t.size = strlen( sharedSecret );
+ for( i = 0; i < nvAuth.t.size; i++ )
+ nvAuth.t.buffer[i] = sharedSecret[i];
+
+ // Set NV index's authorization policy
+ // to zero sized policy since we won't be
+ // using policy to authorize.
+
+ authPolicy.t.size = 0;
+ }
+ else
+ {
+ // Zero sized encrypted salt, since the session
+ // is unsalted.
+
+ encryptedSalt.t.size = 0;
+
+ // No symmetric algorithm.
+ symmetric.algorithm = TPM_ALG_NULL;
+
+ //
+ // Create the NV index's authorization policy
+ // using a trial policy session.
+ //
+ rval = StartAuthSessionWithParams( &trialPolicySession,
+ TPM_RH_NULL, 0, TPM_RH_NULL, 0, &nonceCaller, &encryptedSalt,
+ TPM_SE_TRIAL,
+ &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_PolicyAuthValue( simpleTestContext,
+ trialPolicySession->sessionHandle, 0, 0 );
+ CheckPassed( rval );
+
+ // Get policy digest.
+ rval = Tss2_Sys_PolicyGetDigest( simpleTestContext,
+ trialPolicySession->sessionHandle,
+ 0, &authPolicy, 0 );
+ CheckPassed( rval );
+
+ // End the trial session by flushing it.
+ rval = Tss2_Sys_FlushContext( simpleTestContext,
+ trialPolicySession->sessionHandle );
+ CheckPassed( rval );
+
+ // And remove the trial policy session from
+ // sessions table.
+ rval = EndAuthSession( trialPolicySession );
+ CheckPassed( rval );
+ }
+
+ // Now set the NV index's attributes:
+ // policyRead, authWrite, and platormCreate.
+ *(UINT32 *)( &nvAttributes ) = 0;
+ if( hmacTest )
+ {
+ nvAttributes.TPMA_NV_AUTHREAD = 1;
+ nvAttributes.TPMA_NV_AUTHWRITE = 1;
+ }
+ else
+ {
+ nvAttributes.TPMA_NV_POLICYREAD = 1;
+ nvAttributes.TPMA_NV_POLICYWRITE = 1;
+ }
+ nvAttributes.TPMA_NV_PLATFORMCREATE = 1;
+
+ // Create the NV index.
+ rval = DefineNvIndex( TPM_RH_PLATFORM, TPM_RS_PW,
+ &nvAuth, &authPolicy, TPM20_INDEX_PASSWORD_TEST,
+ TPM_ALG_SHA256, nvAttributes, 32 );
+ CheckPassed( rval );
+
+ // Add index and associated authorization value to
+ // entity table. This helps when we need
+ // to calculate HMACs.
+ AddEntity( TPM20_INDEX_PASSWORD_TEST, &nvAuth );
+ CheckPassed( rval );
+
+ // Get the name of the NV index.
+ rval = (*HandleToNameFunctionPtr)(
+ TPM20_INDEX_PASSWORD_TEST,
+ &nvName );
+ CheckPassed( rval );
+
+
+ //
+ // Start HMAC or real (non-trial) policy authorization session:
+ // it's an unbound and unsalted session, no symmetric
+ // encryption algorithm, and SHA256 is the session's
+ // hash algorithm.
+ //
+
+ // Zero sized encrypted salt, since the session
+ // is unsalted.
+ encryptedSalt.t.size = 0;
+
+ // No symmetric algorithm.
+ symmetric.algorithm = TPM_ALG_NULL;
+
+ // Create the session, hmac or policy depending
+ // on hmacTest.
+ // Session state (session handle, nonces, etc.) gets
+ // saved into nvSession structure for later use.
+ if( hmacTest )
+ tpmSe = TPM_SE_HMAC;
+ else
+ tpmSe = TPM_SE_POLICY;
+
+ rval = StartAuthSessionWithParams( &nvSession, TPM_RH_NULL,
+ 0, TPM_RH_NULL, 0, &nonceCaller, &encryptedSalt, tpmSe,
+ &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+
+ // Get the name of the session and save it in
+ // the nvSession structure.
+ rval = (*HandleToNameFunctionPtr)( nvSession->sessionHandle,
+ &(nvSession->name) );
+ CheckPassed( rval );
+
+ // Initialize NV write data.
+ nvWriteData.t.size = sizeof( dataToWrite );
+ for( i = 0; i < nvWriteData.t.size; i++ )
+ {
+ nvWriteData.t.buffer[i] = dataToWrite[i];
+ }
+
+ //
+ // Now setup for writing the NV index.
+ //
+ if( !hmacTest )
+ {
+ // Send policy command.
+ rval = Tss2_Sys_PolicyAuthValue( simpleTestContext,
+ nvSession->sessionHandle, 0, 0 );
+ CheckPassed( rval );
+ }
+
+ // First call prepare in order to create cpBuffer.
+ rval = Tss2_Sys_NV_Write_Prepare( simpleTestContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvWriteData, 0 );
+ CheckPassed( rval );
+
+ // Configure command authorization area, except for HMAC.
+ nvCmdAuths.cmdAuths[0]->sessionHandle =
+ nvSession->sessionHandle;
+ nvCmdAuths.cmdAuths[0]->nonce.t.size = 1;
+ nvCmdAuths.cmdAuths[0]->nonce.t.buffer[0] = 0xa5;
+ *( (UINT8 *)(&sessionAttributes ) ) = 0;
+ nvCmdAuths.cmdAuths[0]->sessionAttributes = sessionAttributes;
+ nvCmdAuths.cmdAuths[0]->sessionAttributes.continueSession = 1;
+
+ // Roll nonces for command
+ RollNonces( nvSession, &nvCmdAuths.cmdAuths[0]->nonce );
+
+ // Complete command authorization area, by computing
+ // HMAC and setting it in nvCmdAuths.
+ rval = ComputeCommandHmacs( simpleTestContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvCmdAuths,
+ TPM_RC_FAILURE );
+ CheckPassed( rval );
+
+ // Finally!! Write the data to the NV index.
+ // If the command is successful, the command
+ // HMAC was correct.
+ sessionCmdRval = Tss2_Sys_NV_Write( simpleTestContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &nvCmdAuths, &nvWriteData, 0, &nvRspAuths );
+ CheckPassed( sessionCmdRval );
+
+ // Roll nonces for response
+ RollNonces( nvSession, &nvRspAuths.rspAuths[0]->nonce );
+
+ if( sessionCmdRval == TPM_RC_SUCCESS )
+ {
+ // If the command was successful, check the
+ // response HMAC to make sure that the
+ // response was received correctly.
+ rval = CheckResponseHMACs( simpleTestContext, sessionCmdRval,
+ &nvCmdAuths, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvRspAuths );
+ CheckPassed( rval );
+ }
+
+ if( !hmacTest )
+ {
+ // Send policy command.
+ rval = Tss2_Sys_PolicyAuthValue( simpleTestContext,
+ nvSession->sessionHandle, 0, 0 );
+ CheckPassed( rval );
+ }
+ // First call prepare in order to create cpBuffer.
+ rval = Tss2_Sys_NV_Read_Prepare( simpleTestContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ sizeof( dataToWrite ), 0 );
+ CheckPassed( rval );
+
+ // Roll nonces for command
+ RollNonces( nvSession, &nvCmdAuths.cmdAuths[0]->nonce );
+
+ // End the session after next command.
+ nvCmdAuths.cmdAuths[0]->sessionAttributes.continueSession = 0;
+
+ // Complete command authorization area, by computing
+ // HMAC and setting it in nvCmdAuths.
+ rval = ComputeCommandHmacs( simpleTestContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvCmdAuths,
+ TPM_RC_FAILURE );
+ CheckPassed( rval );
+
+ // And now read the data back.
+ // If the command is successful, the command
+ // HMAC was correct.
+ sessionCmdRval = Tss2_Sys_NV_Read( simpleTestContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &nvCmdAuths, sizeof( dataToWrite ), 0,
+ &nvReadData, &nvRspAuths );
+ CheckPassed( sessionCmdRval );
+
+ // Roll nonces for response
+ RollNonces( nvSession, &nvRspAuths.rspAuths[0]->nonce );
+
+ if( sessionCmdRval == TPM_RC_SUCCESS )
+ {
+ // If the command was successful, check the
+ // response HMAC to make sure that the
+ // response was received correctly.
+ rval = CheckResponseHMACs( simpleTestContext, sessionCmdRval,
+ &nvCmdAuths, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvRspAuths );
+ CheckPassed( rval );
+ }
+
+ // Check that write and read data are equal.
+ if( memcmp( (void *)&nvReadData.t.buffer[0],
+ (void *)&nvWriteData.t.buffer[0], nvReadData.t.size ) )
+ {
+ TpmClientPrintf( 0, "ERROR!! read data not equal to written data\n" );
+ Cleanup();
+ }
+
+ //
+ // Now cleanup: undefine the NV index and delete
+ // the NV index's entity table entry.
+ //
+
+ // Setup authorization for undefining the NV index.
+ nvCmdAuths.cmdAuths[0]->sessionHandle = TPM_RS_PW;
+ nvCmdAuths.cmdAuths[0]->nonce.t.size = 0;
+ nvCmdAuths.cmdAuths[0]->hmac.t.size = 0;
+
+ // Undefine the NV index.
+ rval = Tss2_Sys_NV_UndefineSpace( simpleTestContext,
+ TPM_RH_PLATFORM, TPM20_INDEX_PASSWORD_TEST,
+ &nvCmdAuths, 0 );
+ CheckPassed( rval );
+
+ // Delete the NV index's entry in the entity table.
+ rval = DeleteEntity( TPM20_INDEX_PASSWORD_TEST );
+ CheckPassed( rval );
+
+ // Remove the real session from sessions table.
+ rval = EndAuthSession( nvSession );
+
+ CheckPassed( rval );
+
+ TeardownSysContext( &simpleTestContext );
+}
+
+
+typedef struct {
+ TPMI_DH_OBJECT tpmKey;
+ TPMI_DH_ENTITY bound;
+ TPM2B_MAX_BUFFER *salt;
+ char hmacTestDescription[50];
+} HMAC_TEST_SETUP;
+
+TPM2B_MAX_BUFFER nullSalt = { { 0, { 0xa4 } }, };
+TPM2B_MAX_BUFFER nonNullSalt = { { 2, { 0xa5, 0 } } };
+
+HMAC_TEST_SETUP hmacTestSetups[] =
+{
+ { TPM_RH_NULL, TPM_RH_NULL, &nullSalt, "UNBOUND/UNSALTED SESSION TEST" },
+ { TPM_RH_NULL, TPM20_INDEX_PASSWORD_TEST, &nullSalt, "BOUND SESSION TEST" },
+ { 0, TPM_RH_NULL, &nonNullSalt, "SALTED SESSION TEST" },
+ { 0, TPM20_INDEX_PASSWORD_TEST, &nonNullSalt, "BOUND/SALTED SESSION TEST" },
+};
+
+#define PLAINTEXT_SESSION 0
+#define DECRYPT_SESSION 1
+#define ENCRYPT_SESSION 2
+
+//UINT8 decryptEncryptSetups[] = { PLAINTEXT_SESSION, DECRYPT_SESSION, ENCRYPT_SESSION };
+UINT8 decryptEncryptSetups[] = { PLAINTEXT_SESSION };
+
+#define CFB_MODE 0
+#define XOR_MODE 1
+
+void HmacSessionTest()
+{
+ UINT32 rval;
+ unsigned int i, j, k, decryptEncryptMode;
+ TPM2B_MAX_NV_BUFFER nvWriteData;
+ UINT8 dataToWrite[] = { 0x00, 0xff, 0x55, 0xaa };
+ TPM2B_NAME nvName;
+ TPM_RC sessionCmdRval;
+
+ SESSION *nvSession;
+ TSS2_SYS_CONTEXT *rdSysContext;
+ TSS2_SYS_CONTEXT *wrSysContext;
+ TPM2B_AUTH nvAuth;
+ TPMT_SYM_DEF symmetric;
+ TPM2B_NONCE nonceOlder;
+
+ // Create two sysContext structures.
+ rdSysContext = InitSysContext( 1000, resMgrTctiContext, &abiVersion );
+ if( rdSysContext == 0 )
+ {
+ InitSysContextFailure();
+ }
+
+ wrSysContext = InitSysContext( 1000, resMgrTctiContext, &abiVersion );
+ if( wrSysContext == 0 )
+ {
+ InitSysContextFailure();
+ }
+
+ char sharedSecret[] = "shared secret";
+
+ char buffer1contents[] = "test";
+ char buffer2contents[] = "string";
+
+ TPM2B_MAX_BUFFER buffer1;
+ TPM2B_MAX_BUFFER buffer2;
+
+// TPM2B_IV ivIn, ivOut;
+ TPM2B_MAX_NV_BUFFER nvData;
+ TPM2B_ENCRYPTED_SECRET encryptedSalt;
+
+ encryptedSalt.t.size = 0;
+// ivIn.t.size = 0;
+// ivOut.t.size = 0;
+
+ buffer1.t.size = strlen( buffer1contents );
+ memcpy (buffer1.t.buffer, buffer1contents, buffer1.t.size );
+ buffer2.t.size = strlen( buffer2contents );
+ memcpy (buffer2.t.buffer, buffer2contents, buffer2.t.size );
+
+
+ for( j = 0; j < sizeof( hmacTestSetups ) / sizeof( HMAC_TEST_SETUP ); j++ )
+ {
+ if( hmacTestSetups[j].salt == &nonNullSalt )
+ {
+ hmacTestSetups[j].tpmKey = handle2048rsa;
+ }
+ }
+ TpmClientPrintf( 0, "\nHMAC SESSION TESTS:\n" );
+
+ for( j = 0; j < sizeof( hmacTestSetups ) / sizeof( HMAC_TEST_SETUP ); j++ )
+ {
+ // Iterate through variations of decrypt and encrypt sessions.
+ for( k = 0; k < sizeof( decryptEncryptSetups ); k++ )
+ {
+ for( decryptEncryptMode = CFB_MODE; decryptEncryptMode < XOR_MODE; decryptEncryptMode++ )
+ {
+ TPMS_AUTH_COMMAND sessionData = { TPM_RS_PW, };
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TPMS_AUTH_COMMAND *sessionDataArray[1] = { &sessionData };
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1] = { &sessionDataOut };
+ TSS2_SYS_CMD_AUTHS sessionsData = { 1, &sessionDataArray[0] };
+ TSS2_SYS_RSP_AUTHS sessionsDataOut = { 1, &sessionDataOutArray[0] };
+
+ TPMT_RSA_DECRYPT inScheme;
+ TPM2B_DATA label;
+ TPM2B_DIGEST authPolicy;
+ TPMA_NV nvAttributes;
+
+ TpmClientPrintf( 0, "\n\n%s:\n", hmacTestSetups[j].hmacTestDescription );
+
+ if( hmacTestSetups[j].tpmKey != TPM_RH_NULL )
+ {
+ sessionsData.cmdAuths[0]->hmac = loadedSha1KeyAuth;
+ sessionsData.cmdAuths[0]->sessionHandle = TPM_RS_PW;
+ sessionsData.cmdAuths[0]->nonce.t.size = 0;
+ *( (UINT8 *)(&sessionData.sessionAttributes ) ) = 0;
+
+ inScheme.scheme = TPM_ALG_OAEP;
+ inScheme.details.oaep.hashAlg = TPM_ALG_SHA1;
+ memcpy( &( label.b.buffer ), "SECRET", 1 + strlen( "SECRET" ) );
+ label.t.size = strlen( "SECRET" ) + 1;
+
+ // Encrypt salt with tpmKey.
+ rval = Tss2_Sys_RSA_Encrypt( sysContext, handle2048rsa,
+ 0, (TPM2B_PUBLIC_KEY_RSA *)( hmacTestSetups[j].salt ),
+ &inScheme, &label, (TPM2B_PUBLIC_KEY_RSA *)&encryptedSalt, 0 );
+ CheckPassed( rval );
+ }
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // NOW CREATE THE INDEX
+ authPolicy.t.size = 0;
+
+ nvAuth.t.size = strlen( sharedSecret );
+ for( i = 0; i < nvAuth.t.size; i++ )
+ nvAuth.t.buffer[i] = sharedSecret[i];
+
+ // Now set the attributes.
+ *(UINT32 *)( &nvAttributes ) = 0;
+ nvAttributes.TPMA_NV_AUTHREAD = 1;
+ nvAttributes.TPMA_NV_AUTHWRITE = 1;
+ nvAttributes.TPMA_NV_PLATFORMCREATE = 1;
+
+ rval = DefineNvIndex( TPM_RH_PLATFORM, TPM_RS_PW, &nvAuth, &authPolicy,
+ TPM20_INDEX_PASSWORD_TEST, TPM_ALG_SHA1, nvAttributes, 32 );
+ CheckPassed( rval );
+
+ AddEntity( TPM20_INDEX_PASSWORD_TEST, &nvAuth );
+ CheckPassed( rval );
+
+ // Get the name using TPM function.
+ rval = (*HandleToNameFunctionPtr)( TPM20_INDEX_PASSWORD_TEST, &nvName );
+ CheckPassed( rval );
+
+ //
+ // Start session
+ //
+ nonceOlder.t.size = GetDigestSize( TPM_ALG_SHA1 );
+ for( i = 0; i < nonceOlder.t.size; i++ )
+ nonceOlder.t.buffer[i] = 0;
+
+ if( decryptEncryptSetups[k] == PLAINTEXT_SESSION )
+ {
+ symmetric.algorithm = TPM_ALG_NULL;
+ }
+ else if( decryptEncryptSetups[k] == DECRYPT_SESSION || decryptEncryptSetups[k] == ENCRYPT_SESSION )
+ {
+ if( decryptEncryptMode == CFB_MODE )
+ {
+ symmetric.algorithm = TPM_ALG_AES;
+ symmetric.keyBits.aes = 128;
+ symmetric.mode.aes = TPM_ALG_CFB;
+ }
+ else if( decryptEncryptMode == XOR_MODE )
+ {
+ symmetric.algorithm = TPM_ALG_XOR;
+ symmetric.keyBits.exclusiveOr = TPM_ALG_SHA256;
+ }
+ }
+
+ rval = StartAuthSessionWithParams( &nvSession, hmacTestSetups[j].tpmKey,
+ hmacTestSetups[j].salt, hmacTestSetups[j].bound, &nvAuth, &nonceOlder, &encryptedSalt,
+ TPM_SE_HMAC, &symmetric, TPM_ALG_SHA1 );
+ CheckPassed( rval );
+
+ // Get and print name of the session.
+ rval = (*HandleToNameFunctionPtr)( nvSession->sessionHandle, &nvSession->name );
+ CheckPassed( rval );
+
+ OpenOutFile( &outFp );
+ TpmClientPrintf( 0, "Name of authSession: " );
+ PrintSizedBuffer( (TPM2B *)&nvSession->name );
+ CloseOutFile( &outFp );
+
+ // Init write data.
+ nvWriteData.t.size = sizeof( dataToWrite );
+
+ for( i = 0; i < nvWriteData.t.size; i++ )
+ {
+ nvWriteData.t.buffer[i] = dataToWrite[i];
+ }
+
+ if( decryptEncryptSetups[k] == DECRYPT_SESSION )
+ {
+ if( decryptEncryptMode == CFB_MODE )
+ {
+// rval = EncryptCFB( &nvSession, &( nvWriteData.b ) );
+ }
+ else if( decryptEncryptMode == XOR_MODE )
+ {
+// rval = EncryptXOR( &nvSession, &( nvWriteData.b ) );
+ }
+ sessionsData.cmdAuths[0]->sessionAttributes.decrypt = 1;
+ }
+ else
+ {
+ sessionsData.cmdAuths[0]->sessionAttributes.decrypt = 0;
+ }
+ sessionsData.cmdAuths[0]->sessionAttributes.encrypt = 0;
+
+ CheckPassed( rval );
+
+ sessionsData.cmdAuths[0]->sessionHandle = nvSession->sessionHandle;
+ sessionsData.cmdAuths[0]->nonce.t.size = 1;
+ sessionsData.cmdAuths[0]->nonce.t.buffer[0] = 0xa5;
+
+ // Roll nonces for command
+ RollNonces( nvSession, &sessionsData.cmdAuths[0]->nonce );
+
+ // Now try writing with bad HMAC.
+ rval = Tss2_Sys_NV_Write_Prepare( wrSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvWriteData, 0 );
+ CheckPassed( rval );
+
+ rval = ComputeCommandHmacs( wrSysContext,
+ TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &sessionsData, TPM_RC_FAILURE );
+ CheckPassed( rval );
+
+ // Diddle with HMAC to force failure
+ sessionsData.cmdAuths[0]->hmac.t.buffer[0] =
+ ~( sessionsData.cmdAuths[0]->hmac.t.buffer[0] );
+
+ sessionCmdRval = Tss2_Sys_NV_Write( wrSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST,
+ &sessionsData, &nvWriteData, 0, &sessionsDataOut );
+ CheckFailed( sessionCmdRval, TPM_RC_S + TPM_RC_1 + TPM_RC_AUTH_FAIL );
+
+ // Since command failed, no need to roll nonces.
+
+ TestDictionaryAttackLockReset();
+
+ // Now try writing with good HMAC.
+
+ // Do stage 1 of NVRead, followed by stage 1 and 2 of NVWrite, followed by
+ // stage 2 of NVRead. This tests that the staged processing is thread-safe.
+ sessionsData.cmdAuths[0]->sessionAttributes.continueSession = 0;
+ rval = Tss2_Sys_NV_Read_Prepare( rdSysContext, TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST, sizeof( dataToWrite ), 0 );
+ CheckPassed( rval );
+
+ sessionsData.cmdAuths[0]->sessionAttributes.continueSession = 1;
+ rval = Tss2_Sys_NV_Write_Prepare( wrSysContext, TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST,
+ &nvWriteData, 0 );
+ CheckPassed( rval );
+
+ rval = ComputeCommandHmacs( wrSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &sessionsData, sessionCmdRval );
+ CheckPassed( rval );
+
+ sessionCmdRval = Tss2_Sys_NV_Write( wrSysContext,
+ TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST, &sessionsData, &nvWriteData, 0, &sessionsDataOut );
+ CheckPassed( sessionCmdRval );
+ if( sessionCmdRval == TPM_RC_SUCCESS )
+ {
+ // Roll nonces for response
+ RollNonces( nvSession, &sessionsDataOut.rspAuths[0]->nonce );
+
+ rval = CheckResponseHMACs( wrSysContext, sessionCmdRval,
+ &sessionsData, TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST, &sessionsDataOut );
+ CheckPassed( rval );
+ }
+
+ // Roll nonces for command
+ RollNonces( nvSession, &sessionsData.cmdAuths[0]->nonce );
+
+ sessionsData.cmdAuths[0]->sessionAttributes.continueSession = 0;
+ rval = ComputeCommandHmacs( rdSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &sessionsData, sessionCmdRval );
+ CheckPassed( rval );
+
+ if( decryptEncryptSetups[k] == ENCRYPT_SESSION )
+ {
+ sessionsData.cmdAuths[0]->sessionAttributes.encrypt = 1;
+ }
+ else
+ {
+ sessionsData.cmdAuths[0]->sessionAttributes.encrypt = 0;
+ }
+ sessionsData.cmdAuths[0]->sessionAttributes.decrypt = 0;
+
+ sessionCmdRval = Tss2_Sys_NV_Read( rdSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &sessionsData, sizeof( dataToWrite ), 0, &nvData, &sessionsDataOut );
+ CheckPassed( sessionCmdRval );
+ if( sessionCmdRval == TPM_RC_SUCCESS )
+ {
+ // Roll nonces for response
+ RollNonces( nvSession, &sessionsDataOut.rspAuths[0]->nonce );
+
+ rval = CheckResponseHMACs( rdSysContext, sessionCmdRval,
+ &sessionsData, TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST, &sessionsDataOut );
+ CheckPassed( rval );
+
+ if( decryptEncryptSetups[k] == ENCRYPT_SESSION )
+ {
+ if( decryptEncryptMode == CFB_MODE )
+ {
+// rval = EncryptCFB( nvSession, &( nvData.b ) );
+ }
+ else if( decryptEncryptMode == XOR_MODE )
+ {
+// rval = EncryptXOR( nvSession, &( nvData.b ) );
+ }
+ CheckPassed( rval );
+ }
+
+ // Check that write actually worked.
+ rval = CompareTPM2B( &(nvWriteData.b), &(nvData.b) );
+ CheckPassed( rval );
+ }
+
+ //
+ // NOTE: When running against version of the simulator for TPM spec versions later
+ // than version 0.98, in order for the session to act as a bound session when accessing
+ // the bind entity, we will need to restart the session here since the name of the bound
+ // entity changed.
+ //
+ if( hmacTestSetups[j].bound != TPM_RH_NULL )
+ {
+ rval = EndAuthSession( nvSession );
+ CheckPassed( rval );
+
+ //
+ // Start session
+ //
+ nonceOlder.t.size = GetDigestSize( TPM_ALG_SHA1 );
+ for( i = 0; i < nonceOlder.t.size; i++ )
+ nonceOlder.t.buffer[i] = 0;
+
+ symmetric.algorithm = TPM_ALG_AES;
+ symmetric.keyBits.aes = 128;
+ symmetric.mode.aes = TPM_ALG_CFB;
+
+ rval = StartAuthSessionWithParams( &nvSession, hmacTestSetups[j].tpmKey, hmacTestSetups[j].salt, hmacTestSetups[j].bound, &nvAuth, &nonceOlder, &encryptedSalt, TPM_SE_HMAC, &symmetric, TPM_ALG_SHA1 );
+ CheckPassed( rval );
+
+ CopySizedByteBuffer( &( nvSession->authValueBind.b ), &( nvAuth.b ) );
+
+ // Now try writing with good HMAC.
+ sessionsData.cmdAuths[0]->sessionHandle = nvSession->sessionHandle;
+ sessionsData.cmdAuths[0]->nonce.t.size = 1;
+ sessionsData.cmdAuths[0]->nonce.t.buffer[0] = 0xa5;
+ sessionsData.cmdAuths[0]->sessionAttributes.continueSession = 1;
+ sessionsData.cmdAuths[0]->sessionAttributes.decrypt = 1;
+
+ // TBD: Need to encrypt data before sending.
+
+ rval = Tss2_Sys_NV_Write_Prepare( wrSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvWriteData, 0 );
+ CheckPassed( rval );
+
+ // Roll nonces for command
+ RollNonces( nvSession, &sessionsData.cmdAuths[0]->nonce );
+
+ rval = ComputeCommandHmacs( wrSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &sessionsData, TPM_RC_FAILURE );
+ CheckPassed( rval );
+
+ sessionCmdRval = Tss2_Sys_NV_Write( wrSysContext, TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST, &sessionsData, &nvWriteData, 0, &sessionsDataOut );
+ sessionsData.cmdAuths[0]->sessionAttributes.decrypt = 0;
+ CheckPassed( sessionCmdRval );
+ if( sessionCmdRval == TPM_RC_SUCCESS )
+ {
+ // Roll nonces for response
+ RollNonces( nvSession, &sessionsDataOut.rspAuths[0]->nonce );
+
+ rval = CheckResponseHMACs( wrSysContext, sessionCmdRval,
+ &sessionsData, TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST, &sessionsDataOut );
+ CheckPassed( rval );
+ }
+
+ // Need to do GetSessionAuditDigest to check that audit digest changed.
+
+ sessionsData.cmdAuths[0]->sessionAttributes.continueSession = 0;
+ sessionsData.cmdAuths[0]->sessionAttributes.encrypt = 1;
+ sessionsData.cmdAuths[0]->sessionAttributes.audit = 1;
+
+ rval = Tss2_Sys_NV_Read_Prepare( rdSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, sizeof( dataToWrite ), 0 );
+ CheckPassed( rval );
+
+ // Roll nonces for command
+ RollNonces( nvSession, &sessionsData.cmdAuths[0]->nonce );
+
+ rval = ComputeCommandHmacs( rdSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &sessionsData, sessionCmdRval );
+ CheckPassed( rval );
+
+ sessionCmdRval = Tss2_Sys_NV_Read( rdSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &sessionsData, sizeof( dataToWrite ), 0, &nvData, &sessionsDataOut );
+ sessionsData.cmdAuths[0]->sessionAttributes.encrypt = 0;
+ sessionsData.cmdAuths[0]->sessionAttributes.audit = 0;
+ if( sessionCmdRval == TPM_RC_SUCCESS )
+ {
+ // Roll nonces for response
+ RollNonces( nvSession, &sessionsDataOut.rspAuths[0]->nonce );
+
+ rval = CheckResponseHMACs( rdSysContext, sessionCmdRval,
+ &sessionsData, TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST, &sessionsDataOut );
+ CheckPassed( rval );
+ }
+
+ // TBD: Need to decrypt response data.
+
+ CheckPassed( rval );
+ // TBD: Need to do GetSessionAuditDigest to check that audit digest changed.
+ }
+
+ // Removed comparison for now until we figure out how to properly
+ // encrypt data before writing to NV index.
+ // rval = CompareTPM2B( &(nvWriteData.b), &(nvData.b) );
+ // CheckPassed( rval );
+
+ sessionsData.cmdAuths[0]->sessionHandle = TPM_RS_PW;
+ sessionsData.cmdAuths[0]->nonce.t.size = 0;
+ sessionsData.cmdAuths[0]->nonce.t.buffer[0] = 0xa5;
+ sessionData.hmac.t.size = 0;
+ // Now undefine the index.
+ rval = Tss2_Sys_NV_UndefineSpace( wrSysContext, TPM_RH_PLATFORM, TPM20_INDEX_PASSWORD_TEST, &sessionsData, 0 );
+ CheckPassed( rval );
+ rval = DeleteEntity( TPM20_INDEX_PASSWORD_TEST );
+ CheckPassed( rval );
+ rval = EndAuthSession( nvSession );
+ CheckPassed( rval );
+ }
+ }
+ }
+
+ TeardownSysContext( &wrSysContext );
+ TeardownSysContext( &rdSysContext );
+
+}
+
+UINT32 writeDataString = 0xdeadbeef;
+
+void TestEncryptDecryptSession()
+{
+ TSS2_RC rval = TSS2_RC_SUCCESS;
+ SESSION *encryptDecryptSession;
+ TPMT_SYM_DEF symmetric;
+ TPM2B_MAX_NV_BUFFER writeData, encryptedWriteData;
+ TPM2B_MAX_NV_BUFFER encryptedReadData, decryptedReadData,
+ readData;
+ size_t decryptParamSize;
+ uint8_t *decryptParamBuffer;
+ size_t encryptParamSize;
+ uint8_t *encryptParamBuffer;
+ TPM2B_AUTH nvAuth;
+ TPM2B_DIGEST authPolicy;
+ TPMA_NV nvAttributes;
+ int i;
+ TPMA_SESSION sessionAttributes;
+ TPM2B_NONCE nonceCaller;
+
+ nonceCaller.t.size = 0;
+
+ // Authorization structure for undefine command.
+ TPMS_AUTH_COMMAND nvUndefineAuth;
+
+ // Create and init authorization area for undefine command:
+ // only 1 authorization area.
+ TPMS_AUTH_COMMAND *nvUndefineAuthArray[1] = { &nvUndefineAuth };
+
+ // Authorization array for command (only has one auth structure).
+ TSS2_SYS_CMD_AUTHS nvUndefineAuths = { 1, &nvUndefineAuthArray[0] };
+
+ TpmClientPrintf( 0, "\n\nDECRYPT/ENCRYPT SESSION TESTS:\n" );
+
+ writeData.t.size = sizeof( writeDataString );
+ memcpy( (void *)&writeData.t.buffer, (void *)&writeDataString,
+ sizeof( writeDataString ) );
+
+
+ // Create NV index with empty auth value.
+ *(UINT32 *)( (void *)&nvAttributes ) = 0;
+ nvAttributes.TPMA_NV_AUTHREAD = 1;
+ nvAttributes.TPMA_NV_AUTHWRITE = 1;
+ nvAttributes.TPMA_NV_PLATFORMCREATE = 1;
+
+ // No authorization required.
+ authPolicy.t.size = 0;
+ nvAuth.t.size = 0;
+ rval = DefineNvIndex( TPM_RH_PLATFORM, TPM_RS_PW,
+ &nvAuth, &authPolicy, TPM20_INDEX_TEST1,
+ TPM_ALG_SHA1, nvAttributes,
+ sizeof( writeDataString ) );
+
+ //
+ // 1st pass with CFB mode.
+ // 2nd pass with XOR mode.
+ //
+ for( i = 0; i < 2; i++ )
+ {
+ // Authorization structure for NV
+ // read/write commands.
+ TPMS_AUTH_COMMAND nvRdWrCmdAuth;
+
+ // Authorization structure for
+ // encrypt/decrypt session.
+ TPMS_AUTH_COMMAND decryptEncryptSessionCmdAuth;
+
+ // Create and init authorization area for
+ // NV read/write commands:
+ // 2 authorization areas.
+ TPMS_AUTH_COMMAND *nvRdWrCmdAuthArray[2] =
+ { &nvRdWrCmdAuth, &decryptEncryptSessionCmdAuth };
+
+ // Authorization array for commands
+ // (has two auth structures).
+ TSS2_SYS_CMD_AUTHS nvRdWrCmdAuths =
+ { 2, &nvRdWrCmdAuthArray[0] };
+
+ // Authorization structure for NV read/write responses.
+ TPMS_AUTH_RESPONSE nvRdWrRspAuth;
+ // Authorization structure for decrypt/encrypt
+ // session responses.
+ TPMS_AUTH_RESPONSE decryptEncryptSessionRspAuth;
+
+ // Create and init authorization area for NV
+ // read/write responses: 2 authorization areas.
+ TPMS_AUTH_RESPONSE *nvRdWrRspAuthArray[2] =
+ { &nvRdWrRspAuth, &decryptEncryptSessionRspAuth };
+ // Authorization array for responses
+ // (has two auth structures).
+ TSS2_SYS_RSP_AUTHS nvRdWrRspAuths =
+ { 2, &nvRdWrRspAuthArray[0] };
+
+ // Setup session parameters.
+ if( i == 0 )
+ {
+ // AES encryption/decryption and CFB mode.
+ symmetric.algorithm = TPM_ALG_AES;
+ symmetric.keyBits.aes = 128;
+ symmetric.mode.aes = TPM_ALG_CFB;
+ }
+ else
+ {
+ // XOR encryption/decryption.
+ symmetric.algorithm = TPM_ALG_XOR;
+ symmetric.keyBits.exclusiveOr = TPM_ALG_SHA256;
+ }
+
+ // Start policy session for decrypt/encrypt session.
+ rval = StartAuthSessionWithParams( &encryptDecryptSession,
+ TPM_RH_NULL, 0, TPM_RH_NULL, 0, &nonceCaller, 0, TPM_SE_POLICY,
+ &symmetric, TPM_ALG_SHA256 );
+ CheckPassed( rval );
+
+ //
+ // Write TPM index with encrypted parameter used
+ // as the data to write. Set session for encrypt.
+ // Use asyncronous APIs to do this.
+ //
+ // 1st time: use null buffer, 2nd time use populated one;
+ // this tests different cases for SetDecryptParam function.
+ //
+
+ // Prepare the input parameters, using unencypted
+ // write data. This will be encrypted before the
+ // command is sent to the TPM.
+ rval = Tss2_Sys_NV_Write_Prepare( sysContext,
+ TPM20_INDEX_TEST1, TPM20_INDEX_TEST1,
+ ( i == 0 ? (TPM2B_MAX_NV_BUFFER *)0 : &writeData ),
+ 0 );
+ CheckPassed( rval );
+
+ // Set up password authorization session structure.
+ nvRdWrCmdAuth.sessionHandle = TPM_RS_PW;
+ nvRdWrCmdAuth.nonce.t.size = 0;
+ *( (UINT8 *)((void *)&nvRdWrCmdAuth.sessionAttributes ) ) = 0;
+ nvRdWrCmdAuth.hmac.t.size = nvAuth.t.size;
+ memcpy( (void *)&nvRdWrCmdAuth.hmac.t.buffer[0],
+ (void *)&nvAuth.t.buffer[0],
+ nvRdWrCmdAuth.hmac.t.size );
+
+ // Set up encrypt/decrypt session structure.
+ decryptEncryptSessionCmdAuth.sessionHandle =
+ encryptDecryptSession->sessionHandle;
+ decryptEncryptSessionCmdAuth.nonce.t.size = 0;
+ *( (UINT8 *)((void *)&sessionAttributes ) ) = 0;
+ decryptEncryptSessionCmdAuth.sessionAttributes =
+ sessionAttributes;
+ decryptEncryptSessionCmdAuth.sessionAttributes.continueSession
+ = 1;
+ decryptEncryptSessionCmdAuth.sessionAttributes.decrypt = 1;
+ decryptEncryptSessionCmdAuth.hmac.t.size = 0;
+
+ rval = Tss2_Sys_SetCmdAuths( sysContext, &nvRdWrCmdAuths );
+ CheckPassed( rval );
+
+ // Get decrypt parameter.
+ rval = Tss2_Sys_GetDecryptParam( sysContext,
+ &decryptParamSize,
+ (const uint8_t **)&decryptParamBuffer );
+ CheckPassed( rval );
+
+ if( i == 0 )
+ {
+ // 1st pass: test case of Prepare inputting a NULL decrypt
+ // param; decryptParamSize should be 0.
+ if( decryptParamSize != 0 )
+ {
+ TpmClientPrintf( 0, "ERROR!! decryptParamSize != 0\n" );
+ Cleanup();
+ }
+ }
+
+ // Roll nonces for command.
+ RollNonces( encryptDecryptSession,
+ &decryptEncryptSessionCmdAuth.nonce );
+
+ // Encrypt write data.
+ rval = EncryptCommandParam( encryptDecryptSession,
+ (TPM2B_MAX_BUFFER *)&encryptedWriteData,
+ (TPM2B_MAX_BUFFER *)&writeData, &nvAuth );
+ CheckPassed( rval );
+
+ // Now set decrypt parameter.
+ rval = Tss2_Sys_SetDecryptParam( sysContext,
+ (uint8_t )encryptedWriteData.t.size,
+ (uint8_t *)&encryptedWriteData.t.buffer[0] );
+ CheckPassed( rval );
+
+ // Now write the data to the NV index.
+ rval = Tss2_Sys_ExecuteAsync( sysContext );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_ExecuteFinish( sysContext, TSS2_TCTI_TIMEOUT_BLOCK );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetRspAuths( sysContext, &nvRdWrRspAuths );
+ CheckPassed( rval );
+
+ // Roll the nonces for response
+ RollNonces( encryptDecryptSession,
+ &nvRdWrRspAuths.rspAuths[1]->nonce );
+
+
+ // Don't need nonces for anything else, so roll
+ // the nonces for next command.
+ RollNonces( encryptDecryptSession,
+ &decryptEncryptSessionCmdAuth.nonce );
+
+ // Now read the data without encrypt set.
+ nvRdWrCmdAuths.cmdAuthsCount = 1;
+ nvRdWrRspAuths.rspAuthsCount = 1;
+ rval = Tss2_Sys_NV_Read( sysContext, TPM20_INDEX_TEST1,
+ TPM20_INDEX_TEST1, &nvRdWrCmdAuths,
+ sizeof( writeDataString ), 0, &readData,
+ &nvRdWrRspAuths );
+ CheckPassed( rval );
+ nvRdWrCmdAuths.cmdAuthsCount = 2;
+ nvRdWrRspAuths.rspAuthsCount = 2;
+
+ // Roll the nonces for response
+ RollNonces( encryptDecryptSession,
+ &nvRdWrRspAuths.rspAuths[1]->nonce );
+
+ // Check that write and read data are equal. This
+ // verifies that the decrypt session was setup correctly.
+ // If it wasn't, the data stored in the TPM would still
+ // be encrypted, and this test would fail.
+ if( memcmp( (void *)&readData.t.buffer[0],
+ (void *)&writeData.t.buffer[0], readData.t.size ) )
+ {
+ TpmClientPrintf( 0, "ERROR!! read data not equal to written data\n" );
+ Cleanup();
+ }
+
+ //
+ // Read TPM index with encrypt session; use
+ // syncronous APIs to do this.
+ //
+
+ rval = Tss2_Sys_NV_Read_Prepare( sysContext, TPM20_INDEX_TEST1,
+ TPM20_INDEX_TEST1, sizeof( writeDataString ), 0 );
+ CheckPassed( rval );
+
+ // Roll the nonces for next command.
+ RollNonces( encryptDecryptSession,
+ &decryptEncryptSessionCmdAuth.nonce );
+
+ decryptEncryptSessionCmdAuth.sessionAttributes.decrypt = 0;
+ decryptEncryptSessionCmdAuth.sessionAttributes.encrypt = 1;
+ decryptEncryptSessionCmdAuth.sessionAttributes.continueSession =
+ 1;
+
+ rval = Tss2_Sys_SetCmdAuths( sysContext, &nvRdWrCmdAuths );
+ CheckPassed( rval );
+
+ //
+ // Now Read the data.
+ //
+ rval = Tss2_Sys_Execute( sysContext );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetEncryptParam( sysContext, &encryptParamSize,
+ (const uint8_t **)&encryptParamBuffer );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetRspAuths( sysContext, &nvRdWrRspAuths );
+ CheckPassed( rval );
+
+ // Roll the nonces for response
+ RollNonces( encryptDecryptSession,
+ &nvRdWrRspAuths.rspAuths[1]->nonce );
+
+ // Decrypt read data.
+ encryptedReadData.t.size = encryptParamSize;
+ memcpy( (void *)&encryptedReadData.t.buffer[0],
+ (void *)encryptParamBuffer, encryptParamSize );
+ rval = DecryptResponseParam( encryptDecryptSession,
+ (TPM2B_MAX_BUFFER *)&decryptedReadData,
+ (TPM2B_MAX_BUFFER *)&encryptedReadData, &nvAuth );
+ CheckPassed( rval );
+
+ // Roll the nonces.
+ RollNonces( encryptDecryptSession,
+ &nvRdWrRspAuths.rspAuths[1]->nonce );
+
+ rval = Tss2_Sys_SetEncryptParam( sysContext,
+ (uint8_t)decryptedReadData.t.size,
+ (uint8_t *)&decryptedReadData.t.buffer[0] );
+ CheckPassed( rval );
+
+ // Get the command results, in this case the read data.
+ rval = Tss2_Sys_NV_Read_Complete( sysContext, &readData );
+ CheckPassed( rval );
+
+ TpmClientPrintf( 0, "Decrypted read data = " );
+ DEBUG_PRINT_BUFFER( &readData.t.buffer[0], (UINT32 )readData.t.size );
+
+ // Check that write and read data are equal.
+ if( memcmp( (void *)&readData.t.buffer[0],
+ (void *)&writeData.t.buffer[0], readData.t.size ) )
+ {
+ TpmClientPrintf( 0, "ERROR!! read data not equal to written data\n" );
+ Cleanup();
+ }
+
+ rval = Tss2_Sys_FlushContext( sysContext,
+ encryptDecryptSession->sessionHandle );
+ CheckPassed( rval );
+
+ rval = EndAuthSession( encryptDecryptSession );
+ CheckPassed( rval );
+ }
+
+ // Set authorization for NV undefine command.
+ nvUndefineAuth.sessionHandle = TPM_RS_PW;
+ nvUndefineAuth.nonce.t.size = 0;
+ *( (UINT8 *)((void *)&nvUndefineAuth.sessionAttributes ) ) = 0;
+ nvUndefineAuth.hmac.t.size = 0;
+
+ // Undefine NV index.
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext,
+ TPM_RH_PLATFORM, TPM20_INDEX_TEST1, &nvUndefineAuths, 0 );
+ CheckPassed( rval );
+}
+
+
+void TestRsaEncryptDecrypt()
+{
+ TPM2B_SENSITIVE_CREATE inSensitive;
+ TPM2B_PUBLIC inPublic;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TPM2B_DATA outsideInfo;
+ TPML_PCR_SELECTION creationPCR;
+ TPM_RC rval;
+ TPM2B_PRIVATE outPrivate;
+ TPM2B_PUBLIC outPublic;
+ TPM2B_CREATION_DATA creationData;
+ TPM2B_DIGEST creationHash;
+ TPMT_TK_CREATION creationTicket;
+ TPM2B_NAME rsaKeyName;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1] = { &sessionData };
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1] = { &sessionDataOut };
+
+ TSS2_SYS_CMD_AUTHS sessionsData = { 1, &sessionDataArray[0] };
+ TSS2_SYS_RSP_AUTHS sessionsDataOut = { 1, &sessionDataOutArray[0] };
+
+ inSensitive.t.sensitive.userAuth = loadedSha1KeyAuth;
+ inSensitive.t.sensitive.data.t.size = 0;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ // Create public/private key pair.
+ inPublic.t.publicArea.type = TPM_ALG_RSA;
+ inPublic.t.publicArea.nameAlg = TPM_ALG_SHA1;
+ *(UINT32 *)( (void *)&( inPublic.t.publicArea.objectAttributes ) ) = 0;
+ inPublic.t.publicArea.objectAttributes.decrypt = 1;
+ inPublic.t.publicArea.authPolicy.t.size = 0;
+
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CTR;
+ inPublic.t.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
+ inPublic.t.publicArea.parameters.rsaDetail.keyBits = 1024;
+ inPublic.t.publicArea.parameters.rsaDetail.exponent = 0;
+ inPublic.t.publicArea.unique.rsa.t.size = 0;
+
+ outsideInfo.t.size = 0;
+ outPublic.t.size = 0;
+ creationData.t.size = 0;
+ rval = Tss2_Sys_Create( sysContext, handle2048rsa, &sessionsData, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR,
+ &outPrivate, &outPublic, &creationData,
+ &creationHash, &creationTicket, &sessionsDataOut );
+
+ CheckPassed( rval );
+
+ // Load private key into TPM
+ rval = Tss2_Sys_Load ( sysContext, handle2048rsa, 0, &outPrivate, &outPublic,
+ &loadedSha1KeyHandle, &rsaKeyName, &sessionsDataOut);
+ CheckPassed( rval );
+
+
+
+ // Encrypt message with public key
+
+ // Print encrypted message.
+
+ // Decrypt message with private key.
+
+ // Print decrypted message.
+
+}
+
+
+void GetSetDecryptParamTests()
+{
+ TPM2B_MAX_NV_BUFFER nvWriteData = { { 4, { 0xde, 0xad, 0xbe, 0xef, } } };
+ TPM2B_MAX_NV_BUFFER nvWriteData1 = { { 4, { 0x01, 0x01, 0x02, 0x03, } } };
+ const uint8_t *decryptParamBuffer;
+ size_t decryptParamSize;
+ size_t cpBufferUsedSize1, cpBufferUsedSize2;
+ const uint8_t *cpBuffer1, *cpBuffer2;
+ TSS2_RC rval;
+ int i;
+ TSS2_SYS_CONTEXT *decryptParamTestSysContext;
+
+ TpmClientPrintf( 0, "\nGET/SET DECRYPT PARAM TESTS:\n" );
+
+ // Create two sysContext structures.
+ decryptParamTestSysContext = InitSysContext( MAX_NV_BUFFER_SIZE, resMgrTctiContext, &abiVersion );
+ if( decryptParamTestSysContext == 0 )
+ {
+ InitSysContextFailure();
+ }
+
+ // Test for bad sequence
+ rval = Tss2_Sys_GetDecryptParam( decryptParamTestSysContext, &decryptParamSize, &decryptParamBuffer );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_SEQUENCE );
+
+ rval = Tss2_Sys_SetDecryptParam( decryptParamTestSysContext, 4, &( nvWriteData.t.buffer[0] ) );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_SEQUENCE );
+
+ // Do Prepare.
+ rval = Tss2_Sys_NV_Write_Prepare( decryptParamTestSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvWriteData1, 0x55aa );
+ CheckPassed( rval );
+
+ // Test for bad reference
+ rval = Tss2_Sys_GetDecryptParam( 0, &decryptParamSize, &decryptParamBuffer );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_REFERENCE );
+
+ rval = Tss2_Sys_GetDecryptParam( decryptParamTestSysContext, 0, &decryptParamBuffer );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_REFERENCE );
+
+ rval = Tss2_Sys_GetDecryptParam( decryptParamTestSysContext, &decryptParamSize, 0 );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_REFERENCE );
+
+ rval = Tss2_Sys_SetDecryptParam( decryptParamTestSysContext, 4, 0 );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_REFERENCE );
+
+ rval = Tss2_Sys_SetDecryptParam( 0, 4, 0 );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_REFERENCE );
+
+ // Test for bad size.
+ rval = Tss2_Sys_SetDecryptParam( decryptParamTestSysContext, 5, &( nvWriteData.t.buffer[0] ) );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_SIZE );
+
+ rval = Tss2_Sys_SetDecryptParam( decryptParamTestSysContext, 3, &( nvWriteData.t.buffer[0] ) );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_SIZE );
+
+ // Test for good size.
+ rval = Tss2_Sys_SetDecryptParam( decryptParamTestSysContext, 4, &( nvWriteData.t.buffer[0] ) );
+ CheckPassed( rval );
+
+ // Make sure that the set operation really did the right thing.
+ rval = Tss2_Sys_GetDecryptParam( decryptParamTestSysContext, &decryptParamSize, &decryptParamBuffer );
+ CheckPassed( rval );
+ for( i = 0; i < 4; i++ )
+ {
+ if( decryptParamBuffer[i] != nvWriteData.t.buffer[i] )
+ {
+ TpmClientPrintf( 0, "ERROR!! decryptParamBuffer[%d] s/b: %2.2x, was: %2.2x\n", i, nvWriteData.t.buffer[i], decryptParamBuffer[i] );
+ Cleanup();
+ }
+ }
+
+ rval = Tss2_Sys_GetCpBuffer( decryptParamTestSysContext, &cpBufferUsedSize1, &cpBuffer1 );
+ CheckPassed( rval );
+
+ OpenOutFile( &outFp );
+#ifdef DEBUG
+ TpmClientPrintf( 0, "cpBuffer = ");
+#endif
+ DEBUG_PRINT_BUFFER( (UINT8 *)cpBuffer1, cpBufferUsedSize1 );
+ CloseOutFile( &outFp );
+
+ // Test for no decrypt param.
+ rval = Tss2_Sys_NV_Read_Prepare( decryptParamTestSysContext, TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST, sizeof( nvWriteData ) - 2, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetDecryptParam( decryptParamTestSysContext, &decryptParamSize, &decryptParamBuffer );
+ CheckFailed( rval, TSS2_SYS_RC_NO_DECRYPT_PARAM );
+
+ rval = Tss2_Sys_SetDecryptParam( decryptParamTestSysContext, 4, &( nvWriteData.t.buffer[0] ) );
+ CheckFailed( rval, TSS2_SYS_RC_NO_DECRYPT_PARAM );
+
+ // Null decrypt param.
+ rval = Tss2_Sys_NV_Write_Prepare( decryptParamTestSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, 0, 0x55aa );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetDecryptParam( decryptParamTestSysContext, &decryptParamSize, &decryptParamBuffer );
+ CheckPassed( rval );
+
+ // Check that size == 0.
+ if( decryptParamSize != 0 )
+ {
+ TpmClientPrintf( 0, "ERROR!! decryptParamSize s/b: 0, was: %u\n", (unsigned int)decryptParamSize );
+ Cleanup();
+ }
+
+ // Test for insufficient size.
+ rval = Tss2_Sys_GetCpBuffer( decryptParamTestSysContext, &cpBufferUsedSize2, &cpBuffer2 );
+ CheckPassed( rval );
+ nvWriteData.t.size = MAX_NV_BUFFER_SIZE -
+ CHANGE_ENDIAN_DWORD( ( (TPM20_Header_In *)( ( (_TSS2_SYS_CONTEXT_BLOB *)decryptParamTestSysContext )->tpmInBuffPtr ) )->commandSize ) +
+ 1;
+ rval = Tss2_Sys_SetDecryptParam( decryptParamTestSysContext, nvWriteData.t.size, &( nvWriteData.t.buffer[0] ) );
+ CheckFailed( rval, TSS2_SYS_RC_INSUFFICIENT_BUFFER );
+
+ // Test that one less will work. This tests that we're checking the correct corner case.
+ nvWriteData.t.size -= 1;
+ rval = Tss2_Sys_SetDecryptParam( decryptParamTestSysContext, nvWriteData.t.size, &( nvWriteData.t.buffer[0] ) );
+ CheckPassed( rval );
+
+
+ rval = Tss2_Sys_NV_Write_Prepare( decryptParamTestSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, 0, 0x55aa );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetDecryptParam( decryptParamTestSysContext, &decryptParamSize, &decryptParamBuffer );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_SetDecryptParam( decryptParamTestSysContext, 4, &( nvWriteData.t.buffer[0] ) );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetCpBuffer( decryptParamTestSysContext, &cpBufferUsedSize2, &cpBuffer2 );
+ CheckPassed( rval );
+
+ OpenOutFile( &outFp );
+#ifdef DEBUG
+ TpmClientPrintf( 0, "cpBuffer = ");
+#endif
+ DEBUG_PRINT_BUFFER( (UINT8 *)cpBuffer2, cpBufferUsedSize2 );
+ CloseOutFile( &outFp );
+
+ if( cpBufferUsedSize1 != cpBufferUsedSize2 )
+ {
+ TpmClientPrintf( 0, "ERROR!! cpBufferUsedSize1(%x) != cpBufferUsedSize2(%x)\n", (UINT32)cpBufferUsedSize1, (UINT32)cpBufferUsedSize2 );
+ Cleanup();
+ }
+ for( i = 0; i < (int)cpBufferUsedSize1; i++ )
+ {
+ if( cpBuffer1[i] != cpBuffer2[i] )
+ {
+ TpmClientPrintf( 0, "ERROR!! cpBufferUsedSize1[%d] s/b: %2.2x, was: %2.2x\n", i, cpBuffer1[i], cpBuffer2[i] );
+ Cleanup();
+ }
+ }
+
+ // Test case of zero sized decrypt param, another case of bad size.
+ nvWriteData1.t.size = 0;
+ rval = Tss2_Sys_NV_Write_Prepare( decryptParamTestSysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvWriteData1, 0x55aa );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_SetDecryptParam( decryptParamTestSysContext, 1, &( nvWriteData.t.buffer[0] ) );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_SIZE );
+
+ TeardownSysContext( &decryptParamTestSysContext );
+}
+
+void GetSetEncryptParamTests()
+{
+ TPM2B_MAX_NV_BUFFER nvWriteData = { { 4, { 0xde, 0xad, 0xbe, 0xef, } } };
+ const uint8_t *encryptParamBuffer;
+ const uint8_t encryptParamBuffer1[4] = { 01, 02, 03, 04 };
+ size_t encryptParamSize;
+ TSS2_RC rval;
+ int i;
+ TPM2B_DIGEST authPolicy;
+ TPMA_NV nvAttributes;
+ TPM2B_AUTH nvAuth;
+
+ TPMS_AUTH_COMMAND sessionData = { TPM_RS_PW, };
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TPMS_AUTH_COMMAND *sessionDataArray[1] = { &sessionData };
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1] = { &sessionDataOut };
+ TSS2_SYS_CMD_AUTHS sessionsData = { 1, &sessionDataArray[0] };
+ TSS2_SYS_RSP_AUTHS sessionsDataOut = { 1, &sessionDataOutArray[0] };
+
+ TPM2B_MAX_NV_BUFFER nvReadData;
+
+ TpmClientPrintf( 0, "\nGET/SET ENCRYPT PARAM TESTS:\n" );
+
+ // Do Prepare.
+ rval = Tss2_Sys_NV_Write_Prepare( sysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvWriteData, 0 );
+ CheckPassed( rval );
+
+ // Test for bad sequence
+ rval = Tss2_Sys_GetEncryptParam( sysContext, &encryptParamSize, &encryptParamBuffer );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_SEQUENCE );
+
+ rval = Tss2_Sys_SetEncryptParam( sysContext, 4, &( nvWriteData.t.buffer[0] ) );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_SEQUENCE );
+
+ // Create NV index
+
+ // Set empty policy and auth value.
+ authPolicy.t.size = 0;
+ nvAuth.t.size = 0;
+
+ // Now set the attributes.
+ *(UINT32 *)( (void *)&nvAttributes ) = 0;
+ nvAttributes.TPMA_NV_AUTHREAD = 1;
+ nvAttributes.TPMA_NV_AUTHWRITE = 1;
+ nvAttributes.TPMA_NV_PLATFORMCREATE = 1;
+
+ rval = DefineNvIndex( TPM_RH_PLATFORM, TPM_RS_PW, &nvAuth, &authPolicy,
+ TPM20_INDEX_PASSWORD_TEST, TPM_ALG_SHA1, nvAttributes, 32 );
+ CheckPassed( rval );
+
+ // Write the index.
+ rval = Tss2_Sys_NV_Write_Prepare( sysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &nvWriteData, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Write( sysContext, TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST, &sessionsData, &nvWriteData, 0, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetEncryptParam( sysContext, &encryptParamSize, &encryptParamBuffer );
+ CheckFailed( rval, TSS2_SYS_RC_NO_ENCRYPT_PARAM );
+
+ // Now read it and do tests on get/set encrypt functions
+ rval = Tss2_Sys_NV_Read_Prepare( sysContext, TPM20_INDEX_PASSWORD_TEST, TPM20_INDEX_PASSWORD_TEST, 4, 0 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_NV_Read( sysContext, TPM20_INDEX_PASSWORD_TEST,
+ TPM20_INDEX_PASSWORD_TEST, &sessionsData, 4, 0, &nvReadData, &sessionsDataOut );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetEncryptParam( sysContext, &encryptParamSize, &encryptParamBuffer );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_SetEncryptParam( sysContext, encryptParamSize, encryptParamBuffer1 );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_GetEncryptParam( sysContext, &encryptParamSize, &encryptParamBuffer );
+ CheckPassed( rval );
+
+ // Test that encryptParamBuffer is the same as encryptParamBuffer1
+ for( i = 0; i < 4; i++ )
+ {
+ if( encryptParamBuffer[i] != encryptParamBuffer1[i] )
+ {
+ TpmClientPrintf( 0, "ERROR!! encryptParamBuffer[%d] s/b: %2.2x, was: %2.2x\n", i, encryptParamBuffer[i], encryptParamBuffer1[i] );
+ Cleanup();
+ }
+ }
+
+ rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM_RH_PLATFORM, TPM20_INDEX_PASSWORD_TEST, &sessionsData, 0 );
+ CheckPassed( rval );
+
+
+ // Test for bad reference
+ rval = Tss2_Sys_GetEncryptParam( 0, &encryptParamSize, &encryptParamBuffer );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_REFERENCE );
+
+ rval = Tss2_Sys_GetEncryptParam( sysContext, 0, &encryptParamBuffer );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_REFERENCE );
+
+ rval = Tss2_Sys_GetEncryptParam( sysContext, &encryptParamSize, 0 );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_REFERENCE );
+
+ rval = Tss2_Sys_SetEncryptParam( sysContext, 4, 0 );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_REFERENCE );
+
+ rval = Tss2_Sys_SetEncryptParam( 0, 4, encryptParamBuffer );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_REFERENCE );
+}
+
+void TestRM()
+{
+ TSS2_TCTI_CONTEXT *otherResMgrTctiContext = 0;
+ TSS2_SYS_CONTEXT *otherSysContext;
+ TPM2B_SENSITIVE_CREATE inSensitive;
+ TPM2B_PUBLIC inPublic;
+ TPM2B_DATA outsideInfo;
+ TPML_PCR_SELECTION creationPCR;
+ TPMS_AUTH_COMMAND sessionData;
+ TPMS_AUTH_RESPONSE sessionDataOut;
+ TSS2_SYS_CMD_AUTHS sessionsData;
+
+ TSS2_SYS_RSP_AUTHS sessionsDataOut;
+ TPM2B_NAME name;
+ TPM2B_PRIVATE outPrivate;
+ TPM2B_PUBLIC outPublic;
+ TPM2B_CREATION_DATA creationData;
+ TPM2B_DIGEST creationHash;
+ TPMT_TK_CREATION creationTicket;
+
+ TPMS_AUTH_COMMAND *sessionDataArray[1];
+ TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
+ TSS2_RC rval = TSS2_RC_SUCCESS;
+
+ TPMS_CONTEXT context;
+ TSS2_TCTI_CONTEXT *tctiContext;
+
+ TPMI_DH_CONTEXT loadedHandle, newHandle, newNewHandle, newHandleDummy;
+ TPMS_CONTEXT newContext;
+ char otherResMgrInterfaceName[] = "Test RM Resource Manager";
+
+ TpmClientPrintf( 0, "\nRM TESTS:\n" );
+
+ sessionDataArray[0] = &sessionData;
+ sessionDataOutArray[0] = &sessionDataOut;
+
+ sessionsDataOut.rspAuths = &sessionDataOutArray[0];
+ sessionsData.cmdAuths = &sessionDataArray[0];
+
+ sessionsDataOut.rspAuthsCount = 1;
+ inSensitive.t.sensitive.userAuth = loadedSha1KeyAuth;
+ inSensitive.t.sensitive.userAuth = loadedSha1KeyAuth;
+ inSensitive.t.sensitive.data.t.size = 0;
+ inSensitive.t.size = loadedSha1KeyAuth.b.size + 2;
+
+ inPublic.t.publicArea.type = TPM_ALG_RSA;
+ inPublic.t.publicArea.nameAlg = TPM_ALG_SHA1;
+
+ // First clear attributes bit field.
+ *(UINT32 *)&( inPublic.t.publicArea.objectAttributes) = 0;
+ inPublic.t.publicArea.objectAttributes.restricted = 1;
+ inPublic.t.publicArea.objectAttributes.userWithAuth = 1;
+ inPublic.t.publicArea.objectAttributes.decrypt = 1;
+ inPublic.t.publicArea.objectAttributes.fixedTPM = 1;
+ inPublic.t.publicArea.objectAttributes.fixedParent = 1;
+ inPublic.t.publicArea.objectAttributes.sensitiveDataOrigin = 1;
+
+ inPublic.t.publicArea.authPolicy.t.size = 0;
+
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_ECB;
+ inPublic.t.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
+ inPublic.t.publicArea.parameters.rsaDetail.keyBits = 1024;
+ inPublic.t.publicArea.parameters.rsaDetail.exponent = 0;
+
+ inPublic.t.publicArea.unique.rsa.t.size = 0;
+
+ outsideInfo.t.size = 0;
+ creationPCR.count = 0;
+
+ sessionData.sessionHandle = TPM_RS_PW;
+
+ // Init nonce.
+ sessionData.nonce.t.size = 0;
+
+ // init hmac
+ sessionData.hmac.t.size = 0;
+
+ // Init session attributes
+ *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;
+
+ sessionsData.cmdAuthsCount = 1;
+ sessionsData.cmdAuths[0] = &sessionData;
+
+ rval = InitTctiResMgrContext( rmInterfaceConfig, &otherResMgrTctiContext, &otherResMgrInterfaceName[0] );
+ if( rval != TSS2_RC_SUCCESS )
+ {
+ TpmClientPrintf( 0, "Resource Mgr, %s, failed initialization: 0x%x. Exiting...\n", resMgrInterfaceInfo.shortName, rval );
+ Cleanup();
+ return;
+ }
+ else
+ {
+ (( TSS2_TCTI_CONTEXT_INTEL *)otherResMgrTctiContext )->status.debugMsgLevel = debugLevel;
+ }
+
+ otherSysContext = InitSysContext( 0, otherResMgrTctiContext, &abiVersion );
+ if( otherSysContext == 0 )
+ {
+ InitSysContextFailure();
+ }
+
+ // TEST OWNERSHIP
+
+ // Try to access a key created by the first TCTI context.
+ sessionData.hmac.t.size = 2;
+ sessionData.hmac.t.buffer[0] = 0x00;
+ sessionData.hmac.t.buffer[1] = 0xff;
+
+ inPublic.t.publicArea.type = TPM_ALG_RSA;
+ inPublic.t.publicArea.nameAlg = TPM_ALG_SHA1;
+
+ // First clear attributes bit field.
+ *(UINT32 *)&( inPublic.t.publicArea.objectAttributes) = 0;
+ inPublic.t.publicArea.objectAttributes.restricted = 1;
+ inPublic.t.publicArea.objectAttributes.userWithAuth = 1;
+ inPublic.t.publicArea.objectAttributes.decrypt = 1;
+ inPublic.t.publicArea.objectAttributes.fixedTPM = 1;
+ inPublic.t.publicArea.objectAttributes.fixedParent = 1;
+ inPublic.t.publicArea.objectAttributes.sensitiveDataOrigin = 1;
+
+ inPublic.t.publicArea.authPolicy.t.size = 0;
+
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
+ inPublic.t.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_ECB;
+ inPublic.t.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
+ inPublic.t.publicArea.parameters.rsaDetail.keyBits = 2048;
+ inPublic.t.publicArea.parameters.rsaDetail.exponent = 0;
+
+ inPublic.t.publicArea.unique.rsa.t.size = 0;
+
+ outsideInfo.t.size = 0;
+
+ // This one should fail, because a different context is trying to use the primary object.
+ outPublic.t.size = 0;
+ creationData.t.size = 0;
+ rval = Tss2_Sys_Create( otherSysContext, handle2048rsa, &sessionsData, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR,
+ &outPrivate, &outPublic, &creationData,
+ &creationHash, &creationTicket, &sessionsDataOut );
+ CheckFailed( rval, TSS2_RESMGR_UNOWNED_HANDLE );
+
+ // This one should pass, because the same context is allowed to save the context.
+ rval = Tss2_Sys_ContextSave( sysContext, handle2048rsa, &context );
+ CheckPassed( rval );
+
+ // This one should pass, since we saved the context first.
+ rval = Tss2_Sys_ContextLoad( otherSysContext, &context, &loadedHandle );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_FlushContext( otherSysContext, loadedHandle );
+ CheckPassed( rval );
+
+ // NOW, DO SOME LOCALITY TESTS
+
+ // Test with null tctiContext ptr.
+ rval = (((TSS2_TCTI_CONTEXT_COMMON_V1 *)otherResMgrTctiContext)->setLocality)( 0, 0 );
+ CheckFailed( rval, TSS2_TCTI_RC_BAD_REFERENCE );
+
+ rval = (((TSS2_TCTI_CONTEXT_COMMON_V1 *)otherResMgrTctiContext)->setLocality)( otherResMgrTctiContext, 0 );
+ CheckPassed( rval );
+
+ // Now try changing localities between send and receive.
+ rval = Tss2_Sys_ContextLoad( otherSysContext, &context, &loadedHandle );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_FlushContext_Prepare( otherSysContext, loadedHandle );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_ExecuteAsync( otherSysContext );
+ CheckPassed( rval );
+
+ // This should fail because locality is changing between send and receive.
+ rval = (((TSS2_TCTI_CONTEXT_COMMON_V1 *)otherResMgrTctiContext)->setLocality)( otherResMgrTctiContext, 1 );
+ CheckFailed( rval, TSS2_TCTI_RC_BAD_SEQUENCE );
+
+ rval = Tss2_Sys_ExecuteFinish( otherSysContext, TSS2_TCTI_TIMEOUT_BLOCK );
+ CheckPassed( rval );
+
+ // NOW, DO SOME CANCEL TESTS
+
+ rval = Tss2_Sys_GetTctiContext( sysContext, &tctiContext );
+ CheckPassed( rval );
+
+ // Try cancel with null tctiContext ptr.
+ rval = (((TSS2_TCTI_CONTEXT_COMMON_V1 *)otherResMgrTctiContext)->cancel)( 0 );
+ CheckFailed( rval, TSS2_TCTI_RC_BAD_REFERENCE );
+
+ // Try cancel when no commands are pending.
+ rval = (((TSS2_TCTI_CONTEXT_COMMON_V1 *)otherResMgrTctiContext)->cancel)( otherResMgrTctiContext );
+ CheckFailed( rval, TSS2_TCTI_RC_BAD_SEQUENCE );
+
+ // Then try cancel with a pending command: send cancel before blocking _Finish call.
+ inPublic.t.publicArea.parameters.rsaDetail.keyBits = 2048;
+ rval = Tss2_Sys_CreatePrimary_Prepare( sysContext, TPM_RH_PLATFORM, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR );
+ CheckPassed( rval );
+
+ //
+ // NOTE: there are race conditions in tests that use cancel and
+ // are expecting to receive the CANCEL response code. The tests
+ // typically pass, but may occasionally fail on the order of
+ // 1 out of 500 or so test passes.
+ //
+ // The OS could delay the test app long enough for the TPM to
+ // complete the CreatePrimary before the test app gets to run
+ // again. To make these tests robust would require some way to
+ // create a critical section in the test app.
+ //
+ sessionData.hmac.t.size = 0;
+ sessionData.nonce.t.size = 0;
+ rval = Tss2_Sys_SetCmdAuths( sysContext, &sessionsData );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_ExecuteAsync( sysContext );
+ CheckPassed( rval );
+
+ rval = (((TSS2_TCTI_CONTEXT_COMMON_V1 *)tctiContext)->cancel)( tctiContext );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_ExecuteFinish( sysContext, TSS2_TCTI_TIMEOUT_BLOCK );
+ CheckFailed( rval, TPM_RC_CANCELED );
+
+ // Then try cancel with a pending command: send cancel after non-blocking _Finish call.
+ rval = Tss2_Sys_CreatePrimary_Prepare( sysContext, TPM_RH_PLATFORM, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_SetCmdAuths( sysContext, &sessionsData );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_ExecuteAsync( sysContext );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_ExecuteFinish( sysContext, 0 );
+ CheckFailed( rval, TSS2_TCTI_RC_TRY_AGAIN );
+
+ rval = (((TSS2_TCTI_CONTEXT_COMMON_V1 *)tctiContext)->cancel)( tctiContext );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_ExecuteFinish( sysContext, TSS2_TCTI_TIMEOUT_BLOCK );
+ CheckFailed( rval, TPM_RC_CANCELED );
+
+ // Then try cancel from a different connection: it should just get a sequence error.
+ rval = Tss2_Sys_CreatePrimary_Prepare( sysContext, TPM_RH_PLATFORM, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_SetCmdAuths( sysContext, &sessionsData );
+ CheckPassed( rval );
+
+ rval = Tss2_Sys_ExecuteAsync( sysContext );
+ CheckPassed( rval );
+
+ rval = (((TSS2_TCTI_CONTEXT_COMMON_V1 *)otherResMgrTctiContext)->cancel)( otherResMgrTctiContext );
+ CheckFailed( rval, TSS2_TCTI_RC_BAD_SEQUENCE );
+
+ rval = Tss2_Sys_ExecuteFinish( sysContext, TSS2_TCTI_TIMEOUT_BLOCK );
+ CheckPassed( rval );
+
+ outPublic.t.size = 0;
+ creationData.t.size = 0;
+ rval = Tss2_Sys_CreatePrimary_Complete( sysContext, &newHandle, &outPublic, &creationData,
+ &creationHash, &creationTicket, &name );
+ CheckPassed( rval );
+
+ //
+ // Now try saving context for object and loading it using a different connection.
+ //
+
+ // First save context.
+ rval = Tss2_Sys_ContextSave( sysContext, newHandle, &newContext );
+ CheckPassed( rval );
+
+ //
+ // Now create an object with different hierarchy. This will make sure that
+ // RM is getting correct hierarchy in it's table.
+ // NOTE: this test can only be verified by looking at RM output.
+ //
+ outPublic.t.size = 0;
+ creationData.t.size = 0;
+ rval = Tss2_Sys_CreatePrimary( sysContext, TPM_RH_ENDORSEMENT, &sessionsData, &inSensitive, &inPublic,
+ &outsideInfo, &creationPCR, &newHandleDummy, &outPublic, &creationData, &creationHash,
+ &creationTicket, &name, &sessionsDataOut );
+ CheckPassed( rval );
+
+ // Now try loading the context using a different connection.
+ rval = Tss2_Sys_ContextLoad( otherSysContext, &newContext, &newNewHandle );
+ CheckPassed( rval );
+
+ // Flush original connection's object.
+ rval = Tss2_Sys_FlushContext( sysContext, newHandle );
+ CheckPassed( rval );
+
+ // Now try flushing new object from wrong connection. Shouldn't be able to.
+ rval = Tss2_Sys_FlushContext( sysContext, newNewHandle );
+ CheckFailed( rval, TSS2_RESMGR_UNOWNED_HANDLE );
+
+ // Now flush new object from other connection. Should work.
+ rval = Tss2_Sys_FlushContext( otherSysContext, newNewHandle );
+ CheckPassed( rval );
+
+ // Now flush dummy object.
+ rval = Tss2_Sys_FlushContext( sysContext, newHandleDummy );
+ CheckPassed( rval );
+
+ rval = TeardownTctiResMgrContext( rmInterfaceConfig, otherResMgrTctiContext, &otherResMgrInterfaceName[0] );
+ CheckPassed( rval );
+
+ TeardownSysContext( &otherSysContext );
+}
+
+void EcEphemeralTest()
+{
+ TSS2_RC rval = TSS2_RC_SUCCESS;
+ TPM2B_ECC_POINT Q;
+ UINT16 counter;
+
+ TpmClientPrintf( 0, "\nEC Ephemeral TESTS:\n" );
+
+ // Test SAPI for case of Q size field not being set to 0.
+ Q.t.size = 0xff;
+ rval = Tss2_Sys_EC_Ephemeral( sysContext, 0, TPM_ECC_BN_P256, &Q, &counter, 0 );
+ CheckFailed( rval, TSS2_SYS_RC_BAD_VALUE );
+
+ Q.t.size = 0;
+ rval = Tss2_Sys_EC_Ephemeral( sysContext, 0, TPM_ECC_BN_P256, &Q, &counter, 0 );
+ CheckPassed( rval );
+}
+
+
+void AbiVersionTests()
+{
+ UINT32 contextSize = 1000;
+ TSS2_RC rval;
+ TSS2_SYS_CONTEXT *sysContext;
+ TSS2_ABI_VERSION tstAbiVersion = { TSSWG_INTEROP, TSS_SAPI_FIRST_FAMILY, TSS_SAPI_FIRST_LEVEL, TSS_SAPI_FIRST_VERSION };
+
+ TpmClientPrintf( 0, "\nABI NEGOTIATION TESTS:\n" );
+
+ // Get the size needed for system context structure.
+ contextSize = Tss2_Sys_GetContextSize( contextSize );
+
+ // Allocate the space for the system context structure.
+ sysContext = (TSS2_SYS_CONTEXT *)malloc( contextSize );
+
+ if( sysContext != 0 )
+ {
+ // Initialized the system context structure.
+ tstAbiVersion.tssCreator = 0xF0000000;
+ rval = Tss2_Sys_Initialize( sysContext, contextSize, resMgrTctiContext, &tstAbiVersion );
+ CheckFailed( rval, TSS2_SYS_RC_ABI_MISMATCH );
+
+ tstAbiVersion.tssCreator = TSSWG_INTEROP;
+ tstAbiVersion.tssFamily = 0xF0000000;
+ rval = Tss2_Sys_Initialize( sysContext, contextSize, resMgrTctiContext, &tstAbiVersion );
+ CheckFailed( rval, TSS2_SYS_RC_ABI_MISMATCH );
+
+ tstAbiVersion.tssFamily = TSS_SAPI_FIRST_FAMILY;
+ tstAbiVersion.tssLevel = 0xF0000000;
+ rval = Tss2_Sys_Initialize( sysContext, contextSize, resMgrTctiContext, &tstAbiVersion );
+ CheckFailed( rval, TSS2_SYS_RC_ABI_MISMATCH );
+
+ tstAbiVersion.tssLevel = TSS_SAPI_FIRST_LEVEL;
+ tstAbiVersion.tssVersion = 0xF0000000;
+ rval = Tss2_Sys_Initialize( sysContext, contextSize, resMgrTctiContext, &tstAbiVersion );
+ CheckFailed( rval, TSS2_SYS_RC_ABI_MISMATCH );
+ }
+ free( sysContext );
+}
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dummy_test();
+
+#ifdef __cplusplus
+}
+#endif
+
+extern TSS2_RC SocketSendTpmCommand(
+ TSS2_TCTI_CONTEXT *tctiContext, /* in */
+ size_t command_size, /* in */
+ uint8_t *command_buffer /* in */
+ );
+
+TSS2_RC SocketReceiveTpmResponse(
+ TSS2_TCTI_CONTEXT *tctiContext, /* in */
+ size_t *response_size, /* out */
+ unsigned char *response_buffer, /* in */
+ int32_t timeout
+ );
+
+void TpmTest()
+{
+ TSS2_RC rval = TSS2_RC_SUCCESS;
+ UINT32 i;
+
+ nullSessionsDataOut.rspAuthsCount = 1;
+ nullSessionsDataOut.rspAuths[0]->nonce = nullSessionNonceOut;
+ nullSessionsDataOut.rspAuths[0]->hmac = nullSessionHmac;
+ nullSessionNonceOut.t.size = 0;
+ nullSessionNonce.t.size = 0;
+
+ loadedSha1KeyAuth.t.size = 2;
+ loadedSha1KeyAuth.t.buffer[0] = 0x00;
+ loadedSha1KeyAuth.t.buffer[1] = 0xff;
+
+ InitEntities();
+
+ InitNullSession( &nullSessionData);
+
+ AbiVersionTests();
+
+ GetSetDecryptParamTests();
+
+ rval = PlatformCommand( resMgrTctiContext, MS_SIM_POWER_ON );
+ CheckPassed( rval );
+
+ rval = PlatformCommand( resMgrTctiContext, MS_SIM_NV_ON );
+ CheckPassed( rval );
+
+ TestTpmStartup();
+
+ GetTpmVersion();
+
+ // Clear DA lockout.
+ TestDictionaryAttackLockReset();
+
+ TestTpmSelftest();
+
+ TestSapiApis();
+
+ TestDictionaryAttackLockReset();
+
+ TestCreate();
+
+ if( startAuthSessionTestOnly == 1 )
+ {
+ TestStartAuthSession();
+ goto endTests;
+ }
+
+ TestHierarchyControl();
+
+ NvIndexProto();
+
+ GetSetEncryptParamTests();
+
+ TestEncryptDecryptSession();
+
+ SimpleHmacOrPolicyTest( true );
+
+ SimpleHmacOrPolicyTest( false );
+
+ for( i = 1; i <= (UINT32)passCount; i++ )
+ {
+ TpmClientPrintf( 0, "\n****** PASS #: %d ******\n\n", i );
+
+ TestTpmGetCapability();
+
+ TestPcrExtend();
+
+ TestHash();
+
+ TestPolicy();
+
+ TestTpmClear();
+
+ TestChangeEps();
+
+ TestChangePps();
+
+ TestHierarchyChangeAuth();
+
+ TestGetRandom();
+
+ if( i < 2 )
+ TestShutdown();
+
+ TestNV();
+
+ TestCreate();
+
+ TestEvict();
+
+ NvIndexProto();
+
+ PasswordTest();
+
+ HmacSessionTest();
+
+ TestQuote();
+
+ TestDictionaryAttackLockReset();
+
+ TestPcrAllocate();
+
+ TestUnseal();
+
+ TestRM();
+
+ EcEphemeralTest();
+#if 0
+ TestRsaEncryptDecrypt();
+#endif
+ }
+
+ // Clear out RM entries for objects.
+ rval = Tss2_Sys_FlushContext( sysContext, handle2048rsa );
+ CheckPassed( rval );
+ rval = Tss2_Sys_FlushContext( sysContext, loadedSha1KeyHandle );
+ CheckPassed( rval );
+
+endTests:
+ PlatformCommand( resMgrTctiContext, MS_SIM_POWER_OFF );
+}
+
+
+char version[] = "0.90";
+
+void PrintHelp()
+{
+ printf( "TPM client test app, Version %s\nUsage: tpmclient [-host hostname|ip_addr] [-port port] [-passes passNum] [-demoDelay delay] [-dbg dbgLevel] [-startAuthSessionTest]\n"
+ "\n"
+ "where:\n"
+ "\n"
+ "-host specifies the host IP address (default: %s)\n"
+ "-port specifies the port number (default: %d)\n"
+ "-passes specifies the number of test passes (default: 1)\n"
+ "-demoDelay specifies a delay in units of loops, not time (default: 0)\n"
+ "-dbgLevel specifies level of debug messages:\n"
+ " 0 (high level test results)\n"
+ " 1 (test app send/receive byte streams)\n"
+ " 2 (resource manager send/receive byte streams)\n"
+ " 3 (resource manager tables)\n"
+ "-startAuthSessionTest enables some special tests of the resource manager for starting sessions\n"
+#ifdef SHARED_OUT_FILE
+ "-out selects the output file (default is stdout)\n"
+#endif
+ , version, DEFAULT_HOSTNAME, DEFAULT_RESMGR_TPM_PORT );
+}
+
+int main(int argc, char* argv[])
+{
+ char hostName[HOSTNAME_LENGTH] = DEFAULT_HOSTNAME;
+ int port = DEFAULT_RESMGR_TPM_PORT;
+ int count;
+ TSS2_RC rval;
+
+ setvbuf (stdout, NULL, _IONBF, BUFSIZ);
+#ifdef SHARED_OUT_FILE
+ if( argc > 12 )
+#else
+ if( argc > 10 )
+#endif
+ {
+ PrintHelp();
+ return 1;
+ }
+ else
+ {
+ for( count = 1; count < argc; count++ )
+ {
+ if( 0 == strcmp( argv[count], "-host" ) )
+ {
+ count++;
+ if( strlen( argv[count] ) + 1 <= HOSTNAME_LENGTH )
+ {
+ if( 1 != sscanf( argv[count], "%199s", &hostName[0] ) )
+ {
+ PrintHelp();
+ return 1;
+ }
+ }
+ else
+ {
+ PrintHelp();
+ return 1;
+ }
+ }
+ else if( 0 == strcmp( argv[count], "-port" ) )
+ {
+ count++;
+ if( 1 != sscanf_s( argv[count], "%d", &port ) )
+ {
+ PrintHelp();
+ return 1;
+ }
+ }
+ else if( 0 == strcmp( argv[count], "-passes" ) )
+ {
+ count++;
+ if( 1 != sscanf_s( argv[count], "%d", &passCount ) )
+ {
+ PrintHelp();
+ return 1;
+ }
+ }
+ else if( 0 == strcmp( argv[count], "-demoDelay" ) )
+ {
+ count++;
+ if( 1 != sscanf_s( argv[count], "%x", &demoDelay ) )
+ {
+ PrintHelp();
+ return 1;
+ }
+ }
+ else if( 0 == strcmp( argv[count], "-dbg" ) )
+ {
+ count++;
+ if( 1 != sscanf_s( argv[count], "%d", &debugLevel ) )
+ {
+ PrintHelp();
+ return 1;
+ }
+ }
+ else if( 0 == strcmp( argv[count], "-startAuthSessionTest" ) )
+ {
+ startAuthSessionTestOnly = 1;
+ }
+#ifdef SHARED_OUT_FILE
+ else if( 0 == strcmp( argv[count], "-out" ) )
+ {
+ count++;
+ if( 1 != sscanf_s( argv[count], "%199s", &outFileName, sizeof( outFileName ) ) )
+ {
+ PrintHelp();
+ return 1;
+ }
+ else
+ {
+ OpenOutFile( &outFp );
+
+ if( outFp == 0 )
+ {
+ printf( "Unable to open file, %s\n", &outFileName[0] );
+ PrintHelp();
+ return 1;
+ }
+ CloseOutFile( &outFp );
+ }
+ }
+#endif
+ else
+ {
+ PrintHelp();
+ return 1;
+ }
+ }
+ }
+
+ if( 0 == strcmp( outFileName, "" ) )
+ {
+ outFp = stdout;
+ }
+ else
+ {
+ outFp = 0;
+ }
+
+ sprintf_s( rmInterfaceConfig, rmInterfaceConfigSize, "%s %d ", hostName, port );
+
+ rval = InitTctiResMgrContext( rmInterfaceConfig, &resMgrTctiContext, &resMgrInterfaceName[0] );
+ if( rval != TSS2_RC_SUCCESS )
+ {
+ TpmClientPrintf( 0, "Resource Mgr, %s, failed initialization: 0x%x. Exiting...\n", resMgrInterfaceInfo.shortName, rval );
+ Cleanup();
+ return( 1 );
+ }
+ else
+ {
+ (( TSS2_TCTI_CONTEXT_INTEL *)resMgrTctiContext )->status.debugMsgLevel = debugLevel;
+ }
+
+ sysContext = InitSysContext( 0, resMgrTctiContext, &abiVersion );
+ if( sysContext == 0 )
+ {
+ InitSysContextFailure();
+ }
+ else
+ {
+ TpmTest();
+
+ rval = TeardownTctiResMgrContext( rmInterfaceConfig, resMgrTctiContext, &resMgrInterfaceName[0] );
+ CheckPassed( rval );
+
+ TeardownSysContext( &sysContext );
+ }
+
+ return 0;
+}
+
+