summaryrefslogtreecommitdiffstats
path: root/src/tpm2/Global.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 21:41:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 21:41:43 +0000
commit92cccad89d1c12b39165d5f0ed7ccd2d44965a1a (patch)
treef59a2764cd8c50959050a428bd8fc935138df750 /src/tpm2/Global.h
parentInitial commit. (diff)
downloadlibtpms-upstream.tar.xz
libtpms-upstream.zip
Adding upstream version 0.9.2.upstream/0.9.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tpm2/Global.h')
-rw-r--r--src/tpm2/Global.h1350
1 files changed, 1350 insertions, 0 deletions
diff --git a/src/tpm2/Global.h b/src/tpm2/Global.h
new file mode 100644
index 0000000..84a0d13
--- /dev/null
+++ b/src/tpm2/Global.h
@@ -0,0 +1,1350 @@
+/********************************************************************************/
+/* */
+/* 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