blob: 76b25a37754fd636ea3f08cde3ac55c4c2c6550f [file] [log] [blame]
/** @file
Provide functions to provide tcg storage core spec related functions.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#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 stucture.
@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 vlaue.
@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 vlaue.
@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 vlaue.
@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 vlaue.
@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 vlaue.
@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);
}