• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
TcgInitTcgCreateStruct(TCG_CREATE_STRUCT * CreateStruct,VOID * Buffer,UINT32 BufferSize)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
TcgStartComPacket(TCG_CREATE_STRUCT * CreateStruct,UINT16 ComId,UINT16 ComIdExtension)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
TcgStartPacket(TCG_CREATE_STRUCT * CreateStruct,UINT32 Tsn,UINT32 Hsn,UINT32 SeqNumber,UINT16 AckType,UINT32 Ack)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
TcgStartSubPacket(TCG_CREATE_STRUCT * CreateStruct,UINT16 Kind)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
TcgEndSubPacket(TCG_CREATE_STRUCT * CreateStruct)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
TcgEndPacket(TCG_CREATE_STRUCT * CreateStruct)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
TcgEndComPacket(TCG_CREATE_STRUCT * CreateStruct,UINT32 * Size)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
TcgAddRawTokenData(TCG_CREATE_STRUCT * CreateStruct,const VOID * Header,UINT8 HeaderSize,const VOID * Data,UINT32 DataSize,BOOLEAN ByteSwapData)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
TcgAddRawByte(TCG_CREATE_STRUCT * CreateStruct,UINT8 Byte)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
TcgAddAtom(TCG_CREATE_STRUCT * CreateStruct,const VOID * Data,UINT32 DataSize,UINT8 ByteOrInt,UINT8 SignOrCont)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
TcgAddByteSequence(TCG_CREATE_STRUCT * CreateStruct,const VOID * Data,UINT32 DataSize,BOOLEAN Continued)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
TcgAddInteger(TCG_CREATE_STRUCT * CreateStruct,const VOID * Data,UINT32 DataSize,BOOLEAN SignedInteger)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
TcgAddUINT8(TCG_CREATE_STRUCT * CreateStruct,UINT8 Value)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
TcgAddUINT16(TCG_CREATE_STRUCT * CreateStruct,UINT16 Value)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
TcgAddUINT32(TCG_CREATE_STRUCT * CreateStruct,UINT32 Value)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
TcgAddUINT64(TCG_CREATE_STRUCT * CreateStruct,UINT64 Value)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
TcgAddBOOLEAN(TCG_CREATE_STRUCT * CreateStruct,BOOLEAN Value)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
TcgAddTcgUid(TCG_CREATE_STRUCT * CreateStruct,TCG_UID Uid)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
TcgAddStartList(TCG_CREATE_STRUCT * CreateStruct)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
TcgAddEndList(TCG_CREATE_STRUCT * CreateStruct)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
TcgAddStartName(TCG_CREATE_STRUCT * CreateStruct)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
TcgAddEndName(TCG_CREATE_STRUCT * CreateStruct)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
TcgAddCall(TCG_CREATE_STRUCT * CreateStruct)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
TcgAddEndOfData(TCG_CREATE_STRUCT * CreateStruct)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
TcgAddEndOfSession(TCG_CREATE_STRUCT * CreateStruct)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
TcgAddStartTransaction(TCG_CREATE_STRUCT * CreateStruct)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
TcgAddEndTransaction(TCG_CREATE_STRUCT * CreateStruct)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
TcgInitTcgParseStruct(TCG_PARSE_STRUCT * ParseStruct,const VOID * Buffer,UINT32 BufferSize)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
TcgGetNextToken(TCG_PARSE_STRUCT * ParseStruct,TCG_TOKEN * TcgToken)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
TcgGetAtomInfo(const TCG_TOKEN * TcgToken,UINT32 * HeaderLength,UINT32 * DataLength,UINT8 * ByteOrInt,UINT8 * SignOrCont)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
TcgGetTokenUINT64(const TCG_TOKEN * TcgToken,UINT64 * Value)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
TcgGetTokenByteSequence(const TCG_TOKEN * TcgToken,UINT32 * Length)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
TcgGetNextUINT8(TCG_PARSE_STRUCT * ParseStruct,UINT8 * Value)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
TcgGetNextUINT16(TCG_PARSE_STRUCT * ParseStruct,UINT16 * Value)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
TcgGetNextUINT32(TCG_PARSE_STRUCT * ParseStruct,UINT32 * Value)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
TcgGetNextUINT64(TCG_PARSE_STRUCT * ParseStruct,UINT64 * Value)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
TcgGetNextBOOLEAN(TCG_PARSE_STRUCT * ParseStruct,BOOLEAN * Value)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
TcgGetNextTcgUid(TCG_PARSE_STRUCT * ParseStruct,TCG_UID * Uid)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
TcgGetNextByteSequence(TCG_PARSE_STRUCT * ParseStruct,const VOID ** Data,UINT32 * Length)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
TcgGetNextTokenType(TCG_PARSE_STRUCT * ParseStruct,TCG_TOKEN_TYPE Type)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
TcgGetNextStartList(TCG_PARSE_STRUCT * ParseStruct)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
TcgGetNextEndList(TCG_PARSE_STRUCT * ParseStruct)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
TcgGetNextStartName(TCG_PARSE_STRUCT * ParseStruct)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
TcgGetNextEndName(TCG_PARSE_STRUCT * ParseStruct)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
TcgGetNextCall(TCG_PARSE_STRUCT * ParseStruct)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
TcgGetNextEndOfData(TCG_PARSE_STRUCT * ParseStruct)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
TcgGetNextEndOfSession(TCG_PARSE_STRUCT * ParseStruct)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
TcgGetNextStartTransaction(TCG_PARSE_STRUCT * ParseStruct)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
TcgGetNextEndTransaction(TCG_PARSE_STRUCT * ParseStruct)1647 TcgGetNextEndTransaction(
1648   TCG_PARSE_STRUCT                  *ParseStruct
1649   )
1650 {
1651   return TcgGetNextTokenType(ParseStruct, TcgTokenTypeEndTransaction);
1652 }
1653