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