/** @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);
|
}
|