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