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