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