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>
--- /dev/null
+/** @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
--- /dev/null
+/** @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
--- /dev/null
+## @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
--- /dev/null
+/** @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