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