Home | History | Annotate | Download | only in TcgStorageCoreLib
      1 /** @file
      2   Provide functions to provide tcg storage core spec related functions.
      3 
      4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <Library/TcgStorageCoreLib.h>
     16 
     17 #include <Library/BaseLib.h>
     18 #include <Library/BaseMemoryLib.h>
     19 #include <Library/DebugLib.h>
     20 //#include <Library/PrintLib.h>
     21 
     22 /**
     23   Required to be called before calling any other Tcg functions with the TCG_CREATE_STRUCT.
     24   Initializes the packet variables to NULL.  Additionally, the buffer will be memset.
     25 
     26   @param [in/out]    CreateStruct    Structure to initialize
     27   @param [in]        Buffer          Buffer allocated by client of library.  It will contain the Tcg encoded packet.  This cannot be null.
     28   @param [in]        BufferSize      Size of buffer provided.  It cannot be 0.
     29 
     30   @retval       Return the action result.
     31 **/
     32 TCG_RESULT
     33 EFIAPI
     34 TcgInitTcgCreateStruct(
     35   TCG_CREATE_STRUCT      *CreateStruct,
     36   VOID                   *Buffer,
     37   UINT32                 BufferSize
     38   )
     39 {
     40   NULL_CHECK(CreateStruct);
     41   NULL_CHECK(Buffer);
     42 
     43   if (BufferSize == 0) {
     44     DEBUG ((DEBUG_INFO, "BufferSize=0\n"));
     45     return (TcgResultFailureZeroSize);
     46   }
     47 
     48   ZeroMem(Buffer, BufferSize);
     49   CreateStruct->BufferSize = BufferSize;
     50   CreateStruct->Buffer = Buffer;
     51   CreateStruct->ComPacket = NULL;
     52   CreateStruct->CurPacket = NULL;
     53   CreateStruct->CurSubPacket = NULL;
     54 
     55   return (TcgResultSuccess);
     56 }
     57 
     58 /**
     59 
     60   Encodes the ComPacket header to the data structure.
     61 
     62   @param[in/out]    CreateStruct          Structure to initialize
     63   @param[in]        ComId                 ComID of the Tcg ComPacket.
     64   @param[in]        ComIdExtension        ComID Extension of the Tcg ComPacket.
     65 
     66 **/
     67 TCG_RESULT
     68 EFIAPI
     69 TcgStartComPacket(
     70   TCG_CREATE_STRUCT   *CreateStruct,
     71   UINT16              ComId,
     72   UINT16              ComIdExtension
     73   )
     74 {
     75   NULL_CHECK(CreateStruct);
     76 
     77   if (CreateStruct->ComPacket != NULL ||
     78       CreateStruct->CurPacket != NULL ||
     79       CreateStruct->CurSubPacket != NULL
     80      ) {
     81     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket,
     82     CreateStruct->CurSubPacket));
     83     return (TcgResultFailureInvalidAction);
     84   }
     85 
     86   if (sizeof(TCG_COM_PACKET) > CreateStruct->BufferSize) {
     87     DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));
     88     return (TcgResultFailureBufferTooSmall);
     89   }
     90 
     91   CreateStruct->ComPacket = (TCG_COM_PACKET*)CreateStruct->Buffer;
     92   CreateStruct->ComPacket->ComIDBE = SwapBytes16(ComId);
     93   CreateStruct->ComPacket->ComIDExtensionBE = SwapBytes16(ComIdExtension);
     94 
     95   return (TcgResultSuccess);
     96 }
     97 
     98 /**
     99 
    100   Starts a new ComPacket in the Data structure.
    101 
    102   @param [in/out]     CreateStruct    Structure used to add Tcg Packet
    103   @param[in]          Tsn             Packet Tper session number
    104   @param[in]          Hsn             Packet Host session number
    105   @param[in]          SeqNumber       Packet Sequence Number
    106   @param[in]          AckType         Packet Acknowledge Type
    107   @param[in]          Ack             Packet Acknowledge
    108 
    109 **/
    110 TCG_RESULT
    111 EFIAPI
    112 TcgStartPacket(
    113   TCG_CREATE_STRUCT    *CreateStruct,
    114   UINT32               Tsn,
    115   UINT32               Hsn,
    116   UINT32               SeqNumber,
    117   UINT16               AckType,
    118   UINT32               Ack
    119   )
    120 {
    121   UINT32 AddedSize;
    122   NULL_CHECK(CreateStruct);
    123 
    124   AddedSize = 0;
    125 
    126   if (CreateStruct->ComPacket == NULL ||
    127       CreateStruct->CurPacket != NULL ||
    128       CreateStruct->CurSubPacket != NULL
    129      ) {
    130     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
    131     return (TcgResultFailureInvalidAction);
    132   }
    133 
    134   // update TCG_COM_PACKET and packet lengths
    135   AddedSize = sizeof(TCG_PACKET);
    136 
    137   if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) {
    138     DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));
    139     return (TcgResultFailureBufferTooSmall);
    140   }
    141 
    142   CreateStruct->CurPacket = (TCG_PACKET*)(CreateStruct->ComPacket->Payload + SwapBytes32(CreateStruct->ComPacket->LengthBE));
    143 
    144   CreateStruct->CurPacket->TperSessionNumberBE = SwapBytes32( Tsn );
    145   CreateStruct->CurPacket->HostSessionNumberBE = SwapBytes32( Hsn );
    146   CreateStruct->CurPacket->SequenceNumberBE = SwapBytes32( SeqNumber );
    147   CreateStruct->CurPacket->AckTypeBE = SwapBytes16( AckType );
    148   CreateStruct->CurPacket->AcknowledgementBE = SwapBytes32( Ack );
    149 
    150   CreateStruct->CurPacket->LengthBE = 0;
    151 
    152   // update TCG_COM_PACKET Length for next pointer
    153   CreateStruct->ComPacket->LengthBE = SwapBytes32( SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize );
    154 
    155   return (TcgResultSuccess);
    156 }
    157 
    158 /**
    159 
    160   Starts a new SubPacket in the Data structure.
    161 
    162   @param[in/out]    CreateStruct        Structure used to start Tcg SubPacket
    163   @param[in]        Kind                SubPacket kind
    164 
    165 **/
    166 TCG_RESULT
    167 EFIAPI
    168 TcgStartSubPacket(
    169   TCG_CREATE_STRUCT    *CreateStruct,
    170   UINT16               Kind
    171   )
    172 {
    173   UINT32 AddedSize;
    174 
    175   NULL_CHECK(CreateStruct);
    176 
    177   AddedSize = 0;
    178 
    179   if (CreateStruct->ComPacket == NULL ||
    180       CreateStruct->CurPacket == NULL ||
    181       CreateStruct->CurSubPacket != NULL
    182      ) {
    183     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
    184     return (TcgResultFailureInvalidAction);
    185   }
    186 
    187   AddedSize = sizeof(TCG_SUB_PACKET);
    188 
    189   if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) {
    190     DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));
    191     return (TcgResultFailureBufferTooSmall);
    192   }
    193 
    194   CreateStruct->CurSubPacket = (TCG_SUB_PACKET*)(CreateStruct->CurPacket->Payload + SwapBytes32(CreateStruct->CurPacket->LengthBE));
    195   CreateStruct->CurSubPacket->KindBE = SwapBytes16(Kind);
    196 
    197   // update lengths
    198   CreateStruct->CurSubPacket->LengthBE = 0;
    199 
    200   // update TCG_COM_PACKET and packet lengths
    201   CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize);
    202   CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + AddedSize);
    203 
    204   return (TcgResultSuccess);
    205 }
    206 
    207 /**
    208 
    209   Ends the current SubPacket in the Data structure.  This function will also perform the 4-byte padding
    210   required for Subpackets.
    211 
    212   @param[in/out]       CreateStruct        Structure used to end the current Tcg SubPacket
    213 
    214 **/
    215 TCG_RESULT
    216 EFIAPI
    217 TcgEndSubPacket(
    218   TCG_CREATE_STRUCT   *CreateStruct
    219   )
    220 {
    221   UINT32 PadSize;
    222 
    223   NULL_CHECK(CreateStruct);
    224 
    225   PadSize = 0;
    226 
    227   if (CreateStruct->ComPacket == NULL ||
    228       CreateStruct->CurPacket == NULL  ||
    229       CreateStruct->CurSubPacket == NULL
    230      ) {
    231     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
    232     return (TcgResultFailureInvalidAction);
    233   }
    234 
    235   // align to 4-byte boundaries, so shift padding
    236   // pad Size does not apply to subpacket Length
    237   PadSize = TCG_SUBPACKET_ALIGNMENT - (SwapBytes32(CreateStruct->CurSubPacket->LengthBE) & (TCG_SUBPACKET_ALIGNMENT - 1));
    238 
    239   if (PadSize == TCG_SUBPACKET_ALIGNMENT) {
    240     PadSize = 0;
    241   }
    242 
    243   if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + PadSize) > CreateStruct->BufferSize) {
    244     DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize));
    245     return (TcgResultFailureBufferTooSmall);
    246   }
    247 
    248   CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + PadSize);
    249   CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + PadSize);
    250 
    251   CreateStruct->CurSubPacket = NULL;
    252 
    253   return (TcgResultSuccess);
    254 }
    255 
    256 /**
    257 
    258   Ends the current Packet in the Data structure.
    259 
    260   @param[in/out]       CreateStruct        Structure used to end the current Tcg Packet
    261 
    262 **/
    263 TCG_RESULT
    264 EFIAPI
    265 TcgEndPacket(
    266   TCG_CREATE_STRUCT     *CreateStruct
    267   )
    268 {
    269   NULL_CHECK(CreateStruct);
    270 
    271   if (CreateStruct->ComPacket == NULL ||
    272       CreateStruct->CurPacket == NULL ||
    273       CreateStruct->CurSubPacket != NULL
    274      ) {
    275     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
    276     return (TcgResultFailureInvalidAction);
    277   }
    278 
    279   CreateStruct->CurPacket = NULL;
    280 
    281   return (TcgResultSuccess);
    282 }
    283 
    284 /**
    285 
    286   Ends the ComPacket in the Data structure and ret
    287 
    288   @param [in/out]       CreateStruct       Structure used to end the Tcg ComPacket
    289   @param [in/out]       Size               Describes the Size of the entire ComPacket (Header and payload). Filled out by function.
    290 
    291 **/
    292 TCG_RESULT
    293 EFIAPI
    294 TcgEndComPacket(
    295   TCG_CREATE_STRUCT      *CreateStruct,
    296   UINT32                 *Size
    297   )
    298 {
    299   NULL_CHECK(CreateStruct);
    300   NULL_CHECK(Size);
    301 
    302   if (CreateStruct->ComPacket == NULL ||
    303       CreateStruct->CurPacket != NULL ||
    304       CreateStruct->CurSubPacket != NULL
    305      ) {
    306     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
    307     return (TcgResultFailureInvalidAction);
    308   }
    309 
    310   *Size = SwapBytes32(CreateStruct->ComPacket->LengthBE) + sizeof(*CreateStruct->ComPacket);
    311   CreateStruct->ComPacket = NULL;
    312 
    313   return (TcgResultSuccess);
    314 }
    315 
    316 /**
    317   Adds raw Data with optional Header
    318 
    319   @param       CreateStruct       The create structure.
    320   @param       Header             The header structure.
    321   @param       HeaderSize         The header size.
    322   @param       Data               The data need to add.
    323   @param       DataSize           The data size.
    324   @param       ByteSwapData       Whether byte or swap data.
    325 
    326 **/
    327 TCG_RESULT
    328 TcgAddRawTokenData(
    329   TCG_CREATE_STRUCT      *CreateStruct,
    330   const VOID             *Header,
    331   UINT8                  HeaderSize,
    332   const VOID             *Data,
    333   UINT32                 DataSize,
    334   BOOLEAN                ByteSwapData
    335   )
    336 {
    337   UINT32 AddedSize;
    338   UINT8* Dest;
    339   const UINT8* DataBytes;
    340   UINT32 Index;
    341 
    342   AddedSize = 0;
    343   Index = 0;
    344   Dest = NULL;
    345 
    346   NULL_CHECK(CreateStruct);
    347 
    348   if ((HeaderSize != 0 && Header == NULL) ||
    349       (DataSize != 0 && Data == NULL)
    350      ) {
    351     DEBUG ((DEBUG_INFO, "HeaderSize=0x%X Header=%p DataSize=0x%X Data=%p\n", HeaderSize, Header, DataSize, Data));
    352     return (TcgResultFailureNullPointer);
    353   }
    354 
    355   if (CreateStruct->ComPacket == NULL ||
    356       CreateStruct->CurPacket == NULL ||
    357       CreateStruct->CurSubPacket == NULL
    358      ) {
    359     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket));
    360     return (TcgResultFailureInvalidAction);
    361   }
    362 
    363   // verify there is enough Buffer Size
    364   AddedSize = HeaderSize + DataSize;
    365   if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) {
    366     return (TcgResultFailureBufferTooSmall);
    367   }
    368 
    369   // Get a pointer to where the new bytes should go
    370   Dest = CreateStruct->ComPacket->Payload + SwapBytes32(CreateStruct->ComPacket->LengthBE);
    371 
    372   switch (HeaderSize) {
    373     case sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM):
    374     case sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM):
    375     case sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM):
    376       CopyMem(Dest, Header, HeaderSize);
    377       Dest += HeaderSize;
    378     case 0: // no Header is valid
    379       break;
    380     // invalid Header Size
    381     default:
    382       DEBUG ((DEBUG_INFO, "unsupported HeaderSize=%u\n", HeaderSize));
    383       return TcgResultFailure;
    384   }
    385 
    386   // copy the Data bytes
    387   if (ByteSwapData) {
    388     DataBytes = (const UINT8*)Data;
    389     for (Index = 0; Index < DataSize; Index++) {
    390       Dest[Index] = DataBytes[DataSize - 1 - Index];
    391     }
    392   } else {
    393     CopyMem(Dest, Data, DataSize);
    394   }
    395 
    396   // Update all the packet sizes
    397   CreateStruct->ComPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize);
    398   CreateStruct->CurPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurPacket->LengthBE) + AddedSize);
    399   CreateStruct->CurSubPacket->LengthBE = SwapBytes32(SwapBytes32(CreateStruct->CurSubPacket->LengthBE) + AddedSize);
    400 
    401   return (TcgResultSuccess);
    402 }
    403 
    404 /**
    405 
    406   Adds a single raw token byte to the Data structure.
    407 
    408   @param[in/out]   CreateStruct        Structure used to add the byte
    409   @param[in]       Byte                Byte to add
    410 
    411 **/
    412 TCG_RESULT
    413 EFIAPI
    414 TcgAddRawByte(
    415   TCG_CREATE_STRUCT     *CreateStruct,
    416   UINT8                 Byte
    417   )
    418 {
    419   return TcgAddRawTokenData(CreateStruct, NULL, 0, &Byte, 1, FALSE);
    420 }
    421 
    422 
    423 /**
    424    simple tokens - atoms: tiny, short, medium, long and empty atoms.
    425    tiny atom can be a signed or unsigned integer.
    426    short, medium, long can be a signed or unsigned integer OR a complete or non-final byte sequence.
    427 
    428   @param       CreateStruct       The create structure.
    429   @param       Data               The data need to add.
    430   @param       DataSize           The data size.
    431   @param       ByteOrInt,         Data format is byte or int.
    432   @param       SignOrCont         sign or cont.
    433 
    434 
    435 **/
    436 TCG_RESULT
    437 TcgAddAtom(
    438   TCG_CREATE_STRUCT   *CreateStruct,
    439   const VOID          *Data,
    440   UINT32              DataSize,
    441   UINT8               ByteOrInt,
    442   UINT8               SignOrCont
    443   )
    444 {
    445   const UINT8* DataBytes;
    446   TCG_SIMPLE_TOKEN_TINY_ATOM TinyAtom;
    447   TCG_SIMPLE_TOKEN_SHORT_ATOM ShortAtom;
    448   TCG_SIMPLE_TOKEN_MEDIUM_ATOM MediumAtom;
    449   TCG_SIMPLE_TOKEN_LONG_ATOM LongAtom;
    450 
    451   NULL_CHECK(CreateStruct);
    452 
    453   if (DataSize == 0) {
    454     if (ByteOrInt == TCG_ATOM_TYPE_INTEGER) {
    455       DEBUG ((DEBUG_INFO, "0-Size integer not allowed\n"));
    456       return TcgResultFailure;
    457     }
    458   } else {
    459     // if DataSize != 0, Data must be valid
    460     NULL_CHECK(Data);
    461   }
    462 
    463   // encode Data using the shortest possible atom
    464   DataBytes = (const UINT8*)Data;
    465   if ((DataSize == 1) &&
    466       (ByteOrInt == TCG_ATOM_TYPE_INTEGER) &&
    467       ((SignOrCont != 0 && ((TCG_TOKEN_TINYATOM_SIGNED_MIN_VALUE <= *(INT8*)Data) && (*(INT8*)Data <= TCG_TOKEN_TINYATOM_SIGNED_MAX_VALUE))) ||
    468        (SignOrCont == 0 && ((*DataBytes <= TCG_TOKEN_TINYATOM_UNSIGNED_MAX_VALUE))))
    469      ) {
    470     TinyAtom.TinyAtomBits.IsZero = 0;
    471     TinyAtom.TinyAtomBits.Sign = SignOrCont;
    472     TinyAtom.TinyAtomBits.Data = *DataBytes & TCG_TOKEN_TINYATOM_UNSIGNED_MAX_VALUE;
    473     return TcgAddRawTokenData(CreateStruct, NULL, 0, (UINT8*)&TinyAtom, sizeof(TCG_SIMPLE_TOKEN_TINY_ATOM), FALSE);
    474   }
    475 
    476   if (DataSize <= TCG_TOKEN_SHORTATOM_MAX_BYTE_SIZE) {
    477     ShortAtom.ShortAtomBits.IsOne = 1;
    478     ShortAtom.ShortAtomBits.IsZero = 0;
    479     ShortAtom.ShortAtomBits.ByteOrInt = ByteOrInt;
    480     ShortAtom.ShortAtomBits.SignOrCont = SignOrCont;
    481     ShortAtom.ShortAtomBits.Length = DataSize & 0x0F;
    482     return TcgAddRawTokenData(CreateStruct, &ShortAtom, sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER);
    483   }
    484 
    485   if (DataSize <= TCG_TOKEN_MEDIUMATOM_MAX_BYTE_SIZE) {
    486     MediumAtom.MediumAtomBits.IsOne1 = 1;
    487     MediumAtom.MediumAtomBits.IsOne2 = 1;
    488     MediumAtom.MediumAtomBits.IsZero = 0;
    489     MediumAtom.MediumAtomBits.ByteOrInt = ByteOrInt;
    490     MediumAtom.MediumAtomBits.SignOrCont = SignOrCont;
    491     MediumAtom.MediumAtomBits.LengthLow = DataSize & 0xFF;
    492     MediumAtom.MediumAtomBits.LengthHigh = (DataSize >> TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) & TCG_MEDIUM_ATOM_LENGTH_HIGH_MASK;
    493     return TcgAddRawTokenData(CreateStruct, &MediumAtom, sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER);
    494   }
    495 
    496   LongAtom.LongAtomBits.IsOne1 = 1;
    497   LongAtom.LongAtomBits.IsOne2 = 1;
    498   LongAtom.LongAtomBits.IsOne3 = 1;
    499   LongAtom.LongAtomBits.IsZero = 0;
    500   LongAtom.LongAtomBits.ByteOrInt = ByteOrInt;
    501   LongAtom.LongAtomBits.SignOrCont = SignOrCont;
    502   LongAtom.LongAtomBits.LengthLow = DataSize & 0xFF;
    503   LongAtom.LongAtomBits.LengthMid = (DataSize >> TCG_LONG_ATOM_LENGTH_MID_SHIFT) & 0xFF;
    504   LongAtom.LongAtomBits.LengthHigh = (DataSize >> TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) & 0xFF;
    505   return TcgAddRawTokenData(CreateStruct, &LongAtom, sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM), Data, DataSize, ByteOrInt == TCG_ATOM_TYPE_INTEGER);
    506 }
    507 
    508 /**
    509 
    510   Adds the Data parameter as a byte sequence to the Data structure.
    511 
    512   @param[in/out]    CreateStruct      Structure used to add the byte sequence
    513   @param[in]        Data              Byte sequence that will be encoded and copied into Data structure
    514   @param[in]        DataSize          Length of Data provided
    515   @param[in]        Continued         TRUE if byte sequence is continued or
    516                                       FALSE if the Data contains the entire byte sequence to be encoded
    517 
    518 **/
    519 TCG_RESULT
    520 EFIAPI
    521 TcgAddByteSequence(
    522   TCG_CREATE_STRUCT     *CreateStruct,
    523   const VOID            *Data,
    524   UINT32                DataSize,
    525   BOOLEAN               Continued
    526   )
    527 {
    528   return TcgAddAtom(CreateStruct, Data, DataSize, TCG_ATOM_TYPE_BYTE, Continued ? 1 : 0);
    529 }
    530 
    531 /**
    532 
    533   Adds an arbitrary-Length integer to the Data structure.
    534   The integer will be encoded using the shortest possible atom.
    535 
    536   @param[in/out]     CreateStruct      Structure used to add the integer
    537   @param[in]         Data              Integer in host byte order that will be encoded and copied into Data structure
    538   @param[in]         DataSize          Length in bytes of the Data provided
    539   @param[in]         SignedInteger     TRUE if the integer is signed or FALSE if the integer is unsigned
    540 
    541 **/
    542 TCG_RESULT
    543 EFIAPI
    544 TcgAddInteger(
    545   TCG_CREATE_STRUCT  *CreateStruct,
    546   const VOID         *Data,
    547   UINT32             DataSize,
    548   BOOLEAN            SignedInteger
    549   )
    550 {
    551   const UINT8* DataBytes;
    552   UINT32 ActualDataSize;
    553   BOOLEAN ValueIsNegative;
    554 
    555   NULL_CHECK(CreateStruct);
    556   NULL_CHECK(Data);
    557 
    558   if (DataSize == 0) {
    559     DEBUG ((DEBUG_INFO, "invalid DataSize=0\n"));
    560     return TcgResultFailure;
    561   }
    562 
    563   DataBytes = (const UINT8*)Data;
    564 
    565   // integer should be represented by smallest atom possible
    566   // so calculate real Data Size
    567   ValueIsNegative = SignedInteger && DataBytes[ DataSize - 1 ] & 0x80;
    568 
    569   // assumes native Data is little endian
    570   // shorten Data to smallest byte representation
    571   for (ActualDataSize = DataSize; ActualDataSize > 1; ActualDataSize--) {
    572     // ignore sign extended  FFs
    573     if (ValueIsNegative && (DataBytes[ActualDataSize - 1] != 0xFF)) {
    574       break;
    575     } else if (!ValueIsNegative && (DataBytes[ActualDataSize - 1] != 0)) {
    576       // ignore extended 00s
    577       break;
    578     }
    579   }
    580 
    581   return TcgAddAtom(CreateStruct, Data, ActualDataSize, TCG_ATOM_TYPE_INTEGER, SignedInteger ? 1 : 0);
    582 }
    583 
    584 /**
    585   Adds an 8-bit unsigned integer to the Data structure.
    586 
    587   @param[in/out]       CreateStruct        Structure used to add the integer
    588   @param[in]           Value               Integer Value to add
    589 
    590 **/
    591 TCG_RESULT
    592 EFIAPI
    593 TcgAddUINT8(
    594   TCG_CREATE_STRUCT   *CreateStruct,
    595   UINT8               Value
    596   )
    597 {
    598   return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);
    599 }
    600 
    601 /**
    602 
    603   Adds a 16-bit unsigned integer to the Data structure.
    604 
    605   @param[in/out]       CreateStruct        Structure used to add the integer
    606   @param[in]           Value               Integer Value to add
    607 
    608 **/
    609 TCG_RESULT
    610 EFIAPI
    611 TcgAddUINT16 (
    612   TCG_CREATE_STRUCT   *CreateStruct,
    613   UINT16              Value
    614   )
    615 {
    616   return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);
    617 }
    618 
    619 /**
    620 
    621   Adds a 32-bit unsigned integer to the Data structure.
    622 
    623   @param[in/out]        CreateStruct        Structure used to add the integer
    624   @param[in]            Value               Integer Value to add
    625 
    626 **/
    627 TCG_RESULT
    628 EFIAPI
    629 TcgAddUINT32(
    630   TCG_CREATE_STRUCT    *CreateStruct,
    631   UINT32               Value
    632   )
    633 {
    634   return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);
    635 }
    636 
    637 
    638 /**
    639 
    640   Adds a 64-bit unsigned integer to the Data structure.
    641 
    642   @param[in/out]      CreateStruct        Structure used to add the integer
    643   @param[in]          Value               Integer Value to add
    644 
    645 **/
    646 TCG_RESULT
    647 EFIAPI
    648 TcgAddUINT64(
    649   TCG_CREATE_STRUCT   *CreateStruct,
    650   UINT64              Value
    651   )
    652 {
    653   return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);
    654 }
    655 
    656 /**
    657   Adds a BOOLEAN to the Data structure.
    658 
    659   @param[in/out]       CreateStruct     Structure used to add the integer
    660   @param[in]           Value              BOOLEAN Value to add
    661 
    662 **/
    663 TCG_RESULT
    664 EFIAPI
    665 TcgAddBOOLEAN(
    666   TCG_CREATE_STRUCT    *CreateStruct,
    667   BOOLEAN              Value
    668   )
    669 {
    670   return TcgAddInteger(CreateStruct, &Value, sizeof(Value), FALSE);
    671 }
    672 
    673 /**
    674   Add tcg uid info.
    675 
    676   @param [in/out]       CreateStruct       Structure used to add the integer
    677   @param                Uid                Input uid info.
    678 
    679   @retval   return the action result.
    680 
    681 **/
    682 TCG_RESULT
    683 EFIAPI
    684 TcgAddTcgUid(
    685   TCG_CREATE_STRUCT   *CreateStruct,
    686   TCG_UID             Uid
    687   )
    688 {
    689   return TcgAddByteSequence(CreateStruct, &Uid, sizeof(TCG_UID), FALSE);
    690 }
    691 
    692 /**
    693   Add start list.
    694 
    695   @param [in/out]       CreateStruct       Structure used to add the integer
    696 
    697   @retval   return the action result.
    698 
    699 **/
    700 TCG_RESULT
    701 EFIAPI
    702 TcgAddStartList(
    703   TCG_CREATE_STRUCT          *CreateStruct
    704   )
    705 {
    706   return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTLIST);
    707 }
    708 
    709 /**
    710   Add end list.
    711 
    712   @param [in/out]       CreateStruct       Structure used to add the integer
    713 
    714   @retval   return the action result.
    715 
    716 **/
    717 TCG_RESULT
    718 EFIAPI
    719 TcgAddEndList(
    720   TCG_CREATE_STRUCT       *CreateStruct
    721   )
    722 {
    723   return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDLIST);
    724 }
    725 
    726 /**
    727   Add start name.
    728 
    729   @param [in/out]       CreateStruct       Structure used to add the integer
    730 
    731   @retval   return the action result.
    732 
    733 **/
    734 TCG_RESULT
    735 EFIAPI
    736 TcgAddStartName(
    737   TCG_CREATE_STRUCT          *CreateStruct
    738   )
    739 {
    740   return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTNAME);
    741 }
    742 
    743 /**
    744   Add end name.
    745 
    746   @param [in/out]       CreateStruct       Structure used to add the integer
    747 
    748   @retval   return the action result.
    749 
    750 **/
    751 TCG_RESULT
    752 EFIAPI
    753 TcgAddEndName(
    754   TCG_CREATE_STRUCT          *CreateStruct
    755   )
    756 {
    757   return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDNAME);
    758 }
    759 
    760 /**
    761   Add end call.
    762 
    763   @param [in/out]       CreateStruct       Structure used to add the integer
    764 
    765   @retval   return the action result.
    766 
    767 **/
    768 TCG_RESULT
    769 EFIAPI
    770 TcgAddCall(
    771   TCG_CREATE_STRUCT      *CreateStruct
    772   )
    773 {
    774   return TcgAddRawByte(CreateStruct, TCG_TOKEN_CALL);
    775 }
    776 
    777 /**
    778   Add end of data.
    779 
    780   @param [in/out]       CreateStruct       Structure used to add the integer
    781 
    782   @retval   return the action result.
    783 
    784 **/
    785 TCG_RESULT
    786 EFIAPI
    787 TcgAddEndOfData(
    788   TCG_CREATE_STRUCT          *CreateStruct
    789   )
    790 {
    791   return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDDATA);
    792 }
    793 
    794 /**
    795   Add end of session.
    796 
    797   @param [in/out]       CreateStruct       Structure used to add the integer
    798 
    799   @retval   return the action result.
    800 
    801 **/
    802 TCG_RESULT
    803 EFIAPI
    804 TcgAddEndOfSession(
    805   TCG_CREATE_STRUCT              *CreateStruct
    806   )
    807 {
    808   return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDSESSION);
    809 }
    810 
    811 /**
    812   Add start transaction.
    813 
    814   @param [in/out]       CreateStruct       Structure used to add the integer
    815 
    816   @retval   return the action result.
    817 
    818 **/
    819 TCG_RESULT
    820 EFIAPI
    821 TcgAddStartTransaction(
    822   TCG_CREATE_STRUCT             *CreateStruct
    823   )
    824 {
    825   return TcgAddRawByte(CreateStruct, TCG_TOKEN_STARTTRANSACTION);
    826 }
    827 
    828 /**
    829   Add end transaction.
    830 
    831   @param [in/out]       CreateStruct       Structure used to add the integer
    832 
    833   @retval   return the action result.
    834 
    835 **/
    836 TCG_RESULT
    837 EFIAPI
    838 TcgAddEndTransaction(
    839   TCG_CREATE_STRUCT           *CreateStruct
    840   )
    841 {
    842   return TcgAddRawByte(CreateStruct, TCG_TOKEN_ENDTRANSACTION);
    843 }
    844 
    845 /**
    846   Initial the tcg parse stucture.
    847 
    848   @param    ParseStruct    Input parse structure.
    849   @param    Buffer         Input buffer data.
    850   @param    BufferSize     Input buffer size.
    851 
    852   @retval   return the action result.
    853 
    854 **/
    855 TCG_RESULT
    856 EFIAPI
    857 TcgInitTcgParseStruct(
    858   TCG_PARSE_STRUCT          *ParseStruct,
    859   const VOID                *Buffer,
    860   UINT32                    BufferSize
    861   )
    862 {
    863   UINT32 ComPacketLength;
    864   UINT32 PacketLength;
    865 
    866   NULL_CHECK(ParseStruct);
    867   NULL_CHECK(Buffer);
    868 
    869   if (BufferSize < sizeof(TCG_COM_PACKET)) {
    870     return (TcgResultFailureBufferTooSmall);
    871   }
    872 
    873   ParseStruct->ComPacket = (TCG_COM_PACKET*)Buffer;
    874 
    875   ComPacketLength = SwapBytes32(ParseStruct->ComPacket->LengthBE);
    876 
    877   if ((BufferSize - sizeof(TCG_COM_PACKET)) < ComPacketLength) {
    878     DEBUG ((DEBUG_INFO, "Buffer %u too small for ComPacket %u\n", BufferSize, ComPacketLength));
    879     return (TcgResultFailureBufferTooSmall);
    880   }
    881 
    882   ParseStruct->BufferSize = BufferSize;
    883   ParseStruct->Buffer = Buffer;
    884 
    885   ParseStruct->CurPacket = NULL;
    886   ParseStruct->CurSubPacket = NULL;
    887   ParseStruct->CurPtr = NULL;
    888 
    889   // if payload > 0, then must have a packet
    890   if (ComPacketLength != 0) {
    891     if (ComPacketLength < sizeof(TCG_PACKET)) {
    892       DEBUG ((DEBUG_INFO, "ComPacket too small for Packet\n"));
    893       return (TcgResultFailureBufferTooSmall);
    894     }
    895     ParseStruct->CurPacket = (TCG_PACKET*)ParseStruct->ComPacket->Payload;
    896 
    897     PacketLength = SwapBytes32(ParseStruct->CurPacket->LengthBE);
    898 
    899     if (PacketLength > 0) {
    900       if (PacketLength < sizeof(TCG_SUB_PACKET)) {
    901           DEBUG ((DEBUG_INFO, "Packet too small for SubPacket\n"));
    902           return (TcgResultFailureBufferTooSmall);
    903       }
    904 
    905       ParseStruct->CurSubPacket = (TCG_SUB_PACKET*)ParseStruct->CurPacket->Payload;
    906     }
    907   }
    908 
    909   //TODO should check for method status list at this point?
    910 
    911   return (TcgResultSuccess);
    912 }
    913 
    914 /**
    915   Get next token info.
    916 
    917   @param    ParseStruct      Input parse structure info.
    918   @param    TcgToken         return the tcg token info.
    919 
    920   @retval   return the action result.
    921 
    922 **/
    923 TCG_RESULT
    924 EFIAPI
    925 TcgGetNextToken(
    926   TCG_PARSE_STRUCT      *ParseStruct,
    927   TCG_TOKEN             *TcgToken
    928   )
    929 {
    930   const UINT8* EndOfSubPacket;
    931   UINT8* TokenEnd;
    932   UINT8 Hdr;
    933   TCG_SIMPLE_TOKEN_SHORT_ATOM* TmpShort;
    934   const TCG_SIMPLE_TOKEN_MEDIUM_ATOM* TmpMed;
    935   const TCG_SIMPLE_TOKEN_LONG_ATOM* TmpLong;
    936 
    937   NULL_CHECK(ParseStruct);
    938   NULL_CHECK(TcgToken);
    939 
    940   if (ParseStruct->ComPacket == NULL ||
    941       ParseStruct->CurPacket == NULL ||
    942       ParseStruct->CurSubPacket == NULL
    943      ) {
    944     DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", ParseStruct->ComPacket, ParseStruct->CurPacket, ParseStruct->CurSubPacket));
    945     return TcgResultFailureInvalidAction;
    946   }
    947 
    948   // initial call, start at sub packet
    949   if (ParseStruct->CurPtr == NULL) {
    950     ParseStruct->CurPtr = ParseStruct->CurSubPacket->Payload;
    951   }
    952 
    953   EndOfSubPacket = ParseStruct->CurSubPacket->Payload + SwapBytes32(ParseStruct->CurSubPacket->LengthBE);
    954   TokenEnd = NULL;
    955 
    956   // confirmed that subpacket Length falls within end of Buffer and TCG_COM_PACKET,
    957   // so simply need to verify the loop stays within current subpacket
    958   if (ParseStruct->CurPtr >= EndOfSubPacket) {
    959     DEBUG ((DEBUG_INFO, "ParseStruct->CurPtr >= EndOfSubPacket\n"));
    960     return (TcgResultFailureEndBuffer);
    961   }
    962 
    963   Hdr = *ParseStruct->CurPtr;
    964   TcgToken->HdrStart = ParseStruct->CurPtr;
    965 
    966   // Tiny Atom range
    967   if (Hdr <= 0x7F) {
    968     // tiny atom Header is only 1 byte, so don't need to verify Size before cast and access
    969     TcgToken->Type = TcgTokenTypeTinyAtom;
    970 
    971     TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_TINY_ATOM);
    972 
    973     // verify caller will have enough Size to reference token
    974     if (TokenEnd >= EndOfSubPacket) {
    975       DEBUG ((DEBUG_INFO, "Tiny Atom TokenEnd >= EndOfSubPacket\n"));
    976       return (TcgResultFailureEndBuffer);
    977     }
    978   }
    979   // Short Atom Range
    980   else if (0x80 <= Hdr && Hdr <= 0xBF) {
    981     // short atom Header is only 1 byte, so don't need to verify Size before cast and access
    982     TmpShort = (TCG_SIMPLE_TOKEN_SHORT_ATOM*)(ParseStruct->CurPtr);
    983     TcgToken->Type = TcgTokenTypeShortAtom;
    984 
    985     TokenEnd = (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM) + TmpShort->ShortAtomBits.Length);
    986 
    987     // verify caller will have enough Size to reference token
    988     if (TokenEnd >= EndOfSubPacket) {
    989       DEBUG ((DEBUG_INFO, "Short Atom TokenEnd >= EndOfSubPacket\n"));
    990       return (TcgResultFailureEndBuffer);
    991     }
    992   }
    993   // Medium Atom Range
    994   else if (0xC0 <= Hdr && Hdr <= 0xDF) {
    995     if (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM) >= EndOfSubPacket) {
    996       return (TcgResultFailureEndBuffer);
    997     }
    998     TmpMed = (const TCG_SIMPLE_TOKEN_MEDIUM_ATOM*)ParseStruct->CurPtr;
    999     TcgToken->Type = TcgTokenTypeMediumAtom;
   1000     TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM) +
   1001                ((TmpMed->MediumAtomBits.LengthHigh << TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) |
   1002                 TmpMed->MediumAtomBits.LengthLow);
   1003 
   1004     // verify caller will have enough Size to reference token
   1005     if (TokenEnd >= EndOfSubPacket) {
   1006       DEBUG ((DEBUG_INFO, "Medium Atom TokenEnd >= EndOfSubPacket\n"));
   1007       return (TcgResultFailureEndBuffer);
   1008     }
   1009   }
   1010   // Long Atom Range
   1011   else if (0xE0 <= Hdr && Hdr <= 0xE3) {
   1012     if (TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM) >= EndOfSubPacket) {
   1013       return (TcgResultFailureEndBuffer);
   1014     }
   1015     TmpLong = (const TCG_SIMPLE_TOKEN_LONG_ATOM*)ParseStruct->CurPtr;
   1016     TcgToken->Type = TcgTokenTypeLongAtom;
   1017 
   1018     TokenEnd = TcgToken->HdrStart + sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM) +
   1019                ((TmpLong->LongAtomBits.LengthHigh << TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) |
   1020                 (TmpLong->LongAtomBits.LengthMid << TCG_LONG_ATOM_LENGTH_MID_SHIFT)   |
   1021                 TmpLong->LongAtomBits.LengthLow);
   1022 
   1023     // verify caller will have enough Size to reference token
   1024     if (TokenEnd >= EndOfSubPacket) {
   1025       DEBUG ((DEBUG_INFO, "Long Atom TokenEnd >= EndOfSubPacket\n"));
   1026       return (TcgResultFailureEndBuffer);
   1027     }
   1028   } else {
   1029     // single byte tokens
   1030     switch (Hdr) {
   1031       case TCG_TOKEN_STARTLIST:
   1032           TcgToken->Type = TcgTokenTypeStartList;
   1033           break;
   1034       case TCG_TOKEN_ENDLIST:
   1035           TcgToken->Type = TcgTokenTypeEndList;
   1036           break;
   1037       case TCG_TOKEN_STARTNAME:
   1038           TcgToken->Type = TcgTokenTypeStartName;
   1039           break;
   1040       case TCG_TOKEN_ENDNAME:
   1041           TcgToken->Type = TcgTokenTypeEndName;
   1042           break;
   1043       case TCG_TOKEN_CALL:
   1044           TcgToken->Type = TcgTokenTypeCall;
   1045           break;
   1046       case TCG_TOKEN_ENDDATA:
   1047           TcgToken->Type = TcgTokenTypeEndOfData;
   1048           break;
   1049       case TCG_TOKEN_ENDSESSION:
   1050           TcgToken->Type = TcgTokenTypeEndOfSession;
   1051           break;
   1052       case TCG_TOKEN_STARTTRANSACTION:
   1053           TcgToken->Type = TcgTokenTypeStartTransaction;
   1054           break;
   1055       case TCG_TOKEN_ENDTRANSACTION:
   1056           TcgToken->Type = TcgTokenTypeEndTransaction;
   1057           break;
   1058       case TCG_TOKEN_EMPTY:
   1059           TcgToken->Type = TcgTokenTypeEmptyAtom;
   1060           break;
   1061       default:
   1062           DEBUG ((DEBUG_INFO, "WARNING: reserved token Type 0x%02X\n", Hdr));
   1063           TcgToken->Type = TcgTokenTypeReserved;
   1064           break;
   1065     }
   1066     ParseStruct->CurPtr++;
   1067     TokenEnd = TcgToken->HdrStart + 1;
   1068   }
   1069 
   1070   // increment curptr for next call
   1071   ParseStruct->CurPtr = TokenEnd;
   1072   return (TcgResultSuccess);
   1073 }
   1074 
   1075 /**
   1076   Get atom info.
   1077 
   1078   @param    TcgToken          Input token info.
   1079   @param    HeaderLength      return the header length.
   1080   @param    DataLength        return the data length.
   1081   @param    ByteOrInt         return the atom Type.
   1082   @param    SignOrCont        return the sign or count info.
   1083 
   1084   @retval   return the action result.
   1085 
   1086 **/
   1087 TCG_RESULT
   1088 EFIAPI
   1089 TcgGetAtomInfo(
   1090   const TCG_TOKEN      *TcgToken,
   1091   UINT32               *HeaderLength,
   1092   UINT32               *DataLength,
   1093   UINT8                *ByteOrInt,
   1094   UINT8                *SignOrCont
   1095   )
   1096 {
   1097   TCG_SIMPLE_TOKEN_TINY_ATOM* TinyAtom;
   1098   TCG_SIMPLE_TOKEN_SHORT_ATOM* ShortAtom;
   1099   TCG_SIMPLE_TOKEN_MEDIUM_ATOM* MediumAtom;
   1100   TCG_SIMPLE_TOKEN_LONG_ATOM* LongAtom;
   1101 
   1102   NULL_CHECK(TcgToken);
   1103   NULL_CHECK(HeaderLength);
   1104   NULL_CHECK(DataLength);
   1105   NULL_CHECK(ByteOrInt);
   1106   NULL_CHECK(SignOrCont);
   1107 
   1108   switch (TcgToken->Type) {
   1109     case TcgTokenTypeTinyAtom: {
   1110       TinyAtom = (TCG_SIMPLE_TOKEN_TINY_ATOM*)TcgToken->HdrStart;
   1111       *ByteOrInt      = TCG_ATOM_TYPE_INTEGER;
   1112       *SignOrCont     = TinyAtom->TinyAtomBits.Sign;
   1113       *HeaderLength   = 0;
   1114       *DataLength     = 0; // tiny atom must be handled as a special case - Header and Data in the same byte
   1115       return TcgResultSuccess;
   1116     }
   1117 
   1118     case TcgTokenTypeShortAtom: {
   1119       ShortAtom = (TCG_SIMPLE_TOKEN_SHORT_ATOM*)TcgToken->HdrStart;
   1120       *ByteOrInt      = ShortAtom->ShortAtomBits.ByteOrInt;
   1121       *SignOrCont     = ShortAtom->ShortAtomBits.SignOrCont;
   1122       *HeaderLength   = sizeof(TCG_SIMPLE_TOKEN_SHORT_ATOM);
   1123       *DataLength     = ShortAtom->ShortAtomBits.Length;
   1124       return TcgResultSuccess;
   1125     }
   1126 
   1127     case TcgTokenTypeMediumAtom: {
   1128       MediumAtom = (TCG_SIMPLE_TOKEN_MEDIUM_ATOM*)TcgToken->HdrStart;
   1129       *ByteOrInt      = MediumAtom->MediumAtomBits.ByteOrInt;
   1130       *SignOrCont     = MediumAtom->MediumAtomBits.SignOrCont;
   1131       *HeaderLength   = sizeof(TCG_SIMPLE_TOKEN_MEDIUM_ATOM);
   1132       *DataLength     = (MediumAtom->MediumAtomBits.LengthHigh << TCG_MEDIUM_ATOM_LENGTH_HIGH_SHIFT) | MediumAtom->MediumAtomBits.LengthLow;
   1133       return TcgResultSuccess;
   1134     }
   1135 
   1136     case TcgTokenTypeLongAtom: {
   1137       LongAtom = (TCG_SIMPLE_TOKEN_LONG_ATOM*)TcgToken->HdrStart;
   1138       *ByteOrInt      = LongAtom->LongAtomBits.ByteOrInt;
   1139       *SignOrCont     = LongAtom->LongAtomBits.SignOrCont;
   1140       *HeaderLength   = sizeof(TCG_SIMPLE_TOKEN_LONG_ATOM);
   1141       *DataLength     = (LongAtom->LongAtomBits.LengthHigh << TCG_LONG_ATOM_LENGTH_HIGH_SHIFT) |
   1142                         (LongAtom->LongAtomBits.LengthMid << TCG_LONG_ATOM_LENGTH_MID_SHIFT) |
   1143                         LongAtom->LongAtomBits.LengthLow;
   1144       return TcgResultSuccess;
   1145     }
   1146 
   1147     default:
   1148       DEBUG ((DEBUG_INFO, "Token Type is not simple atom (%d)\n", TcgToken->Type));
   1149       return (TcgResultFailureInvalidType);
   1150   }
   1151 }
   1152 
   1153 /**
   1154   Get token specified value.
   1155 
   1156   @param    TcgToken   Input token info.
   1157   @param    Value      return the value.
   1158 
   1159   @retval   return the action result.
   1160 
   1161 **/
   1162 TCG_RESULT
   1163 EFIAPI
   1164 TcgGetTokenUINT64(
   1165   const TCG_TOKEN      *TcgToken,
   1166   UINT64               *Value
   1167   )
   1168 {
   1169   UINT32 HdrLength;
   1170   UINT32 DataLength;
   1171   UINT8 ByteOrInt;
   1172   UINT8 IsSigned;
   1173   TCG_SIMPLE_TOKEN_TINY_ATOM* TmpTiny;
   1174   const UINT8* Data;
   1175   UINT32 Index;
   1176 
   1177   NULL_CHECK(TcgToken);
   1178   NULL_CHECK(Value);
   1179 
   1180   Index = 0;
   1181   *Value = 0;
   1182   ERROR_CHECK(TcgGetAtomInfo(TcgToken, &HdrLength, &DataLength, &ByteOrInt, &IsSigned));
   1183 
   1184   if (ByteOrInt != TCG_ATOM_TYPE_INTEGER) {
   1185     DEBUG ((DEBUG_INFO, "Invalid Type, expected integer not byte sequence\n"));
   1186     return TcgResultFailureInvalidType;
   1187   }
   1188 
   1189   if (IsSigned != 0) {
   1190     DEBUG ((DEBUG_INFO, "Integer is signed, expected unsigned\n"));
   1191     return TcgResultFailureInvalidType;
   1192   }
   1193 
   1194   // special case for tiny atom
   1195   // Header and Data are in one byte, so extract only the Data bitfield
   1196   if (TcgToken->Type == TcgTokenTypeTinyAtom) {
   1197     TmpTiny = (TCG_SIMPLE_TOKEN_TINY_ATOM*)TcgToken->HdrStart;
   1198     *Value = TmpTiny->TinyAtomBits.Data;
   1199     return TcgResultSuccess;
   1200   }
   1201 
   1202   if (DataLength > sizeof(UINT64)) {
   1203     DEBUG ((DEBUG_INFO, "Length %d is greater than Size of UINT64\n", DataLength));
   1204     return TcgResultFailureBufferTooSmall;
   1205   }
   1206 
   1207   // read big-endian integer
   1208   Data = TcgToken->HdrStart + HdrLength;
   1209   for (Index = 0; Index < DataLength; Index++) {
   1210     *Value = LShiftU64(*Value, 8) | Data[Index];
   1211   }
   1212 
   1213   return TcgResultSuccess;
   1214 }
   1215 
   1216 /**
   1217   Get token byte sequence.
   1218 
   1219   @param    TcgToken   Input token info.
   1220   @param    Length     Input the length info.
   1221 
   1222   @retval   Return the value data.
   1223 
   1224 **/
   1225 UINT8*
   1226 EFIAPI
   1227 TcgGetTokenByteSequence(
   1228   const TCG_TOKEN     *TcgToken,
   1229   UINT32              *Length
   1230   )
   1231 {
   1232   UINT32 HdrLength;
   1233   UINT8 ByteOrInt;
   1234   UINT8 SignOrCont;
   1235 
   1236   if (TcgToken == NULL || Length == NULL) {
   1237     return NULL;
   1238   }
   1239 
   1240   *Length = 0;
   1241   if (TcgGetAtomInfo(TcgToken, &HdrLength, Length, &ByteOrInt, &SignOrCont) != TcgResultSuccess) {
   1242     DEBUG ((DEBUG_INFO, "Failed to get simple token info\n"));
   1243     return NULL;
   1244   }
   1245 
   1246   if (ByteOrInt != TCG_ATOM_TYPE_BYTE) {
   1247     DEBUG ((DEBUG_INFO, "Invalid Type, expected byte sequence not integer\n"));
   1248     return NULL;
   1249   }
   1250 
   1251   return (TcgToken->HdrStart + HdrLength);
   1252 }
   1253 
   1254 /**
   1255   Get next specify value.
   1256 
   1257   @param    ParseStruct   Input parse structure.
   1258   @param    Value         Return vlaue.
   1259 
   1260   @retval   return the action result.
   1261 
   1262 **/
   1263 TCG_RESULT
   1264 EFIAPI
   1265 TcgGetNextUINT8(
   1266   TCG_PARSE_STRUCT      *ParseStruct,
   1267   UINT8                 *Value
   1268   )
   1269 {
   1270   UINT64 Value64;
   1271   TCG_TOKEN Tok;
   1272 
   1273   NULL_CHECK(Value);
   1274 
   1275   ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
   1276   ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));
   1277 
   1278   if (Value64 > MAX_UINT8) {
   1279     return TcgResultFailure;
   1280   }
   1281 
   1282   *Value = (UINT8)Value64;
   1283 
   1284   return TcgResultSuccess;
   1285 }
   1286 
   1287 /**
   1288   Get next specify value.
   1289 
   1290   @param    ParseStruct   Input parse structure.
   1291   @param    Value         Return vlaue.
   1292 
   1293   @retval   return the action result.
   1294 
   1295 **/
   1296 TCG_RESULT
   1297 EFIAPI
   1298 TcgGetNextUINT16(
   1299   TCG_PARSE_STRUCT     *ParseStruct,
   1300   UINT16               *Value
   1301   )
   1302 {
   1303   UINT64 Value64;
   1304   TCG_TOKEN Tok;
   1305 
   1306   NULL_CHECK(Value);
   1307 
   1308   ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
   1309   ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));
   1310 
   1311   if (Value64 > MAX_UINT16) {
   1312     return TcgResultFailure;
   1313   }
   1314 
   1315   *Value = (UINT16)Value64;
   1316 
   1317   return TcgResultSuccess;
   1318 }
   1319 
   1320 /**
   1321   Get next specify value.
   1322 
   1323   @param    ParseStruct   Input parse structure.
   1324   @param    Value         Return vlaue.
   1325 
   1326   @retval   return the action result.
   1327 
   1328 **/
   1329 TCG_RESULT
   1330 EFIAPI
   1331 TcgGetNextUINT32(
   1332   TCG_PARSE_STRUCT          *ParseStruct,
   1333   UINT32                    *Value
   1334   )
   1335 {
   1336   UINT64 Value64;
   1337   TCG_TOKEN Tok;
   1338 
   1339   NULL_CHECK(Value);
   1340 
   1341   ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
   1342   ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));
   1343 
   1344   if (Value64 > MAX_UINT32) {
   1345     return TcgResultFailure;
   1346   }
   1347 
   1348   *Value = (UINT32)Value64;
   1349 
   1350   return TcgResultSuccess;
   1351 }
   1352 
   1353 /**
   1354   Get next specify value.
   1355 
   1356   @param    ParseStruct   Input parse structure.
   1357   @param    Value         Return vlaue.
   1358 
   1359   @retval   return the action result.
   1360 
   1361 **/
   1362 TCG_RESULT
   1363 EFIAPI
   1364 TcgGetNextUINT64(
   1365   TCG_PARSE_STRUCT           *ParseStruct,
   1366   UINT64                     *Value
   1367   )
   1368 {
   1369   TCG_TOKEN Tok;
   1370   ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
   1371   ERROR_CHECK(TcgGetTokenUINT64(&Tok, Value));
   1372   return TcgResultSuccess;
   1373 }
   1374 
   1375 /**
   1376   Get next specify value.
   1377 
   1378   @param    ParseStruct   Input parse structure.
   1379   @param    Value         Return vlaue.
   1380 
   1381   @retval   return the action result.
   1382 
   1383 **/
   1384 TCG_RESULT
   1385 EFIAPI
   1386 TcgGetNextBOOLEAN(
   1387   TCG_PARSE_STRUCT        *ParseStruct,
   1388   BOOLEAN                 *Value
   1389   )
   1390 {
   1391   UINT64 Value64;
   1392   TCG_TOKEN Tok;
   1393 
   1394   NULL_CHECK(Value);
   1395 
   1396   ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
   1397   ERROR_CHECK(TcgGetTokenUINT64(&Tok, &Value64));
   1398 
   1399   if (Value64 > 1) {
   1400     return TcgResultFailure;
   1401   }
   1402 
   1403   *Value = (BOOLEAN)Value64;
   1404 
   1405   return TcgResultSuccess;
   1406 }
   1407 
   1408 /**
   1409   Get next tcg uid info.
   1410 
   1411   @param    ParseStruct    Input parse structure.
   1412   @param    Uid            Get the uid info.
   1413 
   1414   @retval   return the action result.
   1415 
   1416 **/
   1417 TCG_RESULT
   1418 EFIAPI
   1419 TcgGetNextTcgUid(
   1420   TCG_PARSE_STRUCT         *ParseStruct,
   1421   TCG_UID                  *Uid
   1422   )
   1423 {
   1424   TCG_TOKEN Tok;
   1425   UINT32 Length;
   1426   const UINT8* ByteSeq;
   1427 
   1428   NULL_CHECK(Uid);
   1429 
   1430   ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
   1431   ByteSeq = TcgGetTokenByteSequence(&Tok, &Length);
   1432 
   1433   if (Length != sizeof(TCG_UID)) {
   1434     DEBUG ((DEBUG_INFO, "Token Length %u != TCG_UID Size %u\n", Length, (UINT32)sizeof(TCG_UID)));
   1435     return TcgResultFailure;
   1436   }
   1437 
   1438   ASSERT (ByteSeq != NULL);
   1439 
   1440   CopyMem(Uid, ByteSeq, sizeof(TCG_UID));
   1441 
   1442   return TcgResultSuccess;
   1443 }
   1444 
   1445 /**
   1446   Get next byte sequence.
   1447 
   1448   @param    ParseStruct     Input parse structure.
   1449   @param    Data            return the data.
   1450   @param    Length          return the length.
   1451 
   1452   @retval   return the action result.
   1453 
   1454 **/
   1455 TCG_RESULT
   1456 EFIAPI
   1457 TcgGetNextByteSequence(
   1458   TCG_PARSE_STRUCT      *ParseStruct,
   1459   const VOID            **Data,
   1460   UINT32                *Length
   1461   )
   1462 {
   1463   TCG_TOKEN Tok;
   1464   const UINT8* Bs;
   1465 
   1466   ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
   1467   Bs = TcgGetTokenByteSequence(&Tok, Length);
   1468 
   1469   if (Bs == NULL) {
   1470     return TcgResultFailure;
   1471   }
   1472   *Data = Bs;
   1473   return TcgResultSuccess;
   1474 }
   1475 
   1476 /**
   1477   Get next token Type.
   1478 
   1479   @param    ParseStruct    Input parse structure.
   1480   @param    Type           Input the type need to check.
   1481 
   1482   @retval   return the action result.
   1483 
   1484 **/
   1485 TCG_RESULT
   1486 EFIAPI
   1487 TcgGetNextTokenType(
   1488   TCG_PARSE_STRUCT        *ParseStruct,
   1489   TCG_TOKEN_TYPE          Type
   1490   )
   1491 {
   1492   TCG_TOKEN Tok;
   1493   ERROR_CHECK(TcgGetNextToken(ParseStruct, &Tok));
   1494   if (Tok.Type != Type) {
   1495     DEBUG ((DEBUG_INFO, "expected Type %u, got Type %u\n", Type, Tok.Type));
   1496     return TcgResultFailure;
   1497   }
   1498   return TcgResultSuccess;
   1499 }
   1500 
   1501 /**
   1502   Get next start list.
   1503 
   1504   @param    ParseStruct   Input parse structure.
   1505 
   1506   @retval   return the action result.
   1507 
   1508 **/
   1509 TCG_RESULT
   1510 EFIAPI
   1511 TcgGetNextStartList(
   1512   TCG_PARSE_STRUCT          *ParseStruct
   1513   )
   1514 {
   1515   return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartList);
   1516 }
   1517 
   1518 /**
   1519   Get next end list.
   1520 
   1521   @param    ParseStruct   Input parse structure.
   1522 
   1523   @retval   return the action result.
   1524 
   1525 **/
   1526 TCG_RESULT
   1527 EFIAPI
   1528 TcgGetNextEndList(
   1529   TCG_PARSE_STRUCT             *ParseStruct
   1530   )
   1531 {
   1532   return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndList);
   1533 }
   1534 
   1535 /**
   1536   Get next start name.
   1537 
   1538   @param    ParseStruct   Input parse structure.
   1539 
   1540   @retval   return the action result.
   1541 
   1542 **/
   1543 TCG_RESULT
   1544 EFIAPI
   1545 TcgGetNextStartName(
   1546   TCG_PARSE_STRUCT              *ParseStruct
   1547   )
   1548 {
   1549   return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartName);
   1550 }
   1551 
   1552 /**
   1553   Get next end name.
   1554 
   1555   @param    ParseStruct   Input parse structure.
   1556 
   1557   @retval   return the action result.
   1558 
   1559 **/
   1560 TCG_RESULT
   1561 EFIAPI
   1562 TcgGetNextEndName(
   1563   TCG_PARSE_STRUCT               *ParseStruct
   1564   )
   1565 {
   1566   return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndName);
   1567 }
   1568 
   1569 /**
   1570   Get next call.
   1571 
   1572   @param    ParseStruct   Input parse structure.
   1573 
   1574   @retval   return the action result.
   1575 
   1576 **/
   1577 TCG_RESULT
   1578 EFIAPI
   1579 TcgGetNextCall(
   1580   TCG_PARSE_STRUCT                   *ParseStruct
   1581   )
   1582 {
   1583   return TcgGetNextTokenType(ParseStruct, TcgTokenTypeCall);
   1584 }
   1585 
   1586 /**
   1587   Get next end data.
   1588 
   1589   @param    ParseStruct   Input parse structure.
   1590 
   1591   @retval   return the action result.
   1592 
   1593 **/
   1594 TCG_RESULT
   1595 EFIAPI
   1596 TcgGetNextEndOfData(
   1597   TCG_PARSE_STRUCT                    *ParseStruct
   1598   )
   1599 {
   1600   return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndOfData);
   1601 }
   1602 
   1603 /**
   1604   Get next end of session.
   1605 
   1606   @param    ParseStruct   Input parse structure.
   1607 
   1608   @retval   return the action result.
   1609 
   1610 **/
   1611 TCG_RESULT
   1612 EFIAPI
   1613 TcgGetNextEndOfSession(
   1614   TCG_PARSE_STRUCT                      *ParseStruct
   1615   )
   1616 {
   1617   return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndOfSession);
   1618 }
   1619 
   1620 /**
   1621   Get next start transaction.
   1622 
   1623   @param    ParseStruct   Input parse structure.
   1624 
   1625   @retval   return the action result.
   1626 
   1627 **/
   1628 TCG_RESULT
   1629 EFIAPI
   1630 TcgGetNextStartTransaction(
   1631   TCG_PARSE_STRUCT                        *ParseStruct
   1632   )
   1633 {
   1634   return TcgGetNextTokenType(ParseStruct, TcgTokenTypeStartTransaction);
   1635 }
   1636 
   1637 /**
   1638   Get next end transaction.
   1639 
   1640   @param    ParseStruct   Input parse structure.
   1641 
   1642   @retval   return the action result.
   1643 
   1644 **/
   1645 TCG_RESULT
   1646 EFIAPI
   1647 TcgGetNextEndTransaction(
   1648   TCG_PARSE_STRUCT                  *ParseStruct
   1649   )
   1650 {
   1651   return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndTransaction);
   1652 }
   1653