diff --git a/src/security/tcg/opal_s3/Makefile.mk b/src/security/tcg/opal_s3/Makefile.mk
index dc3225a9ec..625d719d59 100644
--- a/src/security/tcg/opal_s3/Makefile.mk
+++ b/src/security/tcg/opal_s3/Makefile.mk
@@ -1 +1,6 @@
## SPDX-License-Identifier: GPL-2.0-only
+
+CPPFLAGS_common-$(CONFIG_TCG_OPAL_S3_UNLOCK) += -I$(src)/vendorcode/intel/tcg_storage_core
+
+smm-$(CONFIG_TCG_OPAL_S3_UNLOCK) += ../../../vendorcode/intel/tcg_storage_core/tcg_storage_core.c
+smm-$(CONFIG_TCG_OPAL_S3_UNLOCK) += ../../../vendorcode/intel/tcg_storage_core/tcg_storage_util.c
diff --git a/src/vendorcode/intel/tcg_storage_core/tcg_storage_core.c b/src/vendorcode/intel/tcg_storage_core/tcg_storage_core.c
new file mode 100644
index 0000000000..ca04c93bd5
--- /dev/null
+++ b/src/vendorcode/intel/tcg_storage_core/tcg_storage_core.c
@@ -0,0 +1,1662 @@
+/* SPDX-License-Identifier: BSD-2-Clause-Patent */
+
+#include "tcg_storage_core_lib.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.
+
+**/
+static 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;
+ break;
+ 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.
+
+
+**/
+static 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);
+}
diff --git a/src/vendorcode/intel/tcg_storage_core/tcg_storage_core_lib.h b/src/vendorcode/intel/tcg_storage_core/tcg_storage_core_lib.h
new file mode 100644
index 0000000000..fd7fac2952
--- /dev/null
+++ b/src/vendorcode/intel/tcg_storage_core/tcg_storage_core_lib.h
@@ -0,0 +1,1287 @@
+/* SPDX-License-Identifier: BSD-2-Clause-Patent */
+
+/** @file
+ Public API for the Tcg Core library to perform the lowest level TCG Data encoding.
+
+ (TCG Storage Architecture Core Specification, Version 2.01, Revision 1.00,
+ https://trustedcomputinggroup.org/tcg-storage-architecture-core-specification/)
+
+ Check http://trustedcomputinggroup.org for latest specification updates.
+
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _TCG_CORE_H_
+#define _TCG_CORE_H_
+
+#include "tcg_storage_core_spec.h"
+
+#define ERROR_CHECK(arg) \
+ { \
+ TCG_RESULT ret = (arg); \
+ if (ret != TcgResultSuccess) { \
+ DEBUG ((DEBUG_INFO, "ERROR_CHECK failed at %a:%u\n", __FILE__, DEBUG_LINE_NUMBER)); \
+ return ret; \
+ } \
+ }
+
+#define METHOD_STATUS_ERROR_CHECK(arg, failRet) \
+ if ((arg) != TCG_METHOD_STATUS_CODE_SUCCESS) { \
+ DEBUG ((DEBUG_INFO, "Method Status error: 0x%02X (%a)\n", arg, TcgMethodStatusString(arg))); \
+ return (failRet); \
+ }
+
+#define NULL_CHECK(arg) \
+ do { \
+ if ((arg) == NULL) { \
+ DEBUG ((DEBUG_INFO, "NULL_CHECK(%a) failed at %a:%u\n", #arg, __FILE__, DEBUG_LINE_NUMBER)); \
+ return TcgResultFailureNullPointer; \
+ } \
+ } while (0)
+
+#pragma pack(1)
+
+/**
+Tcg result codes.
+
+The result code indicates if the Tcg function call was successful or not
+**/
+typedef enum {
+ //
+ // This is the return result upon successful completion of a Tcg function call
+ //
+ TcgResultSuccess,
+
+ //
+ // This is the return "catchall" result for the failure of a Tcg function call
+ //
+ TcgResultFailure,
+
+ //
+ // This is the return result if a required parameter was Null for a Tcg function call
+ //
+ TcgResultFailureNullPointer,
+
+ //
+ // This is the return result if a required buffersize was 0 for a Tcg function call
+ //
+ TcgResultFailureZeroSize,
+
+ //
+ // This is the return result if a Tcg function call was executed out of order.
+ // For instance, starting a Tcg subpacket before starting its Tcg packet.
+ //
+ TcgResultFailureInvalidAction,
+
+ //
+ // This is the return result if the buffersize provided is not big enough to add a requested Tcg encoded item.
+ //
+ TcgResultFailureBufferTooSmall,
+
+ //
+ // This is the return result for a Tcg parse function if the end of the parsed Buffer is reached, yet Data is still attempted to be retrieved.
+ // For instance, attempting to retrieve another Tcg token from the Buffer after it has reached the end of the Tcg subpacket payload.
+ //
+ TcgResultFailureEndBuffer,
+
+ //
+ // This is the return result for a Tcg parse function if the Tcg Token item requested is not the expected type.
+ // For instance, the caller requested to receive an integer and the Tcg token was a byte sequence.
+ //
+ TcgResultFailureInvalidType,
+} TCG_RESULT;
+
+//
+// Structure that is used to build the Tcg ComPacket. It contains the start Buffer pointer and the current position of the
+// Tcg ComPacket, current Tcg Packet and Tcg SubPacket. This structure must be initialized
+// by calling tcgInitTcgCreateStruct before it is used as parameter to any other Tcg function.
+// This structure should NOT be directly modified by the client of this library.
+//
+// NOTE: WE MAY MAKE THIS AN ABSTRACT STRUCTURE WITH A DEFINED SIZE AND KEEP THE VARIABLES
+// INTERNAL AND ONLY KNOWN TO THE TCG LIBRARY
+//
+// tcgInitTcgCreateStruct
+//
+typedef struct {
+ //
+ // Buffer allocated and freed by the client of the Tcg library.
+ // This is the Buffer that shall contain the final Tcg encoded compacket.
+ //
+ VOID *Buffer;
+
+ //
+ // Size of the Buffer provided.
+ //
+ UINT32 BufferSize;
+
+ //
+ // Pointer to the start of the Tcg ComPacket. It should point to a location within Buffer.
+ //
+ TCG_COM_PACKET *ComPacket;
+
+ //
+ // Current Tcg Packet that is being created. It should point to a location within Buffer.
+ //
+ TCG_PACKET *CurPacket;
+
+ //
+ // Current Tcg SubPacket that is being created. It should point to a location within Buffer.
+ //
+ TCG_SUB_PACKET *CurSubPacket;
+
+ //
+ // Flag used to indicate if the Buffer of the structure should be filled out.
+ // This is intended to be used to support a use-case where the client of library
+ // can perform all the desired tcg calls to determine what the actual Size of the final compacket will be.
+ // Then the client can allocate the required Buffer Size and re-run the tcg calls.
+ // THIS MAY NOT BE IMPLEMENTED... REQUIRES MORE THOUGHT BECAUSE YOU CANNOT SOLVE ISSUE FOR RECEIVE
+ //
+ BOOLEAN DryRun;
+} TCG_CREATE_STRUCT;
+
+//
+// Structure that is used to parse the Tcg response received. It contains the response Buffer pointer
+// and the current position of the Tcg ComPacket, current Tcg Packet and Tcg SubPacket being parsed.
+// This structure must be initialized by calling tcgInitTcgParseStruct before it is used as parameter to any other Tcg parse function.
+// This structure should NOT be directly modified by the client of this library.
+//
+// NOTE: WE MAY MAKE THIS AN ABSTRACT STRUCTURE WITH A DEFINED SIZE AND KEEP THE VARIABLES
+// INTERNAL AND ONLY KNOWN TO THE TCG LIBRARY
+//
+// @sa tcgInitTcgParseStruct
+//
+typedef struct {
+ //
+ // Buffer allocated and freed by the client of the Tcg library.
+ // This is the Buffer that contains the Tcg response to decode/parse.
+ //
+ const VOID *Buffer;
+
+ //
+ // Size of the Buffer provided.
+ //
+ UINT32 BufferSize;
+
+ //
+ // Pointer to the start of the Tcg ComPacket. It should point to a location within Buffer.
+ //
+ TCG_COM_PACKET *ComPacket;
+
+ //
+ // Current Tcg Packet that is being created. It should point to a location within Buffer.
+ //
+ TCG_PACKET *CurPacket;
+
+ //
+ // Current Tcg SubPacket that is being created. It should point to a location within Buffer.
+ //
+ TCG_SUB_PACKET *CurSubPacket;
+
+ //
+ // Current pointer within the current subpacket payload.
+ //
+ UINT8 *CurPtr;
+} TCG_PARSE_STRUCT;
+
+//
+// Structure that is used to represent a Tcg Token that is retrieved by Tcg parse functions.
+//
+typedef struct {
+ //
+ // Describes the type of Tcg token the Hdr start points to.
+ //
+ TCG_TOKEN_TYPE Type;
+
+ //
+ // Pointer to the beginning of the Header of the Tcg token
+ //
+ UINT8 *HdrStart;
+} TCG_TOKEN;
+
+/**
+
+ 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.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgInitTcgCreateStruct (
+ TCG_CREATE_STRUCT *CreateStruct,
+ VOID *Buffer,
+ UINT32 BufferSize
+ );
+
+/**
+
+ 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
+ );
+
+/**
+
+ 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
+ );
+
+/**
+
+ 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
+ );
+
+/**
+
+ 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
+ );
+
+/**
+
+ 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
+ );
+
+/**
+
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+
+ 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
+ );
+
+/**
+
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+
+ 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
+ );
+
+/**
+
+ 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
+ );
+
+/**
+
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ Adds a Start List token to the Data structure.
+
+ @param[in/out] CreateStruct Structure used to add the token
+
+**/
+TCG_RESULT
+EFIAPI
+TcgAddStartList (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+
+ Adds an End List token to the Data structure.
+
+ @param [in/out] CreateStruct Structure used to add the token
+
+**/
+TCG_RESULT
+EFIAPI
+TcgAddEndList (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+ Adds a Start Name token to the Data structure.
+
+ @param[in/out] CreateStruct Structure used to add the token
+
+**/
+TCG_RESULT
+EFIAPI
+TcgAddStartName (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+
+ Adds an End Name token to the Data structure.
+
+ @param [in/out] CreateStruct Structure used to add the token
+
+**/
+TCG_RESULT
+EFIAPI
+TcgAddEndName (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+ Adds a Call token to the Data structure.
+
+ @param [in/out] CreateStruct Structure used to add the token
+
+**/
+TCG_RESULT
+EFIAPI
+TcgAddCall (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+
+Adds an End of Data token to the Data structure.
+
+@param[in/out] CreateStruct Structure used to add the token
+
+**/
+TCG_RESULT
+EFIAPI
+TcgAddEndOfData (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+
+Adds an End of Session token to the Data structure.
+
+@param [in/out] CreateStruct Structure used to add the token
+
+**/
+TCG_RESULT
+EFIAPI
+TcgAddEndOfSession (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+ Adds a Start Transaction token to the Data structure.
+
+ @param [in/out] CreateStruct Structure used to add the token
+
+**/
+TCG_RESULT
+EFIAPI
+TcgAddStartTransaction (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+ Adds an End Transaction token to the Data structure.
+
+ @param[in/out] CreateStruct Structure used to add the token
+
+**/
+TCG_RESULT
+EFIAPI
+TcgAddEndTransaction (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ Get next start list.
+
+ @param ParseStruct Input parse structure.
+
+ @retval return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetNextStartList (
+ TCG_PARSE_STRUCT *ParseStruct
+ );
+
+/**
+ Get next end list.
+
+ @param ParseStruct Input parse structure.
+
+ @retval return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetNextEndList (
+ TCG_PARSE_STRUCT *ParseStruct
+ );
+
+/**
+ Get next start name.
+
+ @param ParseStruct Input parse structure.
+
+ @retval return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetNextStartName (
+ TCG_PARSE_STRUCT *ParseStruct
+ );
+
+/**
+ Get next end name.
+
+ @param ParseStruct Input parse structure.
+
+ @retval return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetNextEndName (
+ TCG_PARSE_STRUCT *ParseStruct
+ );
+
+/**
+ Get next call.
+
+ @param ParseStruct Input parse structure.
+
+ @retval return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetNextCall (
+ TCG_PARSE_STRUCT *ParseStruct
+ );
+
+/**
+ Get next end data.
+
+ @param ParseStruct Input parse structure.
+
+ @retval return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetNextEndOfData (
+ TCG_PARSE_STRUCT *ParseStruct
+ );
+
+/**
+ Get next end of session.
+
+ @param ParseStruct Input parse structure.
+
+ @retval return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetNextEndOfSession (
+ TCG_PARSE_STRUCT *ParseStruct
+ );
+
+/**
+ Get next start transaction.
+
+ @param ParseStruct Input parse structure.
+
+ @retval return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetNextStartTransaction (
+ TCG_PARSE_STRUCT *ParseStruct
+ );
+
+/**
+ Get next end transaction.
+
+ @param ParseStruct Input parse structure.
+
+ @retval return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetNextEndTransaction (
+ TCG_PARSE_STRUCT *ParseStruct
+ );
+
+// end of parse functions
+
+typedef
+BOOLEAN
+(EFIAPI *TCG_LEVEL0_ENUM_CALLBACK)(
+ const TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader,
+ TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER *Feature,
+ UINTN FeatureSize, // includes header
+ VOID *Context
+ );
+
+/**
+ Adds call token and method Header (invoking id, and method id).
+
+ @param CreateStruct The input create structure.
+ @param InvokingId Invoking id.
+ @param MethodId Method id.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgStartMethodCall (
+ TCG_CREATE_STRUCT *CreateStruct,
+ TCG_UID InvokingId,
+ TCG_UID MethodId
+ );
+
+/**
+ Adds START LIST token.
+
+ @param CreateStruct The input create structure.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgStartParameters (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+ Adds END LIST token.
+
+ @param CreateStruct The input create structure.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgEndParameters (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+ Adds END Data token and method list.
+
+ @param CreateStruct The input create structure.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgEndMethodCall (
+ TCG_CREATE_STRUCT *CreateStruct
+ );
+
+/**
+
+ Adds Start Session call to the data structure. This creates the entire ComPacket structure and
+ returns the size of the entire compacket in the size parameter.
+
+ @param [in/out] CreateStruct Structure used to add the start session call
+ @param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
+ @param [in] ComId ComID for the ComPacket
+ @param [in] ComIdExtension Extended ComID for the ComPacket
+ @param [in] HostSessionId Host Session ID
+ @param [in] SpId Security Provider to start session with
+ @param [in] Write Write option for start session. TRUE = start session requests write access
+ @param [in] HostChallengeLength Length of the host challenge. Length should be 0 if hostChallenge is NULL
+ @param [in] HostChallenge Host challenge for Host Signing Authority. If NULL, then no Host Challenge shall be sent.
+ @param [in] HostSigningAuthority Host Signing Authority used for start session. If NULL, then no Host Signing Authority shall be sent.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgCreateStartSession (
+ TCG_CREATE_STRUCT *CreateStruct,
+ UINT32 *Size,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 HostSessionId,
+ TCG_UID SpId,
+ BOOLEAN Write,
+ UINT32 HostChallengeLength,
+ const VOID *HostChallenge,
+ TCG_UID HostSigningAuthority
+ );
+
+/**
+ Creates ComPacket with a Method call that sets the PIN column for the row specified.
+ This assumes a start session has already been opened with the desired SP.
+
+ @param [in/out] CreateStruct Structure used to add method call.
+ @param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
+ @param [in] ComId ComID for the ComPacket
+ @param [in] ComIdExtension Extended ComID for the ComPacket
+ @param [in] TperSession Tper Session ID for the Packet
+ @param [in] HostSession Host Session ID for the Packet
+ @param [in] SidRow UID of row of current SP to set PIN column
+ @param [in] Password value of PIN to set
+ @param [in] PasswordSize Size of PIN
+
+**/
+TCG_RESULT
+EFIAPI
+TcgCreateSetCPin (
+ TCG_CREATE_STRUCT *CreateStruct,
+ UINT32 *Size,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 TperSession,
+ UINT32 HostSession,
+ TCG_UID SidRow,
+ const VOID *Password,
+ UINT32 PasswordSize
+ );
+
+/**
+ Creates ComPacket with a Method call that sets the "Enabled" column for the row specified using the value specified.
+ This assumes a start session has already been opened with the desired SP.
+
+ @param [in/out] CreateStruct Structure used to add method call
+ @param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
+ @param [in] ComId ComID for the ComPacket
+ @param [in] ComIdExtension Extended ComID for the ComPacket
+ @param [in] TperSession Tper Session ID for the Packet
+ @param [in] HostSession Host Session ID for the Packet
+ @param [in] AuthorityUid Authority UID to modify the "Enabled" column for
+ @param [in] Enabled Value to set the "Enabled" column to
+
+**/
+TCG_RESULT
+EFIAPI
+TcgSetAuthorityEnabled (
+ TCG_CREATE_STRUCT *CreateStruct,
+ UINT32 *Size,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 TperSession,
+ UINT32 HostSession,
+ TCG_UID AuthorityUid,
+ BOOLEAN Enabled
+ );
+
+/**
+
+ Creates ComPacket with EndSession.
+ This assumes a start session has already been opened.
+
+ @param [in/out] CreateStruct Structure used to add Endsession
+ @param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
+ @param [in] ComId ComID for the ComPacket
+ @param [in] ComIdExtension Extended ComID for the ComPacket
+ @param [in] HostSessionId Host Session ID for the Packet
+ @param [in] TpSessionId Tper Session ID for the Packet
+
+**/
+TCG_RESULT
+EFIAPI
+TcgCreateEndSession (
+ TCG_CREATE_STRUCT *CreateStruct,
+ UINT32 *Size,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 HostSessionId,
+ UINT32 TpSessionId
+ );
+
+/**
+
+ Retrieves human-readable token type name.
+
+ @param[in] Type Token type to retrieve
+
+**/
+const CHAR8 *
+EFIAPI
+TcgTokenTypeString (
+ TCG_TOKEN_TYPE Type
+ );
+
+/**
+ Returns the method status of the current subpacket. Does not affect the current position
+ in the ComPacket. In other words, it can be called whenever you have a valid SubPacket.
+
+ @param [in/out] ParseStruct Structure used to parse received TCG response
+ @param [in/out] MethodStatus Method status retrieved of the current SubPacket
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetMethodStatus (
+ const TCG_PARSE_STRUCT *ParseStruct,
+ UINT8 *MethodStatus
+ );
+
+/**
+ Returns a human-readable string representing a method status return code.
+
+ @param[in] MethodStatus Method status to translate to a string
+
+
+ @retval return the string info.
+**/
+const CHAR8 *
+EFIAPI
+TcgMethodStatusString (
+ UINT8 MethodStatus
+ );
+
+/**
+ Retrieves the comID and Extended comID of the ComPacket in the Tcg response.
+ It is intended to be used to confirm the received Tcg response is intended for user that received it.
+
+ @param [in] ParseStruct Structure used to parse received TCG response.
+ @param [in/out] ComId comID retrieved from received ComPacket.
+ @param [in/out] ComIdExtension Extended comID retrieved from received ComPacket
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetComIds (
+ const TCG_PARSE_STRUCT *ParseStruct,
+ UINT16 *ComId,
+ UINT16 *ComIdExtension
+ );
+
+/**
+ Checks if the ComIDs of the response match the expected values.
+
+ @param[in] ParseStruct Structure used to parse received TCG response
+ @param[in] ExpectedComId Expected comID
+ @param[in] ExpectedComIdExtension Expected extended comID
+
+**/
+TCG_RESULT
+EFIAPI
+TcgCheckComIds (
+ const TCG_PARSE_STRUCT *ParseStruct,
+ UINT16 ExpectedComId,
+ UINT16 ExpectedComIdExtension
+ );
+
+/**
+ Parses the Sync Session response contained in the parseStruct to retrieve Tper session ID. If the Sync Session response
+ parameters do not match the comID, extended ComID and host session ID then a failure is returned.
+
+ @param[in/out] ParseStruct Structure used to parse received TCG response, contains Sync Session response.
+ @param[in] ComId Expected ComID that is compared to actual ComID of response
+ @param[in] ComIdExtension Expected Extended ComID that is compared to actual Extended ComID of response
+ @param[in] HostSessionId Expected Host Session ID that is compared to actual Host Session ID of response
+ @param[in/out] TperSessionId Tper Session ID retrieved from the Sync Session response.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgParseSyncSession (
+ const TCG_PARSE_STRUCT *ParseStruct,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 HostSessionId,
+ UINT32 *TperSessionId
+ );
+
+/**
+ Create set ace.
+
+ @param CreateStruct Input create structure.
+ @param Size size info.
+ @param ComId ComId info.
+ @param ComIdExtension ComId extension info.
+ @param TperSession Tper session data.
+ @param HostSession Host session data.
+ @param AceRow Ace row info.
+ @param Authority1 Authority 1 info.
+ @param LogicalOperator Logical operator info.
+ @param Authority2 Authority 2 info.
+
+ @retval Return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgCreateSetAce (
+ TCG_CREATE_STRUCT *CreateStruct,
+ UINT32 *Size,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 TperSession,
+ UINT32 HostSession,
+ TCG_UID AceRow,
+ TCG_UID Authority1,
+ BOOLEAN LogicalOperator,
+ TCG_UID Authority2
+ );
+
+/**
+ Enum level 0 discovery.
+
+ @param DiscoveryHeader Discovery header.
+ @param Callback Callback function.
+ @param Context The context for the function.
+
+ @retval return true if the callback return TRUE, else return FALSE.
+
+**/
+BOOLEAN
+EFIAPI
+TcgEnumLevel0Discovery (
+ const TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader,
+ TCG_LEVEL0_ENUM_CALLBACK Callback,
+ VOID *Context
+ );
+
+/**
+ Get Feature code from the header.
+
+ @param DiscoveryHeader The discovery header.
+ @param FeatureCode return the Feature code.
+ @param FeatureSize return the Feature size.
+
+ @retval return the Feature code data.
+**/
+TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER *
+EFIAPI
+TcgGetFeature (
+ const TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader,
+ UINT16 FeatureCode,
+ UINTN *FeatureSize
+ );
+
+/**
+ Determines if the protocol provided is part of the provided supported protocol list.
+
+ @param[in] ProtocolList Supported protocol list to investigate
+ @param[in] Protocol Protocol value to determine if supported
+
+ @return TRUE = protocol is supported, FALSE = protocol is not supported
+**/
+BOOLEAN
+EFIAPI
+TcgIsProtocolSupported (
+ const TCG_SUPPORTED_SECURITY_PROTOCOLS *ProtocolList,
+ UINT16 Protocol
+ );
+
+/**
+ Determines if the Locking Feature "Locked" bit is set in the level 0 discovery response.
+
+ @param[in] Discovery Level 0 discovery response
+
+ @return TRUE = Locked is set, FALSE = Locked is false
+
+**/
+BOOLEAN
+EFIAPI
+TcgIsLocked (
+ const TCG_LEVEL0_DISCOVERY_HEADER *Discovery
+ );
+
+#pragma pack()
+
+#endif // _TCG_CORE_H_
diff --git a/src/vendorcode/intel/tcg_storage_core/tcg_storage_core_spec.h b/src/vendorcode/intel/tcg_storage_core/tcg_storage_core_spec.h
new file mode 100644
index 0000000000..2233edeb38
--- /dev/null
+++ b/src/vendorcode/intel/tcg_storage_core/tcg_storage_core_spec.h
@@ -0,0 +1,389 @@
+/* SPDX-License-Identifier: BSD-2-Clause-Patent */
+
+/** @file
+ TCG defined values and structures.
+
+ (TCG Storage Architecture Core Specification, Version 2.01, Revision 1.00,
+ https://trustedcomputinggroup.org/tcg-storage-architecture-core-specification/)
+
+ Check http://trustedcomputinggroup.org for latest specification updates.
+
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _TCG_STORAGE_CORE_H_
+#define _TCG_STORAGE_CORE_H_
+
+#include "tcg_uefi_compat.h"
+
+#pragma pack(1)
+
+/// UID in host native byte order
+typedef UINT64 TCG_UID;
+
+#define TCG_TO_UID(b0, b1, b2, b3, b4, b5, b6, b7) (TCG_UID)(\
+ (UINT64)(b0) | \
+ ((UINT64)(b1) << 8) | \
+ ((UINT64)(b2) << 16) | \
+ ((UINT64)(b3) << 24) | \
+ ((UINT64)(b4) << 32) | \
+ ((UINT64)(b5) << 40) | \
+ ((UINT64)(b6) << 48) | \
+ ((UINT64)(b7) << 56))
+
+typedef struct {
+ UINT32 ReservedBE;
+ UINT16 ComIDBE;
+ UINT16 ComIDExtensionBE;
+ UINT32 OutstandingDataBE;
+ UINT32 MinTransferBE;
+ UINT32 LengthBE;
+ UINT8 Payload[0];
+} TCG_COM_PACKET;
+
+typedef struct {
+ UINT32 TperSessionNumberBE;
+ UINT32 HostSessionNumberBE;
+ UINT32 SequenceNumberBE;
+ UINT16 ReservedBE;
+ UINT16 AckTypeBE;
+ UINT32 AcknowledgementBE;
+ UINT32 LengthBE;
+ UINT8 Payload[0];
+} TCG_PACKET;
+
+#define TCG_SUBPACKET_ALIGNMENT 4// 4-byte alignment per spec
+
+typedef struct {
+ UINT8 ReservedBE[6];
+ UINT16 KindBE;
+ UINT32 LengthBE;
+ UINT8 Payload[0];
+} TCG_SUB_PACKET;
+
+#define SUBPACKET_KIND_DATA 0x0000
+#define SUBPACKET_KIND_CREDIT_CONTROL 0x8001
+
+#define TCG_ATOM_TYPE_INTEGER 0x0
+#define TCG_ATOM_TYPE_BYTE 0x1
+typedef struct {
+ UINT8 Data : 6;
+ UINT8 Sign : 1;
+ UINT8 IsZero : 1;
+} TCG_TINY_ATOM_BITS;
+
+typedef union {
+ UINT8 Raw;
+ TCG_TINY_ATOM_BITS TinyAtomBits;
+} TCG_SIMPLE_TOKEN_TINY_ATOM;
+
+typedef struct {
+ UINT8 Length : 4;
+ UINT8 SignOrCont : 1;
+ UINT8 ByteOrInt : 1;
+ UINT8 IsZero : 1;
+ UINT8 IsOne : 1;
+} TCG_SHORT_ATOM_BITS;
+
+typedef union {
+ UINT8 RawHeader;
+ TCG_SHORT_ATOM_BITS ShortAtomBits;
+} TCG_SIMPLE_TOKEN_SHORT_ATOM;
+
+#define TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT 0x8
+#define TCG_MEDIUM_ATOM_LENGTH_HIGH_MASK 0x7
+
+typedef struct {
+ UINT8 LengthHigh : 3;
+ UINT8 SignOrCont : 1;
+ UINT8 ByteOrInt : 1;
+ UINT8 IsZero : 1;
+ UINT8 IsOne1 : 1;
+ UINT8 IsOne2 : 1;
+ UINT8 LengthLow;
+} TCG_MEDIUM_ATOM_BITS;
+
+typedef union {
+ UINT16 RawHeader;
+ TCG_MEDIUM_ATOM_BITS MediumAtomBits;
+} TCG_SIMPLE_TOKEN_MEDIUM_ATOM;
+
+#define TCG_LONG_ATOM_LENGTH_HIGH_SHIFT 16
+#define TCG_LONG_ATOM_LENGTH_MID_SHIFT 8
+
+typedef struct {
+ UINT8 SignOrCont : 1;
+ UINT8 ByteOrInt : 1;
+ UINT8 Reserved : 2;
+ UINT8 IsZero : 1;
+ UINT8 IsOne1 : 1;
+ UINT8 IsOne2 : 1;
+ UINT8 IsOne3 : 1;
+ UINT8 LengthHigh;
+ UINT8 LengthMid;
+ UINT8 LengthLow;
+} TCG_LONG_ATOM_BITS;
+
+typedef union {
+ UINT32 RawHeader;
+ TCG_LONG_ATOM_BITS LongAtomBits;
+} TCG_SIMPLE_TOKEN_LONG_ATOM;
+
+// TCG Core Spec v2 - Table 04 - Token Types
+typedef enum {
+ TcgTokenTypeReserved,
+ TcgTokenTypeTinyAtom,
+ TcgTokenTypeShortAtom,
+ TcgTokenTypeMediumAtom,
+ TcgTokenTypeLongAtom,
+ TcgTokenTypeStartList,
+ TcgTokenTypeEndList,
+ TcgTokenTypeStartName,
+ TcgTokenTypeEndName,
+ TcgTokenTypeCall,
+ TcgTokenTypeEndOfData,
+ TcgTokenTypeEndOfSession,
+ TcgTokenTypeStartTransaction,
+ TcgTokenTypeEndTransaction,
+ TcgTokenTypeEmptyAtom,
+} TCG_TOKEN_TYPE;
+
+#pragma pack()
+
+#define TCG_TOKEN_SHORTATOM_MAX_BYTE_SIZE 0x0F
+#define TCG_TOKEN_MEDIUMATOM_MAX_BYTE_SIZE 0x7FF
+#define TCG_TOKEN_LONGATOM_MAX_BYTE_SIZE 0xFFFFFF
+
+#define TCG_TOKEN_TINYATOM_UNSIGNED_MAX_VALUE 0x3F
+#define TCG_TOKEN_TINYATOM_SIGNED_MAX_VALUE 0x1F
+#define TCG_TOKEN_TINYATOM_SIGNED_MIN_VALUE -32
+
+// TOKEN TYPES
+#define TCG_TOKEN_TINYATOM 0x00
+#define TCG_TOKEN_TINYSIGNEDATOM 0x40
+#define TCG_TOKEN_SHORTATOM 0x80
+#define TCG_TOKEN_SHORTSIGNEDATOM 0x90
+#define TCG_TOKEN_SHORTBYTESATOM 0xA0
+#define TCG_TOKEN_MEDIUMATOM 0xC0
+#define TCG_TOKEN_MEDIUMSIGNEDATOM 0xC8
+#define TCG_TOKEN_MEDIUMBYTESATOM 0xD0
+#define TCG_TOKEN_LONGATOM 0xE0
+#define TCG_TOKEN_LONGSIGNEDATOM 0xE1
+#define TCG_TOKEN_LONGBYTESATOM 0xE2
+#define TCG_TOKEN_STARTLIST 0xF0
+#define TCG_TOKEN_ENDLIST 0xF1
+#define TCG_TOKEN_STARTNAME 0xF2
+#define TCG_TOKEN_ENDNAME 0xF3
+// 0xF4 - 0xF7 TCG Reserved
+#define TCG_TOKEN_CALL 0xF8
+#define TCG_TOKEN_ENDDATA 0xF9
+#define TCG_TOKEN_ENDSESSION 0xFA
+#define TCG_TOKEN_STARTTRANSACTION 0xFB
+#define TCG_TOKEN_ENDTRANSACTION 0xFC
+// 0xFD - 0xFE TCG Reserved
+#define TCG_TOKEN_EMPTY 0xFF
+
+// CELLBLOCK reserved Names
+#define TCG_CELL_BLOCK_TABLE_NAME (UINT8)0x00
+#define TCG_CELL_BLOCK_START_ROW_NAME (UINT8)0x01
+#define TCG_CELL_BLOCK_END_ROW_NAME (UINT8)0x02
+#define TCG_CELL_BLOCK_START_COLUMN_NAME (UINT8)0x03
+#define TCG_CELL_BLOCK_END_COLUMN_NAME (UINT8)0x04
+
+// METHOD STATUS CODES
+#define TCG_METHOD_STATUS_CODE_SUCCESS 0x00
+#define TCG_METHOD_STATUS_CODE_NOT_AUTHORIZED 0x01
+#define TCG_METHOD_STATUS_CODE_OBSOLETE 0x02
+#define TCG_METHOD_STATUS_CODE_SP_BUSY 0x03
+#define TCG_METHOD_STATUS_CODE_SP_FAILED 0x04
+#define TCG_METHOD_STATUS_CODE_SP_DISABLED 0x05
+#define TCG_METHOD_STATUS_CODE_SP_FROZEN 0x06
+#define TCG_METHOD_STATUS_CODE_NO_SESSIONS_AVAILABLE 0x07
+#define TCG_METHOD_STATUS_CODE_UNIQUENESS_CONFLICT 0x08
+#define TCG_METHOD_STATUS_CODE_INSUFFICIENT_SPACE 0x09
+#define TCG_METHOD_STATUS_CODE_INSUFFICIENT_ROWS 0x0A
+#define TCG_METHOD_STATUS_CODE_INVALID_PARAMETER 0x0C
+#define TCG_METHOD_STATUS_CODE_OBSOLETE2 0x0D
+#define TCG_METHOD_STATUS_CODE_OBSOLETE3 0x0E
+#define TCG_METHOD_STATUS_CODE_TPER_MALFUNCTION 0x0F
+#define TCG_METHOD_STATUS_CODE_TRANSACTION_FAILURE 0x10
+#define TCG_METHOD_STATUS_CODE_RESPONSE_OVERFLOW 0x11
+#define TCG_METHOD_STATUS_CODE_AUTHORITY_LOCKED_OUT 0x12
+#define TCG_METHOD_STATUS_CODE_FAIL 0x3F
+
+// Feature Codes
+#define TCG_FEATURE_INVALID (UINT16)0x0000
+#define TCG_FEATURE_TPER (UINT16)0x0001
+#define TCG_FEATURE_LOCKING (UINT16)0x0002
+#define TCG_FEATURE_GEOMETRY_REPORTING (UINT16)0x0003
+#define TCG_FEATURE_SINGLE_USER_MODE (UINT16)0x0201
+#define TCG_FEATURE_DATASTORE_TABLE (UINT16)0x0202
+#define TCG_FEATURE_OPAL_SSC_V1_0_0 (UINT16)0x0200
+#define TCG_FEATURE_OPAL_SSC_V2_0_0 (UINT16)0x0203
+#define TCG_FEATURE_OPAL_SSC_LITE (UINT16)0x0301
+#define TCG_FEATURE_PYRITE_SSC (UINT16)0x0302
+#define TCG_FEATURE_PYRITE_SSC_V2_0_0 (UINT16)0x0303
+#define TCG_FEATURE_BLOCK_SID (UINT16)0x0402
+#define TCG_FEATURE_DATA_REMOVAL (UINT16)0x0404
+
+// ACE Expression values
+#define TCG_ACE_EXPRESSION_AND 0x0
+#define TCG_ACE_EXPRESSION_OR 0x1
+
+/****************************************************************************
+TRUSTED RECEIVE - supported security protocols list (SP_Specific = 0000h)
+ATA 8 Rev6a Table 68 7.57.6.2
+****************************************************************************/
+// Security Protocol IDs
+#define TCG_SECURITY_PROTOCOL_INFO 0x00
+#define TCG_OPAL_SECURITY_PROTOCOL_1 0x01
+#define TCG_OPAL_SECURITY_PROTOCOL_2 0x02
+#define TCG_SECURITY_PROTOCOL_TCG3 0x03
+#define TCG_SECURITY_PROTOCOL_TCG4 0x04
+#define TCG_SECURITY_PROTOCOL_TCG5 0x05
+#define TCG_SECURITY_PROTOCOL_TCG6 0x06
+#define TCG_SECURITY_PROTOCOL_CBCS 0x07
+#define TCG_SECURITY_PROTOCOL_TAPE_DATA 0x20
+#define TCG_SECURITY_PROTOCOL_DATA_ENCRYPT_CONFIG 0x21
+#define TCG_SECURITY_PROTOCOL_SA_CREATION_CAPS 0x40
+#define TCG_SECURITY_PROTOCOL_IKEV2_SCSI 0x41
+#define TCG_SECURITY_PROTOCOL_JEDEC_UFS 0xEC
+#define TCG_SECURITY_PROTOCOL_SDCARD_SECURITY 0xED
+#define TCG_SECURITY_PROTOCOL_IEEE_1667 0xEE
+#define TCG_SECURITY_PROTOCOL_ATA_DEVICE_SERVER_PASS 0xEF
+
+// Security Protocol Specific IDs
+#define TCG_SP_SPECIFIC_PROTOCOL_LIST 0x0000
+#define TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY 0x0001
+
+#define TCG_RESERVED_COMID 0x0000
+
+// Defined in TCG Storage Feature Set:Block SID Authentication spec,
+// ComId used for BlockSid command is hardcode 0x0005.
+#define TCG_BLOCKSID_COMID 0x0005
+
+#pragma pack(1)
+typedef struct {
+ UINT8 Reserved[6];
+ UINT16 ListLength_BE; // 6 - 7
+ UINT8 List[504]; // 8...
+} TCG_SUPPORTED_SECURITY_PROTOCOLS;
+
+// Level 0 Discovery
+typedef struct {
+ UINT32 LengthBE; // number of valid bytes in discovery response, not including length field
+ UINT16 VerMajorBE;
+ UINT16 VerMinorBE;
+ UINT8 Reserved[8];
+ UINT8 VendorUnique[32];
+} TCG_LEVEL0_DISCOVERY_HEADER;
+
+typedef struct _TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER {
+ UINT16 FeatureCode_BE;
+ UINT8 Reserved : 4;
+ UINT8 Version : 4;
+ UINT8 Length; // length of feature dependent data in bytes
+} TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER;
+
+typedef struct {
+ TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER Header;
+ UINT8 LockingSupported : 1;
+ UINT8 LockingEnabled : 1; // means the locking security provider (SP) is enabled
+ UINT8 Locked : 1; // means at least 1 locking range is enabled
+ UINT8 MediaEncryption : 1;
+ UINT8 MbrEnabled : 1;
+ UINT8 MbrDone : 1;
+ UINT8 Reserved : 2;
+ UINT8 Reserved515[11];
+} TCG_LOCKING_FEATURE_DESCRIPTOR;
+
+typedef struct {
+ TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER Header;
+ UINT8 SIDValueState : 1;
+ UINT8 SIDBlockedState : 1;
+ UINT8 Reserved4 : 6;
+ UINT8 HardwareReset : 1;
+ UINT8 Reserved5 : 7;
+ UINT8 Reserved615[10];
+} TCG_BLOCK_SID_FEATURE_DESCRIPTOR;
+
+typedef struct {
+ TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER Header;
+ UINT8 SyncSupported : 1;
+ UINT8 AsyncSupported : 1;
+ UINT8 AckNakSupported : 1;
+ UINT8 BufferMgmtSupported : 1;
+ UINT8 StreamingSupported : 1;
+ UINT8 Reserved4b5 : 1;
+ UINT8 ComIdMgmtSupported : 1;
+ UINT8 Reserved4b7 : 1;
+ UINT8 Reserved515[11];
+} TCG_TPER_FEATURE_DESCRIPTOR;
+
+#pragma pack()
+
+// Special Purpose UIDs
+#define TCG_UID_NULL TCG_TO_UID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
+#define TCG_UID_THIS_SP TCG_TO_UID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
+#define TCG_UID_SMUID TCG_TO_UID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF)
+
+// Session Manager Method UIDS
+#define TCG_UID_SM_PROPERTIES TCG_TO_UID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x01)
+#define TCG_UID_SM_START_SESSION TCG_TO_UID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x02)
+#define TCG_UID_SM_SYNC_SESSION TCG_TO_UID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03)
+#define TCG_UID_SM_START_TRUSTED_SESSION TCG_TO_UID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x04)
+#define TCG_UID_SM_SYNC_TRUSTED_SESSION TCG_TO_UID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x05)
+#define TCG_UID_SM_CLOSE_SESSION TCG_TO_UID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x06)
+
+// MethodID UIDs
+#define TCG_UID_METHOD_DELETE_SP TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01)
+#define TCG_UID_METHOD_CREATE_TABLE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02)
+#define TCG_UID_METHOD_DELETE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03)
+#define TCG_UID_METHOD_CREATE_ROW TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04)
+#define TCG_UID_METHOD_DELETE_ROW TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05)
+#define TCG_UID_METHOD_NEXT TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08)
+#define TCG_UID_METHOD_GET_FREE_SPACE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x09)
+#define TCG_UID_METHOD_GET_FREE_ROWS TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A)
+#define TCG_UID_METHOD_DELETE_METHOD TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0B)
+#define TCG_UID_METHOD_GET_ACL TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0D)
+#define TCG_UID_METHOD_ADD_ACE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E)
+#define TCG_UID_METHOD_REMOVE_ACE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0F)
+#define TCG_UID_METHOD_GEN_KEY TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10)
+#define TCG_UID_METHOD_GET_PACKAGE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12)
+#define TCG_UID_METHOD_SET_PACKAGE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13)
+#define TCG_UID_METHOD_GET TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16)
+#define TCG_UID_METHOD_SET TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17)
+#define TCG_UID_METHOD_AUTHENTICATE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1C)
+#define TCG_UID_METHOD_ISSUE_SP TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01)
+#define TCG_UID_METHOD_GET_CLOCK TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x01)
+#define TCG_UID_METHOD_RESET_CLOCK TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x02)
+#define TCG_UID_METHOD_SET_CLOCK_HIGH TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x03)
+#define TCG_UID_METHOD_SET_LAG_HIGH TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x04)
+#define TCG_UID_METHOD_SET_CLOCK_LOW TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x05)
+#define TCG_UID_METHOD_SET_LAG_LOW TCG_TO_UID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x06)
+#define TCG_UID_METHOD_INCREMENT_COUNTER TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x07)
+#define TCG_UID_METHOD_RANDOM TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01)
+#define TCG_UID_METHOD_SALT TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x02)
+#define TCG_UID_METHOD_DECRYPT_INIT TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x03)
+#define TCG_UID_METHOD_DECRYPT TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x04)
+#define TCG_UID_METHOD_DECRYPT_FINALIZE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x05)
+#define TCG_UID_METHOD_ENCRYPT_INIT TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x06)
+#define TCG_UID_METHOD_ENCRYPT TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x07)
+#define TCG_UID_METHOD_ENCRYPT_FINALIZE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x08)
+#define TCG_UID_METHOD_HMAC_INIT TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x09)
+#define TCG_UID_METHOD_HMAC TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x0A)
+#define TCG_UID_METHOD_HMAC_FINALIZE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x0B)
+#define TCG_UID_METHOD_HASH_INIT TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x0C)
+#define TCG_UID_METHOD_HASH TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x0D)
+#define TCG_UID_METHOD_HASH_FINALIZE TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x0E)
+#define TCG_UID_METHOD_SIGN TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x0F)
+#define TCG_UID_METHOD_VERIFY TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x10)
+#define TCG_UID_METHOD_XOR TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x11)
+#define TCG_UID_METHOD_ADD_LOG TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0A, 0x01)
+#define TCG_UID_METHOD_CREATE_LOG TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0A, 0x02)
+#define TCG_UID_METHOD_CLEAR_LOG TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0A, 0x03)
+#define TCG_UID_METHOD_FLUSH_LOG TCG_TO_UID(0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0A, 0x04)
+
+#endif // TCG_H_
diff --git a/src/vendorcode/intel/tcg_storage_core/tcg_storage_util.c b/src/vendorcode/intel/tcg_storage_core/tcg_storage_util.c
new file mode 100644
index 0000000000..db8ccff548
--- /dev/null
+++ b/src/vendorcode/intel/tcg_storage_core/tcg_storage_util.c
@@ -0,0 +1,901 @@
+/* SPDX-License-Identifier: BSD-2-Clause-Patent */
+
+#include "tcg_storage_core_lib.h"
+
+typedef struct {
+ UINT16 FeatureCode;
+ TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER *Feature;
+ UINTN FeatureSize;
+} TCG_FIND_FEATURE_CTX;
+
+/**
+ Returns a human-readable string representing a method status return code.
+
+ @param[in] MethodStatus Method status to translate to a string
+
+
+ @retval return the string info.
+**/
+const CHAR8 *
+EFIAPI
+TcgMethodStatusString (
+ UINT8 MethodStatus
+ )
+{
+ switch (MethodStatus) {
+ #define C(status) case TCG_METHOD_STATUS_CODE_ ## status: return #status
+ C (SUCCESS);
+ C (NOT_AUTHORIZED);
+ C (OBSOLETE);
+ C (SP_BUSY);
+ C (SP_FAILED);
+ C (SP_DISABLED);
+ C (SP_FROZEN);
+ C (NO_SESSIONS_AVAILABLE);
+ C (UNIQUENESS_CONFLICT);
+ C (INSUFFICIENT_SPACE);
+ C (INSUFFICIENT_ROWS);
+ C (INVALID_PARAMETER);
+ C (OBSOLETE2);
+ C (OBSOLETE3);
+ C (TPER_MALFUNCTION);
+ C (TRANSACTION_FAILURE);
+ C (RESPONSE_OVERFLOW);
+ C (AUTHORITY_LOCKED_OUT);
+ C (FAIL);
+ #undef C
+ }
+
+ return "unknown";
+}
+
+/**
+ adds call token and method Header (invoking id, and method id).
+
+ @param CreateStruct The input create structure.
+ @param InvokingId Invoking id.
+ @param MethodId Method id.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgStartMethodCall (
+ TCG_CREATE_STRUCT *CreateStruct,
+ TCG_UID InvokingId,
+ TCG_UID MethodId
+ )
+{
+ 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);
+ }
+
+ ERROR_CHECK (TcgAddCall (CreateStruct));
+ ERROR_CHECK (TcgAddTcgUid (CreateStruct, InvokingId));
+ ERROR_CHECK (TcgAddTcgUid (CreateStruct, MethodId));
+
+ return TcgResultSuccess;
+}
+
+/**
+ Adds START LIST token.
+
+ @param CreateStruct The input create structure.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgStartParameters (
+ 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);
+ }
+
+ return TcgAddStartList (CreateStruct);
+}
+
+/**
+ Adds END LIST token.
+
+ @param CreateStruct The input create structure.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgEndParameters (
+ 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);
+ }
+
+ return TcgAddEndList (CreateStruct);
+}
+
+/**
+ Adds END Data token and method list.
+
+ @param CreateStruct The input create structure.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgEndMethodCall (
+ 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);
+ }
+
+ ERROR_CHECK (TcgAddEndOfData (CreateStruct));
+
+ ERROR_CHECK (TcgAddStartList (CreateStruct));
+ ERROR_CHECK (TcgAddUINT8 (CreateStruct, 0x00)); // expected to complete properly
+ ERROR_CHECK (TcgAddUINT8 (CreateStruct, 0x00)); // reserved
+ ERROR_CHECK (TcgAddUINT8 (CreateStruct, 0x00)); // reserved
+ ERROR_CHECK (TcgAddEndList (CreateStruct));
+
+ return TcgResultSuccess;
+}
+
+/**
+ Retrieves the comID and Extended comID of the ComPacket in the Tcg response.
+ It is intended to be used to confirm the received Tcg response is intended for user that received it.
+
+ @param [in] ParseStruct Structure used to parse received TCG response.
+ @param [in/out] ComId comID retrieved from received ComPacket.
+ @param [in/out] ComIdExtension Extended comID retrieved from received ComPacket
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetComIds (
+ const TCG_PARSE_STRUCT *ParseStruct,
+ UINT16 *ComId,
+ UINT16 *ComIdExtension
+ )
+{
+ NULL_CHECK (ParseStruct);
+ NULL_CHECK (ComId);
+ NULL_CHECK (ComIdExtension);
+
+ if (ParseStruct->ComPacket == NULL) {
+ DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p\n", ParseStruct->ComPacket));
+ return TcgResultFailureInvalidAction;
+ }
+
+ *ComId = SwapBytes16 (ParseStruct->ComPacket->ComIDBE);
+ *ComIdExtension = SwapBytes16 (ParseStruct->ComPacket->ComIDExtensionBE);
+
+ return TcgResultSuccess;
+}
+
+/**
+ Checks if the ComIDs of the response match the expected values.
+
+ @param[in] ParseStruct Structure used to parse received TCG response
+ @param[in] ExpectedComId Expected comID
+ @param[in] ExpectedComIdExtension Expected extended comID
+
+**/
+TCG_RESULT
+EFIAPI
+TcgCheckComIds (
+ const TCG_PARSE_STRUCT *ParseStruct,
+ UINT16 ExpectedComId,
+ UINT16 ExpectedComIdExtension
+ )
+{
+ UINT16 ParseComId;
+ UINT16 ParseComIdExtension;
+
+ ERROR_CHECK (TcgGetComIds (ParseStruct, &ParseComId, &ParseComIdExtension));
+ if ((ParseComId != ExpectedComId) || (ParseComIdExtension != ExpectedComIdExtension)) {
+ DEBUG ((DEBUG_INFO, "Com ID: Actual 0x%02X Expected 0x%02X\n", ParseComId, ExpectedComId));
+ DEBUG ((DEBUG_INFO, "Extended Com ID: 0x%02X Expected 0x%02X\n", ParseComIdExtension, ExpectedComIdExtension));
+ return TcgResultFailure;
+ }
+
+ return TcgResultSuccess;
+}
+
+/**
+ Returns the method status of the current subpacket. Does not affect the current position
+ in the ComPacket. In other words, it can be called whenever you have a valid SubPacket.
+
+ @param [in/out] ParseStruct Structure used to parse received TCG response
+ @param [in/out] MethodStatus Method status retrieved of the current SubPacket
+
+**/
+TCG_RESULT
+EFIAPI
+TcgGetMethodStatus (
+ const TCG_PARSE_STRUCT *ParseStruct,
+ UINT8 *MethodStatus
+ )
+{
+ TCG_PARSE_STRUCT TmpParseStruct;
+ TCG_TOKEN TcgToken;
+ UINT8 Reserved1, Reserved2;
+
+ NULL_CHECK (ParseStruct);
+ NULL_CHECK (MethodStatus);
+
+ 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;
+ }
+
+ // duplicate ParseStruct, then don't need to "reset" location cur ptr
+ CopyMem (&TmpParseStruct, ParseStruct, sizeof (TCG_PARSE_STRUCT));
+
+ // method status list exists after the end method call in the subpacket
+ // skip tokens until ENDDATA is found
+ do {
+ ERROR_CHECK (TcgGetNextToken (&TmpParseStruct, &TcgToken));
+ } while (TcgToken.Type != TcgTokenTypeEndOfData);
+
+ // only reach here if enddata is found
+ // at this point, the curptr is pointing at method status list beginning
+ ERROR_CHECK (TcgGetNextStartList (&TmpParseStruct));
+ ERROR_CHECK (TcgGetNextUINT8 (&TmpParseStruct, MethodStatus));
+ ERROR_CHECK (TcgGetNextUINT8 (&TmpParseStruct, &Reserved1));
+ ERROR_CHECK (TcgGetNextUINT8 (&TmpParseStruct, &Reserved2));
+ ERROR_CHECK (TcgGetNextEndList (&TmpParseStruct));
+
+ if (Reserved1 != 0) {
+ DEBUG ((DEBUG_INFO, "Method status reserved1 = 0x%02X (expected 0)\n", Reserved1));
+ return TcgResultFailure;
+ }
+
+ if (Reserved2 != 0) {
+ DEBUG ((DEBUG_INFO, "Method status reserved2 = 0x%02X (expected 0)\n", Reserved1));
+ return TcgResultFailure;
+ }
+
+ return TcgResultSuccess;
+}
+
+/**
+ Return the toke type string info.
+
+ @param Type Input the type info.
+
+ @retval Return the string for this type.
+
+**/
+const CHAR8 *
+EFIAPI
+TcgTokenTypeString (
+ TCG_TOKEN_TYPE Type
+ )
+{
+ switch (Type) {
+ case TcgTokenTypeReserved: return "Reserved";
+ case TcgTokenTypeTinyAtom: return "Tiny Atom";
+ case TcgTokenTypeShortAtom: return "Short Atom";
+ case TcgTokenTypeMediumAtom: return "Medium Atom";
+ case TcgTokenTypeLongAtom: return "Long Atom";
+ case TcgTokenTypeStartList: return "Start List";
+ case TcgTokenTypeEndList: return "End List";
+ case TcgTokenTypeStartName: return "Start Name";
+ case TcgTokenTypeEndName: return "End Name";
+ case TcgTokenTypeCall: return "Call";
+ case TcgTokenTypeEndOfData: return "End of Data";
+ case TcgTokenTypeEndOfSession: return "End of Session";
+ case TcgTokenTypeStartTransaction: return "Start Transaction";
+ case TcgTokenTypeEndTransaction: return "End Transaction";
+ case TcgTokenTypeEmptyAtom: return "Empty atom";
+ }
+
+ return "Unknown";
+}
+
+/**
+
+ Adds Start Session call to the data structure. This creates the entire ComPacket structure and
+ returns the size of the entire compacket in the size parameter.
+
+ @param [in/out] CreateStruct Structure used to add the start session call
+ @param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
+ @param [in] ComId ComID for the ComPacket
+ @param [in] ComIdExtension Extended ComID for the ComPacket
+ @param [in] HostSessionId Host Session ID
+ @param [in] SpId Security Provider to start session with
+ @param [in] Write Write option for start session. TRUE = start session requests write access
+ @param [in] HostChallengeLength Length of the host challenge. Length should be 0 if hostChallenge is NULL
+ @param [in] HostChallenge Host challenge for Host Signing Authority. If NULL, then no Host Challenge shall be sent.
+ @param [in] HostSigningAuthority Host Signing Authority used for start session. If NULL, then no Host Signing Authority shall be sent.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgCreateStartSession (
+ TCG_CREATE_STRUCT *CreateStruct,
+ UINT32 *Size,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 HostSessionId,
+ TCG_UID SpId,
+ BOOLEAN Write,
+ UINT32 HostChallengeLength,
+ const VOID *HostChallenge,
+ TCG_UID HostSigningAuthority
+ )
+{
+ ERROR_CHECK (TcgStartComPacket (CreateStruct, ComId, ComIdExtension));
+ ERROR_CHECK (TcgStartPacket (CreateStruct, 0x0, 0x0, 0x0, 0x0, 0x0));
+ ERROR_CHECK (TcgStartSubPacket (CreateStruct, 0x0));
+ ERROR_CHECK (TcgStartMethodCall (CreateStruct, TCG_UID_SMUID, TCG_UID_SM_START_SESSION));
+ ERROR_CHECK (TcgStartParameters (CreateStruct));
+ ERROR_CHECK (TcgAddUINT32 (CreateStruct, HostSessionId));
+ ERROR_CHECK (TcgAddTcgUid (CreateStruct, SpId));
+ ERROR_CHECK (TcgAddBOOLEAN (CreateStruct, Write));
+
+ // optional parameters
+ if ((HostChallenge != NULL) && (HostChallengeLength != 0)) {
+ ERROR_CHECK (TcgAddStartName (CreateStruct));
+ ERROR_CHECK (TcgAddUINT8 (CreateStruct, 0x00)); // TODO Create Enum for Method Optional Parameters?
+ ERROR_CHECK (TcgAddByteSequence (CreateStruct, HostChallenge, HostChallengeLength, FALSE));
+ ERROR_CHECK (TcgAddEndName (CreateStruct));
+ }
+
+ // optional parameters
+ if (HostSigningAuthority != 0) {
+ ERROR_CHECK (TcgAddStartName (CreateStruct));
+ ERROR_CHECK (TcgAddUINT8 (CreateStruct, 0x03)); // TODO Create Enum for Method Optional Parameters?
+ ERROR_CHECK (TcgAddTcgUid (CreateStruct, HostSigningAuthority));
+ ERROR_CHECK (TcgAddEndName (CreateStruct));
+ }
+
+ ERROR_CHECK (TcgEndParameters (CreateStruct));
+ ERROR_CHECK (TcgEndMethodCall (CreateStruct));
+ ERROR_CHECK (TcgEndSubPacket (CreateStruct));
+ ERROR_CHECK (TcgEndPacket (CreateStruct));
+ ERROR_CHECK (TcgEndComPacket (CreateStruct, Size));
+
+ return TcgResultSuccess;
+}
+
+/**
+ Parses the Sync Session response contained in the parseStruct to retrieve Tper session ID. If the Sync Session response
+ parameters do not match the comID, extended ComID and host session ID then a failure is returned.
+
+ @param[in/out] ParseStruct Structure used to parse received TCG response, contains Sync Session response.
+ @param[in] ComId Expected ComID that is compared to actual ComID of response
+ @param[in] ComIdExtension Expected Extended ComID that is compared to actual Extended ComID of response
+ @param[in] HostSessionId Expected Host Session ID that is compared to actual Host Session ID of response
+ @param[in/out] TperSessionId Tper Session ID retrieved from the Sync Session response.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgParseSyncSession (
+ const TCG_PARSE_STRUCT *ParseStruct,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 HostSessionId,
+ UINT32 *TperSessionId
+ )
+{
+ UINT8 MethodStatus;
+ TCG_PARSE_STRUCT TmpParseStruct;
+ UINT16 ParseComId;
+ UINT16 ParseExtComId;
+ TCG_UID InvokingUID;
+ TCG_UID MethodUID;
+ UINT32 RecvHostSessionId;
+
+ NULL_CHECK (ParseStruct);
+ NULL_CHECK (TperSessionId);
+
+ CopyMem (&TmpParseStruct, ParseStruct, sizeof (TCG_PARSE_STRUCT));
+
+ // verify method status is good
+ ERROR_CHECK (TcgGetMethodStatus (&TmpParseStruct, &MethodStatus));
+ METHOD_STATUS_ERROR_CHECK (MethodStatus, TcgResultFailure);
+
+ // verify comids
+ ERROR_CHECK (TcgGetComIds (&TmpParseStruct, &ParseComId, &ParseExtComId));
+
+ if ((ComId != ParseComId) || (ComIdExtension != ParseExtComId)) {
+ DEBUG ((DEBUG_INFO, "unmatched comid (exp: 0x%X recv: 0x%X) or comid extension (exp: 0x%X recv: 0x%X)\n", ComId, ParseComId, ComIdExtension, ParseExtComId));
+ return TcgResultFailure;
+ }
+
+ ERROR_CHECK (TcgGetNextCall (&TmpParseStruct));
+ ERROR_CHECK (TcgGetNextTcgUid (&TmpParseStruct, &InvokingUID));
+ ERROR_CHECK (TcgGetNextTcgUid (&TmpParseStruct, &MethodUID));
+ ERROR_CHECK (TcgGetNextStartList (&TmpParseStruct));
+ ERROR_CHECK (TcgGetNextUINT32 (&TmpParseStruct, &RecvHostSessionId));
+ ERROR_CHECK (TcgGetNextUINT32 (&TmpParseStruct, TperSessionId));
+ ERROR_CHECK (TcgGetNextEndList (&TmpParseStruct));
+ ERROR_CHECK (TcgGetNextEndOfData (&TmpParseStruct));
+
+ if (InvokingUID != TCG_UID_SMUID) {
+ DEBUG ((DEBUG_INFO, "Invoking UID did not match UID_SMUID\n"));
+ return TcgResultFailure;
+ }
+
+ if (MethodUID != TCG_UID_SM_SYNC_SESSION) {
+ DEBUG ((DEBUG_INFO, "Method UID did not match UID_SM_SYNC_SESSION\n"));
+ return TcgResultFailure;
+ }
+
+ if (HostSessionId != RecvHostSessionId) {
+ DEBUG ((DEBUG_INFO, "unmatched HostSessionId (exp: 0x%X recv: 0x%X)\n", HostSessionId, RecvHostSessionId));
+ return TcgResultFailure;
+ }
+
+ return TcgResultSuccess;
+}
+
+/**
+
+ Creates ComPacket with EndSession.
+ This assumes a start session has already been opened.
+
+ @param [in/out] CreateStruct Structure used to add Endsession
+ @param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
+ @param [in] ComId ComID for the ComPacket
+ @param [in] ComIdExtension Extended ComID for the ComPacket
+ @param [in] HostSessionId Host Session ID for the Packet
+ @param [in] TpSessionId Tper Session ID for the Packet
+
+**/
+TCG_RESULT
+EFIAPI
+TcgCreateEndSession (
+ TCG_CREATE_STRUCT *CreateStruct,
+ UINT32 *Size,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 HostSessionId,
+ UINT32 TpSessionId
+ )
+{
+ ERROR_CHECK (TcgStartComPacket (CreateStruct, ComId, ComIdExtension));
+ ERROR_CHECK (TcgStartPacket (CreateStruct, TpSessionId, HostSessionId, 0x0, 0x0, 0x0));
+ ERROR_CHECK (TcgStartSubPacket (CreateStruct, 0x0));
+ ERROR_CHECK (TcgAddEndOfSession (CreateStruct));
+ ERROR_CHECK (TcgEndSubPacket (CreateStruct));
+ ERROR_CHECK (TcgEndPacket (CreateStruct));
+ ERROR_CHECK (TcgEndComPacket (CreateStruct, Size));
+
+ return TcgResultSuccess;
+}
+
+/**
+ Set start method.
+
+ @param CreateStruct Input create structure.
+ @param Row Input the row info.
+ @param ColumnNumber the column info.
+
+**/
+static TCG_RESULT
+EFIAPI
+TcgStartMethodSet (
+ TCG_CREATE_STRUCT *CreateStruct,
+ TCG_UID Row,
+ UINT32 ColumnNumber
+ )
+{
+ ERROR_CHECK (TcgStartMethodCall (CreateStruct, Row, TCG_UID_METHOD_SET));
+ ERROR_CHECK (TcgStartParameters (CreateStruct));
+ ERROR_CHECK (TcgAddStartName (CreateStruct));
+ ERROR_CHECK (TcgAddUINT8 (CreateStruct, 0x01)); // "Values"
+ ERROR_CHECK (TcgAddStartList (CreateStruct));
+ ERROR_CHECK (TcgAddStartName (CreateStruct));
+ ERROR_CHECK (TcgAddUINT32 (CreateStruct, ColumnNumber));
+ return TcgResultSuccess;
+}
+
+/**
+ Set end method.
+
+ @param CreateStruct Input create structure.
+
+**/
+static TCG_RESULT
+EFIAPI
+TcgEndMethodSet (
+ TCG_CREATE_STRUCT *CreateStruct
+ )
+{
+ ERROR_CHECK (TcgAddEndName (CreateStruct));
+ ERROR_CHECK (TcgAddEndList (CreateStruct));
+ ERROR_CHECK (TcgAddEndName (CreateStruct));
+ ERROR_CHECK (TcgEndParameters (CreateStruct));
+ ERROR_CHECK (TcgEndMethodCall (CreateStruct));
+ return TcgResultSuccess;
+}
+
+/**
+ Creates ComPacket with a Method call that sets the PIN column for the row specified.
+ This assumes a start session has already been opened with the desired SP.
+
+ @param [in/out] CreateStruct Structure used to add method call.
+ @param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
+ @param [in] ComId ComID for the ComPacket
+ @param [in] ComIdExtension Extended ComID for the ComPacket
+ @param [in] TperSession Tper Session ID for the Packet
+ @param [in] HostSession Host Session ID for the Packet
+ @param [in] SidRow UID of row of current SP to set PIN column
+ @param [in] Password value of PIN to set
+ @param [in] PasswordSize Size of PIN
+
+**/
+TCG_RESULT
+EFIAPI
+TcgCreateSetCPin (
+ TCG_CREATE_STRUCT *CreateStruct,
+ UINT32 *Size,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 TperSession,
+ UINT32 HostSession,
+ TCG_UID SidRow,
+ const VOID *Password,
+ UINT32 PasswordSize
+ )
+{
+ // set new SID Password
+ ERROR_CHECK (TcgStartComPacket (CreateStruct, ComId, ComIdExtension));
+ ERROR_CHECK (TcgStartPacket (CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));
+ ERROR_CHECK (TcgStartSubPacket (CreateStruct, 0x0));
+ ERROR_CHECK (TcgStartMethodSet (CreateStruct, SidRow, 0x03)); // "PIN"
+ ERROR_CHECK (TcgAddByteSequence (CreateStruct, Password, PasswordSize, FALSE));
+ ERROR_CHECK (TcgEndMethodSet (CreateStruct));
+ ERROR_CHECK (TcgEndSubPacket (CreateStruct));
+ ERROR_CHECK (TcgEndPacket (CreateStruct));
+ ERROR_CHECK (TcgEndComPacket (CreateStruct, Size));
+ return TcgResultSuccess;
+}
+
+/**
+ Creates ComPacket with a Method call that sets the "Enabled" column for the row specified using the value specified.
+ This assumes a start session has already been opened with the desired SP.
+
+ @param [in/out] CreateStruct Structure used to add method call
+ @param [in/out] Size Describes the size of the entire ComPacket (header and payload). Filled out by function.
+ @param [in] ComId ComID for the ComPacket
+ @param [in] ComIdExtension Extended ComID for the ComPacket
+ @param [in] TperSession Tper Session ID for the Packet
+ @param [in] HostSession Host Session ID for the Packet
+ @param [in] AuthorityUid Authority UID to modify the "Enabled" column for
+ @param [in] Enabled Value to set the "Enabled" column to
+
+**/
+TCG_RESULT
+EFIAPI
+TcgSetAuthorityEnabled (
+ TCG_CREATE_STRUCT *CreateStruct,
+ UINT32 *Size,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 TperSession,
+ UINT32 HostSession,
+ TCG_UID AuthorityUid,
+ BOOLEAN Enabled
+ )
+{
+ ERROR_CHECK (TcgStartComPacket (CreateStruct, ComId, ComIdExtension));
+ ERROR_CHECK (TcgStartPacket (CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));
+ ERROR_CHECK (TcgStartSubPacket (CreateStruct, 0x0));
+ ERROR_CHECK (TcgStartMethodSet (CreateStruct, AuthorityUid, 0x05)); // "Enabled"
+ ERROR_CHECK (TcgAddBOOLEAN (CreateStruct, Enabled));
+ ERROR_CHECK (TcgEndMethodSet (CreateStruct));
+ ERROR_CHECK (TcgEndSubPacket (CreateStruct));
+ ERROR_CHECK (TcgEndPacket (CreateStruct));
+ ERROR_CHECK (TcgEndComPacket (CreateStruct, Size));
+ return TcgResultSuccess;
+}
+
+/**
+ Create set ace.
+
+ @param CreateStruct Input create structure.
+ @param Size size info.
+ @param ComId ComId info.
+ @param ComIdExtension ComId extension info.
+ @param TperSession Tper session data.
+ @param HostSession Host session data.
+ @param AceRow Ace row info.
+ @param Authority1 Authority 1 info.
+ @param LogicalOperator Logical operator info.
+ @param Authority2 Authority 2 info.
+
+ @retval Return the action result.
+
+**/
+TCG_RESULT
+EFIAPI
+TcgCreateSetAce (
+ TCG_CREATE_STRUCT *CreateStruct,
+ UINT32 *Size,
+ UINT16 ComId,
+ UINT16 ComIdExtension,
+ UINT32 TperSession,
+ UINT32 HostSession,
+ TCG_UID AceRow,
+ TCG_UID Authority1,
+ BOOLEAN LogicalOperator,
+ TCG_UID Authority2
+ )
+{
+ UINT8 HalfUidAuthorityObjectRef[4];
+ UINT8 HalfUidBooleanAce[4];
+
+ HalfUidAuthorityObjectRef[0] = 0x0;
+ HalfUidAuthorityObjectRef[1] = 0x0;
+ HalfUidAuthorityObjectRef[2] = 0xC;
+ HalfUidAuthorityObjectRef[3] = 0x5;
+
+ HalfUidBooleanAce[0] = 0x0;
+ HalfUidBooleanAce[1] = 0x0;
+ HalfUidBooleanAce[2] = 0x4;
+ HalfUidBooleanAce[3] = 0xE;
+
+ ERROR_CHECK (TcgStartComPacket (CreateStruct, ComId, ComIdExtension));
+ ERROR_CHECK (TcgStartPacket (CreateStruct, TperSession, HostSession, 0x0, 0x0, 0x0));
+ ERROR_CHECK (TcgStartSubPacket (CreateStruct, 0x0));
+ ERROR_CHECK (TcgStartMethodSet (CreateStruct, AceRow, 0x03)); // "BooleanExpr"
+ ERROR_CHECK (TcgAddStartList (CreateStruct));
+ ERROR_CHECK (TcgAddStartName (CreateStruct));
+ ERROR_CHECK (TcgAddByteSequence (CreateStruct, HalfUidAuthorityObjectRef, sizeof (HalfUidAuthorityObjectRef), FALSE));
+ ERROR_CHECK (TcgAddTcgUid (CreateStruct, Authority1));
+ ERROR_CHECK (TcgAddEndName (CreateStruct));
+ ERROR_CHECK (TcgAddStartName (CreateStruct));
+ ERROR_CHECK (TcgAddByteSequence (CreateStruct, HalfUidAuthorityObjectRef, sizeof (HalfUidAuthorityObjectRef), FALSE));
+ ERROR_CHECK (TcgAddTcgUid (CreateStruct, Authority2));
+ ERROR_CHECK (TcgAddEndName (CreateStruct));
+
+ ERROR_CHECK (TcgAddStartName (CreateStruct));
+ ERROR_CHECK (TcgAddByteSequence (CreateStruct, HalfUidBooleanAce, sizeof (HalfUidBooleanAce), FALSE));
+ ERROR_CHECK (TcgAddBOOLEAN (CreateStruct, LogicalOperator));
+ ERROR_CHECK (TcgAddEndName (CreateStruct));
+ ERROR_CHECK (TcgAddEndList (CreateStruct));
+ ERROR_CHECK (TcgEndMethodSet (CreateStruct));
+ ERROR_CHECK (TcgEndSubPacket (CreateStruct));
+ ERROR_CHECK (TcgEndPacket (CreateStruct));
+ ERROR_CHECK (TcgEndComPacket (CreateStruct, Size));
+ return TcgResultSuccess;
+}
+
+/**
+ Enum level 0 discovery.
+
+ @param DiscoveryHeader Discovery header.
+ @param Callback Callback function.
+ @param Context The context for the function.
+
+ @retval return true if the callback return TRUE, else return FALSE.
+
+**/
+BOOLEAN
+EFIAPI
+TcgEnumLevel0Discovery (
+ const TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader,
+ TCG_LEVEL0_ENUM_CALLBACK Callback,
+ VOID *Context
+ )
+{
+ UINT32 BytesLeft;
+ const UINT8 *DiscoveryBufferPtr;
+ UINT32 FeatLength;
+ TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER *Feat;
+
+ //
+ // Total bytes including descriptors but not including the Length field
+ //
+ BytesLeft = SwapBytes32 (DiscoveryHeader->LengthBE);
+
+ //
+ // If discovery Header is not valid, exit
+ //
+ if (BytesLeft == 0) {
+ return FALSE;
+ }
+
+ //
+ // Subtract the Length of the Header, except the Length field, which is not included
+ //
+ BytesLeft -= (sizeof (TCG_LEVEL0_DISCOVERY_HEADER) - sizeof (DiscoveryHeader->LengthBE));
+
+ //
+ // Move ptr to first descriptor
+ //
+ DiscoveryBufferPtr = (const UINT8 *)DiscoveryHeader + sizeof (TCG_LEVEL0_DISCOVERY_HEADER);
+
+ while (BytesLeft > sizeof (TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER)) {
+ //
+ // Pointer to beginning of descriptor (including common Header)
+ //
+ Feat = (TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER *)DiscoveryBufferPtr;
+
+ FeatLength = Feat->Length + sizeof (TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER);
+
+ //
+ // Not enough bytes left for Feature descriptor
+ //
+ if (BytesLeft < FeatLength) {
+ break;
+ }
+
+ //
+ // Report the Feature to the callback
+ //
+ if (Callback (DiscoveryHeader, Feat, FeatLength, Context)) {
+ return TRUE;
+ }
+
+ //
+ // Descriptor Length only describes Data after common Header
+ //
+ BytesLeft -= FeatLength;
+ DiscoveryBufferPtr += FeatLength;
+ }
+
+ return FALSE;
+}
+
+/**
+ The callback function for Get Feature function.
+
+ @param DiscoveryHeader Input discovery header.
+ @param Feature Input Feature.
+ @param FeatureSize Input Feature size.
+ @param Context The context.
+
+**/
+static BOOLEAN
+EFIAPI
+TcgFindFeatureCallback (
+ const TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader,
+ TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER *Feature,
+ UINTN FeatureSize,
+ VOID *Context
+ )
+{
+ TCG_FIND_FEATURE_CTX *FindCtx;
+
+ FindCtx = (TCG_FIND_FEATURE_CTX *)Context;
+ if ( SwapBytes16 (Feature->FeatureCode_BE) == FindCtx->FeatureCode ) {
+ FindCtx->Feature = Feature;
+ FindCtx->FeatureSize = FeatureSize;
+ return TRUE; // done enumerating features
+ }
+
+ return FALSE; // continue enumerating
+}
+
+/**
+ Get Feature code from the header.
+
+ @param DiscoveryHeader The discovery header.
+ @param FeatureCode return the Feature code.
+ @param FeatureSize return the Feature size.
+
+ @retval return the Feature code data.
+**/
+TCG_LEVEL0_FEATURE_DESCRIPTOR_HEADER *
+EFIAPI
+TcgGetFeature (
+ const TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader,
+ UINT16 FeatureCode,
+ UINTN *FeatureSize
+ )
+{
+ TCG_FIND_FEATURE_CTX FindCtx;
+
+ FindCtx.FeatureCode = FeatureCode;
+ FindCtx.Feature = NULL;
+ FindCtx.FeatureSize = 0;
+
+ TcgEnumLevel0Discovery (DiscoveryHeader, TcgFindFeatureCallback, &FindCtx);
+ if (FeatureSize != NULL) {
+ *FeatureSize = FindCtx.FeatureSize;
+ }
+
+ return FindCtx.Feature;
+}
+
+/**
+ Determines if the protocol provided is part of the provided supported protocol list.
+
+ @param[in] ProtocolList Supported protocol list to investigate
+ @param[in] Protocol Protocol value to determine if supported
+
+ @return TRUE = protocol is supported, FALSE = protocol is not supported
+**/
+BOOLEAN
+EFIAPI
+TcgIsProtocolSupported (
+ const TCG_SUPPORTED_SECURITY_PROTOCOLS *ProtocolList,
+ UINT16 Protocol
+ )
+{
+ UINT16 Index;
+ UINT16 ListLength;
+
+ ListLength = SwapBytes16 (ProtocolList->ListLength_BE);
+
+ if (ListLength > sizeof (ProtocolList->List)) {
+ DEBUG ((DEBUG_INFO, "WARNING: list Length is larger than max allowed Value; truncating\n"));
+ ListLength = sizeof (ProtocolList->List);
+ }
+
+ for (Index = 0; Index < ListLength; Index++) {
+ if (ProtocolList->List[Index] == Protocol) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Check whether lock or not.
+
+ @param Discovery
+
+ @retval TRUE if lock, FALSE if not lock.
+**/
+BOOLEAN
+EFIAPI
+TcgIsLocked (
+ const TCG_LEVEL0_DISCOVERY_HEADER *Discovery
+ )
+{
+ UINTN Size;
+ TCG_LOCKING_FEATURE_DESCRIPTOR *LockDescriptor;
+
+ Size = 0;
+ LockDescriptor = (TCG_LOCKING_FEATURE_DESCRIPTOR *)TcgGetFeature (Discovery, TCG_FEATURE_LOCKING, &Size);
+
+ if ((LockDescriptor != NULL) && (Size >= sizeof (*LockDescriptor))) {
+ DEBUG ((DEBUG_INFO, "locked: %d\n", LockDescriptor->Locked));
+ return LockDescriptor->Locked;
+ }
+
+ //
+ // Descriptor was not found
+ //
+ return FALSE;
+}
diff --git a/src/vendorcode/intel/tcg_storage_core/tcg_uefi_compat.h b/src/vendorcode/intel/tcg_storage_core/tcg_uefi_compat.h
new file mode 100644
index 0000000000..e81690fb9d
--- /dev/null
+++ b/src/vendorcode/intel/tcg_storage_core/tcg_uefi_compat.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef VENDORCODE_INTEL_TCG_STORAGE_CORE_UEFI_COMPAT_H
+#define VENDORCODE_INTEL_TCG_STORAGE_CORE_UEFI_COMPAT_H
+
+#include
+#include
+
+typedef u8 UINT8;
+typedef u16 UINT16;
+typedef u32 UINT32;
+typedef u64 UINT64;
+typedef s8 INT8;
+typedef s16 INT16;
+typedef s32 INT32;
+typedef s64 INT64;
+typedef char CHAR8;
+typedef size_t UINTN;
+typedef ptrdiff_t INTN;
+typedef void VOID;
+typedef bool BOOLEAN;
+
+#ifndef TRUE
+#define TRUE true
+#endif
+#ifndef FALSE
+#define FALSE false
+#endif
+
+#define EFIAPI
+
+#define CopyMem(d, s, n) memcpy((d), (s), (n))
+#define ZeroMem(d, n) memset((d), 0, (n))
+
+static inline UINT16 SwapBytes16(UINT16 v) { return __builtin_bswap16(v); }
+static inline UINT32 SwapBytes32(UINT32 v) { return __builtin_bswap32(v); }
+static inline UINT64 SwapBytes64(UINT64 v) { return __builtin_bswap64(v); }
+
+static inline UINT64 LShiftU64(UINT64 v, UINTN n) { return v << n; }
+
+#ifndef MAX_UINT8
+#define MAX_UINT8 ((UINT8)0xff)
+#endif
+#ifndef MAX_UINT16
+#define MAX_UINT16 ((UINT16)0xffff)
+#endif
+#ifndef MAX_UINT32
+#define MAX_UINT32 ((UINT32)0xffffffffu)
+#endif
+
+/* Keep DEBUG() calls compile-time silent in SMM. */
+#define DEBUG_INFO 0
+#define DEBUG_WARN 0
+#define DEBUG_ERROR 0
+#define DEBUG_LINE_NUMBER __LINE__
+#define DEBUG(x) do { } while (0)
+
+#define ASSERT(x) do { } while (0)
+
+#endif