/********************************************************************************/
/*										*/
/*			Internal Global Type Definitions			*/
/*			     Written by Ken Goldman				*/
/*		       IBM Thomas J. Watson Research Center			*/
/*            $Id: Global.h 1658 2021-01-22 23:14:01Z kgoldman $		*/
/*										*/
/*  Licenses and Notices							*/
/*										*/
/*  1. Copyright Licenses:							*/
/*										*/
/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
/*    derivative works, distribute, display and perform the Source Code and	*/
/*    derivative works thereof, and to grant others the rights granted herein.	*/
/*										*/
/*  - The TCG grants to the user of the other parts of the specification 	*/
/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
/*    display, and perform the specification solely for the purpose of 		*/
/*    developing products based on such documents.				*/
/*										*/
/*  2. Source Code Distribution Conditions:					*/
/*										*/
/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
/*    this list of conditions and the following disclaimers.			*/
/*										*/
/*  - Redistributions in binary form must reproduce the above copyright 	*/
/*    licenses, this list of conditions	and the following disclaimers in the 	*/
/*    documentation and/or other materials provided with the distribution.	*/
/*										*/
/*  3. Disclaimers:								*/
/*										*/
/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
/*  information on specification licensing rights available through TCG 	*/
/*  membership agreements.							*/
/*										*/
/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
/*										*/
/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
/*    liability, including liability for infringement of any proprietary 	*/
/*    rights, relating to use of information in this specification and to the	*/
/*    implementation of this specification, and TCG disclaims all liability for	*/
/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
/*    arising in any way out of use or reliance upon this specification or any 	*/
/*    information herein.							*/
/*										*/
/*  (c) Copyright IBM Corp. and others, 2016 - 2021				*/
/*										*/
/********************************************************************************/

/* 5.9	Global.h */
/* 5.9.2	Includes */

#if !defined _TPM_H_
#error "Should only be instanced in TPM.h"
#endif

#ifndef         GLOBAL_H
#define         GLOBAL_H
_REDUCE_WARNING_LEVEL_(2)
#include <string.h>
#include <stddef.h>
_NORMAL_WARNING_LEVEL_
#include "BackwardsCompatibility.h" // libtpms added

#include "Capabilities.h"
#include "TpmTypes.h"
#include "CommandAttributes.h"
#include "CryptTest.h"
#include "BnValues.h"
#include "CryptHash.h"
#include "CryptSym.h"
#include "CryptRand.h"
#include "CryptEcc.h"
#include "CryptRsa.h"
#include "CryptTest.h"
#include "TpmError.h"
#include "NV.h"
#include "ACT.h"
#include "Utils.h"		    // libtpms added

//** Defines and Types
    
//*** Size Types
// These types are used to differentiate the two different size values used.
//
// NUMBYTES is used when a size is a number of bytes (usually a TPM2B)
typedef UINT16  NUMBYTES;

//*** Other Types
// An AUTH_VALUE is a BYTE array containing a digest (TPMU_HA)
typedef BYTE    AUTH_VALUE[sizeof(TPMU_HA)];

/* A TIME_INFO is a BYTE array that can contain a TPMS_TIME_INFO */
typedef BYTE    TIME_INFO[sizeof(TPMS_TIME_INFO)];

/* A NAME is a BYTE array that can contain a TPMU_NAME */
typedef BYTE    NAME[sizeof(TPMU_NAME)];

/* Definition for a PROOF value */
TPM2B_TYPE(PROOF, PROOF_SIZE);

/* Definition for a Primary Seed value */
TPM2B_TYPE(SEED, PRIMARY_SEED_SIZE);

/* A CLOCK_NONCE is used to tag the time value in the authorization session and in the ticket
   computation so that the ticket expires when there is a time discontinuity. When the clock stops
   during normal operation, the nonce is 64-bit value kept in RAM but it is a 32-bit counter when
   the clock only stops during power events. */
#if CLOCK_STOPS
typedef UINT64          CLOCK_NONCE;
#else
typedef UINT32          CLOCK_NONCE;
#endif

// 5.9.3	Loaded Object Structures
// 5.9.3.1	Description
// The structures in this section define the object layout as it exists in TPM memory.
// Two types of objects are defined: an ordinary object such as a key, and a sequence object that
// may be a hash, HMAC, or event.

/* 5.9.3.2	OBJECT_ATTRIBUTES */
/* An OBJECT_ATTRIBUTES structure contains the variable attributes of an object. These properties
   are not part of the public properties but are used by the TPM in managing the object. An
   OBJECT_ATTRIBUTES is used in the definition of the OBJECT data type. */
typedef struct
{
#if LITTLE_ENDIAN_TPM == YES                          /* libtpms added */
    unsigned            publicOnly : 1;     //0) SET if only the public portion of
    //   an object is loaded
    unsigned            epsHierarchy : 1;   //1) SET if the object belongs to EPS
    //   Hierarchy
    unsigned            ppsHierarchy : 1;   //2) SET if the object belongs to PPS
    //   Hierarchy
    unsigned            spsHierarchy : 1;   //3) SET f the object belongs to SPS
    //   Hierarchy
    unsigned            evict : 1;          //4) SET if the object is a platform or
    //   owner evict object.  Platform-
    //   evict object belongs to PPS
    //   hierarchy, owner-evict object
    //   belongs to SPS or EPS hierarchy.
    //   This bit is also used to mark a
    //   completed sequence object so it
    //   will be flush when the
    //   SequenceComplete command succeeds.
    unsigned            primary : 1;        //5) SET for a primary object
    unsigned            temporary : 1;      //6) SET for a temporary object
    unsigned            stClear : 1;        //7) SET for an stClear object
    unsigned            hmacSeq : 1;        //8) SET for an HMAC or MAC sequence object
    unsigned            hashSeq : 1;        //9) SET for a hash sequence object
    unsigned            eventSeq : 1;       //10) SET for an event sequence object
    unsigned            ticketSafe : 1;     //11) SET if a ticket is safe to create
    //    for hash sequence object
    unsigned            firstBlock : 1;     //12) SET if the first block of hash
    //    data has been received.  It
    //    works with ticketSafe bit
    unsigned            isParent : 1;       //13) SET if the key has the proper
    //    attributes to be a parent key
    unsigned            privateExp : 1;     //14) SET when the private exponent
    //    of an RSA key has been validated.
    unsigned            occupied : 1;       //15) SET when the slot is occupied.
    unsigned            derivation : 1;     //16) SET when the key is a derivation
    //        parent
    unsigned            external : 1;       //17) SET when the object is loaded with
    //    TPM2_LoadExternal();
    unsigned            reserved : 14;      //18-31)  /* libtpms added */
#endif                                                /* libtpms added */
#if BIG_ENDIAN_TPM == YES                             /* libtpms added begin */
    unsigned            reserved : 14;      //18-31)
    unsigned            external : 1;       //17) SET when the object is loaded with
    unsigned            derivation : 1;     //16) SET when the key is a derivation
    unsigned            occupied : 1;       //15) SET when the slot is occupied.
    unsigned            privateExp : 1;     //14) SET when the private exponent
    unsigned            isParent : 1;       //13) SET if the key has the proper
    unsigned            firstBlock : 1;     //12) SET if the first block of hash
    unsigned            ticketSafe : 1;     //11) SET if a ticket is safe to create
    unsigned            eventSeq : 1;       //10) SET for an event sequence object
    unsigned            hashSeq : 1;        //9) SET for a hash sequence object
    unsigned            hmacSeq : 1;        //8) SET for an HMAC sequence object
    unsigned            stClear : 1;        //7) SET for an stClear object
    unsigned            temporary : 1;      //6) SET for a temporary object
    unsigned            primary : 1;        //5) SET for a primary object

    unsigned            evict : 1;          //4) SET if the object is a platform or
    unsigned            spsHierarchy : 1;   //3) SET f the object belongs to SPS
    unsigned            ppsHierarchy : 1;   //2) SET if the object belongs to PPS
    unsigned            epsHierarchy : 1;   //1) SET if the object belongs to EPS
    unsigned            publicOnly : 1;     //0) SET if only the public portion of
#endif                                                /* libtpms added end */
} OBJECT_ATTRIBUTES;

#if ALG_RSA
/* There is an overload of the sensitive.rsa.t.size field of a TPMT_SENSITIVE when an RSA key is
   loaded. When the sensitive->sensitive contains an RSA key with all of the CRT values, then the
   MSB of the size field will be set to indicate that the buffer contains all 5 of the CRT private
   key values. */
#define     RSA_prime_flag      0x8000
#endif

/* 5.9.3.3 OBJECT Structure */
/* An OBJECT structure holds the object public, sensitive, and meta-data associated. This structure
   is implementation dependent. For this implementation, the structure is not optimized for space
   but rather for clarity of the reference implementation. Other implementations may choose to
   overlap portions of the structure that are not used simultaneously. These changes would
   necessitate changes to the source code but those changes would be compatible with the reference
   implementation. */
typedef struct OBJECT
{
    // The attributes field is required to be first followed by the publicArea.
    // This allows the overlay of the object structure and a sequence structure
    OBJECT_ATTRIBUTES   attributes;         // object attributes
    TPMT_PUBLIC         publicArea;         // public area of an object
    TPMT_SENSITIVE      sensitive;          // sensitive area of an object
#if ALG_RSA
    privateExponent_t   privateExponent;    // Additional field for the private
#endif
    TPM2B_NAME          qualifiedName;      // object qualified name
    TPMI_DH_OBJECT      evictHandle;        // if the object is an evict object,
    // the original handle is kept here.
    // The 'working' handle will be the
    // handle of an object slot.
    TPM2B_NAME          name;               // Name of the object name. Kept here
    // to avoid repeatedly computing it.

    // libtpms added: SEED_COMPAT_LEVEL to use for deriving child keys
    SEED_COMPAT_LEVEL   seedCompatLevel;
    // libtpms added: OBJECT lies in NVRAM; to avoid that it needs different number
    // of bytes on 32 bit and 64 bit architectures, we need to make sure it's the
    // same size; simple padding at the end works here
    UINT8               _pad[3];
} OBJECT;

/* 5.9.3.4	HASH_OBJECT Structure */
/* This structure holds a hash sequence object or an event sequence object. */
/* The first four components of this structure are manually set to be the same as the first four
   components of the object structure. This prevents the object from being inadvertently misused as
   sequence objects occupy the same memory as a regular object. A debug check is present to make
   sure that the offsets are what they are supposed to be. */
/* NOTE: In a future version, this will probably be renamed as SEQUENCE_OBJECT */
typedef struct HASH_OBJECT
{
    OBJECT_ATTRIBUTES   attributes;         // The attributes of the HASH object
    TPMI_ALG_PUBLIC     type;               // algorithm
    TPMI_ALG_HASH       nameAlg;            // name algorithm
    TPMA_OBJECT         objectAttributes;   // object attributes
    // The data below is unique to a sequence object
    TPM2B_AUTH          auth;               // authorization for use of sequence
    union
    {
	HASH_STATE      hashState[HASH_COUNT];
	HMAC_STATE      hmacState;
    }                   state;
} HASH_OBJECT;
typedef BYTE  HASH_OBJECT_BUFFER[sizeof(HASH_OBJECT)];

/* 5.9.3.5	ANY_OBJECT */
/* This is the union for holding either a sequence object or a regular object. for ContextSave() and
   ContextLoad() */
typedef union ANY_OBJECT
{
    OBJECT              entity;
    HASH_OBJECT         hash;
} ANY_OBJECT;
typedef BYTE    ANY_OBJECT_BUFFER[sizeof(ANY_OBJECT)];

/* 5.9.4	AUTH_DUP Types */
/* These values are used in the authorization processing. */
typedef UINT32          AUTH_ROLE;
#define AUTH_NONE       ((AUTH_ROLE)(0))
#define AUTH_USER       ((AUTH_ROLE)(1))
#define AUTH_ADMIN      ((AUTH_ROLE)(2))
#define AUTH_DUP        ((AUTH_ROLE)(3))

/* 5.9.5	Active Session Context */
/* 5.9.5.1	Description */
/* The structures in this section define the internal structure of a session context. */
/* 5.9.5.2	SESSION_ATTRIBUTES */
/* The attributes in the SESSION_ATTRIBUTES structure track the various properties of the
   session. It maintains most of the tracking state information for the policy session. It is used
   within the SESSION structure. */
typedef struct SESSION_ATTRIBUTES
{
#if LITTLE_ENDIAN_TPM == YES                     /* libtpms added */
    unsigned    isPolicy : 1;           //1) SET if the session may only be used
    //   for policy
    unsigned    isAudit : 1;            //2) SET if the session is used for audit
    unsigned    isBound : 1;            //3) SET if the session is bound to with an
    //   entity. This attribute will be CLEAR
    //   if either isPolicy or isAudit is SET.
    unsigned    isCpHashDefined : 1;    //4) SET if the cpHash has been defined
    //   This attribute is not SET unless
    //   'isPolicy' is SET.
    unsigned    isAuthValueNeeded : 1;  //5) SET if the authValue is required for
    //   computing the session HMAC. This
    //   attribute is not SET unless 'isPolicy'
    //   is SET.
    unsigned    isPasswordNeeded : 1;   //6) SET if a password authValue is required
    //   for authorization This attribute is not
    //   SET unless 'isPolicy' is SET.
    unsigned    isPPRequired : 1;       //7) SET if physical presence is required to
    //   be asserted when the authorization is
    //   checked. This attribute is not SET
    //   unless 'isPolicy' is SET.
    unsigned    isTrialPolicy : 1;      //8) SET if the policy session is created
    //   for trial of the policy's policyHash
    //   generation. This attribute is not SET
    //   unless 'isPolicy' is SET.
    unsigned    isDaBound : 1;          //9) SET if the bind entity had noDA CLEAR.
    //   If this is SET, then an authorization
    //   failure using this session will count
    //   against lockout even if the object
    //   being authorized is exempt from DA.
    unsigned    isLockoutBound : 1;     //10) SET if the session is bound to
    //    lockoutAuth.
    unsigned    includeAuth : 1;        //11) This attribute is SET when the
    //    authValue of an object is to be
    //    included in the computation of the
    //    HMAC key for the command and response
    //    computations. (was 'requestWasBound')
    unsigned    checkNvWritten : 1;     //12) SET if the TPMA_NV_WRITTEN attribute
    //    needs to be checked when the policy is
    //    used for authorization for NV access.
    //    If this is SET for any other type, the
    //    policy will fail.
    unsigned    nvWrittenState : 1;     //13) SET if TPMA_NV_WRITTEN is required to
    //    be SET. Used when 'checkNvWritten' is
    //    SET
    unsigned    isTemplateSet : 1;      //14) SET if the templateHash needs to be
    //    checked for Create, CreatePrimary, or
    //    CreateLoaded.
    unsigned    _reserved : 18;         //15-32  /* libtpms added */
#endif                                           /* libtpms added */
#if BIG_ENDIAN_TPM == YES                        /* libtpms added begin */
    unsigned    _reserved : 18;         //15-32
    unsigned    isTemplateSet : 1;      //14) SET if the templateHash needs to be
    unsigned    nvWrittenState : 1;     //13) SET if TPMA_NV_WRITTEN is required to
    unsigned    checkNvWritten : 1;     //12) SET if the TPMA_NV_WRITTEN attribute
    unsigned    includeAuth : 1;        //11) This attribute is SET when the
    unsigned    isLockoutBound : 1;     //10) SET if the session is bound to
    unsigned    isDaBound : 1;          //9) SET if the bind entity had noDA CLEAR.
    unsigned    isTrialPolicy : 1;      //8) SET if the policy session is created
    unsigned    isPPRequired : 1;       //7) SET if physical presence is required to
    unsigned    isPasswordNeeded : 1;   //6) SET if a password authValue is required
    unsigned    isAuthValueNeeded : 1;  //5) SET if the authValue is required for
    unsigned    isCpHashDefined : 1;    //4) SET if the cpHash has been defined
    unsigned    isBound : 1;            //3) SET if the session is bound to with an
    unsigned    isAudit : 1;            //2) SET if the session is used for audit
    unsigned    isPolicy : 1;           //1) SET if the session may only be used
#endif                                           /* libtpms added end */
} SESSION_ATTRIBUTES;

/* 5.9.5.3	SESSION Structure */
/* The SESSION structure contains all the context of a session except for the associated
   contextID. */
/* NOTE: The contextID of a session is only relevant when the session context is stored off the
   TPM. */
typedef struct SESSION
{
    SESSION_ATTRIBUTES  attributes;         // session attributes
    UINT32              pcrCounter;         // PCR counter value when PCR is
    // included (policy session)
    // If no PCR is included, this
    // value is 0.
    UINT64              startTime;          // The value in g_time
    // when the session was started (policy session)
    UINT64              timeout;            // The timeout relative to g_time
    // There is no timeout if this value
    // is 0.
    CLOCK_NONCE         epoch;              // The g_clockEpoch value when the
    // session was started. If g_clockEpoch
    // does not match this value when the
    // timeout is used, then
    // then the command will fail.
    TPM_CC              commandCode;        // command code (policy session)
    TPM_ALG_ID          authHashAlg;        // session hash algorithm
    TPMA_LOCALITY       commandLocality;    // command locality (policy session)
    TPMT_SYM_DEF        symmetric;          // session symmetric algorithm (if any)
    TPM2B_AUTH          sessionKey;         // session secret value used for
    // this session
    TPM2B_NONCE         nonceTPM;           // last TPM-generated nonce for
    // generating HMAC and encryption keys
    union
    {
	TPM2B_NAME      boundEntity;        // value used to track the entity to
	// which the session is bound
	TPM2B_DIGEST    cpHash;             // the required cpHash value for the
	// command being authorized
	TPM2B_DIGEST    nameHash;           // the required nameHash
	TPM2B_DIGEST    templateHash;       // the required template for creation
    } u1;
    union
    {
	TPM2B_DIGEST    auditDigest;        // audit session digest
	TPM2B_DIGEST    policyDigest;       // policyHash
    } u2;                                   // audit log and policyHash may
    // share space to save memory
} SESSION;
#define     EXPIRES_ON_RESET    INT32_MIN
#define     TIMEOUT_ON_RESET    UINT64_MAX
#define     EXPIRES_ON_RESTART  (INT32_MIN + 1)
#define     TIMEOUT_ON_RESTART  (UINT64_MAX - 1)
typedef BYTE        SESSION_BUF[sizeof(SESSION)];

/* 5.9.7	PCR */
/* 5.9.7.1	PCR_SAVE Structure */
/* The PCR_SAVE structure type contains the PCR data that are saved across power cycles. Only the
   static PCR are required to be saved across power cycles. The DRTM and resettable PCR are not
   saved. The number of static and resettable PCR is determined by the platform-specific
   specification to which the TPM is built. */

#define PCR_SAVE_SPACE(HASH, Hash)  BYTE Hash[NUM_STATIC_PCR][HASH##_DIGEST_SIZE];

typedef struct PCR_SAVE
{
    FOR_EACH_HASH(PCR_SAVE_SPACE)

    // This counter increments whenever the PCR are updated.
    // NOTE: A platform-specific specification may designate
    //       certain PCR changes as not causing this counter
    //       to increment.
    UINT32              pcrCounter;
} PCR_SAVE;

/* 5.9.6.2	PCR_POLICY */
#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
/* This structure holds the PCR policies, one for each group of PCR controlled by policy. */
typedef struct PCR_POLICY
{
    TPMI_ALG_HASH       hashAlg[NUM_POLICY_PCR_GROUP];
    TPM2B_DIGEST        a_unused; /* libtpms: renamed field since not used and not initialized */
    TPM2B_DIGEST        policy[NUM_POLICY_PCR_GROUP];
} PCR_POLICY;
#endif

/* 5.9.6.3	PCR_AUTHVALUE */
/* This structure holds the PCR policies, one for each group of PCR controlled by policy. */
typedef struct PCR_AUTH_VALUE
{
    TPM2B_DIGEST        auth[NUM_AUTHVALUE_PCR_GROUP];
} PCR_AUTHVALUE;

/* 5.9.7	STARTUP_TYPE */
/* This enumeration is the possible startup types. The type is determined by the combination of
   TPM2_ShutDown() and TPM2_Startup(). */
typedef enum
    {
	SU_RESET,
	SU_RESTART,
	SU_RESUME
    } STARTUP_TYPE;

/* 5.9.8	NV */
/* 5.9.8.1	NV_INDEX */
/* The NV_INDEX structure defines the internal format for an NV index. The indexData size varies
   according to the type of the index. In this implementation, all of the index is manipulated as a
   unit. */
typedef struct NV_INDEX
{
    TPMS_NV_PUBLIC      publicArea;
    TPM2B_AUTH          authValue;
} NV_INDEX;

/* 5.9.8.2	NV_REF */
/* An NV_REF is an opaque value returned by the NV subsystem. It is used to reference and NV Index
   in a relatively efficient way. Rather than having to continually search for an Index, its
   reference value may be used. In this implementation, an NV_REF is a byte pointer that points to
   the copy of the NV memory that is kept in RAM. */
typedef UINT32           NV_REF;
typedef BYTE            *NV_RAM_REF;

/* 5.9.8.3	NV_PIN */
/* This structure deals with the possible endianness differences between the canonical form of the
   TPMS_NV_PIN_COUNTER_PARAMETERS structure and the internal value. The structures allow the data in
   a PIN index to be read as an 8-octet value using NvReadUINT64Data(). That function will byte swap
   all the values on a little endian system. This will put the bytes with the 4-octet values in the
   correct order but will swap the pinLimit and pinCount values. When written, the PIN index is
   simply handled as a normal index with the octets in canonical order. */
#if BIG_ENDIAN_TPM
typedef struct
{
    UINT32      pinCount;
    UINT32      pinLimit;
} PIN_DATA;
#else
typedef struct
{
    UINT32      pinLimit;
    UINT32      pinCount;
} PIN_DATA;
#endif
typedef union
{
    UINT64     intVal;
    PIN_DATA   pin;
} NV_PIN;

/* 5.9.9	COMMIT_INDEX_MASK */
/* This is the define for the mask value that is used when manipulating the bits in the commit bit
   array. The commit counter is a 64-bit value and the low order bits are used to index the
   commitArray. This mask value is applied to the commit counter to extract the bit number in the
   array. */
#if ALG_ECC
#define COMMIT_INDEX_MASK ((UINT16)((sizeof(gr.commitArray)*8)-1))
#endif

/* 5.9.10	RAM Global Values */
/* 5.9.10.1	Description */
/* The values in this section are only extant in RAM or ROM as constant values. */
/* 5.9.10.2	Crypto Self-Test Values */
EXTERN ALGORITHM_VECTOR     g_implementedAlgorithms;
EXTERN ALGORITHM_VECTOR     g_toTest;

/* 5.9.10.3	g_rcIndex[] */
/* This array is used to contain the array of values that are added to a return code when it is a
   parameter-, handle-, or session-related error. This is an implementation choice and the same
   result can be achieved by using a macro. */
#define g_rcIndexInitializer {  TPM_RC_1, TPM_RC_2, TPM_RC_3, TPM_RC_4,	\
	    TPM_RC_5, TPM_RC_6, TPM_RC_7, TPM_RC_8,			\
	    TPM_RC_9, TPM_RC_A, TPM_RC_B, TPM_RC_C,			\
	    TPM_RC_D, TPM_RC_E, TPM_RC_F }
EXTERN const UINT16     g_rcIndex[15] INITIALIZER(g_rcIndexInitializer);

/* 5.9.10.4	g_exclusiveAuditSession */
/* This location holds the session handle for the current exclusive audit session. If there is no
   exclusive audit session, the location is set to TPM_RH_UNASSIGNED. */
EXTERN TPM_HANDLE       g_exclusiveAuditSession;

/* 5.9.10.5	g_time */
/* This is the value in which we keep the current command time. This is initialized at the start of
   each command. The time is the accumulated time since the last time that the TPM's timer was last
   powered up. Clock is the accumulated time since the last time that the TPM was cleared. g_time is
   in mS. */
EXTERN  UINT64          g_time;

/* 5.9.10.6	g_timeEpoch */
/* This value contains the current clock Epoch. It changes when there is a clock discontinuity. It
   may be necessary to place this in NV should the timer be able to run across a power down of the
   TPM but not in all cases (e.g. dead battery). If the nonce is placed in NV, it should go in gp
   because it should be changing slowly. */
#if CLOCK_STOPS
EXTERN CLOCK_NONCE       g_timeEpoch;
#else
#define g_timeEpoch      gp.timeEpoch
#endif

/* 5.9.10.7 g_phEnable */
/* This is the platform hierarchy control and determines if the platform hierarchy is
   available. This value is SET on each TPM2_Startup(). The default value is SET. */
EXTERN BOOL             g_phEnable;

/* 5.9.10.8 g_pcrReConfig */
/* This value is SET if a TPM2_PCR_Allocate() command successfully executed since the last
   TPM2_Startup(). If so, then the next shutdown is required to be Shutdown(CLEAR). */
EXTERN BOOL             g_pcrReConfig;

/* 5.9.10.9 g_DRTMHandle */
/* This location indicates the sequence object handle that holds the DRTM sequence data. When not
   used, it is set to TPM_RH_UNASSIGNED. A sequence DRTM sequence is started on either _TPM_Init()
   or _TPM_Hash_Start(). */
EXTERN TPMI_DH_OBJECT   g_DRTMHandle;

/* 5.9.10.10 g_DrtmPreStartup */
/* This value indicates that an H-CRTM occurred after _TPM_Init() but before TPM2_Startup(). The
   define for PRE_STARTUP_FLAG is used to add the g_DrtmPreStartup value to gp_orderlyState at
   shutdown. This hack is to avoid adding another NV variable. */
EXTERN  BOOL            g_DrtmPreStartup;

/* 5.9.10.11 g_StartupLocality3 */
/* This value indicates that a TPM2_Startup() occurred at locality 3. Otherwise, it at locality
   0. The define for STARTUP_LOCALITY_3 is to indicate that the startup was not at locality 0. This
   hack is to avoid adding another NV variable. */
EXTERN  BOOL            g_StartupLocality3;

/* 5.9.10.12 TPM_SU_NONE */
/* Part 2 defines the two shutdown/startup types that may be used in TPM2_Shutdown() and
   TPM2_Starup(). This additional define is used by the TPM to indicate that no shutdown was
   received. */
/* NOTE: This is a reserved value. */
#define SU_NONE_VALUE           (0xFFFF)
#define TPM_SU_NONE             (TPM_SU)(SU_NONE_VALUE)

/* 5.9.10.13 TPM_SU_DA_USED */
/* As with TPM_SU_NONE, this value is added to allow indication that the shutdown was not orderly
   and that a DA=protected object was reference during the previous cycle. */
#define SU_DA_USED_VALUE    (SU_NONE_VALUE - 1)
#define TPM_SU_DA_USED      (TPM_SU)(SU_DA_USED_VALUE)

/* 5.9.10.14 Startup Flags */
/* These flags are included in gp.orderlyState. These are hacks and are being used to avoid having
   to change the layout of gp. The PRE_STARTUP_FLAG indicates that a
   _TPM_Hash_Start()/_Data()/_End() sequence was received after _TPM_Init() but before
   TPM2_StartUp(). STARTUP_LOCALITY_3 indicates that the last TPM2_Startup() was received at
   locality 3. These flags are only relevant if after a TPM2_Shutdown(STATE). */
#define PRE_STARTUP_FLAG	 0x8000
#define STARTUP_LOCALITY_3   0x4000
#define TPM_SU_STATE_MASK ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3) // libtpms added
#if USE_DA_USED

/*     5.9.10.15 g_daUsed */
/* This location indicates if a DA-protected value is accessed during a boot cycle. If none has,
   then there is no need to increment failedTries on the next non-orderly startup. This bit is
   merged with gp.orderlyState when gp.orderly is set to SU_NONE_VALUE */

/* This global is set to FALSE on startup (after a decision has been made on whether to increment
   the failedTries or not).  On a first attempt to access a DA protected object: this global is set
   to 1, the orderlyState is set to SU_DA_USED, committed to NV and the command execution returns
   with RC_RETRY (without exposing any information on the DA attempt).  */
EXTERN	BOOL			g_daUsed;
#endif

/* 5.9.10.16 g_updateNV */
/* This flag indicates if NV should be updated at the end of a command. This flag is set to UT_NONE
   at the beginning of each command in ExecuteCommand(). This flag is checked in ExecuteCommand()
   after the detailed actions of a command complete. If the command execution was successful and
   this flag is not UT_NONE, any pending NV writes will be committed to NV. UT_ORDERLY causes any
   RAM data to be written to the orderly space for staging the write to NV. */
typedef BYTE        UPDATE_TYPE;
#define UT_NONE     (UPDATE_TYPE)0
#define UT_NV       (UPDATE_TYPE)1
#define UT_ORDERLY  (UPDATE_TYPE)(UT_NV + 2)
EXTERN UPDATE_TYPE          g_updateNV;
/* 5.9.10.17 g_powerWasLost */
/* This flag is used to indicate if the power was lost. It is SET in _TPM__Init(). This flag is
   cleared by TPM2_Startup() after all power-lost activities are completed. */
/* NOTE: When power is applied, this value can come up as anything. However, _plat__WasPowerLost()
   will provide the proper indication in that case. So, when power is actually lost, we get the
   correct answer. When power was not lost, but the power-lost processing has not been completed
   before the next _TPM_Init(), then the TPM still does the correct thing. */
EXTERN BOOL             g_powerWasLost;

/* 5.9.10.18 g_clearOrderly */
/* This flag indicates if the execution of a command should cause the orderly state to be cleared.
   This flag is set to FALSE at the beginning of each command in ExecuteCommand() and is checked in
   ExecuteCommand() after the detailed actions of a command complete but before the check of
   g_updateNV. If this flag is TRUE, and the orderly state is not SU_NONE_VALUE, then the orderly
   state in NV memory will be changed to SU_NONE_VALUE or SU_DA_USED_VALUE. */
EXTERN BOOL             g_clearOrderly;

/* 5.9.10.19 g_prevOrderlyState */
/* This location indicates how the TPM was shut down before the most recent TPM2_Startup(). This
   value, along with the startup type, determines if the TPM should do a TPM Reset, TPM Restart, or
   TPM Resume. */
EXTERN TPM_SU           g_prevOrderlyState;

/* 5.9.10.20 g_nvOk */
/* This value indicates if the NV integrity check was successful or not. If not and the failure was
   severe, then the TPM would have been put into failure mode after it had been re-manufactured. If
   the NV failure was in the area where the state-save data is kept, then this variable will have a
   value of FALSE indicating that a TPM2_Startup(CLEAR) is required. */
EXTERN BOOL             g_nvOk;

/* NV availability is sampled as the start of each command and stored here so that its value remains
   consistent during the command execution */
EXTERN TPM_RC           g_NvStatus;

/* 5.9.10.21 g_platformUnique */
/* This location contains the unique value(s) used to identify the TPM. It is loaded on every
   _TPM2_Startup() The first value is used to seed the RNG. The second value is used as a vendor
   authValue. The value used by the RNG would be the value derived from the chip unique value (such
   as fused) with a dependency on the authorities of the code in the TPM boot path. The second would
   be derived from the chip unique value with a dependency on the details of the code in the boot
   path. That is, the first value depends on the various signers of the code and the second depends
   on what was signed. The TPM vendor should not be able to know the first value but they are
   expected to know the second. */
EXTERN TPM2B_AUTH       g_platformUniqueAuthorities; // Reserved for RNG
EXTERN TPM2B_AUTH       g_platformUniqueDetails;   // referenced by VENDOR_PERMANENT

//*********************************************************************************
//*********************************************************************************
//** Persistent Global Values
//*********************************************************************************
//*********************************************************************************
//*** Description
// The values in this section are global values that are persistent across power
// events. The lifetime of the values determines the structure in which the value
// is placed.

/* 5.9.11.2	PERSISTENT_DATA */
/* This structure holds the persistent values that only change as a consequence of a specific
   Protected Capability and are not affected by TPM power events (TPM2_Startup() or
   TPM2_Shutdown(). */
typedef struct
{
    //*********************************************************************************
    //          Hierarchy
    //*********************************************************************************
    // The values in this section are related to the hierarchies.
    BOOL                disableClear;       // TRUE if TPM2_Clear() using
    // lockoutAuth is disabled
    // Hierarchy authPolicies
    TPMI_ALG_HASH       ownerAlg;
    TPMI_ALG_HASH       endorsementAlg;
    TPMI_ALG_HASH       lockoutAlg;
    TPM2B_DIGEST        ownerPolicy;
    TPM2B_DIGEST        endorsementPolicy;
    TPM2B_DIGEST        lockoutPolicy;
    // Hierarchy authValues
    TPM2B_AUTH          ownerAuth;
    TPM2B_AUTH          endorsementAuth;
    TPM2B_AUTH          lockoutAuth;
    // Primary Seeds
    TPM2B_SEED          EPSeed;
    TPM2B_SEED          SPSeed;
    TPM2B_SEED          PPSeed;
    // SEED_COMPAT_LEVELs related to creation time of seeds
    SEED_COMPAT_LEVEL   EPSeedCompatLevel; // libtpms added begin
    SEED_COMPAT_LEVEL   SPSeedCompatLevel;
    SEED_COMPAT_LEVEL   PPSeedCompatLevel; // libtpms added end
    // Note there is a nullSeed in the state_reset memory.
    // Hierarchy proofs
    TPM2B_PROOF          phProof;
    TPM2B_PROOF          shProof;
    TPM2B_PROOF          ehProof;
    // Note there is a nullProof in the state_reset memory.
    //*********************************************************************************
    //          Reset Events
    //*********************************************************************************
    // A count that increments at each TPM reset and never get reset during the life
    // time of TPM.  The value of this counter is initialized to 1 during TPM
    // manufacture process. It is used to invalidate all saved contexts after a TPM
    // Reset.
    UINT64              totalResetCount;
    // This counter increments on each TPM Reset. The counter is reset by
    // TPM2_Clear().
    UINT32              resetCount;
    //*********************************************************************************
    //          PCR
    //*********************************************************************************
    // This structure hold the policies for those PCR that have an update policy.
    // This implementation only supports a single group of PCR controlled by
    // policy. If more are required, then this structure would be changed to
    // an array.
#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
    PCR_POLICY          pcrPolicies;
#endif
    // This structure indicates the allocation of PCR. The structure contains a
    // list of PCR allocations for each implemented algorithm. If no PCR are
    // allocated for an algorithm, a list entry still exists but the bit map
    // will contain no SET bits.
    TPML_PCR_SELECTION  pcrAllocated;
    //*********************************************************************************
    //          Physical Presence
    //*********************************************************************************
    // The PP_LIST type contains a bit map of the commands that require physical
    // to be asserted when the authorization is evaluated. Physical presence will be
    // checked if the corresponding bit in the array is SET and if the authorization
    // handle is TPM_RH_PLATFORM.
    //
    // These bits may be changed with TPM2_PP_Commands().
    BYTE                ppList[(COMMAND_COUNT + 7) / 8];
    //*********************************************************************************
    //          Dictionary attack values
    //*********************************************************************************
    // These values are used for dictionary attack tracking and control.
    UINT32              failedTries;        // the current count of unexpired
    // authorization failures
    UINT32              maxTries;           // number of unexpired authorization
    // failures before the TPM is in
    // lockout
    UINT32              recoveryTime;       // time between authorization failures
    // before failedTries is decremented
    UINT32              lockoutRecovery;    // time that must expire between
    // authorization failures associated
    // with lockoutAuth
    BOOL                lockOutAuthEnabled; // TRUE if use of lockoutAuth is
    // allowed
    //*****************************************************************************
    //            Orderly State
    //*****************************************************************************
    // The orderly state for current cycle
    TPM_SU              orderlyState;
    //*****************************************************************************
    //           Command audit values.
    //*****************************************************************************
    BYTE                auditCommands[((COMMAND_COUNT + 1) + 7) / 8];
    TPMI_ALG_HASH       auditHashAlg;
    UINT64              auditCounter;
    //*****************************************************************************
    //           Algorithm selection
    //*****************************************************************************
    //
    // The 'algorithmSet' value indicates the collection of algorithms that are
    // currently in used on the TPM.  The interpretation of value is vendor dependent.
    UINT32              algorithmSet;
    //*****************************************************************************
    //           Firmware version
    //*****************************************************************************
    // The firmwareV1 and firmwareV2 values are instanced in TimeStamp.c. This is
    // a scheme used in development to allow determination of the linker build time
    // of the TPM. An actual implementation would implement these values in a way that
    // is consistent with vendor needs. The values are maintained in RAM for simplified
    // access with a master version in NV.  These values are modified in a
    // vendor-specific way.
    // g_firmwareV1 contains the more significant 32-bits of the vendor version number.
    // In the reference implementation, if this value is printed as a hex
    // value, it will have the format of YYYYMMDD
    UINT32              firmwareV1;
    // g_firmwareV1 contains the less significant 32-bits of the vendor version number.
    // In the reference implementation, if this value is printed as a hex
    // value, it will have the format of 00 HH MM SS
    UINT32              firmwareV2;
    //*****************************************************************************
    //           Timer Epoch
    //*****************************************************************************
    // timeEpoch contains a nonce that has a vendor=specific size (should not be
    // less than 8 bytes. This nonce changes when the clock epoch changes. The clock
    // epoch changes when there is a discontinuity in the timing of the TPM.
#if !CLOCK_STOPS
    CLOCK_NONCE         timeEpoch;
#endif
} PERSISTENT_DATA;
EXTERN PERSISTENT_DATA  gp;

/* 5.9.11.3 ORDERLY_DATA */
/* The data in this structure is saved to NV on each TPM2_Shutdown(). */
typedef struct orderly_data
{
    //*****************************************************************************
    //           TIME
    //*****************************************************************************
    // Clock has two parts. One is the state save part and one is the NV part. The
    // state save version is updated on each command. When the clock rolls over, the
    // NV version is updated. When the TPM starts up, if the TPM was shutdown in and
    // orderly way, then the sClock value is used to initialize the clock. If the
    // TPM shutdown was not orderly, then the persistent value is used and the safe
    // attribute is clear.
    UINT64              clock;              // The orderly version of clock
    TPMI_YES_NO         clockSafe;          // Indicates if the clock value is
    // safe.
    // In many implementations, the quality of the entropy available is not that
    // high. To compensate, the current value of the drbgState can be saved and
    // restored on each power cycle. This prevents the internal state from reverting
    // to the initial state on each power cycle and starting with a limited amount
    // of entropy. By keeping the old state and adding entropy, the entropy will
    // accumulate.
    DRBG_STATE          drbgState;
    // These values allow the accumulation of self-healing time across orderly shutdown
    // of the TPM.
#if ACCUMULATE_SELF_HEAL_TIMER
    UINT64              selfHealTimer;  // current value of s_selfHealTimer
    UINT64              lockoutTimer;   // current value of s_lockoutTimer
    UINT64              time;           // current value of g_time at shutdown
#endif // ACCUMULATE_SELF_HEAL_TIMER

#ifndef __ACT_DISABLED	// libtpms added
#error ACT not supported in ORDERLY_DATA!
    // These are the ACT Timeout values. They are saved with the other timers
#define DefineActData(N)  ACT_STATE      ACT_##N;
    FOR_EACH_ACT(DefineActData)

    // this is the 'signaled' attribute data for all the ACT. It is done this way so
    // that they can be manipulated by ACT number rather than having to access a
    // structure.
    UINT16              signaledACT;
    UINT16              preservedSignaled;
#endif			// libtpms added
} ORDERLY_DATA;
#if ACCUMULATE_SELF_HEAL_TIMER
#define     s_selfHealTimer     go.selfHealTimer
#define     s_lockoutTimer      go.lockoutTimer
#endif  // ACCUMULATE_SELF_HEAL_TIMER
#  define drbgDefault go.drbgState
EXTERN ORDERLY_DATA     go;

/* 5.9.11.4  STATE_CLEAR_DATA */
/* This structure contains the data that is saved on Shutdown(STATE). and restored on
   Startup(STATE).  The values are set to their default settings on any Startup(Clear). In other
   words the data is only persistent across TPM Resume. */
/* If the comments associated with a parameter indicate a default reset value, the value is applied
   on each Startup(CLEAR). */
typedef struct state_clear_data
{
    //*****************************************************************************
    //           Hierarchy Control
    //*****************************************************************************
    BOOL                shEnable;           // default reset is SET
    BOOL                ehEnable;           // default reset is SET
    BOOL                phEnableNV;         // default reset is SET
    TPMI_ALG_HASH       platformAlg;        // default reset is TPM_ALG_NULL
    TPM2B_DIGEST        platformPolicy;     // default reset is an Empty Buffer
    TPM2B_AUTH          platformAuth;       // default reset is an Empty Buffer
    //*****************************************************************************
    //           PCR
    //*****************************************************************************
    // The set of PCR to be saved on Shutdown(STATE)
    PCR_SAVE            pcrSave;            // default reset is 0...0
    // This structure hold the authorization values for those PCR that have an
    // update authorization.
    // This implementation only supports a single group of PCR controlled by
    // authorization. If more are required, then this structure would be changed to
    // an array.
    PCR_AUTHVALUE       pcrAuthValues;

#ifndef __ACT_DISABLED	// libtpms added
    //*****************************************************************************
    //           ACT
    //*****************************************************************************
#define DefineActPolicySpace(N)     TPMT_HA     act_##N;
    FOR_EACH_ACT(DefineActPolicySpace)

#endif			// libtpms added
} STATE_CLEAR_DATA;
EXTERN STATE_CLEAR_DATA gc;

/* 5.9.11.5 State Reset Data */
/* This structure contains data is that is saved on Shutdown(STATE) and restored on the subsequent
   Startup(ANY). That is, the data is preserved across TPM Resume and TPM Restart. */
/* If a default value is specified in the comments this value is applied on TPM Reset. */
typedef struct state_reset_data
{
    //*****************************************************************************
    //          Hierarchy Control
    //*****************************************************************************
    TPM2B_PROOF          nullProof;          // The proof value associated with
    // the TPM_RH_NULL hierarchy. The
    // default reset value is from the RNG.
    TPM2B_SEED          nullSeed;           // The seed value for the TPM_RN_NULL
    SEED_COMPAT_LEVEL   nullSeedCompatLevel; // libtpms added
    // hierarchy. The default reset value
    // is from the RNG.
    //*****************************************************************************
    //           Context
    //*****************************************************************************
    // The 'clearCount' counter is incremented each time the TPM successfully executes
    // a TPM Resume. The counter is included in each saved context that has 'stClear'
    // SET (including descendants of keys that have 'stClear' SET). This prevents these
    // objects from being loaded after a TPM Resume.
    // If 'clearCount' is at its maximum value when the TPM receives a Shutdown(STATE),
    // the TPM will return TPM_RC_RANGE and the TPM will only accept Shutdown(CLEAR).
    UINT32              clearCount;         // The default reset value is 0.
    UINT64              objectContextID;    // This is the context ID for a saved
    //  object context. The default reset
    //  value is 0.
    CONTEXT_SLOT        contextArray[MAX_ACTIVE_SESSIONS];    // This array contains
    // contains the values used to track
    // the version numbers of saved
    // contexts (see
    // Session.c in for details). The
    // default reset value is {0}.
    CONTEXT_COUNTER     contextCounter;     // This is the value from which the
    // 'contextID' is derived. The
    // default reset value is {0}.
    //*****************************************************************************
    //           Command Audit
    //*****************************************************************************
    // When an audited command completes, ExecuteCommand() checks the return
    // value.  If it is TPM_RC_SUCCESS, and the command is an audited command, the
    // TPM will extend the cpHash and rpHash for the command to this value. If this
    // digest was the Zero Digest before the cpHash was extended, the audit counter
    // is incremented.
    TPM2B_DIGEST        commandAuditDigest; // This value is set to an Empty Digest
    // by TPM2_GetCommandAuditDigest() or a
    // TPM Reset.
    //*****************************************************************************
    //           Boot counter
    //*****************************************************************************
    UINT32              restartCount;       // This counter counts TPM Restarts.
    // The default reset value is 0.
    //*********************************************************************************
    //            PCR
    //*********************************************************************************
    // This counter increments whenever the PCR are updated. This counter is preserved
    // across TPM Resume even though the PCR are not preserved. This is because
    // sessions remain active across TPM Restart and the count value in the session
    // is compared to this counter so this counter must have values that are unique
    // as long as the sessions are active.
    // NOTE: A platform-specific specification may designate that certain PCR changes
    //       do not increment this counter to increment.
    UINT32              pcrCounter;         // The default reset value is 0.
#if ALG_ECC
    //*****************************************************************************
    //         ECDAA
    //*****************************************************************************
    UINT64              commitCounter;      // This counter increments each time
    // TPM2_Commit() returns
    // TPM_RC_SUCCESS. The default reset
    // value is 0.
    TPM2B_NONCE         commitNonce;        // This random value is used to compute
    // the commit values. The default reset
    // value is from the RNG.
    // This implementation relies on the number of bits in g_commitArray being a
    // power of 2 (8, 16, 32, 64, etc.) and no greater than 64K.
    BYTE                 commitArray[16];   // The default reset value is {0}.
#endif // ALG_ECC
} STATE_RESET_DATA;
EXTERN STATE_RESET_DATA gr;

										// libtpms added begin
/* The s_ContextSlotMask masks CONTEXT_SLOT values; this variable can have
 * only two valid values, 0xff or 0xffff. The former is used to simulate
 * a CONTEXT_SLOT defined as UINT8, the latter is used for the CONTEXT_SLOT
 * when it is a UINT16. The original TPM 2 code uses a cast to CONTEXT_SLOT
 * to truncate larger values and has been modified to use CONTEXT_SLOT_MASKED
 * to achieve the same effect with the above two values.
 *
 * Using CONTEXT_SLOT_MASKED we make sure that when we write values into
 * gr.contextArray that these values are properly masked/truncated so that
 * when we read values from gr.contextArray that we don't have to mask
 * them again.
 *
 * s_ContextSlotMask may only be initialized to 0xff when resuming an older
 * state from the time when CONTEXT_SLOT was UINT8, otherwise it must be set
 * to 0xffff. We set it to 0xffff in SessionStartup(SU_CLEAR) and to be
 * able to save the TPM state really early (and restore it) also in
 * TPM_Manufacture().
 */
EXTERN CONTEXT_SLOT s_ContextSlotMask;
#define CONTEXT_SLOT_MASKED(val) ((CONTEXT_SLOT)(val) & s_ContextSlotMask)	// libtpms added end

/* 5.9.12 NV Layout */
/* The NV data organization is */
/* a) a PERSISTENT_DATA structure */
/* b) a STATE_RESET_DATA structure */
/* c) a STATE_CLEAR_DATA structure */
/* d) an ORDERLY_DATA structure */
/* e) the user defined NV index space */

/* libtpms added: to put certain data structure at fixed offsets
 *                to give the ones below some room to expand
 */
#define NV_PERSISTENT_DATA  (0)
#define NV_STATE_RESET_DATA (NV_PERSISTENT_DATA + sizeof(PERSISTENT_DATA))
#define NV_STATE_CLEAR_DATA (NV_STATE_RESET_DATA + sizeof(STATE_RESET_DATA))
#define NV_ORDERLY_DATA     (NV_STATE_CLEAR_DATA + sizeof(STATE_CLEAR_DATA))
#define NV_INDEX_RAM_DATA   TPM2_ROUNDUP(NV_ORDERLY_DATA + sizeof(ORDERLY_DATA),\
                                         1024) /* libtpms added */
#define NV_USER_DYNAMIC     (NV_INDEX_RAM_DATA + sizeof(s_indexOrderlyRam))
#define NV_USER_DYNAMIC_END     NV_MEMORY_SIZE

/* 5.9.13 Global Macro Definitions */
/* The NV_READ_PERSISTENT and NV_WRITE_PERSISTENT macros are used to access members of the
   PERSISTENT_DATA structure in NV. */
#define NV_READ_PERSISTENT(to, from)					\
    NvRead(&to, offsetof(PERSISTENT_DATA, from), sizeof(to))
#define NV_WRITE_PERSISTENT(to, from)					\
    NvWrite(offsetof(PERSISTENT_DATA, to), sizeof(gp.to), &from)
#define CLEAR_PERSISTENT(item)						\
    NvClearPersistent(offsetof(PERSISTENT_DATA, item), sizeof(gp.item))
#define NV_SYNC_PERSISTENT(item) NV_WRITE_PERSISTENT(item, gp.item)

/* At the start of command processing, the index of the command is determined. This index value is
   used to access the various data tables that contain per-command information. There are multiple
   options for how the per-command tables can be implemented. This is resolved in
   GetClosestCommandIndex(). */
typedef UINT16      COMMAND_INDEX;
#define UNIMPLEMENTED_COMMAND_INDEX     ((COMMAND_INDEX)(~0))
#if 0                                      /* libtpms added */
typedef struct _COMMAND_FLAGS_
{
#if LITTLE_ENDIAN_TPM == YES               /* libtpms added */
    unsigned    trialPolicy : 1;    //1) If SET, one of the handles references a
    //   trial policy and authorization may be
    //   skipped. This is only allowed for a policy
    //   command.
    unsigned    reserved : 31;     //2-31) /* libtpms added begin */
#endif
#if BIG_ENDIAN_TPM == YES
    unsigned    reserved : 31;     //2-31)
    unsigned    trialPolicy : 1;    //1) If SET, one of the handles references a
#endif                                     /* libtpms added end */
} COMMAND_FLAGS;
#endif                                     /* libtpms added */

/* This structure is used to avoid having to manage a large number of parameters being passed
   through various levels of the command input processing.

   The following macros are used to define the space for the CP and RP hashes. Space is provided
   for each implemented hash algorithm because it is not known what the caller may use.
*/

#define CP_HASH(HASH, Hash)           TPM2B_##HASH##_DIGEST   Hash##CpHash;
#define RP_HASH(HASH, Hash)           TPM2B_##HASH##_DIGEST   Hash##RpHash;

typedef struct _COMMAND_
{
    TPM_ST           tag;               // the parsed command tag
    TPM_CC           code;              // the parsed command code
    COMMAND_INDEX    index;             // the computed command index
    UINT32           handleNum;         // the number of entity handles in the
    //   handle area of the command
    TPM_HANDLE       handles[MAX_HANDLE_NUM]; // the parsed handle values
    UINT32           sessionNum;        // the number of sessions found
    INT32            parameterSize;     // starts out with the parsed command size
    // and is reduced and values are unmarshaled. Just before calling the command actions, this
    // should be zero.  After the command actions, this number should grow as values are marshaled
    // in to the response buffer.
    INT32            authSize;          // this is initialized with the parsed size
    // of authorizationSize field and should be zero when the authorizations are parsed.
    BYTE            *parameterBuffer;   // input to ExecuteCommand
    BYTE            *responseBuffer;    // input to ExecuteCommand
    FOR_EACH_HASH(CP_HASH)              // space for the CP hashes
    FOR_EACH_HASH(RP_HASH)              // space for the RP hashes
} COMMAND;

// Global string constants for consistency in KDF function calls. These string constants are shared
// across functions to make sure that they are all using consistent string values.
#define STRING_INITIALIZER(value)   {{sizeof(value), {value}}}
#define TPM2B_STRING(name, value)					\
    typedef union name##_ {						\
	struct  {							\
	    UINT16  size;						\
	    BYTE    buffer[sizeof(value)];				\
	} t;								\
	TPM2B   b;							\
    } TPM2B_##name##_;							\
    EXTERN  const TPM2B_##name##_      name##_ INITIALIZER(STRING_INITIALIZER(value)); \
    EXTERN  const TPM2B               *name INITIALIZER(&name##_.b)
TPM2B_STRING(PRIMARY_OBJECT_CREATION, "Primary Object Creation");
TPM2B_STRING(CFB_KEY, "CFB");
TPM2B_STRING(CONTEXT_KEY, "CONTEXT");
TPM2B_STRING(INTEGRITY_KEY, "INTEGRITY");
TPM2B_STRING(SECRET_KEY, "SECRET");
TPM2B_STRING(SESSION_KEY, "ATH");
TPM2B_STRING(STORAGE_KEY, "STORAGE");
TPM2B_STRING(XOR_KEY, "XOR");
TPM2B_STRING(COMMIT_STRING, "ECDAA Commit");
TPM2B_STRING(DUPLICATE_STRING, "DUPLICATE");
TPM2B_STRING(IDENTITY_STRING, "IDENTITY");
TPM2B_STRING(OBFUSCATE_STRING, "OBFUSCATE");
#if SELF_TEST
TPM2B_STRING(OAEP_TEST_STRING, "OAEP Test Value");
#endif // SELF_TEST

// 5.9.14	From CryptTest.c
// This structure contains the self-test state values for the cryptographic modules.
EXTERN CRYPTO_SELF_TEST_STATE   g_cryptoSelfTestState;

/* 5.9.15 From Manufacture.c */
EXTERN BOOL              g_manufactured;
/* This value indicates if a TPM2_Startup() commands has been receive since the power on event.
   This flag is maintained in power simulation module because this is the only place that may
   reliably set this flag to FALSE. */
EXTERN BOOL              g_initialized;

/* 5.9.16 Private data */
#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
/* From SessionProcess.c */
/* The following arrays are used to save command sessions information so that the command
   handle/session buffer does not have to be preserved for the duration of the command. These arrays
   are indexed by the session index in accordance with the order of sessions in the session area of
   the command. */

/* Array of the authorization session handles */
EXTERN TPM_HANDLE       s_sessionHandles[MAX_SESSION_NUM];

/* Array of authorization session attributes */
EXTERN TPMA_SESSION     s_attributes[MAX_SESSION_NUM];

/* Array of handles authorized by the corresponding authorization sessions; and if none, then
   TPM_RH_UNASSIGNED value is used */

EXTERN TPM_HANDLE s_associatedHandles[MAX_SESSION_NUM];

/* Array of nonces provided by the caller for the corresponding sessions */
EXTERN TPM2B_NONCE      s_nonceCaller[MAX_SESSION_NUM];

/* Array of authorization values (HMAC's or passwords) for the corresponding sessions */
EXTERN TPM2B_AUTH       s_inputAuthValues[MAX_SESSION_NUM];

/* Array of pointers to the SESSION structures for the sessions in a command */
EXTERN SESSION          *s_usedSessions[MAX_SESSION_NUM];

/* Special value to indicate an undefined session index */
#define             UNDEFINED_INDEX     (0xFFFF)
/* Index of the session used for encryption of a response parameter */
EXTERN UINT32           s_encryptSessionIndex;

/* Index of the session used for decryption of a command parameter */
EXTERN UINT32           s_decryptSessionIndex;

/* Index of a session used for audit */
EXTERN UINT32           s_auditSessionIndex;

/* The cpHash for command audit */
#if CC_GetCommandAuditDigest
EXTERN TPM2B_DIGEST    s_cpHashForCommandAudit;
#endif

/* Flag indicating if NV update is pending for the lockOutAuthEnabled or failedTries DA parameter */
EXTERN BOOL             s_DAPendingOnNV;

#endif // SESSION_PROCESS_C

/* 5.9.16.2	From DA.c */
#if defined DA_C || defined GLOBAL_C || defined MANUFACTURE_C

/* From DA.c */
/* This variable holds the accumulated time since the last time that failedTries was
   decremented. This value is in millisecond. */

#if !ACCUMULATE_SELF_HEAL_TIMER
EXTERN UINT64       s_selfHealTimer;

/* This variable holds the accumulated time that the lockoutAuth has been blocked. */
EXTERN UINT64       s_lockoutTimer;

#endif // ACCUMULATE_SELF_HEAL_TIMER
#endif // DA_C

/* 5.9.16.3	From NV.c */

#if defined NV_C || defined GLOBAL_C

/* From NV.c */
/* This marks the end of the NV area. This is a run-time variable as it might not be compile-time
   constant. */
EXTERN NV_REF   s_evictNvEnd;

/* This space is used to hold the index data for an orderly Index. It also contains the attributes
   for the index. */
EXTERN BYTE      s_indexOrderlyRam[RAM_INDEX_SPACE];   // The orderly NV Index data

/* This value contains the current max counter value. It is written to the end of allocatable NV
   space each time an index is deleted or added. This value is initialized on Startup. The indices
   are searched and the maximum of all the current counter indices and this value is the initial
   value for this. */
EXTERN UINT64    s_maxCounter;

/* This is space used for the NV Index cache. As with a persistent object, the contents of a
   referenced index are copied into the cache so that the NV Index memory scanning and data copying
   can be reduced. Only code that operates on NV Index data should use this cache directly. When
   that action code runs, s_lastNvIndex will contain the index header information. It will have been
   loaded when the handles were verified. */
/* NOTE: An NV index handle can appear in many commands that do not operate on the NV data
   (e.g. TPM2_StartAuthSession()). However, only one NV Index at a time is ever directly referenced
   by any command. If that changes, then the NV Index caching needs to be changed to accommodate
   that. Currently, the code will verify that only one NV Index is referenced by the handles of the
   command. */

EXTERN      NV_INDEX         s_cachedNvIndex;
EXTERN      NV_REF           s_cachedNvRef;
EXTERN      BYTE            *s_cachedNvRamRef;

/* Initial NV Index/evict object iterator value */
#define     NV_REF_INIT     (NV_REF)0xFFFFFFFF
#endif

/* 5.9.16.4	From Object.c */
#if defined OBJECT_C || defined GLOBAL_C

/* This type is the container for an object. */

EXTERN OBJECT           s_objects[MAX_LOADED_OBJECTS];
#endif // OBJECT_C

/* 5.9.17.5	From PCR.c */

#if defined PCR_C || defined GLOBAL_C

/* The following macro is used to define the per-implemented-hash space. This implementation
   reserves space for all implemented hashes. */

#define PCR_ALL_HASH(HASH, Hash)    BYTE    Hash##Pcr[HASH##_DIGEST_SIZE];

typedef struct
{
    FOR_EACH_HASH(PCR_ALL_HASH)
} PCR;

typedef struct
{
    unsigned int    stateSave : 1;              // if the PCR value should be
    // saved in state save
    unsigned int    resetLocality : 5;          // The locality that the PCR
    // can be reset
    unsigned int    extendLocality : 5;         // The locality that the PCR
    // can be extend
} PCR_Attributes;
EXTERN PCR          s_pcrs[IMPLEMENTATION_PCR];
#endif // PCR_C

/* 5.9.16.6	From Session.c */

#if defined SESSION_C || defined GLOBAL_C

/* Container for HMAC or policy session tracking information */
typedef struct
{
    BOOL                occupied;
    SESSION             session;        // session structure
} SESSION_SLOT;
EXTERN SESSION_SLOT     s_sessions[MAX_LOADED_SESSIONS];
/* The index in contextArray that has the value of the oldest saved session context. When no context
   is saved, this will have a value that is greater than or equal to MAX_ACTIVE_SESSIONS. */

EXTERN UINT32            s_oldestSavedSession;
/* The number of available session slot openings.  When this is 1, a session can't be created or
   loaded if the GAP is maxed out. The exception is that the oldest saved session context can always
   be loaded (assuming that there is a space in memory to put it) */
EXTERN int               s_freeSessionSlots;

#endif // SESSION_C

/* 5.9.16.7	From IoBuffers.c */

#if defined IO_BUFFER_C || defined GLOBAL_C

/* The value of s_actionIoAllocation is the number of UINT64 values allocated. It is used to set the
   pointer for the response structure.  */
EXTERN UINT64   s_actionIoBuffer[768];      // action I/O buffer
EXTERN UINT32   s_actionIoAllocation;       // number of UIN64 allocated for the action input
					    // structure
#endif // MEMORY_LIB_C

/* 5.9.16.8	From TPMFail.c */

/* This value holds the address of the string containing the name of the function in which the
   failure occurred. This address value isn't useful for anything other than helping the vendor to
   know in which file the failure occurred. */
EXTERN BOOL      g_inFailureMode;       // Indicates that the TPM is in failure mode
#if SIMULATION
EXTERN BOOL      g_forceFailureMode;    // flag to force failure mode during test
#endif
typedef void(FailFunction)(const char *function, int line, int code);
#if defined TPM_FAIL_C || defined GLOBAL_C || 1
EXTERN UINT32    s_failFunction;
EXTERN UINT32    s_failLine;            // the line in the file at which
// the error was signaled
EXTERN UINT32    s_failCode;            // the error code used
EXTERN FailFunction    *LibFailCallback;
#endif // TPM_FAIL_C

//*****************************************************************************
//*** From ACT_spt.c
//*****************************************************************************
// This value is used to indicate if an ACT has been updated since the last
// TPM2_Startup() (one bit for each ACT). If the ACT is not updated
// (TPM2_ACT_SetTimeout()) after a startup, then on each TPM2_Shutdown() the TPM will
// save 1/2 of the current timer value. This prevents an attack on the ACT by saving
// the counter and then running for a long period of time before doing a TPM Restart.
// A quick TPM2_Shutdown() after each
EXTERN UINT16                       s_ActUpdated;

/* 5.9.16.9	From CommandCodeAttributes.c */

extern  const  TPMA_CC               s_ccAttr[];
extern  const  COMMAND_ATTRIBUTES    s_commandAttributes[];

#endif // GLOBAL_H
