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