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