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