15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published 25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library 35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 4: Supporting Routines 45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0" 55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16 65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014 75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury 85679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#define TPM_FAIL_C 95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "InternalRoutines.h" 105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include <assert.h> 115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// On MS C compiler, can save the alignment state and set the alignment to 1 for the duration of the 135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_Types.h include. This will avoid a lot of alignment warnings from the compiler for the unaligned 145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// structures. The alignment of the structures is not important as this function does not use any of the 155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// structures in TPM_Types.h and only include it for the #defines of the capabilities, properties, and 165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// command code values. 175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#pragma pack(push, 1) 195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "TPM_Types.h" 205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#pragma pack (pop) 215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "swap.h" 225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Typedefs 255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// These defines are used primarily for sizing of the local response buffer. 275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#pragma pack(push,1) 295679752bf24c21135884e987c4077e2f7184897Vadim Bendeburytypedef struct { 305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ST tag; 315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 size; 325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_RC code; 335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} HEADER; 345679752bf24c21135884e987c4077e2f7184897Vadim Bendeburytypedef struct { 355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 size; 365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury struct { 375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 function; 385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 line; 395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 code; 405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } values; 415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_RC returnCode; 425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} GET_TEST_RESULT_PARAMETERS; 435679752bf24c21135884e987c4077e2f7184897Vadim Bendeburytypedef struct { 445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_YES_NO moreData; 455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_CAP capability; // Always TPM_CAP_TPM_PROPERTIES 465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPML_TAGGED_TPM_PROPERTY tpmProperty; // a single tagged property 475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} GET_CAPABILITY_PARAMETERS; 485679752bf24c21135884e987c4077e2f7184897Vadim Bendeburytypedef struct { 495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury HEADER header; 505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury GET_TEST_RESULT_PARAMETERS getTestResult; 515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} TEST_RESPONSE; 525679752bf24c21135884e987c4077e2f7184897Vadim Bendeburytypedef struct { 535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury HEADER header; 545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury GET_CAPABILITY_PARAMETERS getCap; 555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} CAPABILITY_RESPONSE; 565679752bf24c21135884e987c4077e2f7184897Vadim Bendeburytypedef union { 575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TEST_RESPONSE test; 585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CAPABILITY_RESPONSE cap; 595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} RESPONSES; 605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#pragma pack(pop) 615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Buffer to hold the responses. This may be a little larger than required due to padding that a compiler 635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// might add. 645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// NOTE: This is not in Global.c because of the specialized data definitions above. Since the data contained in this 665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// structure is not relevant outside of the execution of a single command (when the TPM is in failure mode. There 675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// is no compelling reason to move all the typedefs to Global.h and this structure to Global.c. 685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifndef __IGNORE_STATE__ // Don't define this value 705679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic BYTE response[sizeof(RESPONSES)]; 715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Local Functions 755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// MarshalUint16() 775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Function to marshal a 16 bit value to the output buffer. 795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 805679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic INT32 815679752bf24c21135884e987c4077e2f7184897Vadim BendeburyMarshalUint16( 825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 integer, 8332be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr BYTE **buffer, 8432be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr INT32 *size 855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 8732be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr return UINT16_Marshal(&integer, buffer, size); 885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// MarshalUint32() 925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Function to marshal a 32 bit value to the output buffer. 945679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic INT32 955679752bf24c21135884e987c4077e2f7184897Vadim BendeburyMarshalUint32( 965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 integer, 9732be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr BYTE **buffer, 9832be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr INT32 *size 995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 10132be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr return UINT32_Marshal(&integer, buffer, size); 1025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 1035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// UnmarshalHeader() 1065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Funtion to unmarshal the 10-byte command header. 1085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1095679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic BOOL 1105679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUnmarshalHeader( 1115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury HEADER *header, 1125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE **buffer, 1135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury INT32 *size 1145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 1165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 usize; 1175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_RC ucode; 1185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( UINT16_Unmarshal(&header->tag, buffer, size) != TPM_RC_SUCCESS 1195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || UINT32_Unmarshal(&usize, buffer, size) != TPM_RC_SUCCESS 1205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || UINT32_Unmarshal(&ucode, buffer, size) != TPM_RC_SUCCESS 1215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return FALSE; 1235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury header->size = usize; 1245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury header->code = ucode; 1255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TRUE; 1265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 1275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Public Functions 1305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// SetForceFailureMode() 1325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is called by the simulator to enable failure mode testing. 1345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1355679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT void 1365679752bf24c21135884e987c4077e2f7184897Vadim BendeburySetForceFailureMode( 1375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury void 1385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 1405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury g_forceFailureMode = TRUE; 1415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 1425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 1437878aefcd59699a343a5699b68a40187e8f878f2Vadim Bendebury 1445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TpmFail() 1475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is called by TPM.lib when a failure occurs. It will set up the failure values to be returned on 1495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM2_GetTestResult(). 1505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1515679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid 1525679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTpmFail( 1535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const char *function, 1545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury int line, int code 1555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 1575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Save the values that indicate where the error occurred. 1585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // On a 64-bit machine, this may truncate the address of the string 1595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // of the function name where the error occurred. 16071e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr memcpy(&s_failFunction, function, sizeof(s_failFunction)); 1615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury s_failLine = line; 1625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury s_failCode = code; 1635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // if asserts are enabled, then do an assert unless the failure mode code 1645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // is being tested 1655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert(g_forceFailureMode); 1665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Clear this flag 1675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury g_forceFailureMode = FALSE; 1685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Jump to the failure mode code. 1695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Note: only get here if asserts are off or if we are testing failure mode 1707878aefcd59699a343a5699b68a40187e8f878f2Vadim Bendebury#ifndef EMBEDDED_MODE 1715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury longjmp(&g_jumpBuffer[0], 1); 1727878aefcd59699a343a5699b68a40187e8f878f2Vadim Bendebury#endif 1735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 1745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TpmFailureMode 1775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is called by the interface code when the platform is in failure mode. 1795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1805679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid 1815679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTpmFailureMode ( 1825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury unsigned int inRequestSize, // IN: command buffer size 1835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury unsigned char *inRequest, // IN: command buffer 1845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury unsigned int *outResponseSize, // OUT: response buffer size 1855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury unsigned char **outResponse // OUT: response buffer 1865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 1885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; 18932be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr INT32 bufferSize; 1905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 marshalSize; 1915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 capability; 1925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury HEADER header; // unmarshaled command header 1935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 pt; // unmarshaled property type 1945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 count; // unmarshaled property count 1955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If there is no command buffer, then just return TPM_RC_FAILURE 1965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(inRequestSize == 0 || inRequest == NULL) 1975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto FailureModeReturn; 1985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If the header is not correct for TPM2_GetCapability() or 1995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // TPM2_GetTestResult() then just return the in failure mode response; 2005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = inRequest; 2015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!UnmarshalHeader(&header, &inRequest, (INT32 *)&inRequestSize)) 2025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto FailureModeReturn; 2035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( header.tag != TPM_ST_NO_SESSIONS 2045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || header.size < 10) 2055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto FailureModeReturn; 2065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury switch (header.code) { 2075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_CC_GetTestResult: 2085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // make sure that the command size is correct 2095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(header.size != 10) 2105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto FailureModeReturn; 2115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = &response[10]; 21232be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = MAX_RESPONSE_SIZE-10; 21332be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize = MarshalUint16(3 * sizeof(UINT32), &buffer, &bufferSize); 21432be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(s_failFunction, &buffer, &bufferSize); 21532be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(s_failLine, &buffer, &bufferSize); 21632be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(s_failCode, &buffer, &bufferSize); 2175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(s_failCode == FATAL_ERROR_NV_UNRECOVERABLE) 21832be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(TPM_RC_NV_UNINITIALIZED, &buffer, &bufferSize); 2195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 22032be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(TPM_RC_FAILURE, &buffer, &bufferSize); 2215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 2235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_CC_GetCapability: 2245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // make sure that the size of the command is exactly the size 2255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // returned for the capability, property, and count 2265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( header.size!= (10 + (3 * sizeof(UINT32))) 2275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // also verify that this is requesting TPM properties 2285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (UINT32_Unmarshal(&capability, &inRequest, 2295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury (INT32 *)&inRequestSize) 2305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != TPM_RC_SUCCESS) 2315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (capability != TPM_CAP_TPM_PROPERTIES) 2325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (UINT32_Unmarshal(&pt, &inRequest, (INT32 *)&inRequestSize) 2335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != TPM_RC_SUCCESS) 2345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (UINT32_Unmarshal(&count, &inRequest, (INT32 *)&inRequestSize) 2355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != TPM_RC_SUCCESS) 2365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 2375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto FailureModeReturn; 2385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If in failure mode because of an unrecoverable read error, and the 2395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // property is 0 and the count is 0, then this is an indication to 2405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // re-manufacture the TPM. Do the re-manufacture but stay in failure 2415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // mode until the TPM is reset. 2425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Note: this behavior is not required by the specification and it is 2435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // OK to leave the TPM permanently bricked due to an unrecoverable NV 2445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // error. 2455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( count == 0 && pt == 0 && s_failCode == FATAL_ERROR_NV_UNRECOVERABLE) 2465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 2475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury g_manufactured = FALSE; 2485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_Manufacture(0); 2495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 2505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(count > 0) 2515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury count = 1; 2525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else if(pt > TPM_PT_FIRMWARE_VERSION_2) 2535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury count = 0; 2545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pt < TPM_PT_MANUFACTURER) 2555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = TPM_PT_MANUFACTURER; 2565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // set up for return 2575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = &response[10]; 25832be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = MAX_RESPONSE_SIZE-10; 2595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // if the request was for a PT less than the last one 2605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // then we indicate more, otherwise, not. 2615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pt < TPM_PT_FIRMWARE_VERSION_2) 2625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *buffer++ = YES; 2635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 2645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *buffer++ = NO; 2655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury marshalSize = 1; 2665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // indicate the capability type 26732be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(capability, &buffer, &bufferSize); 2685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // indicate the number of values that are being returned (0 or 1) 26932be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(count, &buffer, &bufferSize); 2705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // indicate the property 27132be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(pt, &buffer, &bufferSize); 2725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(count > 0) 2735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury switch (pt) { 2745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_PT_MANUFACTURER: 2755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the vendor ID unique to each TPM manufacturer 2765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef MANUFACTURER 2775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = *(UINT32*)MANUFACTURER; 2785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else 2795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = 0; 2805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 2815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 2825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_PT_VENDOR_STRING_1: 2835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the first four characters of the vendor ID string 2845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef VENDOR_STRING_1 2855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = *(UINT32*)VENDOR_STRING_1; 2865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else 2875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = 0; 2885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 2895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 2905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_PT_VENDOR_STRING_2: 2915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the second four characters of the vendor ID string 2925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef VENDOR_STRING_2 2935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = *(UINT32*)VENDOR_STRING_2; 2945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else 2955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = 0; 2965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 2975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 2985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_PT_VENDOR_STRING_3: 2995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the third four characters of the vendor ID string 3005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef VENDOR_STRING_3 3015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = *(UINT32*)VENDOR_STRING_3; 3025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else 3035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = 0; 3045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 3055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 3065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_PT_VENDOR_STRING_4: 3075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the fourth four characters of the vendor ID string 3085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef VENDOR_STRING_4 3095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = *(UINT32*)VENDOR_STRING_4; 3105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else 3115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = 0; 3125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 3135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 3145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_PT_VENDOR_TPM_TYPE: 3155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // vendor-defined value indicating the TPM model 3165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // We just make up a number here 3175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = 1; 3185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 3195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_PT_FIRMWARE_VERSION_1: 3205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the more significant 32-bits of a vendor-specific value 3215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // indicating the version of the firmware 3225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef FIRMWARE_V1 3235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = FIRMWARE_V1; 3245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else 3255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = 0; 3265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 3275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 3285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury default: // TPM_PT_FIRMWARE_VERSION_2: 3295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the less significant 32-bits of a vendor-specific value 3305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // indicating the version of the firmware 3315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef FIRMWARE_V2 3325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = FIRMWARE_V2; 3335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else 3345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pt = 0; 3355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 3365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 3375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 33832be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(pt, &buffer, &bufferSize); 3395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 3405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury default: // default for switch (cc) 3415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto FailureModeReturn; 3425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 3435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Now do the header 3445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = response; 34532be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = 10; 3465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury marshalSize = marshalSize + 10; // Add the header size to the 3475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // stuff already marshaled 34832be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr MarshalUint16(TPM_ST_NO_SESSIONS, &buffer, &bufferSize); // structure tag 34932be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr MarshalUint32(marshalSize, &buffer, &bufferSize); // responseSize 35032be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr MarshalUint32(TPM_RC_SUCCESS, &buffer, &bufferSize); // response code 3515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *outResponseSize = marshalSize; 3525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *outResponse = (unsigned char *)&response; 3535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 3545679752bf24c21135884e987c4077e2f7184897Vadim BendeburyFailureModeReturn: 3555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = response; 35632be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = 10; 35732be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize = MarshalUint16(TPM_ST_NO_SESSIONS, &buffer, &bufferSize); 35832be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(10, &buffer, &bufferSize); 35932be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr marshalSize += MarshalUint32(TPM_RC_FAILURE, &buffer, &bufferSize); 3605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *outResponseSize = marshalSize; 3615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *outResponse = (unsigned char *)response; 3625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 3635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 364