]> git.proxmox.com Git - mirror_edk2.git/commitdiff
SecurityPkg: TcgStorageCoreLib: Add TCG storage core library.
authorEric Dong <eric.dong@intel.com>
Tue, 29 Mar 2016 06:41:20 +0000 (14:41 +0800)
committerFeng Tian <feng.tian@intel.com>
Tue, 29 Mar 2016 07:37:29 +0000 (15:37 +0800)
APIs used to create commands defined by TCG storage core spec.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
SecurityPkg/Include/Library/TcgStorageCoreLib.h [new file with mode: 0644]
SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCore.c [new file with mode: 0644]
SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCoreLib.inf [new file with mode: 0644]
SecurityPkg/Library/TcgStorageCoreLib/TcgStorageUtil.c [new file with mode: 0644]

diff --git a/SecurityPkg/Include/Library/TcgStorageCoreLib.h b/SecurityPkg/Include/Library/TcgStorageCoreLib.h
new file mode 100644 (file)
index 0000000..67ccf22
--- /dev/null
@@ -0,0 +1,1310 @@
+/** @file\r
+  Public API for the Tcg Core library to perform the lowest level TCG Data encoding.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _TCG_CORE_H_\r
+#define _TCG_CORE_H_\r
+\r
+#include <IndustryStandard/TcgStorageCore.h>\r
+\r
+#define ERROR_CHECK(arg)                                                         \\r
+  {                                                                              \\r
+    TCG_RESULT ret = (arg);                                                      \\r
+    if (ret != TcgResultSuccess) {                                               \\r
+      DEBUG ((DEBUG_INFO, "ERROR_CHECK failed at %s:%u\n", __FILE__, __LINE__)); \\r
+      return ret;                                                                \\r
+    }                                                                            \\r
+  }\r
+\r
+#define METHOD_STATUS_ERROR_CHECK(arg, failRet)                                                  \\r
+  if ((arg) != TCG_METHOD_STATUS_CODE_SUCCESS) {                                                 \\r
+    DEBUG ((DEBUG_INFO, "Method Status error: 0x%02X (%s)\n", arg, TcgMethodStatusString(arg))); \\r
+    return (failRet);                                                                            \\r
+  }\r
+\r
+#define NULL_CHECK(arg)                                                                   \\r
+  do {                                                                                    \\r
+    if ((arg) == NULL) {                                                                  \\r
+      DEBUG ((DEBUG_INFO, "NULL_CHECK(%s) failed at %s:%u\n", #arg, __FILE__, __LINE__)); \\r
+      return TcgResultFailureNullPointer;                                                 \\r
+    }                                                                                     \\r
+  } while (0)\r
+\r
+#pragma pack(1)\r
+\r
+/**\r
+Tcg result codes.\r
+\r
+The result code indicates if the Tcg function call was successful or not\r
+**/\r
+typedef enum {\r
+  //\r
+  // This is the return result upon successful completion of a Tcg function call\r
+  //\r
+  TcgResultSuccess,\r
+\r
+  //\r
+  // This is the return "catchall" result for the failure of a Tcg function call\r
+  //\r
+  TcgResultFailure,\r
+\r
+  //\r
+  // This is the return result if a required parameter was Null for a Tcg function call\r
+  //\r
+  TcgResultFailureNullPointer,\r
+\r
+  //\r
+  // This is the return result if a required buffersize was 0 for a Tcg function call\r
+  //\r
+  TcgResultFailureZeroSize,\r
+\r
+  //\r
+  // This is the return result if a Tcg function call was executed out of order.\r
+  // For instance, starting a Tcg subpacket before starting its Tcg packet.\r
+  //\r
+  TcgResultFailureInvalidAction,\r
+\r
+  //\r
+  // This is the return result if the buffersize provided is not big enough to add a requested Tcg encoded item.\r
+  //\r
+  TcgResultFailureBufferTooSmall,\r
+\r
+  //\r
+  // This is the return result for a Tcg parse function if the end of the parsed Buffer is reached, yet Data is still attempted to be retrieved.\r
+  // For instance, attempting to retrieve another Tcg token from the Buffer after it has reached the end of the Tcg subpacket payload.\r
+  //\r
+  TcgResultFailureEndBuffer,\r
+\r
+  //\r
+  // This is the return result for a Tcg parse function if the Tcg Token item requested is not the expected type.\r
+  // For instance, the caller requested to receive an integer and the Tcg token was a byte sequence.\r
+  //\r
+  TcgResultFailureInvalidType,\r
+} TCG_RESULT;\r
+\r
+//\r
+// Structure that is used to build the Tcg ComPacket.  It contains the start Buffer pointer and the current position of the\r
+// Tcg ComPacket, current Tcg Packet and Tcg SubPacket. This structure must be initialized\r
+// by calling tcgInitTcgCreateStruct before it is used as parameter to any other Tcg function.\r
+// This structure should NOT be directly modified by the client of this library.\r
+//\r
+//  NOTE:  WE MAY MAKE THIS AN ABSTRACT STRUCTURE WITH A DEFINED SIZE AND KEEP THE VARIABLES\r
+//         INTERNAL AND ONLY KNOWN TO THE TCG LIBRARY\r
+//\r
+// tcgInitTcgCreateStruct\r
+//\r
+typedef struct {\r
+  //\r
+  // Buffer allocated and freed by the client of the Tcg library.\r
+  // This is the Buffer that shall contain the final Tcg encoded compacket.\r
+  //\r
+  VOID              *Buffer;\r
+\r
+  //\r
+  // Size of the Buffer provided.\r
+  //\r
+  UINT32            BufferSize;\r
+\r
+  //\r
+  //Pointer to the start of the Tcg ComPacket.  It should point to a location within Buffer.\r
+  //\r
+  TCG_COM_PACKET    *ComPacket;\r
+\r
+  //\r
+  // Current Tcg Packet that is being created.  It should point to a location within Buffer.\r
+  //\r
+  TCG_PACKET        *CurPacket;\r
+\r
+  //\r
+  // Current Tcg SubPacket that is being created.  It should point to a location within Buffer.\r
+  //\r
+  TCG_SUB_PACKET    *CurSubPacket;\r
+\r
+  //\r
+  // Flag used to indicate if the Buffer of the structure should be filled out.\r
+  // This is intended to be used to support a use-case where the client of library\r
+  // can perform all the desired tcg calls to determine what the actual Size of the final compacket will be.\r
+  // Then the client can allocate the required Buffer Size and re-run the tcg calls.\r
+  // THIS MAY NOT BE IMPLEMENTED... REQUIRES MORE THOUGHT BECAUSE YOU CANNOT SOLVE ISSUE FOR RECEIVE\r
+  //\r
+  BOOLEAN          DryRun;\r
+} TCG_CREATE_STRUCT;\r
+\r
+//\r
+// Structure that is used to parse the Tcg response received.  It contains the response Buffer pointer\r
+// and the current position of the Tcg ComPacket, current Tcg Packet and Tcg SubPacket being parsed.\r
+// This structure must be initialized by calling tcgInitTcgParseStruct before it is used as parameter to any other Tcg parse function.\r
+// This structure should NOT be directly modified by the client of this library.\r
+//\r
+//  NOTE:  WE MAY MAKE THIS AN ABSTRACT STRUCTURE WITH A DEFINED SIZE AND KEEP THE VARIABLES\r
+//         INTERNAL AND ONLY KNOWN TO THE TCG LIBRARY\r
+//\r
+// @sa tcgInitTcgParseStruct\r
+//\r
+typedef struct  {\r
+  //\r
+  // Buffer allocated and freed by the client of the Tcg library.\r
+  // This is the Buffer that contains the Tcg response to decode/parse.\r
+  //\r
+  const VOID*         Buffer;\r
+\r
+  //\r
+  //Size of the Buffer provided.\r
+  //\r
+  UINT32              BufferSize;\r
+\r
+  //\r
+  // Pointer to the start of the Tcg ComPacket.  It should point to a location within Buffer.\r
+  //\r
+  TCG_COM_PACKET      *ComPacket;\r
+\r
+  //\r
+  // Current Tcg Packet that is being created.  It should point to a location within Buffer.\r
+  //\r
+  TCG_PACKET          *CurPacket;\r
+\r
+  //\r
+  // Current Tcg SubPacket that is being created.  It should point to a location within Buffer.\r
+  //\r
+  TCG_SUB_PACKET      *CurSubPacket;\r
+\r
+  //\r
+  // Current pointer within the current subpacket payload.\r
+  //\r
+  UINT8               *CurPtr;\r
+} TCG_PARSE_STRUCT ;\r
+\r
+\r
+//\r
+// Structure that is used to represent a Tcg Token that is retrieved by Tcg parse functions.\r
+//\r
+typedef struct {\r
+  //\r
+  // Describes the type of Tcg token the Hdr start points to.\r
+  //\r
+  TCG_TOKEN_TYPE    Type;\r
+\r
+  //\r
+  // Pointer to the beginning of the Header of the Tcg token\r
+  //\r
+  UINT8             *HdrStart;\r
+} TCG_TOKEN ;\r
+\r
+/**\r
+\r
+  Required to be called before calling any other Tcg functions with the TCG_CREATE_STRUCT.\r
+  Initializes the packet variables to NULL.  Additionally, the buffer will be memset.\r
+\r
+  @param[in/out]   CreateStruct   Structure to initialize\r
+  @param[in]       Buffer         Buffer allocated by client of library.  It will contain the Tcg encoded packet.  This cannot be null.\r
+  @param[in]       BufferSize     Size of buffer provided.  It cannot be 0.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgInitTcgCreateStruct(\r
+  TCG_CREATE_STRUCT      *CreateStruct,\r
+  VOID                   *Buffer,\r
+  UINT32                 BufferSize\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Encodes the ComPacket header to the data structure.\r
+\r
+  @param[in/out]    CreateStruct       Structure to initialize\r
+  @param[in]        ComId              ComID of the Tcg ComPacket.\r
+  @param[in]        ComIdExtension     ComID Extension of the Tcg ComPacket.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartComPacket(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT16              ComId,\r
+  UINT16              ComIdExtension\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Starts a new ComPacket in the Data structure.\r
+\r
+  @param[in/out]    CreateStruct       Structure used to add Tcg Packet\r
+  @param[in]        Tsn                Packet Tper session number\r
+  @param[in]        Hsn                Packet Host session number\r
+  @param[in]        SeqNumber          Packet Sequence Number\r
+  @param[in]        AckType            Packet Acknowledge Type\r
+  @param[in]        Ack                Packet Acknowledge\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartPacket(\r
+  TCG_CREATE_STRUCT       *CreateStruct,\r
+  UINT32                  Tsn,\r
+  UINT32                  Hsn,\r
+  UINT32                  SeqNumber,\r
+  UINT16                  AckType,\r
+  UINT32                  Ack\r
+  );\r
+\r
+/**\r
+\r
+  Starts a new SubPacket in the Data structure.\r
+\r
+  @param[in/out]    CreateStruct       Structure used to start Tcg SubPacket\r
+  @param[in]        Kind               SubPacket kind\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartSubPacket(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT16              Kind\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Ends the current SubPacket in the Data structure.  This function will also perform the 4-byte padding\r
+  required for Subpackets.\r
+\r
+  @param[in/out]        CreateStruct       Structure used to end the current Tcg SubPacket\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndSubPacket(\r
+  TCG_CREATE_STRUCT   *CreateStruct\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Ends the current Packet in the Data structure.\r
+\r
+  @param[in/out]       CreateStruct        Structure used to end the current Tcg Packet\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndPacket(\r
+  TCG_CREATE_STRUCT     *CreateStruct\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Ends the ComPacket in the Data structure and ret\r
+\r
+  @param[in/out]       CreateStruct    Structure used to end the Tcg ComPacket\r
+  @param[in/out]       Size                Describes the Size of the entire ComPacket (Header and payload). Filled out by function.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndComPacket(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT32              *Size\r
+  );\r
+\r
+/**\r
+  Adds a single raw token byte to the Data structure.\r
+\r
+  @param[in/out]   CreateStruct      Structure used to add the byte\r
+  @param [in]      Byte              Byte to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddRawByte(\r
+  TCG_CREATE_STRUCT  *CreateStruct,\r
+  UINT8              Byte\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Adds the Data parameter as a byte sequence to the Data structure.\r
+\r
+  @param [in/out]    CreateStruct   Structure used to add the byte sequence\r
+  @param[in]         Data           Byte sequence that will be encoded and copied into Data structure\r
+  @param[in]         DataSize       Length of Data provided\r
+  @param[in]         Continued      TRUE if byte sequence is continued or\r
+                                    FALSE if the Data contains the entire byte sequence to be encoded\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddByteSequence(\r
+  TCG_CREATE_STRUCT     *CreateStruct,\r
+  const VOID            *Data,\r
+  UINT32                DataSize,\r
+  BOOLEAN               Continued\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Adds an arbitrary-Length integer to the Data structure.\r
+\r
+  The integer will be encoded using the shortest possible atom.\r
+\r
+  @param[in/out]     CreateStruct        Structure used to add the integer\r
+  @param[in]         Data                Integer in host byte order that will be encoded and copied into Data structure\r
+  @param[in]         DataSize            Length in bytes of the Data provided\r
+  @param[in]         SignedInteger       TRUE if the integer is signed or FALSE if the integer is unsigned\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddInteger(\r
+  TCG_CREATE_STRUCT  *CreateStruct,\r
+  const VOID         *Data,\r
+  UINT32             DataSize,\r
+  BOOLEAN            SignedInteger\r
+  );\r
+\r
+\r
+/**\r
+  Adds an 8-bit unsigned integer to the Data structure.\r
+\r
+  @param[in/out]     CreateStruct        Structure used to add the integer\r
+  @param[in]         Value               Integer Value to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddUINT8(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT8               Value\r
+  );\r
+\r
+/**\r
+\r
+  Adds a 16-bit unsigned integer to the Data structure.\r
+\r
+  @param[in/out]       CreateStruct        Structure used to add the integer\r
+  @param[in]           Value               Integer Value to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddUINT16 (\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT16              Value\r
+  );\r
+\r
+/**\r
+\r
+  Adds a 32-bit unsigned integer to the Data structure.\r
+\r
+  @param[in/out]        CreateStruct        Structure used to add the integer\r
+  @param[in]            Value               Integer Value to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddUINT32(\r
+  TCG_CREATE_STRUCT    *CreateStruct,\r
+  UINT32               Value\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Adds a 64-bit unsigned integer to the Data structure.\r
+\r
+  @param[in/out]      CreateStruct        Structure used to add the integer\r
+  @param[in]          Value               Integer Value to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddUINT64(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT64              Value\r
+  );\r
+\r
+/**\r
+  Adds a BOOLEAN to the Data structure.\r
+\r
+  @param[in/out]       CreateStruct     Structure used to add the integer\r
+  @param[in]           Value              BOOLEAN Value to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddBOOLEAN(\r
+  TCG_CREATE_STRUCT    *CreateStruct,\r
+  BOOLEAN              Value\r
+  );\r
+\r
+/**\r
+  Add tcg uid info.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+  @param                Uid                Input uid info.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddTcgUid(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  TCG_UID             Uid\r
+  );\r
+\r
+/**\r
+ Adds a Start List token to the Data structure.\r
+\r
+ @param[in/out]   CreateStruct      Structure used to add the token\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddStartList(\r
+  TCG_CREATE_STRUCT    *CreateStruct\r
+  );\r
+\r
+\r
+/**\r
+\r
+ Adds an End List token to the Data structure.\r
+\r
+ @param [in/out]    CreateStruct      Structure used to add the token\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddEndList(\r
+  TCG_CREATE_STRUCT     *CreateStruct\r
+  );\r
+\r
+\r
+/**\r
+ Adds a Start Name token to the Data structure.\r
+\r
+ @param[in/out]    CreateStruct    Structure used to add the token\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddStartName(\r
+  TCG_CREATE_STRUCT      *CreateStruct\r
+  );\r
+\r
+\r
+/**\r
+\r
+ Adds an End Name token to the Data structure.\r
+\r
+ @param [in/out]   CreateStruct      Structure used to add the token\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddEndName(\r
+  TCG_CREATE_STRUCT            *CreateStruct\r
+  );\r
+\r
+\r
+/**\r
+ Adds a Call token to the Data structure.\r
+\r
+ @param  [in/out]    CreateStruct    Structure used to add the token\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddCall(\r
+  TCG_CREATE_STRUCT            *CreateStruct\r
+  );\r
+\r
+\r
+/**\r
+\r
+Adds an End of Data token to the Data structure.\r
+\r
+@param[in/out]   CreateStruct    Structure used to add the token\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddEndOfData(\r
+  TCG_CREATE_STRUCT            *CreateStruct\r
+  );\r
+\r
+\r
+/**\r
+\r
+Adds an End of Session token to the Data structure.\r
+\r
+@param [in/out]    CreateStruct  Structure used to add the token\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddEndOfSession(\r
+  TCG_CREATE_STRUCT             *CreateStruct\r
+  );\r
+\r
+\r
+/**\r
+ Adds a Start Transaction token to the Data structure.\r
+\r
+ @param [in/out]    CreateStruct  Structure used to add the token\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddStartTransaction(\r
+  TCG_CREATE_STRUCT              *CreateStruct\r
+  );\r
+\r
+\r
+/**\r
+ Adds an End Transaction token to the Data structure.\r
+\r
+ @param[in/out]   CreateStruct   Structure used to add the token\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddEndTransaction(\r
+  TCG_CREATE_STRUCT             *CreateStruct\r
+  );\r
+\r
+/**\r
+  Initial the tcg parse stucture.\r
+\r
+  @param    ParseStruct    Input parse structure.\r
+  @param    Buffer         Input buffer data.\r
+  @param    BufferSize     Input buffer size.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgInitTcgParseStruct(\r
+  TCG_PARSE_STRUCT          *ParseStruct,\r
+  const VOID                *Buffer,\r
+  UINT32                    BufferSize\r
+  );\r
+\r
+/**\r
+  Get next token info.\r
+\r
+  @param    ParseStruct      Input parse structure info.\r
+  @param    TcgToken         return the tcg token info.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextToken(\r
+  TCG_PARSE_STRUCT      *ParseStruct,\r
+  TCG_TOKEN             *TcgToken\r
+  );\r
+\r
+/**\r
+  Get next token Type.\r
+\r
+  @param    ParseStruct    Input parse structure.\r
+  @param    Type           Input the type need to check.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextTokenType(\r
+  TCG_PARSE_STRUCT        *ParseStruct,\r
+  TCG_TOKEN_TYPE          Type\r
+  );\r
+\r
+/**\r
+  Get atom info.\r
+\r
+  @param    TcgToken          Input token info.\r
+  @param    HeaderLength      return the header length.\r
+  @param    DataLength        return the data length.\r
+  @param    ByteOrInt         return the atom Type.\r
+  @param    SignOrCont        return the sign or count info.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetAtomInfo(\r
+  const TCG_TOKEN      *TcgToken,\r
+  UINT32               *HeaderLength,\r
+  UINT32               *DataLength,\r
+  UINT8                *ByteOrInt,\r
+  UINT8                *SignOrCont\r
+  );\r
+\r
+/**\r
+  Get token byte sequence.\r
+\r
+  @param    TcgToken   Input token info.\r
+  @param    Length     Input the length info.\r
+\r
+  @retval   Return the value data.\r
+\r
+**/\r
+UINT8*\r
+EFIAPI\r
+TcgGetTokenByteSequence(\r
+  const TCG_TOKEN     *TcgToken,\r
+  UINT32              *Length\r
+  );\r
+\r
+/**\r
+  Get token specified value.\r
+\r
+  @param    TcgToken   Input token info.\r
+  @param    Value      return the value.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetTokenUINT64(\r
+  const TCG_TOKEN      *TcgToken,\r
+  UINT64               *Value\r
+  );\r
+\r
+\r
+/**\r
+  Get next specify value.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+  @param    Value         Return vlaue.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextUINT8(\r
+  TCG_PARSE_STRUCT      *ParseStruct,\r
+  UINT8                 *Value\r
+  );\r
+\r
+\r
+/**\r
+  Get next specify value.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+  @param    Value         Return vlaue.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextUINT16(\r
+  TCG_PARSE_STRUCT     *ParseStruct,\r
+  UINT16               *Value\r
+  );\r
+\r
+/**\r
+  Get next specify value.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+  @param    Value         Return vlaue.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextUINT32(\r
+  TCG_PARSE_STRUCT          *ParseStruct,\r
+  UINT32                    *Value\r
+  );\r
+\r
+/**\r
+  Get next specify value.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+  @param    Value         Return vlaue.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextUINT64(\r
+  TCG_PARSE_STRUCT           *ParseStruct,\r
+  UINT64                     *Value\r
+  );\r
+\r
+/**\r
+  Get next specify value.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+  @param    Value         Return vlaue.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextBOOLEAN(\r
+  TCG_PARSE_STRUCT        *ParseStruct,\r
+  BOOLEAN                 *Value\r
+  );\r
+\r
+/**\r
+  Get next tcg uid info.\r
+\r
+  @param    ParseStruct    Input parse structure.\r
+  @param    Uid            Get the uid info.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextTcgUid(\r
+  TCG_PARSE_STRUCT         *ParseStruct,\r
+  TCG_UID                  *Uid\r
+  );\r
+\r
+/**\r
+  Get next byte sequence.\r
+\r
+  @param    ParseStruct     Input parse structure.\r
+  @param    Data            return the data.\r
+  @param    Length          return the length.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextByteSequence(\r
+  TCG_PARSE_STRUCT      *ParseStruct,\r
+  const VOID            **Data,\r
+  UINT32                *Length\r
+  );\r
+\r
+/**\r
+  Get next start list.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextStartList(\r
+  TCG_PARSE_STRUCT          *ParseStruct\r
+  );\r
+\r
+/**\r
+  Get next end list.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextEndList(\r
+  TCG_PARSE_STRUCT             *ParseStruct\r
+  );\r
+\r
+/**\r
+  Get next start name.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextStartName(\r
+  TCG_PARSE_STRUCT              *ParseStruct\r
+  );\r
+\r
+/**\r
+  Get next end name.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextEndName(\r
+  TCG_PARSE_STRUCT               *ParseStruct\r
+  );\r
+\r
+/**\r
+  Get next call.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextCall(\r
+  TCG_PARSE_STRUCT                   *ParseStruct\r
+  );\r
+\r
+/**\r
+  Get next end data.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextEndOfData(\r
+  TCG_PARSE_STRUCT                    *ParseStruct\r
+  );\r
+\r
+/**\r
+  Get next end of session.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextEndOfSession(\r
+  TCG_PARSE_STRUCT                      *ParseStruct\r
+  );\r
+\r
+/**\r
+  Get next start transaction.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextStartTransaction(\r
+  TCG_PARSE_STRUCT                        *ParseStruct\r
+  );\r
+\r
+/**\r
+  Get next end transaction.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextEndTransaction(\r
+  TCG_PARSE_STRUCT                  *ParseStruct\r
+  );\r
+\r
+// end of parse functions\r
+\r
+\r
+typedef\r
+BOOLEAN\r
+(EFIAPI* TCG_LEVEL0_ENUM_CALLBACK) (\r
+  const TCG_LEVEL0_DISCOVERY_HEADER      *DiscoveryHeader,\r
+  TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER   *Feature,\r
+  UINTN                                  FeatureSize, // includes header\r
+  VOID                                   *Context\r
+);\r
+\r
+/**\r
+  Adds call token and method Header (invoking id, and method id).\r
+\r
+  @param    CreateStruct             The input create structure.\r
+  @param    InvokingId               Invoking id.\r
+  @param    MethodId                 Method id.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartMethodCall(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  TCG_UID             InvokingId,\r
+  TCG_UID             MethodId\r
+  );\r
+\r
+/**\r
+  Adds START LIST token.\r
+\r
+  @param    CreateStruct        The input create structure.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartParameters(\r
+  TCG_CREATE_STRUCT           *CreateStruct\r
+  );\r
+\r
+/**\r
+  Adds END LIST token.\r
+\r
+  @param    CreateStruct        The input create structure.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndParameters(\r
+  TCG_CREATE_STRUCT   *CreateStruct\r
+  );\r
+\r
+/**\r
+  Adds END Data token and method list.\r
+\r
+  @param    CreateStruct        The input create structure.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndMethodCall(\r
+  TCG_CREATE_STRUCT      *CreateStruct\r
+  );\r
+\r
+/**\r
+\r
+  Adds Start Session call to the data structure.  This creates the entire ComPacket structure and\r
+  returns the size of the entire compacket in the size parameter.\r
+\r
+  @param [in/out]    CreateStruct               Structure used to add the start session call\r
+  @param [in/out]    Size                       Describes the size of the entire ComPacket (header and payload). Filled out by function.\r
+  @param [in]        ComId                      ComID for the ComPacket\r
+  @param [in]        ComIdExtension             Extended ComID for the ComPacket\r
+  @param [in]        HostSessionId              Host Session ID\r
+  @param [in]        SpId                       Security Provider to start session with\r
+  @param [in]        Write                      Write option for start session.  TRUE = start session requests write access\r
+  @param [in]        HostChallengeLength        Length of the host challenge.  Length should be 0 if hostChallenge is NULL\r
+  @param [in]        HostChallenge              Host challenge for Host Signing Authority.  If NULL, then no Host Challenge shall be sent.\r
+  @param [in]        HostSigningAuthority       Host Signing Authority used for start session.  If NULL, then no Host Signing Authority shall be sent.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgCreateStartSession(\r
+  TCG_CREATE_STRUCT     *CreateStruct,\r
+  UINT32                *Size,\r
+  UINT16                ComId,\r
+  UINT16                ComIdExtension,\r
+  UINT32                HostSessionId,\r
+  TCG_UID               SpId,\r
+  BOOLEAN               Write,\r
+  UINT32                HostChallengeLength,\r
+  const VOID            *HostChallenge,\r
+  TCG_UID               HostSigningAuthority\r
+  );\r
+\r
+/**\r
+  Creates ComPacket with a Method call that sets the PIN column for the row specified.\r
+  This assumes a start session has already been opened with the desired SP.\r
+\r
+  @param [in/out]   CreateStruct           Structure used to add method call.\r
+  @param [in/out]   Size                   Describes the size of the entire ComPacket (header and payload). Filled out by function.\r
+  @param [in]       ComId                  ComID for the ComPacket\r
+  @param [in]       ComIdExtension         Extended ComID for the ComPacket\r
+  @param [in]       TperSession            Tper Session ID for the Packet\r
+  @param [in]       HostSession            Host Session ID for the Packet\r
+  @param [in]       SidRow                 UID of row of current SP to set PIN column\r
+  @param [in]       Password               value of PIN to set\r
+  @param [in]       PasswordSize           Size of PIN\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgCreateSetCPin(\r
+  TCG_CREATE_STRUCT       *CreateStruct,\r
+  UINT32                  *Size,\r
+  UINT16                  ComId,\r
+  UINT16                  ComIdExtension,\r
+  UINT32                  TperSession,\r
+  UINT32                  HostSession,\r
+  TCG_UID                 SidRow,\r
+  const VOID              *Password,\r
+  UINT32                  PasswordSize\r
+  );\r
+\r
+/**\r
+ Creates ComPacket with a Method call that sets the "Enabled" column for the row specified using the value specified.\r
+ This assumes a start session has already been opened with the desired SP.\r
+\r
+ @param [in/out]  CreateStruct          Structure used to add method call\r
+ @param [in/out]  Size                  Describes the size of the entire ComPacket (header and payload). Filled out by function.\r
+ @param [in]      ComId                 ComID for the ComPacket\r
+ @param [in]      ComIdExtension        Extended ComID for the ComPacket\r
+ @param [in]      TperSession           Tper Session ID for the Packet\r
+ @param [in]      HostSession           Host Session ID for the Packet\r
+ @param [in]      AuthorityUid          Authority UID to modify the "Enabled" column for\r
+ @param [in]      Enabled               Value to set the "Enabled" column to\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgSetAuthorityEnabled(\r
+  TCG_CREATE_STRUCT           *CreateStruct,\r
+  UINT32                      *Size,\r
+  UINT16                      ComId,\r
+  UINT16                      ComIdExtension,\r
+  UINT32                      TperSession,\r
+  UINT32                      HostSession,\r
+  TCG_UID                     AuthorityUid,\r
+  BOOLEAN                     Enabled\r
+  );\r
+\r
+/**\r
+\r
+  Creates ComPacket with EndSession.\r
+  This assumes a start session has already been opened.\r
+\r
+  @param  [in/out]    CreateStruct        Structure used to add Endsession\r
+  @param  [in/out]    Size                Describes the size of the entire ComPacket (header and payload). Filled out by function.\r
+  @param  [in]        ComId               ComID for the ComPacket\r
+  @param  [in]        ComIdExtension      Extended ComID for the ComPacket\r
+  @param  [in]        HostSessionId         Host Session ID for the Packet\r
+  @param  [in]        TpSessionId         Tper Session ID for the Packet\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgCreateEndSession(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT32              *Size,\r
+  UINT16              ComId,\r
+  UINT16              ComIdExtension,\r
+  UINT32              HostSessionId,\r
+  UINT32              TpSessionId\r
+  );\r
+\r
+\r
+/**\r
+\r
+ Retrieves human-readable token type name.\r
+\r
+ @param[in]   Type  Token type to retrieve\r
+\r
+**/\r
+CHAR8*\r
+EFIAPI\r
+TcgTokenTypeString(\r
+  TCG_TOKEN_TYPE  Type\r
+  );\r
+\r
+/**\r
+ Returns the method status of the current subpacket.  Does not affect the current position\r
+ in the ComPacket.  In other words, it can be called whenever you have a valid SubPacket.\r
+\r
+ @param [in/out]  ParseStruct       Structure used to parse received TCG response\r
+ @param [in/out]  MethodStatus      Method status retrieved of the current SubPacket\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetMethodStatus(\r
+  const TCG_PARSE_STRUCT            *ParseStruct,\r
+  UINT8                             *MethodStatus\r
+  );\r
+\r
+/**\r
+  Returns a human-readable string representing a method status return code.\r
+\r
+  @param[in]  MethodStatus   Method status to translate to a string\r
+\r
+\r
+  @retval   return the string info.\r
+**/\r
+CHAR8*\r
+EFIAPI\r
+TcgMethodStatusString(\r
+  UINT8 MethodStatus\r
+  );\r
+\r
+\r
+/**\r
+  Retrieves the comID and Extended comID of the ComPacket in the Tcg response.\r
+  It is intended to be used to confirm the received Tcg response is intended for user that received it.\r
+\r
+  @param [in]        ParseStruct        Structure used to parse received TCG response.\r
+  @param [in/out]    ComId              comID retrieved from received ComPacket.\r
+  @param [in/out]    ComIdExtension     Extended comID retrieved from received ComPacket\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetComIds(\r
+  const TCG_PARSE_STRUCT     *ParseStruct,\r
+  UINT16                     *ComId,\r
+  UINT16                     *ComIdExtension\r
+  );\r
+\r
+/**\r
+  Checks if the ComIDs of the response match the expected values.\r
+\r
+  @param[in]   ParseStruct               Structure used to parse received TCG response\r
+  @param[in]   ExpectedComId             Expected comID\r
+  @param[in]   ExpectedComIdExtension    Expected extended comID\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgCheckComIds(\r
+  const TCG_PARSE_STRUCT     *ParseStruct,\r
+  UINT16                     ExpectedComId,\r
+  UINT16                     ExpectedComIdExtension\r
+  );\r
+\r
+/**\r
+ Parses the Sync Session response contained in the parseStruct to retrieve Tper session ID.  If the Sync Session response\r
+ parameters do not match the comID, extended ComID and host session ID then a failure is returned.\r
+\r
+ @param[in/out]   ParseStruct          Structure used to parse received TCG response, contains Sync Session response.\r
+ @param[in]       ComId                Expected ComID that is compared to actual ComID of response\r
+ @param[in]       ComIdExtension       Expected Extended ComID that is compared to actual Extended ComID of response\r
+ @param[in]       HostSessionId        Expected Host Session ID that is compared to actual  Host Session ID of response\r
+ @param[in/out]   TperSessionId        Tper Session ID retrieved from the Sync Session response.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgParseSyncSession(\r
+  const TCG_PARSE_STRUCT  *ParseStruct,\r
+  UINT16                  ComId,\r
+  UINT16                  ComIdExtension,\r
+  UINT32                  HostSessionId,\r
+  UINT32                  *TperSessionId\r
+  );\r
+\r
+/**\r
+  Create set ace.\r
+\r
+  @param     CreateStruct      Input create structure.\r
+  @param     Size              size info.\r
+  @param     ComId             ComId info.\r
+  @param     ComIdExtension    ComId extension info.\r
+  @param     TperSession       Tper session data.\r
+  @param     HostSession       Host session data.\r
+  @param     AceRow            Ace row info.\r
+  @param     Authority1        Authority 1 info.\r
+  @param     LogicalOperator   Logiccal operator info.\r
+  @param     Authority2        Authority 2 info.\r
+\r
+  @retval    Return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgCreateSetAce(\r
+  TCG_CREATE_STRUCT        *CreateStruct,\r
+  UINT32                   *Size,\r
+  UINT16                   ComId,\r
+  UINT16                   ComIdExtension,\r
+  UINT32                   TperSession,\r
+  UINT32                   HostSession,\r
+  TCG_UID                  AceRow,\r
+  TCG_UID                  Authority1,\r
+  BOOLEAN                  LogicalOperator,\r
+  TCG_UID                  Authority2\r
+  );\r
+\r
+/**\r
+  Enum level 0 discovery.\r
+\r
+  @param     DiscoveryHeader   Discovery header.\r
+  @param     Callback          Callback function.\r
+  @param     Context           The context for the function.\r
+\r
+  @retval    return true if the callback return TRUE, else return FALSE.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TcgEnumLevel0Discovery(\r
+  const TCG_LEVEL0_DISCOVERY_HEADER  *DiscoveryHeader,\r
+  TCG_LEVEL0_ENUM_CALLBACK           Callback,\r
+  VOID                               *Context\r
+  );\r
+\r
+/**\r
+  Get Feature code from the header.\r
+\r
+  @param     DiscoveryHeader    The discovery header.\r
+  @param     FeatureCode        reutrn the Feature code.\r
+  @param     FeatureSize        return the Feature size.\r
+\r
+  @retval    return the Feature code data.\r
+**/\r
+TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER*\r
+EFIAPI\r
+TcgGetFeature(\r
+  const TCG_LEVEL0_DISCOVERY_HEADER  *DiscoveryHeader,\r
+  UINT16                             FeatureCode,\r
+  UINTN                              *FeatureSize\r
+  );\r
+\r
+/**\r
+  Determines if the protocol provided is part of the provided supported protocol list.\r
+\r
+  @param[in]  ProtocolList     Supported protocol list to investigate\r
+  @param[in]  Protocol         Protocol value to determine if supported\r
+\r
+  @return TRUE = protocol is supported, FALSE = protocol is not supported\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TcgIsProtocolSupported(\r
+  const TCG_SUPPORTED_SECURITY_PROTOCOLS   *ProtocolList,\r
+  UINT16                                   Protocol\r
+  );\r
+\r
+/**\r
+  Determines if the Locking Feature "Locked" bit is set in the level 0 discovery response.\r
+\r
+  @param[in]  Discovery              Level 0 discovery response\r
+\r
+  @return TRUE = Locked is set, FALSE = Locked is false\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TcgIsLocked(\r
+  const TCG_LEVEL0_DISCOVERY_HEADER      *Discovery\r
+  );\r
+\r
+#pragma pack()\r
+\r
+\r
+#endif // _TCG_CORE_H_\r
diff --git a/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCore.c b/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCore.c
new file mode 100644 (file)
index 0000000..e333b55
--- /dev/null
@@ -0,0 +1,1650 @@
+/** @file\r
+  Provide functions to provide tcg storage core spec related functions.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Library/TcgStorageCoreLib.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+//#include <Library/PrintLib.h>\r
+\r
+/**\r
+  Required to be called before calling any other Tcg functions with the TCG_CREATE_STRUCT.\r
+  Initializes the packet variables to NULL.  Additionally, the buffer will be memset.\r
+\r
+  @param [in/out]    CreateStruct    Structure to initialize\r
+  @param [in]        Buffer          Buffer allocated by client of library.  It will contain the Tcg encoded packet.  This cannot be null.\r
+  @param [in]        BufferSize      Size of buffer provided.  It cannot be 0.\r
+\r
+  @retval       Return the action result.\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgInitTcgCreateStruct(\r
+  TCG_CREATE_STRUCT      *CreateStruct,\r
+  VOID                   *Buffer,\r
+  UINT32                 BufferSize\r
+  )\r
+{\r
+  NULL_CHECK(CreateStruct);\r
+  NULL_CHECK(Buffer);\r
+\r
+  if (BufferSize == 0) {\r
+    DEBUG ((DEBUG_INFO, "BufferSize=0\n"));\r
+    return (TcgResultFailureZeroSize);\r
+  }\r
+\r
+  ZeroMem(Buffer, BufferSize);\r
+  CreateStruct->BufferSize = BufferSize;\r
+  CreateStruct->Buffer = Buffer;\r
+  CreateStruct->ComPacket = NULL;\r
+  CreateStruct->CurPacket = NULL;\r
+  CreateStruct->CurSubPacket = NULL;\r
+\r
+  return (TcgResultSuccess);\r
+}\r
+\r
+/**\r
+\r
+  Encodes the ComPacket header to the data structure.\r
+\r
+  @param[in/out]    CreateStruct          Structure to initialize\r
+  @param[in]        ComId                 ComID of the Tcg ComPacket.\r
+  @param[in]        ComIdExtension        ComID Extension of the Tcg ComPacket.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartComPacket(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT16              ComId,\r
+  UINT16              ComIdExtension\r
+  )\r
+{\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  if (CreateStruct->ComPacket != NULL ||\r
+      CreateStruct->CurPacket != NULL ||\r
+      CreateStruct->CurSubPacket != NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket,\r
+    CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  if (sizeof(TCG_COM_PACKET) > CreateStruct->BufferSize) {\r
+    DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));\r
+    return (TcgResultFailureBufferTooSmall);\r
+  }\r
+\r
+  CreateStruct->ComPacket = (TCG_COM_PACKET*)CreateStruct->Buffer;\r
+  CreateStruct->ComPacket->ComIDBE = SwapBytes16(ComId);\r
+  CreateStruct->ComPacket->ComIDExtensionBE = SwapBytes16(ComIdExtension);\r
+\r
+  return (TcgResultSuccess);\r
+}\r
+\r
+/**\r
+\r
+  Starts a new ComPacket in the Data structure.\r
+\r
+  @param [in/out]     CreateStruct    Structure used to add Tcg Packet\r
+  @param[in]          Tsn             Packet Tper session number\r
+  @param[in]          Hsn             Packet Host session number\r
+  @param[in]          SeqNumber       Packet Sequence Number\r
+  @param[in]          AckType         Packet Acknowledge Type\r
+  @param[in]          Ack             Packet Acknowledge\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartPacket(\r
+  TCG_CREATE_STRUCT    *CreateStruct,\r
+  UINT32               Tsn,\r
+  UINT32               Hsn,\r
+  UINT32               SeqNumber,\r
+  UINT16               AckType,\r
+  UINT32               Ack\r
+  )\r
+{\r
+  UINT32 AddedSize;\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  AddedSize = 0;\r
+\r
+  if (CreateStruct->ComPacket == NULL ||\r
+      CreateStruct->CurPacket != NULL ||\r
+      CreateStruct->CurSubPacket != NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  // update TCG_COM_PACKET and packet lengths\r
+  AddedSize = sizeof(TCG_PACKET);\r
+\r
+  if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) {\r
+    DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));\r
+    return (TcgResultFailureBufferTooSmall);\r
+  }\r
+\r
+  CreateStruct->CurPacket = (TCG_PACKET*)(CreateStruct->ComPacket->Payload + SwapBytes32(CreateStruct->ComPacket->LengthBE));\r
+\r
+  CreateStruct->CurPacket->TperSessionNumberBE = SwapBytes32( Tsn );\r
+  CreateStruct->CurPacket->HostSessionNumberBE = SwapBytes32( Hsn );\r
+  CreateStruct->CurPacket->SequenceNumberBE = SwapBytes32( SeqNumber );\r
+  CreateStruct->CurPacket->AckTypeBE = SwapBytes16( AckType );\r
+  CreateStruct->CurPacket->AcknowledgementBE = SwapBytes32( Ack );\r
+\r
+  CreateStruct->CurPacket->LengthBE = 0;\r
+\r
+  // update TCG_COM_PACKET Length for next pointer\r
+  CreateStruct->ComPacket->LengthBE = SwapBytes32( SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize );\r
+\r
+  return (TcgResultSuccess);\r
+}\r
+\r
+/**\r
+\r
+  Starts a new SubPacket in the Data structure.\r
+\r
+  @param[in/out]    CreateStruct        Structure used to start Tcg SubPacket\r
+  @param[in]        Kind                SubPacket kind\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartSubPacket(\r
+  TCG_CREATE_STRUCT    *CreateStruct,\r
+  UINT16               Kind\r
+  )\r
+{\r
+  UINT32 AddedSize;\r
+\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  AddedSize = 0;\r
+\r
+  if (CreateStruct->ComPacket == NULL ||\r
+      CreateStruct->CurPacket == NULL ||\r
+      CreateStruct->CurSubPacket != NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  AddedSize = sizeof(TCG_SUB_PACKET);\r
+\r
+  if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) {\r
+    DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));\r
+    return (TcgResultFailureBufferTooSmall);\r
+  }\r
+\r
+  CreateStruct->CurSubPacket = (TCG_SUB_PACKET*)(CreateStruct->CurPacket->Payload + SwapBytes32(CreateStruct->CurPacket->LengthBE));\r
+  CreateStruct->CurSubPacket->KindBE = SwapBytes16(Kind);\r
+\r
+  // update lengths\r
+  CreateStruct->CurSubPacket->LengthBE = 0;\r
+\r
+  // update TCG_COM_PACKET and packet lengths\r
+  CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize);\r
+  CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + AddedSize);\r
+\r
+  return (TcgResultSuccess);\r
+}\r
+\r
+/**\r
+\r
+  Ends the current SubPacket in the Data structure.  This function will also perform the 4-byte padding\r
+  required for Subpackets.\r
+\r
+  @param[in/out]       CreateStruct        Structure used to end the current Tcg SubPacket\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndSubPacket(\r
+  TCG_CREATE_STRUCT   *CreateStruct\r
+  )\r
+{\r
+  UINT32 PadSize;\r
+\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  PadSize = 0;\r
+\r
+  if (CreateStruct->ComPacket == NULL ||\r
+      CreateStruct->CurPacket == NULL  ||\r
+      CreateStruct->CurSubPacket == NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  // align to 4-byte boundaries, so shift padding\r
+  // pad Size does not apply to subpacket Length\r
+  PadSize = TCG_SUBPACKET_ALIGNMENT - (SwapBytes32(CreateStruct->CurSubPacket->LengthBE) & (TCG_SUBPACKET_ALIGNMENT - 1));\r
+\r
+  if (PadSize == TCG_SUBPACKET_ALIGNMENT) {\r
+    PadSize = 0;\r
+  }\r
+\r
+  if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + PadSize) > CreateStruct->BufferSize) {\r
+    DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));\r
+    return (TcgResultFailureBufferTooSmall);\r
+  }\r
+\r
+  CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + PadSize);\r
+  CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + PadSize);\r
+\r
+  CreateStruct->CurSubPacket = NULL;\r
+\r
+  return (TcgResultSuccess);\r
+}\r
+\r
+/**\r
+\r
+  Ends the current Packet in the Data structure.\r
+\r
+  @param[in/out]       CreateStruct        Structure used to end the current Tcg Packet\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndPacket(\r
+  TCG_CREATE_STRUCT     *CreateStruct\r
+  )\r
+{\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  if (CreateStruct->ComPacket == NULL ||\r
+      CreateStruct->CurPacket == NULL ||\r
+      CreateStruct->CurSubPacket != NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  CreateStruct->CurPacket = NULL;\r
+\r
+  return (TcgResultSuccess);\r
+}\r
+\r
+/**\r
+\r
+  Ends the ComPacket in the Data structure and ret\r
+\r
+  @param [in/out]       CreateStruct       Structure used to end the Tcg ComPacket\r
+  @param [in/out]       Size               Describes the Size of the entire ComPacket (Header and payload). Filled out by function.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndComPacket(\r
+  TCG_CREATE_STRUCT      *CreateStruct,\r
+  UINT32                 *Size\r
+  )\r
+{\r
+  NULL_CHECK(CreateStruct);\r
+  NULL_CHECK(Size);\r
+\r
+  if (CreateStruct->ComPacket == NULL ||\r
+      CreateStruct->CurPacket != NULL ||\r
+      CreateStruct->CurSubPacket != NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  *Size = SwapBytes32(CreateStruct->ComPacket->LengthBE) + sizeof(*CreateStruct->ComPacket);\r
+  CreateStruct->ComPacket = NULL;\r
+\r
+  return (TcgResultSuccess);\r
+}\r
+\r
+/**\r
+  Adds raw Data with optional Header\r
+\r
+  @param       CreateStruct       The create structure.\r
+  @param       Header             The header structure.\r
+  @param       HeaderSize         The header size.\r
+  @param       Data               The data need to add.\r
+  @param       DataSize           The data size.\r
+  @param       ByteSwapData       Whether byte or swap data.\r
+\r
+**/\r
+TCG_RESULT\r
+TcgAddRawTokenData(\r
+  TCG_CREATE_STRUCT      *CreateStruct,\r
+  const VOID             *Header,\r
+  UINT8                  HeaderSize,\r
+  const VOID             *Data,\r
+  UINT32                 DataSize,\r
+  BOOLEAN                ByteSwapData\r
+  )\r
+{\r
+  UINT32 AddedSize;\r
+  UINT8* Dest;\r
+  const UINT8* DataBytes;\r
+  UINT32 Index;\r
+\r
+  AddedSize = 0;\r
+  Index = 0;\r
+  Dest = NULL;\r
+\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  if ((HeaderSize != 0 && Header == NULL) ||\r
+      (DataSize != 0 && Data == NULL)\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "HeaderSize=0x%X Header=%p DataSize=0x%X Data=%p\n", HeaderSize, Header, DataSize, Data));\r
+    return (TcgResultFailureNullPointer);\r
+  }\r
+\r
+  if (CreateStruct->ComPacket == NULL ||\r
+      CreateStruct->CurPacket == NULL ||\r
+      CreateStruct->CurSubPacket == NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  // verify there is enough Buffer Size\r
+  AddedSize = HeaderSize + DataSize;\r
+  if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) {\r
+    return (TcgResultFailureBufferTooSmall);\r
+  }\r
+\r
+  // Get a pointer to where the new bytes should go\r
+  Dest = CreateStruct->ComPacket->Payload + SwapBytes32(CreateStruct->ComPacket->LengthBE);\r
+\r
+  switch (HeaderSize) {\r
+    case sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM):\r
+    case sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM):\r
+    case sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM):\r
+      CopyMem(Dest, Header, HeaderSize);\r
+      Dest += HeaderSize;\r
+    case 0: // no Header is valid\r
+      break;\r
+    // invalid Header Size\r
+    default:\r
+      DEBUG ((DEBUG_INFO, "unsupported HeaderSize=%u\n", HeaderSize));\r
+      return TcgResultFailure;\r
+  }\r
+\r
+  // copy the Data bytes\r
+  if (ByteSwapData) {\r
+    DataBytes = (const UINT8*)Data;\r
+    for (Index = 0; Index < DataSize; Index++) {\r
+      Dest[Index] = DataBytes[DataSize - 1 - Index];\r
+    }\r
+  } else {\r
+    CopyMem(Dest, Data, DataSize);\r
+  }\r
+\r
+  // Update all the packet sizes\r
+  CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize);\r
+  CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + AddedSize);\r
+  CreateStruct->CurSubPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurSubPacket->LengthBE) + AddedSize);\r
+\r
+  return (TcgResultSuccess);\r
+}\r
+\r
+/**\r
+\r
+  Adds a single raw token byte to the Data structure.\r
+\r
+  @param[in/out]   CreateStruct        Structure used to add the byte\r
+  @param[in]       Byte                Byte to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddRawByte(\r
+  TCG_CREATE_STRUCT     *CreateStruct,\r
+  UINT8                 Byte\r
+  )\r
+{\r
+  return TcgAddRawTokenData(CreateStruct, NULL, 0, &Byte, 1, FALSE);\r
+}\r
+\r
+\r
+/**\r
+   simple tokens - atoms: tiny, short, medium, long and empty atoms.\r
+   tiny atom can be a signed or unsigned integer.\r
+   short, medium, long can be a signed or unsigned integer OR a complete or non-final byte sequence.\r
+\r
+  @param       CreateStruct       The create structure.\r
+  @param       Data               The data need to add.\r
+  @param       DataSize           The data size.\r
+  @param       ByteOrInt,         Data format is byte or int.\r
+  @param       SignOrCont         sign or cont.\r
+\r
+\r
+**/\r
+TCG_RESULT\r
+TcgAddAtom(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  const VOID          *Data,\r
+  UINT32              DataSize,\r
+  UINT8               ByteOrInt,\r
+  UINT8               SignOrCont\r
+  )\r
+{\r
+  const UINT8* DataBytes;\r
+  TCG_SIMPLE_TOKEN_TINY_ATOM TinyAtom;\r
+  TCG_SIMPLE_TOKEN_SHORT_ATOM ShortAtom;\r
+  TCG_SIMPLE_TOKEN_MEDIUM_ATOM MediumAtom;\r
+  TCG_SIMPLE_TOKEN_LONG_ATOM LongAtom;\r
+\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  if (DataSize == 0) {\r
+    if (ByteOrInt == TCG_ATOM_TYPE_INTEGER) {\r
+      DEBUG ((DEBUG_INFO, "0-Size integer not allowed\n"));\r
+      return TcgResultFailure;\r
+    }\r
+  } else {\r
+    // if DataSize != 0, Data must be valid\r
+    NULL_CHECK(Data);\r
+  }\r
+\r
+  // encode Data using the shortest possible atom\r
+  DataBytes = (const UINT8*)Data;\r
+  if ((DataSize == 1) &&\r
+      (ByteOrInt == TCG_ATOM_TYPE_INTEGER) &&\r
+      ((SignOrCont != 0 && ((TCG_TOKEN_TINYATOM_SIGNED_MIN_VALUE <= *(INT8*)Data) && (*(INT8*)Data <= TCG_TOKEN_TINYATOM_SIGNED_MAX_VALUE))) ||\r
+       (SignOrCont == 0 && ((*DataBytes <= TCG_TOKEN_TINYATOM_UNSIGNED_MAX_VALUE))))\r
+     ) {\r
+    TinyAtom.TinyAtomBits.IsZero = 0;\r
+    TinyAtom.TinyAtomBits.Sign = SignOrCont;\r
+    TinyAtom.TinyAtomBits.Data = *DataBytes & TCG_TOKEN_TINYATOM_UNSIGNED_MAX_VALUE;\r
+    return TcgAddRawTokenData(CreateStruct, NULL, 0, (UINT8*)&TinyAtom, sizeof(TCG_SIMPLE_TOKEN_TINY_ATOM), FALSE);\r
+  }\r
+\r
+  if (DataSize <= TCG_TOKEN_SHORTATOM_MAX_BYTE_SIZE) {\r
+    ShortAtom.ShortAtomBits.IsOne = 1;\r
+    ShortAtom.ShortAtomBits.IsZero = 0;\r
+    ShortAtom.ShortAtomBits.ByteOrInt = ByteOrInt;\r
+    ShortAtom.ShortAtomBits.SignOrCont = SignOrCont;\r
+    ShortAtom.ShortAtomBits.Length = DataSize & 0x0F;\r
+    return TcgAddRawTokenData(CreateStruct, &ShortAtom, sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER);\r
+  }\r
+\r
+  if (DataSize <= TCG_TOKEN_MEDIUMATOM_MAX_BYTE_SIZE) {\r
+    MediumAtom.MediumAtomBits.IsOne1 = 1;\r
+    MediumAtom.MediumAtomBits.IsOne2 = 1;\r
+    MediumAtom.MediumAtomBits.IsZero = 0;\r
+    MediumAtom.MediumAtomBits.ByteOrInt = ByteOrInt;\r
+    MediumAtom.MediumAtomBits.SignOrCont = SignOrCont;\r
+    MediumAtom.MediumAtomBits.LengthLow = DataSize & 0xFF;\r
+    MediumAtom.MediumAtomBits.LengthHigh = (DataSize >> TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) & TCG_MEDIUM_ATOM_LENGTH_HIGH_MASK;\r
+    return TcgAddRawTokenData(CreateStruct, &MediumAtom, sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER);\r
+  }\r
+\r
+  LongAtom.LongAtomBits.IsOne1 = 1;\r
+  LongAtom.LongAtomBits.IsOne2 = 1;\r
+  LongAtom.LongAtomBits.IsOne3 = 1;\r
+  LongAtom.LongAtomBits.IsZero = 0;\r
+  LongAtom.LongAtomBits.ByteOrInt = ByteOrInt;\r
+  LongAtom.LongAtomBits.SignOrCont = SignOrCont;\r
+  LongAtom.LongAtomBits.LengthLow = DataSize & 0xFF;\r
+  LongAtom.LongAtomBits.LengthMid = (DataSize >> TCG_LONG_ATOM_LENGTH_MID_SHIFT) & 0xFF;\r
+  LongAtom.LongAtomBits.LengthHigh = (DataSize >> TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) & 0xFF;\r
+  return TcgAddRawTokenData(CreateStruct, &LongAtom, sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER);\r
+}\r
+\r
+/**\r
+\r
+  Adds the Data parameter as a byte sequence to the Data structure.\r
+\r
+  @param[in/out]    CreateStruct      Structure used to add the byte sequence\r
+  @param[in]        Data              Byte sequence that will be encoded and copied into Data structure\r
+  @param[in]        DataSize          Length of Data provided\r
+  @param[in]        Continued         TRUE if byte sequence is continued or\r
+                                      FALSE if the Data contains the entire byte sequence to be encoded\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddByteSequence(\r
+  TCG_CREATE_STRUCT     *CreateStruct,\r
+  const VOID            *Data,\r
+  UINT32                DataSize,\r
+  BOOLEAN               Continued\r
+  )\r
+{\r
+  return TcgAddAtom(CreateStruct, Data, DataSize, TCG_ATOM_TYPE_BYTE, Continued ? 1 : 0);\r
+}\r
+\r
+/**\r
+\r
+  Adds an arbitrary-Length integer to the Data structure.\r
+  The integer will be encoded using the shortest possible atom.\r
+\r
+  @param[in/out]     CreateStruct      Structure used to add the integer\r
+  @param[in]         Data              Integer in host byte order that will be encoded and copied into Data structure\r
+  @param[in]         DataSize          Length in bytes of the Data provided\r
+  @param[in]         SignedInteger     TRUE if the integer is signed or FALSE if the integer is unsigned\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddInteger(\r
+  TCG_CREATE_STRUCT  *CreateStruct,\r
+  const VOID         *Data,\r
+  UINT32             DataSize,\r
+  BOOLEAN            SignedInteger\r
+  )\r
+{\r
+  const UINT8* DataBytes;\r
+  UINT32 ActualDataSize;\r
+  BOOLEAN ValueIsNegative;\r
+\r
+  NULL_CHECK(CreateStruct);\r
+  NULL_CHECK(Data);\r
+\r
+  if (DataSize == 0) {\r
+    DEBUG ((DEBUG_INFO, "invalid DataSize=0\n"));\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  DataBytes = (const UINT8*)Data;\r
+\r
+  // integer should be represented by smallest atom possible\r
+  // so calculate real Data Size\r
+  ValueIsNegative = SignedInteger && DataBytes[ DataSize - 1 ] & 0x80;\r
+\r
+  // assumes native Data is little endian\r
+  // shorten Data to smallest byte representation\r
+  for (ActualDataSize = DataSize; ActualDataSize > 1; ActualDataSize--) {\r
+    // ignore sign extended  FFs\r
+    if (ValueIsNegative && (DataBytes[ActualDataSize - 1] != 0xFF)) {\r
+      break;\r
+    } else if (!ValueIsNegative && (DataBytes[ActualDataSize - 1] != 0)) {\r
+      // ignore extended 00s\r
+      break;\r
+    }\r
+  }\r
+\r
+  return TcgAddAtom(CreateStruct, Data, ActualDataSize, TCG_ATOM_TYPE_INTEGER, SignedInteger ? 1 : 0);\r
+}\r
+\r
+/**\r
+  Adds an 8-bit unsigned integer to the Data structure.\r
+\r
+  @param[in/out]       CreateStruct        Structure used to add the integer\r
+  @param[in]           Value               Integer Value to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddUINT8(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT8               Value\r
+  )\r
+{\r
+  return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);\r
+}\r
+\r
+/**\r
+\r
+  Adds a 16-bit unsigned integer to the Data structure.\r
+\r
+  @param[in/out]       CreateStruct        Structure used to add the integer\r
+  @param[in]           Value               Integer Value to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddUINT16 (\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT16              Value\r
+  )\r
+{\r
+  return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);\r
+}\r
+\r
+/**\r
+\r
+  Adds a 32-bit unsigned integer to the Data structure.\r
+\r
+  @param[in/out]        CreateStruct        Structure used to add the integer\r
+  @param[in]            Value               Integer Value to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddUINT32(\r
+  TCG_CREATE_STRUCT    *CreateStruct,\r
+  UINT32               Value\r
+  )\r
+{\r
+  return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);\r
+}\r
+\r
+\r
+/**\r
+\r
+  Adds a 64-bit unsigned integer to the Data structure.\r
+\r
+  @param[in/out]      CreateStruct        Structure used to add the integer\r
+  @param[in]          Value               Integer Value to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddUINT64(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT64              Value\r
+  )\r
+{\r
+  return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);\r
+}\r
+\r
+/**\r
+  Adds a BOOLEAN to the Data structure.\r
+\r
+  @param[in/out]       CreateStruct     Structure used to add the integer\r
+  @param[in]           Value              BOOLEAN Value to add\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddBOOLEAN(\r
+  TCG_CREATE_STRUCT    *CreateStruct,\r
+  BOOLEAN              Value\r
+  )\r
+{\r
+  return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);\r
+}\r
+\r
+/**\r
+  Add tcg uid info.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+  @param                Uid                Input uid info.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddTcgUid(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  TCG_UID             Uid\r
+  )\r
+{\r
+  return TcgAddByteSequence(CreateStruct, &Uid, sizeof(TCG_UID), FALSE);\r
+}\r
+\r
+/**\r
+  Add start list.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddStartList(\r
+  TCG_CREATE_STRUCT          *CreateStruct\r
+  )\r
+{\r
+  return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTLIST);\r
+}\r
+\r
+/**\r
+  Add end list.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddEndList(\r
+  TCG_CREATE_STRUCT       *CreateStruct\r
+  )\r
+{\r
+  return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDLIST);\r
+}\r
+\r
+/**\r
+  Add start name.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddStartName(\r
+  TCG_CREATE_STRUCT          *CreateStruct\r
+  )\r
+{\r
+  return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTNAME);\r
+}\r
+\r
+/**\r
+  Add end name.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddEndName(\r
+  TCG_CREATE_STRUCT          *CreateStruct\r
+  )\r
+{\r
+  return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDNAME);\r
+}\r
+\r
+/**\r
+  Add end call.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddCall(\r
+  TCG_CREATE_STRUCT      *CreateStruct\r
+  )\r
+{\r
+  return TcgAddRawByte(CreateStruct, TCG_TOKEN_CALL);\r
+}\r
+\r
+/**\r
+  Add end of data.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddEndOfData(\r
+  TCG_CREATE_STRUCT          *CreateStruct\r
+  )\r
+{\r
+  return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDDATA);\r
+}\r
+\r
+/**\r
+  Add end of session.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddEndOfSession(\r
+  TCG_CREATE_STRUCT              *CreateStruct\r
+  )\r
+{\r
+  return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDSESSION);\r
+}\r
+\r
+/**\r
+  Add start transaction.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddStartTransaction(\r
+  TCG_CREATE_STRUCT             *CreateStruct\r
+  )\r
+{\r
+  return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTTRANSACTION);\r
+}\r
+\r
+/**\r
+  Add end transaction.\r
+\r
+  @param [in/out]       CreateStruct       Structure used to add the integer\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgAddEndTransaction(\r
+  TCG_CREATE_STRUCT           *CreateStruct\r
+  )\r
+{\r
+  return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDTRANSACTION);\r
+}\r
+\r
+/**\r
+  Initial the tcg parse stucture.\r
+\r
+  @param    ParseStruct    Input parse structure.\r
+  @param    Buffer         Input buffer data.\r
+  @param    BufferSize     Input buffer size.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgInitTcgParseStruct(\r
+  TCG_PARSE_STRUCT          *ParseStruct,\r
+  const VOID                *Buffer,\r
+  UINT32                    BufferSize\r
+  )\r
+{\r
+  UINT32 ComPacketLength;\r
+  UINT32 PacketLength;\r
+\r
+  NULL_CHECK(ParseStruct);\r
+  NULL_CHECK(Buffer);\r
+\r
+  if (BufferSize < sizeof(TCG_COM_PACKET)) {\r
+    return (TcgResultFailureBufferTooSmall);\r
+  }\r
+\r
+  ParseStruct->ComPacket = (TCG_COM_PACKET*)Buffer;\r
+\r
+  ComPacketLength = SwapBytes32(ParseStruct->ComPacket->LengthBE);\r
+\r
+  if ((BufferSize - sizeof(TCG_COM_PACKET)) < ComPacketLength) {\r
+    DEBUG ((DEBUG_INFO, "Buffer %u too small for ComPacket %u\n", BufferSize, ComPacketLength));\r
+    return (TcgResultFailureBufferTooSmall);\r
+  }\r
+\r
+  ParseStruct->BufferSize = BufferSize;\r
+  ParseStruct->Buffer = Buffer;\r
+\r
+  ParseStruct->CurPacket = NULL;\r
+  ParseStruct->CurSubPacket = NULL;\r
+  ParseStruct->CurPtr = NULL;\r
+\r
+  // if payload > 0, then must have a packet\r
+  if (ComPacketLength != 0) {\r
+    if (ComPacketLength < sizeof(TCG_PACKET)) {\r
+      DEBUG ((DEBUG_INFO, "ComPacket too small for Packet\n"));\r
+      return (TcgResultFailureBufferTooSmall);\r
+    }\r
+    ParseStruct->CurPacket = (TCG_PACKET*)ParseStruct->ComPacket->Payload;\r
+\r
+    PacketLength = SwapBytes32(ParseStruct->CurPacket->LengthBE);\r
+\r
+    if (PacketLength > 0) {\r
+      if (PacketLength < sizeof(TCG_SUB_PACKET)) {\r
+          DEBUG ((DEBUG_INFO, "Packet too small for SubPacket\n"));\r
+          return (TcgResultFailureBufferTooSmall);\r
+      }\r
+\r
+      ParseStruct->CurSubPacket = (TCG_SUB_PACKET*)ParseStruct->CurPacket->Payload;\r
+    }\r
+  }\r
+\r
+  //TODO should check for method status list at this point?\r
+\r
+  return (TcgResultSuccess);\r
+}\r
+\r
+/**\r
+  Get next token info.\r
+\r
+  @param    ParseStruct      Input parse structure info.\r
+  @param    TcgToken         return the tcg token info.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextToken(\r
+  TCG_PARSE_STRUCT      *ParseStruct,\r
+  TCG_TOKEN             *TcgToken\r
+  )\r
+{\r
+  const UINT8* EndOfSubPacket;\r
+  UINT8* TokenEnd;\r
+  UINT8 Hdr;\r
+  TCG_SIMPLE_TOKEN_SHORT_ATOM* TmpShort;\r
+  const TCG_SIMPLE_TOKEN_MEDIUM_ATOM* TmpMed;\r
+  const TCG_SIMPLE_TOKEN_LONG_ATOM* TmpLong;\r
+\r
+  NULL_CHECK(ParseStruct);\r
+  NULL_CHECK(TcgToken);\r
+\r
+  if (ParseStruct->ComPacket == NULL ||\r
+      ParseStruct->CurPacket == NULL ||\r
+      ParseStruct->CurSubPacket == NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", ParseStruct->ComPacket, ParseStruct->CurPacket, ParseStruct->CurSubPacket));\r
+    return TcgResultFailureInvalidAction;\r
+  }\r
+\r
+  // initial call, start at sub packet\r
+  if (ParseStruct->CurPtr == NULL) {\r
+    ParseStruct->CurPtr = ParseStruct->CurSubPacket->Payload;\r
+  }\r
+\r
+  EndOfSubPacket = ParseStruct->CurSubPacket->Payload + SwapBytes32(ParseStruct->CurSubPacket->LengthBE);\r
+  TokenEnd = NULL;\r
+\r
+  // confirmed that subpacket Length falls within end of Buffer and TCG_COM_PACKET,\r
+  // so simply need to verify the loop stays within current subpacket\r
+  if (ParseStruct->CurPtr >= EndOfSubPacket) {\r
+    DEBUG ((DEBUG_INFO, "ParseStruct->CurPtr >= EndOfSubPacket\n"));\r
+    return (TcgResultFailureEndBuffer);\r
+  }\r
+\r
+  Hdr = *ParseStruct->CurPtr;\r
+  TcgToken->HdrStart = ParseStruct->CurPtr;\r
+\r
+  // Tiny Atom range\r
+  if (Hdr <= 0x7F) {\r
+    // tiny atom Header is only 1 byte, so don't need to verify Size before cast and access\r
+    TcgToken->Type = TcgTokenTypeTinyAtom;\r
+\r
+    TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_TINY_ATOM);\r
+\r
+    // verify caller will have enough Size to reference token\r
+    if (TokenEnd >= EndOfSubPacket) {\r
+      DEBUG ((DEBUG_INFO, "Tiny Atom TokenEnd >= EndOfSubPacket\n"));\r
+      return (TcgResultFailureEndBuffer);\r
+    }\r
+  }\r
+  // Short Atom Range\r
+  else if (0x80 <= Hdr && Hdr <= 0xBF) {\r
+    // short atom Header is only 1 byte, so don't need to verify Size before cast and access\r
+    TmpShort = (TCG_SIMPLE_TOKEN_SHORT_ATOM*)(ParseStruct->CurPtr);\r
+    TcgToken->Type = TcgTokenTypeShortAtom;\r
+\r
+    TokenEnd = (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM) + TmpShort->ShortAtomBits.Length);\r
+\r
+    // verify caller will have enough Size to reference token\r
+    if (TokenEnd >= EndOfSubPacket) {\r
+      DEBUG ((DEBUG_INFO, "Short Atom TokenEnd >= EndOfSubPacket\n"));\r
+      return (TcgResultFailureEndBuffer);\r
+    }\r
+  }\r
+  // Medium Atom Range\r
+  else if (0xC0 <= Hdr && Hdr <= 0xDF) {\r
+    if (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM) >= EndOfSubPacket) {\r
+      return (TcgResultFailureEndBuffer);\r
+    }\r
+    TmpMed = (const TCG_SIMPLE_TOKEN_MEDIUM_ATOM*)ParseStruct->CurPtr;\r
+    TcgToken->Type = TcgTokenTypeMediumAtom;\r
+    TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM) +\r
+               ((TmpMed->MediumAtomBits.LengthHigh << TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) |\r
+                TmpMed->MediumAtomBits.LengthLow);\r
+\r
+    // verify caller will have enough Size to reference token\r
+    if (TokenEnd >= EndOfSubPacket) {\r
+      DEBUG ((DEBUG_INFO, "Medium Atom TokenEnd >= EndOfSubPacket\n"));\r
+      return (TcgResultFailureEndBuffer);\r
+    }\r
+  }\r
+  // Long Atom Range\r
+  else if (0xE0 <= Hdr && Hdr <= 0xE3) {\r
+    if (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM) >= EndOfSubPacket) {\r
+      return (TcgResultFailureEndBuffer);\r
+    }\r
+    TmpLong = (const TCG_SIMPLE_TOKEN_LONG_ATOM*)ParseStruct->CurPtr;\r
+    TcgToken->Type = TcgTokenTypeLongAtom;\r
+\r
+    TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM) +\r
+               ((TmpLong->LongAtomBits.LengthHigh << TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) |\r
+                (TmpLong->LongAtomBits.LengthMid << TCG_LONG_ATOM_LENGTH_MID_SHIFT)   |\r
+                TmpLong->LongAtomBits.LengthLow);\r
+\r
+    // verify caller will have enough Size to reference token\r
+    if (TokenEnd >= EndOfSubPacket) {\r
+      DEBUG ((DEBUG_INFO, "Long Atom TokenEnd >= EndOfSubPacket\n"));\r
+      return (TcgResultFailureEndBuffer);\r
+    }\r
+  } else {\r
+    // single byte tokens\r
+    switch (Hdr) {\r
+      case TCG_TOKEN_STARTLIST:\r
+          TcgToken->Type = TcgTokenTypeStartList;\r
+          break;\r
+      case TCG_TOKEN_ENDLIST:\r
+          TcgToken->Type = TcgTokenTypeEndList;\r
+          break;\r
+      case TCG_TOKEN_STARTNAME:\r
+          TcgToken->Type = TcgTokenTypeStartName;\r
+          break;\r
+      case TCG_TOKEN_ENDNAME:\r
+          TcgToken->Type = TcgTokenTypeEndName;\r
+          break;\r
+      case TCG_TOKEN_CALL:\r
+          TcgToken->Type = TcgTokenTypeCall;\r
+          break;\r
+      case TCG_TOKEN_ENDDATA:\r
+          TcgToken->Type = TcgTokenTypeEndOfData;\r
+          break;\r
+      case TCG_TOKEN_ENDSESSION:\r
+          TcgToken->Type = TcgTokenTypeEndOfSession;\r
+          break;\r
+      case TCG_TOKEN_STARTTRANSACTION:\r
+          TcgToken->Type = TcgTokenTypeStartTransaction;\r
+          break;\r
+      case TCG_TOKEN_ENDTRANSACTION:\r
+          TcgToken->Type = TcgTokenTypeEndTransaction;\r
+          break;\r
+      case TCG_TOKEN_EMPTY:\r
+          TcgToken->Type = TcgTokenTypeEmptyAtom;\r
+          break;\r
+      default:\r
+          DEBUG ((DEBUG_INFO, "WARNING: reserved token Type 0x%02X\n", Hdr));\r
+          TcgToken->Type = TcgTokenTypeReserved;\r
+          break;\r
+    }\r
+    ParseStruct->CurPtr++;\r
+    TokenEnd = TcgToken->HdrStart + 1;\r
+  }\r
+\r
+  // increment curptr for next call\r
+  ParseStruct->CurPtr = TokenEnd;\r
+  return (TcgResultSuccess);\r
+}\r
+\r
+/**\r
+  Get atom info.\r
+\r
+  @param    TcgToken          Input token info.\r
+  @param    HeaderLength      return the header length.\r
+  @param    DataLength        return the data length.\r
+  @param    ByteOrInt         return the atom Type.\r
+  @param    SignOrCont        return the sign or count info.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetAtomInfo(\r
+  const TCG_TOKEN      *TcgToken,\r
+  UINT32               *HeaderLength,\r
+  UINT32               *DataLength,\r
+  UINT8                *ByteOrInt,\r
+  UINT8                *SignOrCont\r
+  )\r
+{\r
+  TCG_SIMPLE_TOKEN_TINY_ATOM* TinyAtom;\r
+  TCG_SIMPLE_TOKEN_SHORT_ATOM* ShortAtom;\r
+  TCG_SIMPLE_TOKEN_MEDIUM_ATOM* MediumAtom;\r
+  TCG_SIMPLE_TOKEN_LONG_ATOM* LongAtom;\r
+\r
+  NULL_CHECK(TcgToken);\r
+  NULL_CHECK(HeaderLength);\r
+  NULL_CHECK(DataLength);\r
+  NULL_CHECK(ByteOrInt);\r
+  NULL_CHECK(SignOrCont);\r
+\r
+  switch (TcgToken->Type) {\r
+    case TcgTokenTypeTinyAtom: {\r
+      TinyAtom = (TCG_SIMPLE_TOKEN_TINY_ATOM*)TcgToken->HdrStart;\r
+      *ByteOrInt      = TCG_ATOM_TYPE_INTEGER;\r
+      *SignOrCont     = TinyAtom->TinyAtomBits.Sign;\r
+      *HeaderLength   = 0;\r
+      *DataLength     = 0; // tiny atom must be handled as a special case - Header and Data in the same byte\r
+      return TcgResultSuccess;\r
+    }\r
+\r
+    case TcgTokenTypeShortAtom: {\r
+      ShortAtom = (TCG_SIMPLE_TOKEN_SHORT_ATOM*)TcgToken->HdrStart;\r
+      *ByteOrInt      = ShortAtom->ShortAtomBits.ByteOrInt;\r
+      *SignOrCont     = ShortAtom->ShortAtomBits.SignOrCont;\r
+      *HeaderLength   = sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM);\r
+      *DataLength     = ShortAtom->ShortAtomBits.Length;\r
+      return TcgResultSuccess;\r
+    }\r
+\r
+    case TcgTokenTypeMediumAtom: {\r
+      MediumAtom = (TCG_SIMPLE_TOKEN_MEDIUM_ATOM*)TcgToken->HdrStart;\r
+      *ByteOrInt      = MediumAtom->MediumAtomBits.ByteOrInt;\r
+      *SignOrCont     = MediumAtom->MediumAtomBits.SignOrCont;\r
+      *HeaderLength   = sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM);\r
+      *DataLength     = (MediumAtom->MediumAtomBits.LengthHigh << TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) | MediumAtom->MediumAtomBits.LengthLow;\r
+      return TcgResultSuccess;\r
+    }\r
+\r
+    case TcgTokenTypeLongAtom: {\r
+      LongAtom = (TCG_SIMPLE_TOKEN_LONG_ATOM*)TcgToken->HdrStart;\r
+      *ByteOrInt      = LongAtom->LongAtomBits.ByteOrInt;\r
+      *SignOrCont     = LongAtom->LongAtomBits.SignOrCont;\r
+      *HeaderLength   = sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM);\r
+      *DataLength     = (LongAtom->LongAtomBits.LengthHigh << TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) |\r
+                        (LongAtom->LongAtomBits.LengthMid << TCG_LONG_ATOM_LENGTH_MID_SHIFT) |\r
+                        LongAtom->LongAtomBits.LengthLow;\r
+      return TcgResultSuccess;\r
+    }\r
+\r
+    default:\r
+      DEBUG ((DEBUG_INFO, "Token Type is not simple atom (%d)\n", TcgToken->Type));\r
+      return (TcgResultFailureInvalidType);\r
+  }\r
+}\r
+\r
+/**\r
+  Get token specified value.\r
+\r
+  @param    TcgToken   Input token info.\r
+  @param    Value      return the value.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetTokenUINT64(\r
+  const TCG_TOKEN      *TcgToken,\r
+  UINT64               *Value\r
+  )\r
+{\r
+  UINT32 HdrLength;\r
+  UINT32 DataLength;\r
+  UINT8 ByteOrInt;\r
+  UINT8 IsSigned;\r
+  TCG_SIMPLE_TOKEN_TINY_ATOM* TmpTiny;\r
+  const UINT8* Data;\r
+  UINT32 Index;\r
+\r
+  NULL_CHECK(TcgToken);\r
+  NULL_CHECK(Value);\r
+\r
+  Index = 0;\r
+  *Value = 0;\r
+  ERROR_CHECK(TcgGetAtomInfo(TcgToken, &HdrLength, &DataLength, &ByteOrInt, &IsSigned));\r
+\r
+  if (ByteOrInt != TCG_ATOM_TYPE_INTEGER) {\r
+    DEBUG ((DEBUG_INFO, "Invalid Type, expected integer not byte sequence\n"));\r
+    return TcgResultFailureInvalidType;\r
+  }\r
+\r
+  if (IsSigned != 0) {\r
+    DEBUG ((DEBUG_INFO, "Integer is signed, expected unsigned\n"));\r
+    return TcgResultFailureInvalidType;\r
+  }\r
+\r
+  // special case for tiny atom\r
+  // Header and Data are in one byte, so extract only the Data bitfield\r
+  if (TcgToken->Type == TcgTokenTypeTinyAtom) {\r
+    TmpTiny = (TCG_SIMPLE_TOKEN_TINY_ATOM*)TcgToken->HdrStart;\r
+    *Value = TmpTiny->TinyAtomBits.Data;\r
+    return TcgResultSuccess;\r
+  }\r
+\r
+  if (DataLength > sizeof(UINT64)) {\r
+    DEBUG ((DEBUG_INFO, "Length %d is greater than Size of UINT64\n", DataLength));\r
+    return TcgResultFailureBufferTooSmall;\r
+  }\r
+\r
+  // read big-endian integer\r
+  Data = TcgToken->HdrStart + HdrLength;\r
+  for (Index = 0; Index < DataLength; Index++) {\r
+    *Value = LShiftU64(*Value, 8) | Data[Index];\r
+  }\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Get token byte sequence.\r
+\r
+  @param    TcgToken   Input token info.\r
+  @param    Length     Input the length info.\r
+\r
+  @retval   Return the value data.\r
+\r
+**/\r
+UINT8*\r
+EFIAPI\r
+TcgGetTokenByteSequence(\r
+  const TCG_TOKEN     *TcgToken,\r
+  UINT32              *Length\r
+  )\r
+{\r
+  UINT32 HdrLength;\r
+  UINT8 ByteOrInt;\r
+  UINT8 SignOrCont;\r
+\r
+  if (TcgToken == NULL || Length == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  *Length = 0;\r
+  if (TcgGetAtomInfo(TcgToken, &HdrLength, Length, &ByteOrInt, &SignOrCont) != TcgResultSuccess) {\r
+    DEBUG ((DEBUG_INFO, "Failed to get simple token info\n"));\r
+    return NULL;\r
+  }\r
+\r
+  if (ByteOrInt != TCG_ATOM_TYPE_BYTE) {\r
+    DEBUG ((DEBUG_INFO, "Invalid Type, expected byte sequence not integer\n"));\r
+    return NULL;\r
+  }\r
+\r
+  return (TcgToken->HdrStart + HdrLength);\r
+}\r
+\r
+/**\r
+  Get next specify value.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+  @param    Value         Return vlaue.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextUINT8(\r
+  TCG_PARSE_STRUCT      *ParseStruct,\r
+  UINT8                 *Value\r
+  )\r
+{\r
+  UINT64 Value64;\r
+  TCG_TOKEN Tok;\r
+\r
+  NULL_CHECK(Value);\r
+\r
+  ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));\r
+  ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));\r
+\r
+  if (Value64 > MAX_UINT8) {\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  *Value = (UINT8)Value64;\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Get next specify value.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+  @param    Value         Return vlaue.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextUINT16(\r
+  TCG_PARSE_STRUCT     *ParseStruct,\r
+  UINT16               *Value\r
+  )\r
+{\r
+  UINT64 Value64;\r
+  TCG_TOKEN Tok;\r
+\r
+  NULL_CHECK(Value);\r
+\r
+  ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));\r
+  ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));\r
+\r
+  if (Value64 > MAX_UINT16) {\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  *Value = (UINT16)Value64;\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Get next specify value.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+  @param    Value         Return vlaue.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextUINT32(\r
+  TCG_PARSE_STRUCT          *ParseStruct,\r
+  UINT32                    *Value\r
+  )\r
+{\r
+  UINT64 Value64;\r
+  TCG_TOKEN Tok;\r
+\r
+  NULL_CHECK(Value);\r
+\r
+  ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));\r
+  ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));\r
+\r
+  if (Value64 > MAX_UINT32) {\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  *Value = (UINT32)Value64;\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Get next specify value.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+  @param    Value         Return vlaue.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextUINT64(\r
+  TCG_PARSE_STRUCT           *ParseStruct,\r
+  UINT64                     *Value\r
+  )\r
+{\r
+  TCG_TOKEN Tok;\r
+  ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));\r
+  ERROR_CHECK(TcgGetTokenUINT64(&Tok, Value));\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Get next specify value.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+  @param    Value         Return vlaue.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextBOOLEAN(\r
+  TCG_PARSE_STRUCT        *ParseStruct,\r
+  BOOLEAN                 *Value\r
+  )\r
+{\r
+  UINT64 Value64;\r
+  TCG_TOKEN Tok;\r
+\r
+  NULL_CHECK(Value);\r
+\r
+  ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));\r
+  ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));\r
+\r
+  if (Value64 > 1) {\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  *Value = (BOOLEAN)Value64;\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Get next tcg uid info.\r
+\r
+  @param    ParseStruct    Input parse structure.\r
+  @param    Uid            Get the uid info.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextTcgUid(\r
+  TCG_PARSE_STRUCT         *ParseStruct,\r
+  TCG_UID                  *Uid\r
+  )\r
+{\r
+  TCG_TOKEN Tok;\r
+  UINT32 Length;\r
+  const UINT8* ByteSeq;\r
+\r
+  NULL_CHECK(Uid);\r
+\r
+  ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));\r
+  ByteSeq = TcgGetTokenByteSequence(&Tok, &Length);\r
+\r
+  if (Length != sizeof(TCG_UID)) {\r
+    DEBUG ((DEBUG_INFO, "Token Length %u != TCG_UID Size %u\n", Length, (UINT32)sizeof(TCG_UID)));\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  CopyMem(Uid, ByteSeq, sizeof(TCG_UID));\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Get next byte sequence.\r
+\r
+  @param    ParseStruct     Input parse structure.\r
+  @param    Data            return the data.\r
+  @param    Length          return the length.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextByteSequence(\r
+  TCG_PARSE_STRUCT      *ParseStruct,\r
+  const VOID            **Data,\r
+  UINT32                *Length\r
+  )\r
+{\r
+  TCG_TOKEN Tok;\r
+  const UINT8* Bs;\r
+\r
+  ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));\r
+  Bs = TcgGetTokenByteSequence(&Tok, Length);\r
+\r
+  if (Bs == NULL) {\r
+    return TcgResultFailure;\r
+  }\r
+  *Data = Bs;\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Get next token Type.\r
+\r
+  @param    ParseStruct    Input parse structure.\r
+  @param    Type           Input the type need to check.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextTokenType(\r
+  TCG_PARSE_STRUCT        *ParseStruct,\r
+  TCG_TOKEN_TYPE          Type\r
+  )\r
+{\r
+  TCG_TOKEN Tok;\r
+  ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));\r
+  if (Tok.Type != Type) {\r
+    DEBUG ((DEBUG_INFO, "expected Type %u, got Type %u\n", Type, Tok.Type));\r
+    return TcgResultFailure;\r
+  }\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Get next start list.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextStartList(\r
+  TCG_PARSE_STRUCT          *ParseStruct\r
+  )\r
+{\r
+  return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartList);\r
+}\r
+\r
+/**\r
+  Get next end list.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextEndList(\r
+  TCG_PARSE_STRUCT             *ParseStruct\r
+  )\r
+{\r
+  return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndList);\r
+}\r
+\r
+/**\r
+  Get next start name.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextStartName(\r
+  TCG_PARSE_STRUCT              *ParseStruct\r
+  )\r
+{\r
+  return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartName);\r
+}\r
+\r
+/**\r
+  Get next end name.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextEndName(\r
+  TCG_PARSE_STRUCT               *ParseStruct\r
+  )\r
+{\r
+  return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndName);\r
+}\r
+\r
+/**\r
+  Get next call.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextCall(\r
+  TCG_PARSE_STRUCT                   *ParseStruct\r
+  )\r
+{\r
+  return TcgGetNextTokenType(ParseStruct, TcgTokenTypeCall);\r
+}\r
+\r
+/**\r
+  Get next end data.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextEndOfData(\r
+  TCG_PARSE_STRUCT                    *ParseStruct\r
+  )\r
+{\r
+  return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndOfData);\r
+}\r
+\r
+/**\r
+  Get next end of session.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextEndOfSession(\r
+  TCG_PARSE_STRUCT                      *ParseStruct\r
+  )\r
+{\r
+  return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndOfSession);\r
+}\r
+\r
+/**\r
+  Get next start transaction.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextStartTransaction(\r
+  TCG_PARSE_STRUCT                        *ParseStruct\r
+  )\r
+{\r
+  return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartTransaction);\r
+}\r
+\r
+/**\r
+  Get next end transaction.\r
+\r
+  @param    ParseStruct   Input parse structure.\r
+\r
+  @retval   return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetNextEndTransaction(\r
+  TCG_PARSE_STRUCT                  *ParseStruct\r
+  )\r
+{\r
+  return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndTransaction);\r
+}\r
diff --git a/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCoreLib.inf b/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCoreLib.inf
new file mode 100644 (file)
index 0000000..a80cb00
--- /dev/null
@@ -0,0 +1,38 @@
+## @file\r
+#  This is a Tcg Storage core library.\r
+#\r
+#  This module is used to provide API used by Opal password solution.\r
+#\r
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+[Defines]\r
+  INF_VERSION                    = 0x00010017\r
+  BASE_NAME                      = TcgStorageCoreLib\r
+  FILE_GUID                      = ad63b09b-1fc9-4789-af0c-5af8a3fb1f9c\r
+  VERSION_STRING                 = 1.0\r
+  MODULE_TYPE                    = BASE\r
+  LIBRARY_CLASS                  = TcgStorageCoreLib|DXE_DRIVER DXE_CORE DXE_SMM_DRIVER\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64\r
+#\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[Sources]\r
+  TcgStorageCore.c\r
+  TcgStorageUtil.c\r
diff --git a/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageUtil.c b/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageUtil.c
new file mode 100644 (file)
index 0000000..30808cd
--- /dev/null
@@ -0,0 +1,907 @@
+/** @file\r
+  Provide functions to provide tcg storage core spec related functions.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Library/TcgStorageCoreLib.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+typedef struct {\r
+    UINT16                                FeatureCode;\r
+    TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER  *Feature;\r
+    UINTN                                 FeatureSize;\r
+} TCG_FIND_FEATURE_CTX;\r
+\r
+/**\r
+  Returns a human-readable string representing a method status return code.\r
+\r
+  @param[in]  MethodStatus   Method status to translate to a string\r
+\r
+\r
+  @retval   return the string info.\r
+**/\r
+CHAR8*\r
+EFIAPI\r
+TcgMethodStatusString(\r
+  UINT8 MethodStatus\r
+  )\r
+{\r
+  switch (MethodStatus) {\r
+    #define C(status) case TCG_METHOD_STATUS_CODE_ ## status: return #status\r
+            C(SUCCESS);\r
+            C(NOT_AUTHORIZED);\r
+            C(OBSOLETE);\r
+            C(SP_BUSY);\r
+            C(SP_FAILED);\r
+            C(SP_DISABLED);\r
+            C(SP_FROZEN);\r
+            C(NO_SESSIONS_AVAILABLE);\r
+            C(UNIQUENESS_CONFLICT);\r
+            C(INSUFFICIENT_SPACE);\r
+            C(INSUFFICIENT_ROWS);\r
+            C(INVALID_PARAMETER);\r
+            C(OBSOLETE2);\r
+            C(OBSOLETE3);\r
+            C(TPER_MALFUNCTION);\r
+            C(TRANSACTION_FAILURE);\r
+            C(RESPONSE_OVERFLOW);\r
+            C(AUTHORITY_LOCKED_OUT);\r
+            C(FAIL);\r
+    #undef C\r
+  }\r
+  return "unknown";\r
+}\r
+\r
+\r
+/**\r
+  adds call token and method Header (invoking id, and method id).\r
+\r
+  @param    CreateStruct             The input create structure.\r
+  @param    InvokingId               Invoking id.\r
+  @param    MethodId                 Method id.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartMethodCall(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  TCG_UID             InvokingId,\r
+  TCG_UID             MethodId\r
+  )\r
+{\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  if (CreateStruct->ComPacket == NULL ||\r
+      CreateStruct->CurPacket == NULL ||\r
+      CreateStruct->CurSubPacket == NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  ERROR_CHECK(TcgAddCall(CreateStruct));\r
+  ERROR_CHECK(TcgAddTcgUid(CreateStruct, InvokingId));\r
+  ERROR_CHECK(TcgAddTcgUid(CreateStruct, MethodId));\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Adds START LIST token.\r
+\r
+  @param    CreateStruct        The input create structure.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartParameters(\r
+  TCG_CREATE_STRUCT           *CreateStruct\r
+  )\r
+{\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  if (CreateStruct->ComPacket == NULL ||\r
+      CreateStruct->CurPacket == NULL ||\r
+      CreateStruct->CurSubPacket == NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  return TcgAddStartList(CreateStruct);\r
+}\r
+\r
+/**\r
+  Adds END LIST token.\r
+\r
+  @param    CreateStruct        The input create structure.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndParameters(\r
+  TCG_CREATE_STRUCT   *CreateStruct\r
+  )\r
+{\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  if (CreateStruct->ComPacket == NULL ||\r
+      CreateStruct->CurPacket == NULL ||\r
+      CreateStruct->CurSubPacket == NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  return TcgAddEndList(CreateStruct);\r
+}\r
+\r
+/**\r
+  Adds END Data token and method list.\r
+\r
+  @param    CreateStruct        The input create structure.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndMethodCall(\r
+  TCG_CREATE_STRUCT      *CreateStruct\r
+  )\r
+{\r
+  NULL_CHECK(CreateStruct);\r
+\r
+  if (CreateStruct->ComPacket == NULL ||\r
+      CreateStruct->CurPacket == NULL ||\r
+      CreateStruct->CurSubPacket == NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));\r
+    return (TcgResultFailureInvalidAction);\r
+  }\r
+\r
+  ERROR_CHECK(TcgAddEndOfData(CreateStruct));\r
+\r
+  ERROR_CHECK(TcgAddStartList(CreateStruct));\r
+  ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00));   // expected to complete properly\r
+  ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00));   // reserved\r
+  ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00));   // reserved\r
+  ERROR_CHECK(TcgAddEndList(CreateStruct));\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Retrieves the comID and Extended comID of the ComPacket in the Tcg response.\r
+  It is intended to be used to confirm the received Tcg response is intended for user that received it.\r
+\r
+  @param [in]        ParseStruct        Structure used to parse received TCG response.\r
+  @param [in/out]    ComId              comID retrieved from received ComPacket.\r
+  @param [in/out]    ComIdExtension     Extended comID retrieved from received ComPacket\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetComIds(\r
+  const TCG_PARSE_STRUCT     *ParseStruct,\r
+  UINT16                     *ComId,\r
+  UINT16                     *ComIdExtension\r
+  )\r
+{\r
+  NULL_CHECK(ParseStruct);\r
+  NULL_CHECK(ComId);\r
+  NULL_CHECK(ComIdExtension);\r
+\r
+  if (ParseStruct->ComPacket == NULL) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p\n", ParseStruct->ComPacket));\r
+    return TcgResultFailureInvalidAction;\r
+  }\r
+\r
+  *ComId = SwapBytes16(ParseStruct->ComPacket->ComIDBE);\r
+  *ComIdExtension = SwapBytes16(ParseStruct->ComPacket->ComIDExtensionBE);\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Checks if the ComIDs of the response match the expected values.\r
+\r
+  @param[in]   ParseStruct               Structure used to parse received TCG response\r
+  @param[in]   ExpectedComId             Expected comID\r
+  @param[in]   ExpectedComIdExtension    Expected extended comID\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgCheckComIds(\r
+  const TCG_PARSE_STRUCT     *ParseStruct,\r
+  UINT16                     ExpectedComId,\r
+  UINT16                     ExpectedComIdExtension\r
+  )\r
+{\r
+  UINT16 ParseComId;\r
+  UINT16 ParseComIdExtension;\r
+\r
+  ERROR_CHECK(TcgGetComIds(ParseStruct, &ParseComId, &ParseComIdExtension));\r
+  if (ParseComId != ExpectedComId || ParseComIdExtension != ExpectedComIdExtension) {\r
+    DEBUG ((DEBUG_INFO, "Com ID: Actual 0x%02X Expected 0x%02X\n", ParseComId, ExpectedComId));\r
+    DEBUG ((DEBUG_INFO, "Extended Com ID: 0x%02X Expected 0x%02X\n", ParseComIdExtension, ExpectedComIdExtension));\r
+    return TcgResultFailure;\r
+  }\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+ Returns the method status of the current subpacket.  Does not affect the current position\r
+ in the ComPacket.  In other words, it can be called whenever you have a valid SubPacket.\r
+\r
+ @param [in/out]  ParseStruct       Structure used to parse received TCG response\r
+ @param [in/out]  MethodStatus      Method status retrieved of the current SubPacket\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgGetMethodStatus(\r
+  const TCG_PARSE_STRUCT            *ParseStruct,\r
+  UINT8                             *MethodStatus\r
+  )\r
+{\r
+  TCG_PARSE_STRUCT TmpParseStruct;\r
+  TCG_TOKEN TcgToken;\r
+  UINT8 Reserved1, Reserved2;\r
+\r
+  NULL_CHECK(ParseStruct);\r
+  NULL_CHECK(MethodStatus);\r
+\r
+  if (ParseStruct->ComPacket == NULL ||\r
+      ParseStruct->CurPacket == NULL ||\r
+      ParseStruct->CurSubPacket == NULL\r
+     ) {\r
+    DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", ParseStruct->ComPacket, ParseStruct->CurPacket, ParseStruct->CurSubPacket));\r
+    return TcgResultFailureInvalidAction;\r
+  }\r
+\r
+  // duplicate ParseStruct, then don't need to "reset" location cur ptr\r
+  CopyMem (&TmpParseStruct, ParseStruct, sizeof(TCG_PARSE_STRUCT));\r
+\r
+  // method status list exists after the end method call in the subpacket\r
+  // skip tokens until ENDDATA is found\r
+  do {\r
+    ERROR_CHECK(TcgGetNextToken(&TmpParseStruct, &TcgToken));\r
+  } while (TcgToken.Type != TcgTokenTypeEndOfData);\r
+\r
+  // only reach here if enddata is found\r
+  // at this point, the curptr is pointing at method status list beginning\r
+  ERROR_CHECK(TcgGetNextStartList(&TmpParseStruct));\r
+  ERROR_CHECK(TcgGetNextUINT8(&TmpParseStruct, MethodStatus));\r
+  ERROR_CHECK(TcgGetNextUINT8(&TmpParseStruct, &Reserved1));\r
+  ERROR_CHECK(TcgGetNextUINT8(&TmpParseStruct, &Reserved2));\r
+  ERROR_CHECK(TcgGetNextEndList(&TmpParseStruct));\r
+\r
+  if (Reserved1 != 0) {\r
+    DEBUG ((DEBUG_INFO, "Method status reserved1 = 0x%02X (expected 0)\n", Reserved1));\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  if (Reserved2 != 0) {\r
+    DEBUG ((DEBUG_INFO, "Method status reserved2 = 0x%02X (expected 0)\n", Reserved1));\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Return the toke type string info.\r
+\r
+  @param    Type       Input the type info.\r
+\r
+  @retval   Return the string for this type.\r
+\r
+**/\r
+CHAR8*\r
+EFIAPI\r
+TcgTokenTypeString(\r
+  TCG_TOKEN_TYPE  Type\r
+  )\r
+{\r
+  switch (Type) {\r
+    case TcgTokenTypeReserved: return "Reserved";\r
+    case TcgTokenTypeTinyAtom: return "Tiny Atom";\r
+    case TcgTokenTypeShortAtom: return "Short Atom";\r
+    case TcgTokenTypeMediumAtom: return "Medium Atom";\r
+    case TcgTokenTypeLongAtom: return "Long Atom";\r
+    case TcgTokenTypeStartList: return "Start List";\r
+    case TcgTokenTypeEndList: return "End List";\r
+    case TcgTokenTypeStartName: return "Start Name";\r
+    case TcgTokenTypeEndName: return "End Name";\r
+    case TcgTokenTypeCall: return "Call";\r
+    case TcgTokenTypeEndOfData: return "End of Data";\r
+    case TcgTokenTypeEndOfSession: return "End of Session";\r
+    case TcgTokenTypeStartTransaction: return "Start Transaction";\r
+    case TcgTokenTypeEndTransaction: return "End Transaction";\r
+    case TcgTokenTypeEmptyAtom: return "Empty atom";\r
+  }\r
+  return "Unknown";\r
+}\r
+\r
+\r
+/**\r
+\r
+  Adds Start Session call to the data structure.  This creates the entire ComPacket structure and\r
+  returns the size of the entire compacket in the size parameter.\r
+\r
+  @param [in/out]    CreateStruct               Structure used to add the start session call\r
+  @param [in/out]    Size                       Describes the size of the entire ComPacket (header and payload). Filled out by function.\r
+  @param [in]        ComId                      ComID for the ComPacket\r
+  @param [in]        ComIdExtension             Extended ComID for the ComPacket\r
+  @param [in]        HostSessionId              Host Session ID\r
+  @param [in]        SpId                       Security Provider to start session with\r
+  @param [in]        Write                      Write option for start session.  TRUE = start session requests write access\r
+  @param [in]        HostChallengeLength        Length of the host challenge.  Length should be 0 if hostChallenge is NULL\r
+  @param [in]        HostChallenge              Host challenge for Host Signing Authority.  If NULL, then no Host Challenge shall be sent.\r
+  @param [in]        HostSigningAuthority       Host Signing Authority used for start session.  If NULL, then no Host Signing Authority shall be sent.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgCreateStartSession(\r
+  TCG_CREATE_STRUCT     *CreateStruct,\r
+  UINT32                *Size,\r
+  UINT16                ComId,\r
+  UINT16                ComIdExtension,\r
+  UINT32                HostSessionId,\r
+  TCG_UID               SpId,\r
+  BOOLEAN               Write,\r
+  UINT32                HostChallengeLength,\r
+  const VOID            *HostChallenge,\r
+  TCG_UID               HostSigningAuthority\r
+  )\r
+{\r
+  ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));\r
+  ERROR_CHECK(TcgStartPacket(CreateStruct, 0x0, 0x0, 0x0, 0x0, 0x0)) ;\r
+  ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));\r
+  ERROR_CHECK(TcgStartMethodCall(CreateStruct, TCG_UID_SMUID, TCG_UID_SM_START_SESSION));\r
+  ERROR_CHECK(TcgStartParameters(CreateStruct));\r
+  ERROR_CHECK(TcgAddUINT32(CreateStruct, HostSessionId));\r
+  ERROR_CHECK(TcgAddTcgUid(CreateStruct, SpId));\r
+  ERROR_CHECK(TcgAddBOOLEAN(CreateStruct, Write));\r
+\r
+  // optional parameters\r
+  if (HostChallenge != NULL && HostChallengeLength != 0) {\r
+    ERROR_CHECK(TcgAddStartName(CreateStruct));\r
+    ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x00));   //TODO Create Enum for Method Optional Parameters?\r
+    ERROR_CHECK(TcgAddByteSequence(CreateStruct, HostChallenge, HostChallengeLength, FALSE));\r
+    ERROR_CHECK(TcgAddEndName(CreateStruct));\r
+  }\r
+  // optional parameters\r
+  if (HostSigningAuthority != 0) {\r
+    ERROR_CHECK(TcgAddStartName(CreateStruct));\r
+    ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x03));   //TODO Create Enum for Method Optional Parameters?\r
+    ERROR_CHECK(TcgAddTcgUid(CreateStruct, HostSigningAuthority));\r
+    ERROR_CHECK(TcgAddEndName(CreateStruct));\r
+  }\r
+\r
+  ERROR_CHECK(TcgEndParameters(CreateStruct));\r
+  ERROR_CHECK(TcgEndMethodCall(CreateStruct));\r
+  ERROR_CHECK(TcgEndSubPacket(CreateStruct));\r
+  ERROR_CHECK(TcgEndPacket(CreateStruct));\r
+  ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+ Parses the Sync Session response contained in the parseStruct to retrieve Tper session ID.  If the Sync Session response\r
+ parameters do not match the comID, extended ComID and host session ID then a failure is returned.\r
+\r
+ @param[in/out]   ParseStruct          Structure used to parse received TCG response, contains Sync Session response.\r
+ @param[in]       ComId                Expected ComID that is compared to actual ComID of response\r
+ @param[in]       ComIdExtension       Expected Extended ComID that is compared to actual Extended ComID of response\r
+ @param[in]       HostSessionId        Expected Host Session ID that is compared to actual  Host Session ID of response\r
+ @param[in/out]   TperSessionId        Tper Session ID retrieved from the Sync Session response.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgParseSyncSession(\r
+  const TCG_PARSE_STRUCT  *ParseStruct,\r
+  UINT16                  ComId,\r
+  UINT16                  ComIdExtension,\r
+  UINT32                  HostSessionId,\r
+  UINT32                  *TperSessionId\r
+  )\r
+{\r
+  UINT8 MethodStatus;\r
+  TCG_PARSE_STRUCT TmpParseStruct;\r
+  UINT16 ParseComId;\r
+  UINT16 ParseExtComId;\r
+  TCG_UID InvokingUID;\r
+  TCG_UID MethodUID;\r
+  UINT32 RecvHostSessionId;\r
+\r
+  NULL_CHECK(ParseStruct);\r
+  NULL_CHECK(TperSessionId);\r
+\r
+  CopyMem (&TmpParseStruct, ParseStruct, sizeof(TCG_PARSE_STRUCT));\r
+\r
+  // verify method status is good\r
+  ERROR_CHECK(TcgGetMethodStatus(&TmpParseStruct, &MethodStatus));\r
+  METHOD_STATUS_ERROR_CHECK (MethodStatus, TcgResultFailure);\r
+\r
+  // verify comids\r
+  ERROR_CHECK(TcgGetComIds(&TmpParseStruct, &ParseComId, &ParseExtComId));\r
+\r
+  if ((ComId != ParseComId) || (ComIdExtension != ParseExtComId)) {\r
+    DEBUG ((DEBUG_INFO, "unmatched comid (exp: 0x%X recv: 0x%X) or comid extension (exp: 0x%X recv: 0x%X)\n", ComId, ParseComId, ComIdExtension, ParseExtComId));\r
+    return TcgResultFailure;\r
+  }\r
+  ERROR_CHECK(TcgGetNextCall(&TmpParseStruct));\r
+  ERROR_CHECK(TcgGetNextTcgUid(&TmpParseStruct, &InvokingUID));\r
+  ERROR_CHECK(TcgGetNextTcgUid(&TmpParseStruct, &MethodUID));\r
+  ERROR_CHECK(TcgGetNextStartList(&TmpParseStruct));\r
+  ERROR_CHECK(TcgGetNextUINT32(&TmpParseStruct, &RecvHostSessionId));\r
+  ERROR_CHECK(TcgGetNextUINT32(&TmpParseStruct, TperSessionId));\r
+  ERROR_CHECK(TcgGetNextEndList(&TmpParseStruct));\r
+  ERROR_CHECK(TcgGetNextEndOfData(&TmpParseStruct));\r
+\r
+  if (InvokingUID != TCG_UID_SMUID) {\r
+    DEBUG ((DEBUG_INFO, "Invoking UID did not match UID_SMUID\n"));\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  if (MethodUID != TCG_UID_SM_SYNC_SESSION) {\r
+    DEBUG ((DEBUG_INFO, "Method UID did not match UID_SM_SYNC_SESSION\n"));\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  if (HostSessionId != RecvHostSessionId) {\r
+    DEBUG ((DEBUG_INFO, "unmatched HostSessionId (exp: 0x%X recv: 0x%X)\n", HostSessionId, RecvHostSessionId));\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+\r
+  Creates ComPacket with EndSession.\r
+  This assumes a start session has already been opened.\r
+\r
+  @param  [in/out]    CreateStruct        Structure used to add Endsession\r
+  @param  [in/out]    Size                Describes the size of the entire ComPacket (header and payload). Filled out by function.\r
+  @param  [in]        ComId               ComID for the ComPacket\r
+  @param  [in]        ComIdExtension      Extended ComID for the ComPacket\r
+  @param  [in]        HostSessionId         Host Session ID for the Packet\r
+  @param  [in]        TpSessionId         Tper Session ID for the Packet\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgCreateEndSession(\r
+  TCG_CREATE_STRUCT   *CreateStruct,\r
+  UINT32              *Size,\r
+  UINT16              ComId,\r
+  UINT16              ComIdExtension,\r
+  UINT32              HostSessionId,\r
+  UINT32              TpSessionId\r
+  )\r
+{\r
+  ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));\r
+  ERROR_CHECK(TcgStartPacket(CreateStruct, TpSessionId, HostSessionId, 0x0, 0x0, 0x0));\r
+  ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));\r
+  ERROR_CHECK(TcgAddEndOfSession(CreateStruct));\r
+  ERROR_CHECK(TcgEndSubPacket(CreateStruct));\r
+  ERROR_CHECK(TcgEndPacket(CreateStruct));\r
+  ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Set start method.\r
+\r
+  @param     CreateStruct   Input create structure.\r
+  @param     Row            Input the row info.\r
+  @param     ColumnNumber   the column info.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgStartMethodSet(\r
+  TCG_CREATE_STRUCT        *CreateStruct,\r
+  TCG_UID                  Row,\r
+  UINT32                   ColumnNumber\r
+  )\r
+{\r
+  ERROR_CHECK(TcgStartMethodCall(CreateStruct, Row, TCG_UID_METHOD_SET));\r
+  ERROR_CHECK(TcgStartParameters(CreateStruct));\r
+  ERROR_CHECK(TcgAddStartName(CreateStruct));\r
+  ERROR_CHECK(TcgAddUINT8(CreateStruct, 0x01)); // "Values"\r
+  ERROR_CHECK(TcgAddStartList(CreateStruct));\r
+  ERROR_CHECK(TcgAddStartName(CreateStruct));\r
+  ERROR_CHECK(TcgAddUINT32(CreateStruct, ColumnNumber));\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Set end method.\r
+\r
+  @param     CreateStruct  Input create structure.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgEndMethodSet(\r
+  TCG_CREATE_STRUCT        *CreateStruct\r
+  )\r
+{\r
+  ERROR_CHECK(TcgAddEndName(CreateStruct));\r
+  ERROR_CHECK(TcgAddEndList(CreateStruct));\r
+  ERROR_CHECK(TcgAddEndName(CreateStruct));\r
+  ERROR_CHECK(TcgEndParameters(CreateStruct));\r
+  ERROR_CHECK(TcgEndMethodCall(CreateStruct));\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Creates ComPacket with a Method call that sets the PIN column for the row specified.\r
+  This assumes a start session has already been opened with the desired SP.\r
+\r
+  @param [in/out]   CreateStruct           Structure used to add method call.\r
+  @param [in/out]   Size                   Describes the size of the entire ComPacket (header and payload). Filled out by function.\r
+  @param [in]       ComId                  ComID for the ComPacket\r
+  @param [in]       ComIdExtension         Extended ComID for the ComPacket\r
+  @param [in]       TperSession            Tper Session ID for the Packet\r
+  @param [in]       HostSession            Host Session ID for the Packet\r
+  @param [in]       SidRow                 UID of row of current SP to set PIN column\r
+  @param [in]       Password               value of PIN to set\r
+  @param [in]       PasswordSize           Size of PIN\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgCreateSetCPin(\r
+  TCG_CREATE_STRUCT       *CreateStruct,\r
+  UINT32                  *Size,\r
+  UINT16                  ComId,\r
+  UINT16                  ComIdExtension,\r
+  UINT32                  TperSession,\r
+  UINT32                  HostSession,\r
+  TCG_UID                 SidRow,\r
+  const VOID              *Password,\r
+  UINT32                  PasswordSize\r
+  )\r
+{\r
+  // set new SID Password\r
+  ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));\r
+  ERROR_CHECK(TcgStartPacket(CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));\r
+  ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));\r
+  ERROR_CHECK(TcgStartMethodSet(CreateStruct, SidRow, 0x03)); // "PIN"\r
+  ERROR_CHECK(TcgAddByteSequence(CreateStruct, Password, PasswordSize, FALSE));\r
+  ERROR_CHECK(TcgEndMethodSet(CreateStruct));\r
+  ERROR_CHECK(TcgEndSubPacket(CreateStruct));\r
+  ERROR_CHECK(TcgEndPacket(CreateStruct));\r
+  ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+ Creates ComPacket with a Method call that sets the "Enabled" column for the row specified using the value specified.\r
+ This assumes a start session has already been opened with the desired SP.\r
+\r
+ @param [in/out]  CreateStruct          Structure used to add method call\r
+ @param [in/out]  Size                  Describes the size of the entire ComPacket (header and payload). Filled out by function.\r
+ @param [in]      ComId                 ComID for the ComPacket\r
+ @param [in]      ComIdExtension        Extended ComID for the ComPacket\r
+ @param [in]      TperSession           Tper Session ID for the Packet\r
+ @param [in]      HostSession           Host Session ID for the Packet\r
+ @param [in]      AuthorityUid          Authority UID to modify the "Enabled" column for\r
+ @param [in]      Enabled               Value to set the "Enabled" column to\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgSetAuthorityEnabled(\r
+  TCG_CREATE_STRUCT           *CreateStruct,\r
+  UINT32                      *Size,\r
+  UINT16                      ComId,\r
+  UINT16                      ComIdExtension,\r
+  UINT32                      TperSession,\r
+  UINT32                      HostSession,\r
+  TCG_UID                     AuthorityUid,\r
+  BOOLEAN                     Enabled\r
+  )\r
+{\r
+  ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));\r
+  ERROR_CHECK(TcgStartPacket(CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));\r
+  ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));\r
+  ERROR_CHECK(TcgStartMethodSet(CreateStruct, AuthorityUid, 0x05)); // "Enabled"\r
+  ERROR_CHECK(TcgAddBOOLEAN(CreateStruct, Enabled));\r
+  ERROR_CHECK(TcgEndMethodSet(CreateStruct));\r
+  ERROR_CHECK(TcgEndSubPacket(CreateStruct));\r
+  ERROR_CHECK(TcgEndPacket(CreateStruct));\r
+  ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Create set ace.\r
+\r
+  @param     CreateStruct      Input create structure.\r
+  @param     Size              size info.\r
+  @param     ComId             ComId info.\r
+  @param     ComIdExtension    ComId extension info.\r
+  @param     TperSession       Tper session data.\r
+  @param     HostSession       Host session data.\r
+  @param     AceRow            Ace row info.\r
+  @param     Authority1        Authority 1 info.\r
+  @param     LogicalOperator   Logiccal operator info.\r
+  @param     Authority2        Authority 2 info.\r
+\r
+  @retval    Return the action result.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+TcgCreateSetAce(\r
+  TCG_CREATE_STRUCT        *CreateStruct,\r
+  UINT32                   *Size,\r
+  UINT16                   ComId,\r
+  UINT16                   ComIdExtension,\r
+  UINT32                   TperSession,\r
+  UINT32                   HostSession,\r
+  TCG_UID                  AceRow,\r
+  TCG_UID                  Authority1,\r
+  BOOLEAN                  LogicalOperator,\r
+  TCG_UID                  Authority2\r
+  )\r
+{\r
+  UINT8 HalfUidAuthorityObjectRef[4];\r
+  UINT8 HalfUidBooleanAce[4];\r
+\r
+  HalfUidAuthorityObjectRef[0] = 0x0;\r
+  HalfUidAuthorityObjectRef[1] = 0x0;\r
+  HalfUidAuthorityObjectRef[2] = 0xC;\r
+  HalfUidAuthorityObjectRef[3] = 0x5;\r
+\r
+  HalfUidBooleanAce[0] = 0x0;\r
+  HalfUidBooleanAce[1] = 0x0;\r
+  HalfUidBooleanAce[2] = 0x4;\r
+  HalfUidBooleanAce[3] = 0xE;\r
+\r
+  ERROR_CHECK(TcgStartComPacket(CreateStruct, ComId, ComIdExtension));\r
+  ERROR_CHECK(TcgStartPacket(CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));\r
+  ERROR_CHECK(TcgStartSubPacket(CreateStruct, 0x0));\r
+  ERROR_CHECK(TcgStartMethodSet(CreateStruct, AceRow, 0x03));     // "BooleanExpr"\r
+  ERROR_CHECK(TcgAddStartList(CreateStruct));\r
+  ERROR_CHECK(TcgAddStartName(CreateStruct));\r
+  ERROR_CHECK(TcgAddByteSequence(CreateStruct, HalfUidAuthorityObjectRef, sizeof(HalfUidAuthorityObjectRef), FALSE));\r
+  ERROR_CHECK(TcgAddTcgUid(CreateStruct, Authority1));\r
+  ERROR_CHECK(TcgAddEndName(CreateStruct));\r
+  ERROR_CHECK(TcgAddStartName(CreateStruct));\r
+  ERROR_CHECK(TcgAddByteSequence(CreateStruct, HalfUidAuthorityObjectRef, sizeof(HalfUidAuthorityObjectRef), FALSE));\r
+  ERROR_CHECK(TcgAddTcgUid(CreateStruct, Authority2));\r
+  ERROR_CHECK(TcgAddEndName(CreateStruct));\r
+\r
+  ERROR_CHECK(TcgAddStartName(CreateStruct));\r
+  ERROR_CHECK(TcgAddByteSequence(CreateStruct, HalfUidBooleanAce, sizeof(HalfUidBooleanAce), FALSE));\r
+  ERROR_CHECK(TcgAddBOOLEAN(CreateStruct, LogicalOperator));\r
+  ERROR_CHECK(TcgAddEndName(CreateStruct));\r
+  ERROR_CHECK(TcgAddEndList(CreateStruct));\r
+  ERROR_CHECK(TcgEndMethodSet(CreateStruct));\r
+  ERROR_CHECK(TcgEndSubPacket(CreateStruct));\r
+  ERROR_CHECK(TcgEndPacket(CreateStruct));\r
+  ERROR_CHECK(TcgEndComPacket(CreateStruct, Size));\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Enum level 0 discovery.\r
+\r
+  @param     DiscoveryHeader   Discovery header.\r
+  @param     Callback          Callback function.\r
+  @param     Context           The context for the function.\r
+\r
+  @retval    return true if the callback return TRUE, else return FALSE.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TcgEnumLevel0Discovery(\r
+  const TCG_LEVEL0_DISCOVERY_HEADER  *DiscoveryHeader,\r
+  TCG_LEVEL0_ENUM_CALLBACK           Callback,\r
+  VOID                               *Context\r
+  )\r
+{\r
+  UINT32                                  BytesLeft;\r
+  const UINT8                             *DiscoveryBufferPtr;\r
+  UINT32                                  FeatLength;\r
+  TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER    *Feat;\r
+\r
+  //\r
+  // Total bytes including descriptors but not including the Length field\r
+  //\r
+  BytesLeft = SwapBytes32(DiscoveryHeader->LengthBE);\r
+\r
+  //\r
+  // If discovery Header is not valid, exit\r
+  //\r
+  if (BytesLeft == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Subtract the Length of the Header, except the Length field, which is not included\r
+  //\r
+  BytesLeft -= (sizeof(TCG_LEVEL0_DISCOVERY_HEADER) - sizeof(DiscoveryHeader->LengthBE));\r
+\r
+  //\r
+  // Move ptr to first descriptor\r
+  //\r
+  DiscoveryBufferPtr = (const UINT8*)DiscoveryHeader + sizeof(TCG_LEVEL0_DISCOVERY_HEADER);\r
+\r
+  while (BytesLeft > sizeof(TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER)) {\r
+    //\r
+    // Pointer to beginning of descriptor (including common Header)\r
+    //\r
+    Feat = (TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER*)DiscoveryBufferPtr;\r
+\r
+    FeatLength = Feat->Length + sizeof(TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER);\r
+\r
+    //\r
+    // Not enough bytes left for Feature descriptor\r
+    //\r
+    if (BytesLeft < FeatLength) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Report the Feature to the callback\r
+    //\r
+    if (Callback(DiscoveryHeader, Feat, FeatLength, Context)) {\r
+      return TRUE;\r
+    }\r
+\r
+    //\r
+    // Descriptor Length only describes Data after common Header\r
+    //\r
+    BytesLeft -= FeatLength;\r
+    DiscoveryBufferPtr += FeatLength;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  The callback function for Get Feature function.\r
+\r
+  @param     DiscoveryHeader   Input discovery header.\r
+  @param     Feature           Input Feature.\r
+  @param     FeatureSize       Input Feature size.\r
+  @param     Context           The context.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TcgFindFeatureCallback(\r
+  const TCG_LEVEL0_DISCOVERY_HEADER           *DiscoveryHeader,\r
+  TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER        *Feature,\r
+  UINTN                                       FeatureSize,\r
+  VOID                                        *Context\r
+  )\r
+{\r
+  TCG_FIND_FEATURE_CTX* FindCtx;\r
+\r
+  FindCtx = (TCG_FIND_FEATURE_CTX*)Context;\r
+  if ( SwapBytes16( Feature->FeatureCode_BE ) == FindCtx->FeatureCode ) {\r
+    FindCtx->Feature = Feature;\r
+    FindCtx->FeatureSize = FeatureSize;\r
+    return TRUE; // done enumerating features\r
+  }\r
+  return FALSE; // continue enumerating\r
+}\r
+\r
+/**\r
+  Get Feature code from the header.\r
+\r
+  @param     DiscoveryHeader    The discovery header.\r
+  @param     FeatureCode        reutrn the Feature code.\r
+  @param     FeatureSize        return the Feature size.\r
+\r
+  @retval    return the Feature code data.\r
+**/\r
+TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER*\r
+EFIAPI\r
+TcgGetFeature(\r
+  const TCG_LEVEL0_DISCOVERY_HEADER  *DiscoveryHeader,\r
+  UINT16                             FeatureCode,\r
+  UINTN                              *FeatureSize\r
+  )\r
+{\r
+  TCG_FIND_FEATURE_CTX FindCtx;\r
+\r
+  FindCtx.FeatureCode = FeatureCode;\r
+  FindCtx.Feature = NULL;\r
+  FindCtx.FeatureSize = 0;\r
+\r
+  TcgEnumLevel0Discovery(DiscoveryHeader, TcgFindFeatureCallback, &FindCtx);\r
+  if (FeatureSize != NULL) {\r
+    *FeatureSize = FindCtx.FeatureSize;\r
+  }\r
+  return FindCtx.Feature;\r
+}\r
+\r
+/**\r
+  Determines if the protocol provided is part of the provided supported protocol list.\r
+\r
+  @param[in]  ProtocolList     Supported protocol list to investigate\r
+  @param[in]  Protocol         Protocol value to determine if supported\r
+\r
+  @return TRUE = protocol is supported, FALSE = protocol is not supported\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TcgIsProtocolSupported(\r
+  const TCG_SUPPORTED_SECURITY_PROTOCOLS   *ProtocolList,\r
+  UINT16                                   Protocol\r
+  )\r
+{\r
+  UINT16 Index;\r
+  UINT16 ListLength;\r
+\r
+  ListLength = SwapBytes16(ProtocolList->ListLength_BE);\r
+\r
+  if (ListLength > sizeof(ProtocolList->List)) {\r
+    DEBUG ((DEBUG_INFO, "WARNING: list Length is larger than max allowed Value; truncating\n"));\r
+    ListLength = sizeof(ProtocolList->List);\r
+  }\r
+\r
+  for (Index = 0; Index < ListLength; Index++) {\r
+    if (ProtocolList->List[Index] == Protocol) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Check whether lock or not.\r
+\r
+  @param     Discovery\r
+\r
+  @retval    TURE if lock, FALSE if not lock.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TcgIsLocked(\r
+  const TCG_LEVEL0_DISCOVERY_HEADER         *Discovery\r
+  )\r
+{\r
+  UINTN Size;\r
+  TCG_LOCKING_FEATURE_DESCRIPTOR     *LockDescriptor;\r
+\r
+  Size = 0;\r
+  LockDescriptor =(TCG_LOCKING_FEATURE_DESCRIPTOR*) TcgGetFeature (Discovery, TCG_FEATURE_LOCKING, &Size);\r
+\r
+  if (LockDescriptor != NULL && Size >= sizeof(*LockDescriptor)) {\r
+    DEBUG ((DEBUG_INFO, "locked: %d\n", LockDescriptor->Locked));\r
+    return LockDescriptor->Locked;\r
+  }\r
+\r
+  //\r
+  // Descriptor was not found\r
+  //\r
+  return FALSE;\r
+}\r