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