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