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