diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCore.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCore.c | 1646 |
1 files changed, 1646 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCore.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCore.c new file mode 100644 index 00000000..8f759312 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCore.c @@ -0,0 +1,1646 @@ +/** @file + Provide functions to provide tcg storage core spec related functions. + +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Library/TcgStorageCoreLib.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +//#include <Library/PrintLib.h> + +/** + Required to be called before calling any other Tcg functions with the TCG_CREATE_STRUCT. + Initializes the packet variables to NULL. Additionally, the buffer will be memset. + + @param [in/out] CreateStruct Structure to initialize + @param [in] Buffer Buffer allocated by client of library. It will contain the Tcg encoded packet. This cannot be null. + @param [in] BufferSize Size of buffer provided. It cannot be 0. + + @retval Return the action result. +**/ +TCG_RESULT +EFIAPI +TcgInitTcgCreateStruct( + TCG_CREATE_STRUCT *CreateStruct, + VOID *Buffer, + UINT32 BufferSize + ) +{ + NULL_CHECK(CreateStruct); + NULL_CHECK(Buffer); + + if (BufferSize == 0) { + DEBUG ((DEBUG_INFO, "BufferSize=0\n")); + return (TcgResultFailureZeroSize); + } + + ZeroMem(Buffer, BufferSize); + CreateStruct->BufferSize = BufferSize; + CreateStruct->Buffer = Buffer; + CreateStruct->ComPacket = NULL; + CreateStruct->CurPacket = NULL; + CreateStruct->CurSubPacket = NULL; + + return (TcgResultSuccess); +} + +/** + + Encodes the ComPacket header to the data structure. + + @param[in/out] CreateStruct Structure to initialize + @param[in] ComId ComID of the Tcg ComPacket. + @param[in] ComIdExtension ComID Extension of the Tcg ComPacket. + +**/ +TCG_RESULT +EFIAPI +TcgStartComPacket( + TCG_CREATE_STRUCT *CreateStruct, + UINT16 ComId, + UINT16 ComIdExtension + ) +{ + NULL_CHECK(CreateStruct); + + if (CreateStruct->ComPacket != NULL || + CreateStruct->CurPacket != NULL || + CreateStruct->CurSubPacket != NULL + ) { + DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, + CreateStruct->CurSubPacket)); + return (TcgResultFailureInvalidAction); + } + + if (sizeof(TCG_COM_PACKET) > CreateStruct->BufferSize) { + DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize)); + return (TcgResultFailureBufferTooSmall); + } + + CreateStruct->ComPacket = (TCG_COM_PACKET*)CreateStruct->Buffer; + CreateStruct->ComPacket->ComIDBE = SwapBytes16(ComId); + CreateStruct->ComPacket->ComIDExtensionBE = SwapBytes16(ComIdExtension); + + return (TcgResultSuccess); +} + +/** + + Starts a new ComPacket in the Data structure. + + @param [in/out] CreateStruct Structure used to add Tcg Packet + @param[in] Tsn Packet Tper session number + @param[in] Hsn Packet Host session number + @param[in] SeqNumber Packet Sequence Number + @param[in] AckType Packet Acknowledge Type + @param[in] Ack Packet Acknowledge + +**/ +TCG_RESULT +EFIAPI +TcgStartPacket( + TCG_CREATE_STRUCT *CreateStruct, + UINT32 Tsn, + UINT32 Hsn, + UINT32 SeqNumber, + UINT16 AckType, + UINT32 Ack + ) +{ + UINT32 AddedSize; + NULL_CHECK(CreateStruct); + + AddedSize = 0; + + if (CreateStruct->ComPacket == NULL || + CreateStruct->CurPacket != NULL || + CreateStruct->CurSubPacket != NULL + ) { + DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket)); + return (TcgResultFailureInvalidAction); + } + + // update TCG_COM_PACKET and packet lengths + AddedSize = sizeof(TCG_PACKET); + + if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) { + DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize)); + return (TcgResultFailureBufferTooSmall); + } + + CreateStruct->CurPacket = (TCG_PACKET*)(CreateStruct->ComPacket->Payload + SwapBytes32(CreateStruct->ComPacket->LengthBE)); + + CreateStruct->CurPacket->TperSessionNumberBE = SwapBytes32( Tsn ); + CreateStruct->CurPacket->HostSessionNumberBE = SwapBytes32( Hsn ); + CreateStruct->CurPacket->SequenceNumberBE = SwapBytes32( SeqNumber ); + CreateStruct->CurPacket->AckTypeBE = SwapBytes16( AckType ); + CreateStruct->CurPacket->AcknowledgementBE = SwapBytes32( Ack ); + + CreateStruct->CurPacket->LengthBE = 0; + + // update TCG_COM_PACKET Length for next pointer + CreateStruct->ComPacket->LengthBE = SwapBytes32( SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize ); + + return (TcgResultSuccess); +} + +/** + + Starts a new SubPacket in the Data structure. + + @param[in/out] CreateStruct Structure used to start Tcg SubPacket + @param[in] Kind SubPacket kind + +**/ +TCG_RESULT +EFIAPI +TcgStartSubPacket( + TCG_CREATE_STRUCT *CreateStruct, + UINT16 Kind + ) +{ + UINT32 AddedSize; + + NULL_CHECK(CreateStruct); + + AddedSize = 0; + + if (CreateStruct->ComPacket == NULL || + CreateStruct->CurPacket == NULL || + CreateStruct->CurSubPacket != NULL + ) { + DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket)); + return (TcgResultFailureInvalidAction); + } + + AddedSize = sizeof(TCG_SUB_PACKET); + + if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) { + DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize)); + return (TcgResultFailureBufferTooSmall); + } + + CreateStruct->CurSubPacket = (TCG_SUB_PACKET*)(CreateStruct->CurPacket->Payload + SwapBytes32(CreateStruct->CurPacket->LengthBE)); + CreateStruct->CurSubPacket->KindBE = SwapBytes16(Kind); + + // update lengths + CreateStruct->CurSubPacket->LengthBE = 0; + + // update TCG_COM_PACKET and packet lengths + CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize); + CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + AddedSize); + + return (TcgResultSuccess); +} + +/** + + Ends the current SubPacket in the Data structure. This function will also perform the 4-byte padding + required for Subpackets. + + @param[in/out] CreateStruct Structure used to end the current Tcg SubPacket + +**/ +TCG_RESULT +EFIAPI +TcgEndSubPacket( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + UINT32 PadSize; + + NULL_CHECK(CreateStruct); + + PadSize = 0; + + if (CreateStruct->ComPacket == NULL || + CreateStruct->CurPacket == NULL || + CreateStruct->CurSubPacket == NULL + ) { + DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket)); + return (TcgResultFailureInvalidAction); + } + + // align to 4-byte boundaries, so shift padding + // pad Size does not apply to subpacket Length + PadSize = TCG_SUBPACKET_ALIGNMENT - (SwapBytes32(CreateStruct->CurSubPacket->LengthBE) & (TCG_SUBPACKET_ALIGNMENT - 1)); + + if (PadSize == TCG_SUBPACKET_ALIGNMENT) { + PadSize = 0; + } + + if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + PadSize) > CreateStruct->BufferSize) { + DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize)); + return (TcgResultFailureBufferTooSmall); + } + + CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + PadSize); + CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + PadSize); + + CreateStruct->CurSubPacket = NULL; + + return (TcgResultSuccess); +} + +/** + + Ends the current Packet in the Data structure. + + @param[in/out] CreateStruct Structure used to end the current Tcg Packet + +**/ +TCG_RESULT +EFIAPI +TcgEndPacket( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + NULL_CHECK(CreateStruct); + + if (CreateStruct->ComPacket == NULL || + CreateStruct->CurPacket == NULL || + CreateStruct->CurSubPacket != NULL + ) { + DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket)); + return (TcgResultFailureInvalidAction); + } + + CreateStruct->CurPacket = NULL; + + return (TcgResultSuccess); +} + +/** + + Ends the ComPacket in the Data structure and ret + + @param [in/out] CreateStruct Structure used to end the Tcg ComPacket + @param [in/out] Size Describes the Size of the entire ComPacket (Header and payload). Filled out by function. + +**/ +TCG_RESULT +EFIAPI +TcgEndComPacket( + TCG_CREATE_STRUCT *CreateStruct, + UINT32 *Size + ) +{ + NULL_CHECK(CreateStruct); + NULL_CHECK(Size); + + if (CreateStruct->ComPacket == NULL || + CreateStruct->CurPacket != NULL || + CreateStruct->CurSubPacket != NULL + ) { + DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket)); + return (TcgResultFailureInvalidAction); + } + + *Size = SwapBytes32(CreateStruct->ComPacket->LengthBE) + sizeof(*CreateStruct->ComPacket); + CreateStruct->ComPacket = NULL; + + return (TcgResultSuccess); +} + +/** + Adds raw Data with optional Header + + @param CreateStruct The create structure. + @param Header The header structure. + @param HeaderSize The header size. + @param Data The data need to add. + @param DataSize The data size. + @param ByteSwapData Whether byte or swap data. + +**/ +TCG_RESULT +TcgAddRawTokenData( + TCG_CREATE_STRUCT *CreateStruct, + const VOID *Header, + UINT8 HeaderSize, + const VOID *Data, + UINT32 DataSize, + BOOLEAN ByteSwapData + ) +{ + UINT32 AddedSize; + UINT8* Dest; + const UINT8* DataBytes; + UINT32 Index; + + AddedSize = 0; + Index = 0; + Dest = NULL; + + NULL_CHECK(CreateStruct); + + if ((HeaderSize != 0 && Header == NULL) || + (DataSize != 0 && Data == NULL) + ) { + DEBUG ((DEBUG_INFO, "HeaderSize=0x%X Header=%p DataSize=0x%X Data=%p\n", HeaderSize, Header, DataSize, Data)); + return (TcgResultFailureNullPointer); + } + + if (CreateStruct->ComPacket == NULL || + CreateStruct->CurPacket == NULL || + CreateStruct->CurSubPacket == NULL + ) { + DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket)); + return (TcgResultFailureInvalidAction); + } + + // verify there is enough Buffer Size + AddedSize = HeaderSize + DataSize; + if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) { + return (TcgResultFailureBufferTooSmall); + } + + // Get a pointer to where the new bytes should go + Dest = CreateStruct->ComPacket->Payload + SwapBytes32(CreateStruct->ComPacket->LengthBE); + + switch (HeaderSize) { + case sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM): + case sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM): + case sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM): + CopyMem(Dest, Header, HeaderSize); + Dest += HeaderSize; + case 0: // no Header is valid + break; + // invalid Header Size + default: + DEBUG ((DEBUG_INFO, "unsupported HeaderSize=%u\n", HeaderSize)); + return TcgResultFailure; + } + + // copy the Data bytes + if (ByteSwapData) { + DataBytes = (const UINT8*)Data; + for (Index = 0; Index < DataSize; Index++) { + Dest[Index] = DataBytes[DataSize - 1 - Index]; + } + } else { + CopyMem(Dest, Data, DataSize); + } + + // Update all the packet sizes + CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize); + CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + AddedSize); + CreateStruct->CurSubPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurSubPacket->LengthBE) + AddedSize); + + return (TcgResultSuccess); +} + +/** + + Adds a single raw token byte to the Data structure. + + @param[in/out] CreateStruct Structure used to add the byte + @param[in] Byte Byte to add + +**/ +TCG_RESULT +EFIAPI +TcgAddRawByte( + TCG_CREATE_STRUCT *CreateStruct, + UINT8 Byte + ) +{ + return TcgAddRawTokenData(CreateStruct, NULL, 0, &Byte, 1, FALSE); +} + + +/** + simple tokens - atoms: tiny, short, medium, long and empty atoms. + tiny atom can be a signed or unsigned integer. + short, medium, long can be a signed or unsigned integer OR a complete or non-final byte sequence. + + @param CreateStruct The create structure. + @param Data The data need to add. + @param DataSize The data size. + @param ByteOrInt, Data format is byte or int. + @param SignOrCont sign or cont. + + +**/ +TCG_RESULT +TcgAddAtom( + TCG_CREATE_STRUCT *CreateStruct, + const VOID *Data, + UINT32 DataSize, + UINT8 ByteOrInt, + UINT8 SignOrCont + ) +{ + const UINT8* DataBytes; + TCG_SIMPLE_TOKEN_TINY_ATOM TinyAtom; + TCG_SIMPLE_TOKEN_SHORT_ATOM ShortAtom; + TCG_SIMPLE_TOKEN_MEDIUM_ATOM MediumAtom; + TCG_SIMPLE_TOKEN_LONG_ATOM LongAtom; + + NULL_CHECK(CreateStruct); + + if (DataSize == 0) { + if (ByteOrInt == TCG_ATOM_TYPE_INTEGER) { + DEBUG ((DEBUG_INFO, "0-Size integer not allowed\n")); + return TcgResultFailure; + } + } else { + // if DataSize != 0, Data must be valid + NULL_CHECK(Data); + } + + // encode Data using the shortest possible atom + DataBytes = (const UINT8*)Data; + if ((DataSize == 1) && + (ByteOrInt == TCG_ATOM_TYPE_INTEGER) && + ((SignOrCont != 0 && ((TCG_TOKEN_TINYATOM_SIGNED_MIN_VALUE <= *(INT8*)Data) && (*(INT8*)Data <= TCG_TOKEN_TINYATOM_SIGNED_MAX_VALUE))) || + (SignOrCont == 0 && ((*DataBytes <= TCG_TOKEN_TINYATOM_UNSIGNED_MAX_VALUE)))) + ) { + TinyAtom.TinyAtomBits.IsZero = 0; + TinyAtom.TinyAtomBits.Sign = SignOrCont; + TinyAtom.TinyAtomBits.Data = *DataBytes & TCG_TOKEN_TINYATOM_UNSIGNED_MAX_VALUE; + return TcgAddRawTokenData(CreateStruct, NULL, 0, (UINT8*)&TinyAtom, sizeof(TCG_SIMPLE_TOKEN_TINY_ATOM), FALSE); + } + + if (DataSize <= TCG_TOKEN_SHORTATOM_MAX_BYTE_SIZE) { + ShortAtom.ShortAtomBits.IsOne = 1; + ShortAtom.ShortAtomBits.IsZero = 0; + ShortAtom.ShortAtomBits.ByteOrInt = ByteOrInt; + ShortAtom.ShortAtomBits.SignOrCont = SignOrCont; + ShortAtom.ShortAtomBits.Length = DataSize & 0x0F; + return TcgAddRawTokenData(CreateStruct, &ShortAtom, sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER); + } + + if (DataSize <= TCG_TOKEN_MEDIUMATOM_MAX_BYTE_SIZE) { + MediumAtom.MediumAtomBits.IsOne1 = 1; + MediumAtom.MediumAtomBits.IsOne2 = 1; + MediumAtom.MediumAtomBits.IsZero = 0; + MediumAtom.MediumAtomBits.ByteOrInt = ByteOrInt; + MediumAtom.MediumAtomBits.SignOrCont = SignOrCont; + MediumAtom.MediumAtomBits.LengthLow = DataSize & 0xFF; + MediumAtom.MediumAtomBits.LengthHigh = (DataSize >> TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) & TCG_MEDIUM_ATOM_LENGTH_HIGH_MASK; + return TcgAddRawTokenData(CreateStruct, &MediumAtom, sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER); + } + + LongAtom.LongAtomBits.IsOne1 = 1; + LongAtom.LongAtomBits.IsOne2 = 1; + LongAtom.LongAtomBits.IsOne3 = 1; + LongAtom.LongAtomBits.IsZero = 0; + LongAtom.LongAtomBits.ByteOrInt = ByteOrInt; + LongAtom.LongAtomBits.SignOrCont = SignOrCont; + LongAtom.LongAtomBits.LengthLow = DataSize & 0xFF; + LongAtom.LongAtomBits.LengthMid = (DataSize >> TCG_LONG_ATOM_LENGTH_MID_SHIFT) & 0xFF; + LongAtom.LongAtomBits.LengthHigh = (DataSize >> TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) & 0xFF; + return TcgAddRawTokenData(CreateStruct, &LongAtom, sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER); +} + +/** + + Adds the Data parameter as a byte sequence to the Data structure. + + @param[in/out] CreateStruct Structure used to add the byte sequence + @param[in] Data Byte sequence that will be encoded and copied into Data structure + @param[in] DataSize Length of Data provided + @param[in] Continued TRUE if byte sequence is continued or + FALSE if the Data contains the entire byte sequence to be encoded + +**/ +TCG_RESULT +EFIAPI +TcgAddByteSequence( + TCG_CREATE_STRUCT *CreateStruct, + const VOID *Data, + UINT32 DataSize, + BOOLEAN Continued + ) +{ + return TcgAddAtom(CreateStruct, Data, DataSize, TCG_ATOM_TYPE_BYTE, Continued ? 1 : 0); +} + +/** + + Adds an arbitrary-Length integer to the Data structure. + The integer will be encoded using the shortest possible atom. + + @param[in/out] CreateStruct Structure used to add the integer + @param[in] Data Integer in host byte order that will be encoded and copied into Data structure + @param[in] DataSize Length in bytes of the Data provided + @param[in] SignedInteger TRUE if the integer is signed or FALSE if the integer is unsigned + +**/ +TCG_RESULT +EFIAPI +TcgAddInteger( + TCG_CREATE_STRUCT *CreateStruct, + const VOID *Data, + UINT32 DataSize, + BOOLEAN SignedInteger + ) +{ + const UINT8* DataBytes; + UINT32 ActualDataSize; + BOOLEAN ValueIsNegative; + + NULL_CHECK(CreateStruct); + NULL_CHECK(Data); + + if (DataSize == 0) { + DEBUG ((DEBUG_INFO, "invalid DataSize=0\n")); + return TcgResultFailure; + } + + DataBytes = (const UINT8*)Data; + + // integer should be represented by smallest atom possible + // so calculate real Data Size + ValueIsNegative = SignedInteger && DataBytes[ DataSize - 1 ] & 0x80; + + // assumes native Data is little endian + // shorten Data to smallest byte representation + for (ActualDataSize = DataSize; ActualDataSize > 1; ActualDataSize--) { + // ignore sign extended FFs + if (ValueIsNegative && (DataBytes[ActualDataSize - 1] != 0xFF)) { + break; + } else if (!ValueIsNegative && (DataBytes[ActualDataSize - 1] != 0)) { + // ignore extended 00s + break; + } + } + + return TcgAddAtom(CreateStruct, Data, ActualDataSize, TCG_ATOM_TYPE_INTEGER, SignedInteger ? 1 : 0); +} + +/** + Adds an 8-bit unsigned integer to the Data structure. + + @param[in/out] CreateStruct Structure used to add the integer + @param[in] Value Integer Value to add + +**/ +TCG_RESULT +EFIAPI +TcgAddUINT8( + TCG_CREATE_STRUCT *CreateStruct, + UINT8 Value + ) +{ + return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE); +} + +/** + + Adds a 16-bit unsigned integer to the Data structure. + + @param[in/out] CreateStruct Structure used to add the integer + @param[in] Value Integer Value to add + +**/ +TCG_RESULT +EFIAPI +TcgAddUINT16 ( + TCG_CREATE_STRUCT *CreateStruct, + UINT16 Value + ) +{ + return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE); +} + +/** + + Adds a 32-bit unsigned integer to the Data structure. + + @param[in/out] CreateStruct Structure used to add the integer + @param[in] Value Integer Value to add + +**/ +TCG_RESULT +EFIAPI +TcgAddUINT32( + TCG_CREATE_STRUCT *CreateStruct, + UINT32 Value + ) +{ + return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE); +} + + +/** + + Adds a 64-bit unsigned integer to the Data structure. + + @param[in/out] CreateStruct Structure used to add the integer + @param[in] Value Integer Value to add + +**/ +TCG_RESULT +EFIAPI +TcgAddUINT64( + TCG_CREATE_STRUCT *CreateStruct, + UINT64 Value + ) +{ + return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE); +} + +/** + Adds a BOOLEAN to the Data structure. + + @param[in/out] CreateStruct Structure used to add the integer + @param[in] Value BOOLEAN Value to add + +**/ +TCG_RESULT +EFIAPI +TcgAddBOOLEAN( + TCG_CREATE_STRUCT *CreateStruct, + BOOLEAN Value + ) +{ + return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE); +} + +/** + Add tcg uid info. + + @param [in/out] CreateStruct Structure used to add the integer + @param Uid Input uid info. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgAddTcgUid( + TCG_CREATE_STRUCT *CreateStruct, + TCG_UID Uid + ) +{ + return TcgAddByteSequence(CreateStruct, &Uid, sizeof(TCG_UID), FALSE); +} + +/** + Add start list. + + @param [in/out] CreateStruct Structure used to add the integer + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgAddStartList( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTLIST); +} + +/** + Add end list. + + @param [in/out] CreateStruct Structure used to add the integer + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgAddEndList( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDLIST); +} + +/** + Add start name. + + @param [in/out] CreateStruct Structure used to add the integer + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgAddStartName( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTNAME); +} + +/** + Add end name. + + @param [in/out] CreateStruct Structure used to add the integer + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgAddEndName( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDNAME); +} + +/** + Add end call. + + @param [in/out] CreateStruct Structure used to add the integer + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgAddCall( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + return TcgAddRawByte(CreateStruct, TCG_TOKEN_CALL); +} + +/** + Add end of data. + + @param [in/out] CreateStruct Structure used to add the integer + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgAddEndOfData( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDDATA); +} + +/** + Add end of session. + + @param [in/out] CreateStruct Structure used to add the integer + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgAddEndOfSession( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDSESSION); +} + +/** + Add start transaction. + + @param [in/out] CreateStruct Structure used to add the integer + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgAddStartTransaction( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTTRANSACTION); +} + +/** + Add end transaction. + + @param [in/out] CreateStruct Structure used to add the integer + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgAddEndTransaction( + TCG_CREATE_STRUCT *CreateStruct + ) +{ + return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDTRANSACTION); +} + +/** + Initial the tcg parse structure. + + @param ParseStruct Input parse structure. + @param Buffer Input buffer data. + @param BufferSize Input buffer size. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgInitTcgParseStruct( + TCG_PARSE_STRUCT *ParseStruct, + const VOID *Buffer, + UINT32 BufferSize + ) +{ + UINT32 ComPacketLength; + UINT32 PacketLength; + + NULL_CHECK(ParseStruct); + NULL_CHECK(Buffer); + + if (BufferSize < sizeof(TCG_COM_PACKET)) { + return (TcgResultFailureBufferTooSmall); + } + + ParseStruct->ComPacket = (TCG_COM_PACKET*)Buffer; + + ComPacketLength = SwapBytes32(ParseStruct->ComPacket->LengthBE); + + if ((BufferSize - sizeof(TCG_COM_PACKET)) < ComPacketLength) { + DEBUG ((DEBUG_INFO, "Buffer %u too small for ComPacket %u\n", BufferSize, ComPacketLength)); + return (TcgResultFailureBufferTooSmall); + } + + ParseStruct->BufferSize = BufferSize; + ParseStruct->Buffer = Buffer; + + ParseStruct->CurPacket = NULL; + ParseStruct->CurSubPacket = NULL; + ParseStruct->CurPtr = NULL; + + // if payload > 0, then must have a packet + if (ComPacketLength != 0) { + if (ComPacketLength < sizeof(TCG_PACKET)) { + DEBUG ((DEBUG_INFO, "ComPacket too small for Packet\n")); + return (TcgResultFailureBufferTooSmall); + } + ParseStruct->CurPacket = (TCG_PACKET*)ParseStruct->ComPacket->Payload; + + PacketLength = SwapBytes32(ParseStruct->CurPacket->LengthBE); + + if (PacketLength > 0) { + if (PacketLength < sizeof(TCG_SUB_PACKET)) { + DEBUG ((DEBUG_INFO, "Packet too small for SubPacket\n")); + return (TcgResultFailureBufferTooSmall); + } + + ParseStruct->CurSubPacket = (TCG_SUB_PACKET*)ParseStruct->CurPacket->Payload; + } + } + + //TODO should check for method status list at this point? + + return (TcgResultSuccess); +} + +/** + Get next token info. + + @param ParseStruct Input parse structure info. + @param TcgToken return the tcg token info. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextToken( + TCG_PARSE_STRUCT *ParseStruct, + TCG_TOKEN *TcgToken + ) +{ + const UINT8* EndOfSubPacket; + UINT8* TokenEnd; + UINT8 Hdr; + TCG_SIMPLE_TOKEN_SHORT_ATOM* TmpShort; + const TCG_SIMPLE_TOKEN_MEDIUM_ATOM* TmpMed; + const TCG_SIMPLE_TOKEN_LONG_ATOM* TmpLong; + + NULL_CHECK(ParseStruct); + NULL_CHECK(TcgToken); + + if (ParseStruct->ComPacket == NULL || + ParseStruct->CurPacket == NULL || + ParseStruct->CurSubPacket == NULL + ) { + DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", ParseStruct->ComPacket, ParseStruct->CurPacket, ParseStruct->CurSubPacket)); + return TcgResultFailureInvalidAction; + } + + // initial call, start at sub packet + if (ParseStruct->CurPtr == NULL) { + ParseStruct->CurPtr = ParseStruct->CurSubPacket->Payload; + } + + EndOfSubPacket = ParseStruct->CurSubPacket->Payload + SwapBytes32(ParseStruct->CurSubPacket->LengthBE); + TokenEnd = NULL; + + // confirmed that subpacket Length falls within end of Buffer and TCG_COM_PACKET, + // so simply need to verify the loop stays within current subpacket + if (ParseStruct->CurPtr >= EndOfSubPacket) { + DEBUG ((DEBUG_INFO, "ParseStruct->CurPtr >= EndOfSubPacket\n")); + return (TcgResultFailureEndBuffer); + } + + Hdr = *ParseStruct->CurPtr; + TcgToken->HdrStart = ParseStruct->CurPtr; + + // Tiny Atom range + if (Hdr <= 0x7F) { + // tiny atom Header is only 1 byte, so don't need to verify Size before cast and access + TcgToken->Type = TcgTokenTypeTinyAtom; + + TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_TINY_ATOM); + + // verify caller will have enough Size to reference token + if (TokenEnd >= EndOfSubPacket) { + DEBUG ((DEBUG_INFO, "Tiny Atom TokenEnd >= EndOfSubPacket\n")); + return (TcgResultFailureEndBuffer); + } + } + // Short Atom Range + else if (0x80 <= Hdr && Hdr <= 0xBF) { + // short atom Header is only 1 byte, so don't need to verify Size before cast and access + TmpShort = (TCG_SIMPLE_TOKEN_SHORT_ATOM*)(ParseStruct->CurPtr); + TcgToken->Type = TcgTokenTypeShortAtom; + + TokenEnd = (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM) + TmpShort->ShortAtomBits.Length); + + // verify caller will have enough Size to reference token + if (TokenEnd >= EndOfSubPacket) { + DEBUG ((DEBUG_INFO, "Short Atom TokenEnd >= EndOfSubPacket\n")); + return (TcgResultFailureEndBuffer); + } + } + // Medium Atom Range + else if (0xC0 <= Hdr && Hdr <= 0xDF) { + if (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM) >= EndOfSubPacket) { + return (TcgResultFailureEndBuffer); + } + TmpMed = (const TCG_SIMPLE_TOKEN_MEDIUM_ATOM*)ParseStruct->CurPtr; + TcgToken->Type = TcgTokenTypeMediumAtom; + TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM) + + ((TmpMed->MediumAtomBits.LengthHigh << TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) | + TmpMed->MediumAtomBits.LengthLow); + + // verify caller will have enough Size to reference token + if (TokenEnd >= EndOfSubPacket) { + DEBUG ((DEBUG_INFO, "Medium Atom TokenEnd >= EndOfSubPacket\n")); + return (TcgResultFailureEndBuffer); + } + } + // Long Atom Range + else if (0xE0 <= Hdr && Hdr <= 0xE3) { + if (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM) >= EndOfSubPacket) { + return (TcgResultFailureEndBuffer); + } + TmpLong = (const TCG_SIMPLE_TOKEN_LONG_ATOM*)ParseStruct->CurPtr; + TcgToken->Type = TcgTokenTypeLongAtom; + + TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM) + + ((TmpLong->LongAtomBits.LengthHigh << TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) | + (TmpLong->LongAtomBits.LengthMid << TCG_LONG_ATOM_LENGTH_MID_SHIFT) | + TmpLong->LongAtomBits.LengthLow); + + // verify caller will have enough Size to reference token + if (TokenEnd >= EndOfSubPacket) { + DEBUG ((DEBUG_INFO, "Long Atom TokenEnd >= EndOfSubPacket\n")); + return (TcgResultFailureEndBuffer); + } + } else { + // single byte tokens + switch (Hdr) { + case TCG_TOKEN_STARTLIST: + TcgToken->Type = TcgTokenTypeStartList; + break; + case TCG_TOKEN_ENDLIST: + TcgToken->Type = TcgTokenTypeEndList; + break; + case TCG_TOKEN_STARTNAME: + TcgToken->Type = TcgTokenTypeStartName; + break; + case TCG_TOKEN_ENDNAME: + TcgToken->Type = TcgTokenTypeEndName; + break; + case TCG_TOKEN_CALL: + TcgToken->Type = TcgTokenTypeCall; + break; + case TCG_TOKEN_ENDDATA: + TcgToken->Type = TcgTokenTypeEndOfData; + break; + case TCG_TOKEN_ENDSESSION: + TcgToken->Type = TcgTokenTypeEndOfSession; + break; + case TCG_TOKEN_STARTTRANSACTION: + TcgToken->Type = TcgTokenTypeStartTransaction; + break; + case TCG_TOKEN_ENDTRANSACTION: + TcgToken->Type = TcgTokenTypeEndTransaction; + break; + case TCG_TOKEN_EMPTY: + TcgToken->Type = TcgTokenTypeEmptyAtom; + break; + default: + DEBUG ((DEBUG_INFO, "WARNING: reserved token Type 0x%02X\n", Hdr)); + TcgToken->Type = TcgTokenTypeReserved; + break; + } + ParseStruct->CurPtr++; + TokenEnd = TcgToken->HdrStart + 1; + } + + // increment curptr for next call + ParseStruct->CurPtr = TokenEnd; + return (TcgResultSuccess); +} + +/** + Get atom info. + + @param TcgToken Input token info. + @param HeaderLength return the header length. + @param DataLength return the data length. + @param ByteOrInt return the atom Type. + @param SignOrCont return the sign or count info. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetAtomInfo( + const TCG_TOKEN *TcgToken, + UINT32 *HeaderLength, + UINT32 *DataLength, + UINT8 *ByteOrInt, + UINT8 *SignOrCont + ) +{ + TCG_SIMPLE_TOKEN_TINY_ATOM* TinyAtom; + TCG_SIMPLE_TOKEN_SHORT_ATOM* ShortAtom; + TCG_SIMPLE_TOKEN_MEDIUM_ATOM* MediumAtom; + TCG_SIMPLE_TOKEN_LONG_ATOM* LongAtom; + + NULL_CHECK(TcgToken); + NULL_CHECK(HeaderLength); + NULL_CHECK(DataLength); + NULL_CHECK(ByteOrInt); + NULL_CHECK(SignOrCont); + + switch (TcgToken->Type) { + case TcgTokenTypeTinyAtom: { + TinyAtom = (TCG_SIMPLE_TOKEN_TINY_ATOM*)TcgToken->HdrStart; + *ByteOrInt = TCG_ATOM_TYPE_INTEGER; + *SignOrCont = TinyAtom->TinyAtomBits.Sign; + *HeaderLength = 0; + *DataLength = 0; // tiny atom must be handled as a special case - Header and Data in the same byte + return TcgResultSuccess; + } + + case TcgTokenTypeShortAtom: { + ShortAtom = (TCG_SIMPLE_TOKEN_SHORT_ATOM*)TcgToken->HdrStart; + *ByteOrInt = ShortAtom->ShortAtomBits.ByteOrInt; + *SignOrCont = ShortAtom->ShortAtomBits.SignOrCont; + *HeaderLength = sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM); + *DataLength = ShortAtom->ShortAtomBits.Length; + return TcgResultSuccess; + } + + case TcgTokenTypeMediumAtom: { + MediumAtom = (TCG_SIMPLE_TOKEN_MEDIUM_ATOM*)TcgToken->HdrStart; + *ByteOrInt = MediumAtom->MediumAtomBits.ByteOrInt; + *SignOrCont = MediumAtom->MediumAtomBits.SignOrCont; + *HeaderLength = sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM); + *DataLength = (MediumAtom->MediumAtomBits.LengthHigh << TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) | MediumAtom->MediumAtomBits.LengthLow; + return TcgResultSuccess; + } + + case TcgTokenTypeLongAtom: { + LongAtom = (TCG_SIMPLE_TOKEN_LONG_ATOM*)TcgToken->HdrStart; + *ByteOrInt = LongAtom->LongAtomBits.ByteOrInt; + *SignOrCont = LongAtom->LongAtomBits.SignOrCont; + *HeaderLength = sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM); + *DataLength = (LongAtom->LongAtomBits.LengthHigh << TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) | + (LongAtom->LongAtomBits.LengthMid << TCG_LONG_ATOM_LENGTH_MID_SHIFT) | + LongAtom->LongAtomBits.LengthLow; + return TcgResultSuccess; + } + + default: + DEBUG ((DEBUG_INFO, "Token Type is not simple atom (%d)\n", TcgToken->Type)); + return (TcgResultFailureInvalidType); + } +} + +/** + Get token specified value. + + @param TcgToken Input token info. + @param Value return the value. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetTokenUINT64( + const TCG_TOKEN *TcgToken, + UINT64 *Value + ) +{ + UINT32 HdrLength; + UINT32 DataLength; + UINT8 ByteOrInt; + UINT8 IsSigned; + TCG_SIMPLE_TOKEN_TINY_ATOM* TmpTiny; + const UINT8* Data; + UINT32 Index; + + NULL_CHECK(TcgToken); + NULL_CHECK(Value); + + Index = 0; + *Value = 0; + ERROR_CHECK(TcgGetAtomInfo(TcgToken, &HdrLength, &DataLength, &ByteOrInt, &IsSigned)); + + if (ByteOrInt != TCG_ATOM_TYPE_INTEGER) { + DEBUG ((DEBUG_INFO, "Invalid Type, expected integer not byte sequence\n")); + return TcgResultFailureInvalidType; + } + + if (IsSigned != 0) { + DEBUG ((DEBUG_INFO, "Integer is signed, expected unsigned\n")); + return TcgResultFailureInvalidType; + } + + // special case for tiny atom + // Header and Data are in one byte, so extract only the Data bitfield + if (TcgToken->Type == TcgTokenTypeTinyAtom) { + TmpTiny = (TCG_SIMPLE_TOKEN_TINY_ATOM*)TcgToken->HdrStart; + *Value = TmpTiny->TinyAtomBits.Data; + return TcgResultSuccess; + } + + if (DataLength > sizeof(UINT64)) { + DEBUG ((DEBUG_INFO, "Length %d is greater than Size of UINT64\n", DataLength)); + return TcgResultFailureBufferTooSmall; + } + + // read big-endian integer + Data = TcgToken->HdrStart + HdrLength; + for (Index = 0; Index < DataLength; Index++) { + *Value = LShiftU64(*Value, 8) | Data[Index]; + } + + return TcgResultSuccess; +} + +/** + Get token byte sequence. + + @param TcgToken Input token info. + @param Length Input the length info. + + @retval Return the value data. + +**/ +UINT8* +EFIAPI +TcgGetTokenByteSequence( + const TCG_TOKEN *TcgToken, + UINT32 *Length + ) +{ + UINT32 HdrLength; + UINT8 ByteOrInt; + UINT8 SignOrCont; + + if (TcgToken == NULL || Length == NULL) { + return NULL; + } + + *Length = 0; + if (TcgGetAtomInfo(TcgToken, &HdrLength, Length, &ByteOrInt, &SignOrCont) != TcgResultSuccess) { + DEBUG ((DEBUG_INFO, "Failed to get simple token info\n")); + return NULL; + } + + if (ByteOrInt != TCG_ATOM_TYPE_BYTE) { + DEBUG ((DEBUG_INFO, "Invalid Type, expected byte sequence not integer\n")); + return NULL; + } + + return (TcgToken->HdrStart + HdrLength); +} + +/** + Get next specify value. + + @param ParseStruct Input parse structure. + @param Value Return value. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextUINT8( + TCG_PARSE_STRUCT *ParseStruct, + UINT8 *Value + ) +{ + UINT64 Value64; + TCG_TOKEN Tok; + + NULL_CHECK(Value); + + ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok)); + ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64)); + + if (Value64 > MAX_UINT8) { + return TcgResultFailure; + } + + *Value = (UINT8)Value64; + + return TcgResultSuccess; +} + +/** + Get next specify value. + + @param ParseStruct Input parse structure. + @param Value Return value. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextUINT16( + TCG_PARSE_STRUCT *ParseStruct, + UINT16 *Value + ) +{ + UINT64 Value64; + TCG_TOKEN Tok; + + NULL_CHECK(Value); + + ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok)); + ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64)); + + if (Value64 > MAX_UINT16) { + return TcgResultFailure; + } + + *Value = (UINT16)Value64; + + return TcgResultSuccess; +} + +/** + Get next specify value. + + @param ParseStruct Input parse structure. + @param Value Return value. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextUINT32( + TCG_PARSE_STRUCT *ParseStruct, + UINT32 *Value + ) +{ + UINT64 Value64; + TCG_TOKEN Tok; + + NULL_CHECK(Value); + + ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok)); + ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64)); + + if (Value64 > MAX_UINT32) { + return TcgResultFailure; + } + + *Value = (UINT32)Value64; + + return TcgResultSuccess; +} + +/** + Get next specify value. + + @param ParseStruct Input parse structure. + @param Value Return value. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextUINT64( + TCG_PARSE_STRUCT *ParseStruct, + UINT64 *Value + ) +{ + TCG_TOKEN Tok; + ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok)); + ERROR_CHECK(TcgGetTokenUINT64(&Tok, Value)); + return TcgResultSuccess; +} + +/** + Get next specify value. + + @param ParseStruct Input parse structure. + @param Value Return value. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextBOOLEAN( + TCG_PARSE_STRUCT *ParseStruct, + BOOLEAN *Value + ) +{ + UINT64 Value64; + TCG_TOKEN Tok; + + NULL_CHECK(Value); + + ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok)); + ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64)); + + if (Value64 > 1) { + return TcgResultFailure; + } + + *Value = (BOOLEAN)Value64; + + return TcgResultSuccess; +} + +/** + Get next tcg uid info. + + @param ParseStruct Input parse structure. + @param Uid Get the uid info. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextTcgUid( + TCG_PARSE_STRUCT *ParseStruct, + TCG_UID *Uid + ) +{ + TCG_TOKEN Tok; + UINT32 Length; + const UINT8* ByteSeq; + + NULL_CHECK(Uid); + + ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok)); + ByteSeq = TcgGetTokenByteSequence(&Tok, &Length); + + if (Length != sizeof(TCG_UID)) { + DEBUG ((DEBUG_INFO, "Token Length %u != TCG_UID Size %u\n", Length, (UINT32)sizeof(TCG_UID))); + return TcgResultFailure; + } + + ASSERT (ByteSeq != NULL); + + CopyMem(Uid, ByteSeq, sizeof(TCG_UID)); + + return TcgResultSuccess; +} + +/** + Get next byte sequence. + + @param ParseStruct Input parse structure. + @param Data return the data. + @param Length return the length. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextByteSequence( + TCG_PARSE_STRUCT *ParseStruct, + const VOID **Data, + UINT32 *Length + ) +{ + TCG_TOKEN Tok; + const UINT8* Bs; + + ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok)); + Bs = TcgGetTokenByteSequence(&Tok, Length); + + if (Bs == NULL) { + return TcgResultFailure; + } + *Data = Bs; + return TcgResultSuccess; +} + +/** + Get next token Type. + + @param ParseStruct Input parse structure. + @param Type Input the type need to check. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextTokenType( + TCG_PARSE_STRUCT *ParseStruct, + TCG_TOKEN_TYPE Type + ) +{ + TCG_TOKEN Tok; + ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok)); + if (Tok.Type != Type) { + DEBUG ((DEBUG_INFO, "expected Type %u, got Type %u\n", Type, Tok.Type)); + return TcgResultFailure; + } + return TcgResultSuccess; +} + +/** + Get next start list. + + @param ParseStruct Input parse structure. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextStartList( + TCG_PARSE_STRUCT *ParseStruct + ) +{ + return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartList); +} + +/** + Get next end list. + + @param ParseStruct Input parse structure. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextEndList( + TCG_PARSE_STRUCT *ParseStruct + ) +{ + return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndList); +} + +/** + Get next start name. + + @param ParseStruct Input parse structure. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextStartName( + TCG_PARSE_STRUCT *ParseStruct + ) +{ + return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartName); +} + +/** + Get next end name. + + @param ParseStruct Input parse structure. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextEndName( + TCG_PARSE_STRUCT *ParseStruct + ) +{ + return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndName); +} + +/** + Get next call. + + @param ParseStruct Input parse structure. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextCall( + TCG_PARSE_STRUCT *ParseStruct + ) +{ + return TcgGetNextTokenType(ParseStruct, TcgTokenTypeCall); +} + +/** + Get next end data. + + @param ParseStruct Input parse structure. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextEndOfData( + TCG_PARSE_STRUCT *ParseStruct + ) +{ + return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndOfData); +} + +/** + Get next end of session. + + @param ParseStruct Input parse structure. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextEndOfSession( + TCG_PARSE_STRUCT *ParseStruct + ) +{ + return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndOfSession); +} + +/** + Get next start transaction. + + @param ParseStruct Input parse structure. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextStartTransaction( + TCG_PARSE_STRUCT *ParseStruct + ) +{ + return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartTransaction); +} + +/** + Get next end transaction. + + @param ParseStruct Input parse structure. + + @retval return the action result. + +**/ +TCG_RESULT +EFIAPI +TcgGetNextEndTransaction( + TCG_PARSE_STRUCT *ParseStruct + ) +{ + return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndTransaction); +} |