1 /** @file 2 This module implements TCG EFI Protocol. 3 4 Caution: This module requires additional review when modified. 5 This driver will have external input - TcgDxePassThroughToTpm 6 This external input must be validated carefully to avoid security issue like 7 buffer overflow, integer overflow. 8 9 TcgDxePassThroughToTpm() will receive untrusted input and do basic validation. 10 11 Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR> 12 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> 13 This program and the accompanying materials 14 are licensed and made available under the terms and conditions of the BSD License 15 which accompanies this distribution. The full text of the license may be found at 16 http://opensource.org/licenses/bsd-license.php 17 18 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 19 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 20 21 **/ 22 23 #include <PiDxe.h> 24 #include <IndustryStandard/Tpm12.h> 25 #include <IndustryStandard/Acpi.h> 26 #include <IndustryStandard/PeImage.h> 27 #include <IndustryStandard/TcpaAcpi.h> 28 29 #include <Guid/GlobalVariable.h> 30 #include <Guid/HobList.h> 31 #include <Guid/TcgEventHob.h> 32 #include <Guid/EventGroup.h> 33 #include <Guid/EventExitBootServiceFailed.h> 34 #include <Guid/TpmInstance.h> 35 36 #include <Protocol/DevicePath.h> 37 #include <Protocol/TcgService.h> 38 #include <Protocol/AcpiTable.h> 39 #include <Protocol/MpService.h> 40 41 #include <Library/DebugLib.h> 42 #include <Library/BaseMemoryLib.h> 43 #include <Library/UefiRuntimeServicesTableLib.h> 44 #include <Library/UefiDriverEntryPoint.h> 45 #include <Library/HobLib.h> 46 #include <Library/UefiBootServicesTableLib.h> 47 #include <Library/BaseLib.h> 48 #include <Library/MemoryAllocationLib.h> 49 #include <Library/PrintLib.h> 50 #include <Library/Tpm12DeviceLib.h> 51 #include <Library/PcdLib.h> 52 #include <Library/UefiLib.h> 53 #include <Library/ReportStatusCodeLib.h> 54 #include <Library/Tpm12CommandLib.h> 55 #include <Library/BaseCryptLib.h> 56 57 #define TCG_DXE_DATA_FROM_THIS(this) \ 58 BASE_CR (this, TCG_DXE_DATA, TcgProtocol) 59 60 typedef struct _TCG_DXE_DATA { 61 EFI_TCG_PROTOCOL TcgProtocol; 62 TCG_EFI_BOOT_SERVICE_CAPABILITY BsCap; 63 EFI_TCG_CLIENT_ACPI_TABLE *TcgClientAcpiTable; 64 EFI_TCG_SERVER_ACPI_TABLE *TcgServerAcpiTable; 65 UINTN EventLogSize; 66 UINT8 *LastEvent; 67 } TCG_DXE_DATA; 68 69 70 71 EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate = { 72 { 73 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE, 74 sizeof (mTcgClientAcpiTemplate), 75 0x02 //Revision 76 // 77 // Compiler initializes the remaining bytes to 0 78 // These fields should be filled in in production 79 // 80 }, 81 0, // 0 for PC Client Platform Class 82 0, // Log Area Max Length 83 (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1) // Log Area Start Address 84 }; 85 86 // 87 // The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example, 88 // the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF, 89 // this _UID can be changed and should match with the _UID setting of the TPM 90 // ACPI device object 91 // 92 EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate = { 93 { 94 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE, 95 sizeof (mTcgServerAcpiTemplate), 96 0x02 //Revision 97 // 98 // Compiler initializes the remaining bytes to 0 99 // These fields should be filled in in production 100 // 101 }, 102 1, // 1 for Server Platform Class 103 0, // Reserved 104 0, // Log Area Max Length 105 (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1), // Log Area Start Address 106 0x0120, // TCG Specification revision 1.2 107 0, // Device Flags 108 0, // Interrupt Flags 109 0, // GPE 110 {0}, // Reserved 3 bytes 111 0, // Global System Interrupt 112 { 113 EFI_ACPI_3_0_SYSTEM_MEMORY, 114 0, 115 0, 116 EFI_ACPI_3_0_BYTE, 117 0 // Base Address 118 }, 119 0, // Reserved 120 {0}, // Configuration Address 121 0xFF, // ACPI _UID value of the device, can be changed for different platforms 122 0, // ACPI _UID value of the device, can be changed for different platforms 123 0, // ACPI _UID value of the device, can be changed for different platforms 124 0 // ACPI _UID value of the device, can be changed for different platforms 125 }; 126 127 UINTN mBootAttempts = 0; 128 CHAR16 mBootVarName[] = L"BootOrder"; 129 130 /** 131 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function 132 Caller is responsible to free LocationBuf. 133 134 @param[out] LocationBuf Returns Processor Location Buffer. 135 @param[out] Num Returns processor number. 136 137 @retval EFI_SUCCESS Operation completed successfully. 138 @retval EFI_UNSUPPORTED MpService protocol not found. 139 140 **/ 141 EFI_STATUS 142 GetProcessorsCpuLocation ( 143 OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf, 144 OUT UINTN *Num 145 ) 146 { 147 EFI_STATUS Status; 148 EFI_MP_SERVICES_PROTOCOL *MpProtocol; 149 UINTN ProcessorNum; 150 UINTN EnabledProcessorNum; 151 EFI_PROCESSOR_INFORMATION ProcessorInfo; 152 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf; 153 UINTN Index; 154 155 Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpProtocol); 156 if (EFI_ERROR (Status)) { 157 // 158 // MP protocol is not installed 159 // 160 return EFI_UNSUPPORTED; 161 } 162 163 Status = MpProtocol->GetNumberOfProcessors( 164 MpProtocol, 165 &ProcessorNum, 166 &EnabledProcessorNum 167 ); 168 if (EFI_ERROR(Status)){ 169 return Status; 170 } 171 172 Status = gBS->AllocatePool( 173 EfiBootServicesData, 174 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum, 175 (VOID **) &ProcessorLocBuf 176 ); 177 if (EFI_ERROR(Status)){ 178 return Status; 179 } 180 181 // 182 // Get each processor Location info 183 // 184 for (Index = 0; Index < ProcessorNum; Index++) { 185 Status = MpProtocol->GetProcessorInfo( 186 MpProtocol, 187 Index, 188 &ProcessorInfo 189 ); 190 if (EFI_ERROR(Status)){ 191 FreePool(ProcessorLocBuf); 192 return Status; 193 } 194 195 // 196 // Get all Processor Location info & measure 197 // 198 CopyMem( 199 &ProcessorLocBuf[Index], 200 &ProcessorInfo.Location, 201 sizeof(EFI_CPU_PHYSICAL_LOCATION) 202 ); 203 } 204 205 *LocationBuf = ProcessorLocBuf; 206 *Num = ProcessorNum; 207 208 return Status; 209 } 210 211 /** 212 This service provides EFI protocol capability information, state information 213 about the TPM, and Event Log state information. 214 215 @param[in] This Indicates the calling context 216 @param[out] ProtocolCapability The callee allocates memory for a TCG_BOOT_SERVICE_CAPABILITY 217 structure and fills in the fields with the EFI protocol 218 capability information and the current TPM state information. 219 @param[out] TCGFeatureFlags This is a pointer to the feature flags. No feature 220 flags are currently defined so this parameter 221 MUST be set to 0. However, in the future, 222 feature flags may be defined that, for example, 223 enable hash algorithm agility. 224 @param[out] EventLogLocation This is a pointer to the address of the event log in memory. 225 @param[out] EventLogLastEntry If the Event Log contains more than one entry, 226 this is a pointer to the address of the start of 227 the last entry in the event log in memory. 228 229 @retval EFI_SUCCESS Operation completed successfully. 230 @retval EFI_INVALID_PARAMETER ProtocolCapability does not match TCG capability. 231 232 **/ 233 EFI_STATUS 234 EFIAPI 235 TcgDxeStatusCheck ( 236 IN EFI_TCG_PROTOCOL *This, 237 OUT TCG_EFI_BOOT_SERVICE_CAPABILITY *ProtocolCapability, 238 OUT UINT32 *TCGFeatureFlags, 239 OUT EFI_PHYSICAL_ADDRESS *EventLogLocation, 240 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry 241 ) 242 { 243 TCG_DXE_DATA *TcgData; 244 245 TcgData = TCG_DXE_DATA_FROM_THIS (This); 246 247 if (ProtocolCapability != NULL) { 248 *ProtocolCapability = TcgData->BsCap; 249 } 250 251 if (TCGFeatureFlags != NULL) { 252 *TCGFeatureFlags = 0; 253 } 254 255 if (EventLogLocation != NULL) { 256 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) { 257 *EventLogLocation = TcgData->TcgClientAcpiTable->Lasa; 258 } else { 259 *EventLogLocation = TcgData->TcgServerAcpiTable->Lasa; 260 } 261 } 262 263 if (EventLogLastEntry != NULL) { 264 if (TcgData->BsCap.TPMDeactivatedFlag || (!TcgData->BsCap.TPMPresentFlag)) { 265 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0; 266 } else { 267 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)TcgData->LastEvent; 268 } 269 } 270 271 return EFI_SUCCESS; 272 } 273 274 /** 275 Single function calculates SHA1 digest value for all raw data. It 276 combines Sha1Init(), Sha1Update() and Sha1Final(). 277 278 @param[in] Data Raw data to be digested. 279 @param[in] DataLen Size of the raw data. 280 @param[out] Digest Pointer to a buffer that stores the final digest. 281 282 @retval EFI_SUCCESS Always successfully calculate the final digest. 283 **/ 284 EFI_STATUS 285 EFIAPI 286 TpmCommHashAll ( 287 IN CONST UINT8 *Data, 288 IN UINTN DataLen, 289 OUT TPM_DIGEST *Digest 290 ) 291 { 292 VOID *Sha1Ctx; 293 UINTN CtxSize; 294 295 CtxSize = Sha1GetContextSize (); 296 Sha1Ctx = AllocatePool (CtxSize); 297 ASSERT (Sha1Ctx != NULL); 298 299 Sha1Init (Sha1Ctx); 300 Sha1Update (Sha1Ctx, Data, DataLen); 301 Sha1Final (Sha1Ctx, (UINT8 *)Digest); 302 303 FreePool (Sha1Ctx); 304 305 return EFI_SUCCESS; 306 } 307 308 /** 309 This service abstracts the capability to do a hash operation on a data buffer. 310 311 @param[in] This Indicates the calling context 312 @param[in] HashData Pointer to the data buffer to be hashed 313 @param[in] HashDataLen Length of the data buffer to be hashed 314 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation 315 @param[in, out] HashedDataLen Resultant length of the hashed data 316 @param[in, out] HashedDataResult Resultant buffer of the hashed data 317 318 @retval EFI_SUCCESS Operation completed successfully. 319 @retval EFI_INVALID_PARAMETER HashDataLen is NULL. 320 @retval EFI_INVALID_PARAMETER HashDataLenResult is NULL. 321 @retval EFI_OUT_OF_RESOURCES Cannot allocate buffer of size *HashedDataLen. 322 @retval EFI_UNSUPPORTED AlgorithmId not supported. 323 @retval EFI_BUFFER_TOO_SMALL *HashedDataLen < sizeof (TCG_DIGEST). 324 325 **/ 326 EFI_STATUS 327 EFIAPI 328 TcgDxeHashAll ( 329 IN EFI_TCG_PROTOCOL *This, 330 IN UINT8 *HashData, 331 IN UINT64 HashDataLen, 332 IN TCG_ALGORITHM_ID AlgorithmId, 333 IN OUT UINT64 *HashedDataLen, 334 IN OUT UINT8 **HashedDataResult 335 ) 336 { 337 if (HashedDataLen == NULL || HashedDataResult == NULL) { 338 return EFI_INVALID_PARAMETER; 339 } 340 341 switch (AlgorithmId) { 342 case TPM_ALG_SHA: 343 if (*HashedDataLen == 0) { 344 *HashedDataLen = sizeof (TPM_DIGEST); 345 *HashedDataResult = AllocatePool ((UINTN) *HashedDataLen); 346 if (*HashedDataResult == NULL) { 347 return EFI_OUT_OF_RESOURCES; 348 } 349 } 350 351 if (*HashedDataLen < sizeof (TPM_DIGEST)) { 352 *HashedDataLen = sizeof (TPM_DIGEST); 353 return EFI_BUFFER_TOO_SMALL; 354 } 355 *HashedDataLen = sizeof (TPM_DIGEST); 356 357 if (*HashedDataResult == NULL) { 358 *HashedDataResult = AllocatePool ((UINTN) *HashedDataLen); 359 } 360 361 return TpmCommHashAll ( 362 HashData, 363 (UINTN) HashDataLen, 364 (TPM_DIGEST*)*HashedDataResult 365 ); 366 default: 367 return EFI_UNSUPPORTED; 368 } 369 } 370 371 /** 372 Add a new entry to the Event Log. 373 374 @param[in, out] EventLogPtr Pointer to the Event Log data. 375 @param[in, out] LogSize Size of the Event Log. 376 @param[in] MaxSize Maximum size of the Event Log. 377 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. 378 @param[in] NewEventData Pointer to the new event data. 379 380 @retval EFI_SUCCESS The new event log entry was added. 381 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. 382 383 **/ 384 EFI_STATUS 385 TpmCommLogEvent ( 386 IN OUT UINT8 **EventLogPtr, 387 IN OUT UINTN *LogSize, 388 IN UINTN MaxSize, 389 IN TCG_PCR_EVENT_HDR *NewEventHdr, 390 IN UINT8 *NewEventData 391 ) 392 { 393 UINTN NewLogSize; 394 395 // 396 // Prevent Event Overflow 397 // 398 if (NewEventHdr->EventSize > (UINTN)(~0) - sizeof (*NewEventHdr)) { 399 return EFI_OUT_OF_RESOURCES; 400 } 401 402 NewLogSize = sizeof (*NewEventHdr) + NewEventHdr->EventSize; 403 if (NewLogSize > MaxSize - *LogSize) { 404 return EFI_OUT_OF_RESOURCES; 405 } 406 407 *EventLogPtr += *LogSize; 408 *LogSize += NewLogSize; 409 CopyMem (*EventLogPtr, NewEventHdr, sizeof (*NewEventHdr)); 410 CopyMem ( 411 *EventLogPtr + sizeof (*NewEventHdr), 412 NewEventData, 413 NewEventHdr->EventSize 414 ); 415 return EFI_SUCCESS; 416 } 417 418 /** 419 Add a new entry to the Event Log. 420 421 @param[in] TcgData TCG_DXE_DATA structure. 422 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. 423 @param[in] NewEventData Pointer to the new event data. 424 425 @retval EFI_SUCCESS The new event log entry was added. 426 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. 427 428 **/ 429 EFI_STATUS 430 EFIAPI 431 TcgDxeLogEventI ( 432 IN TCG_DXE_DATA *TcgData, 433 IN TCG_PCR_EVENT_HDR *NewEventHdr, 434 IN UINT8 *NewEventData 435 ) 436 { 437 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) { 438 TcgData->LastEvent = (UINT8*)(UINTN)TcgData->TcgClientAcpiTable->Lasa; 439 return TpmCommLogEvent ( 440 &TcgData->LastEvent, 441 &TcgData->EventLogSize, 442 (UINTN)TcgData->TcgClientAcpiTable->Laml, 443 NewEventHdr, 444 NewEventData 445 ); 446 } else { 447 TcgData->LastEvent = (UINT8*)(UINTN)TcgData->TcgServerAcpiTable->Lasa; 448 return TpmCommLogEvent ( 449 &TcgData->LastEvent, 450 &TcgData->EventLogSize, 451 (UINTN)TcgData->TcgServerAcpiTable->Laml, 452 NewEventHdr, 453 NewEventData 454 ); 455 } 456 } 457 458 /** 459 This service abstracts the capability to add an entry to the Event Log. 460 461 @param[in] This Indicates the calling context 462 @param[in] TCGLogData Pointer to the start of the data buffer containing 463 the TCG_PCR_EVENT data structure. All fields in 464 this structure are properly filled by the caller. 465 @param[in, out] EventNumber The event number of the event just logged 466 @param[in] Flags Indicate additional flags. Only one flag has been 467 defined at this time, which is 0x01 and means the 468 extend operation should not be performed. All 469 other bits are reserved. 470 471 @retval EFI_SUCCESS Operation completed successfully. 472 @retval EFI_OUT_OF_RESOURCES Insufficient memory in the event log to complete this action. 473 474 **/ 475 EFI_STATUS 476 EFIAPI 477 TcgDxeLogEvent ( 478 IN EFI_TCG_PROTOCOL *This, 479 IN TCG_PCR_EVENT *TCGLogData, 480 IN OUT UINT32 *EventNumber, 481 IN UINT32 Flags 482 ) 483 { 484 TCG_DXE_DATA *TcgData; 485 486 if (TCGLogData == NULL){ 487 return EFI_INVALID_PARAMETER; 488 } 489 490 TcgData = TCG_DXE_DATA_FROM_THIS (This); 491 492 if (TcgData->BsCap.TPMDeactivatedFlag || (!TcgData->BsCap.TPMPresentFlag)) { 493 return EFI_DEVICE_ERROR; 494 } 495 return TcgDxeLogEventI ( 496 TcgData, 497 (TCG_PCR_EVENT_HDR*)TCGLogData, 498 TCGLogData->Event 499 ); 500 } 501 502 /** 503 This service is a proxy for commands to the TPM. 504 505 @param[in] This Indicates the calling context 506 @param[in] TpmInputParameterBlockSize Size of the TPM input parameter block 507 @param[in] TpmInputParameterBlock Pointer to the TPM input parameter block 508 @param[in] TpmOutputParameterBlockSize Size of the TPM output parameter block 509 @param[in] TpmOutputParameterBlock Pointer to the TPM output parameter block 510 511 @retval EFI_SUCCESS Operation completed successfully. 512 @retval EFI_INVALID_PARAMETER Invalid ordinal. 513 @retval EFI_UNSUPPORTED Current Task Priority Level >= EFI_TPL_CALLBACK. 514 @retval EFI_TIMEOUT The TIS timed-out. 515 516 **/ 517 EFI_STATUS 518 EFIAPI 519 TcgDxePassThroughToTpm ( 520 IN EFI_TCG_PROTOCOL *This, 521 IN UINT32 TpmInputParameterBlockSize, 522 IN UINT8 *TpmInputParameterBlock, 523 IN UINT32 TpmOutputParameterBlockSize, 524 IN UINT8 *TpmOutputParameterBlock 525 ) 526 { 527 if (TpmInputParameterBlock == NULL || 528 TpmOutputParameterBlock == NULL || 529 TpmInputParameterBlockSize == 0 || 530 TpmOutputParameterBlockSize == 0) { 531 return EFI_INVALID_PARAMETER; 532 } 533 534 return Tpm12SubmitCommand ( 535 TpmInputParameterBlockSize, 536 TpmInputParameterBlock, 537 &TpmOutputParameterBlockSize, 538 TpmOutputParameterBlock 539 ); 540 } 541 542 /** 543 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result, 544 and add an entry to the Event Log. 545 546 @param[in] TcgData TCG_DXE_DATA structure. 547 @param[in] HashData Physical address of the start of the data buffer 548 to be hashed, extended, and logged. 549 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData 550 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. 551 @param[in] NewEventData Pointer to the new event data. 552 553 @retval EFI_SUCCESS Operation completed successfully. 554 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. 555 @retval EFI_DEVICE_ERROR The command was unsuccessful. 556 557 **/ 558 EFI_STATUS 559 EFIAPI 560 TcgDxeHashLogExtendEventI ( 561 IN TCG_DXE_DATA *TcgData, 562 IN UINT8 *HashData, 563 IN UINT64 HashDataLen, 564 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr, 565 IN UINT8 *NewEventData 566 ) 567 { 568 EFI_STATUS Status; 569 570 if (!TcgData->BsCap.TPMPresentFlag) { 571 return EFI_DEVICE_ERROR; 572 } 573 574 if (HashDataLen > 0 || HashData != NULL) { 575 Status = TpmCommHashAll ( 576 HashData, 577 (UINTN) HashDataLen, 578 &NewEventHdr->Digest 579 ); 580 if (EFI_ERROR(Status)) { 581 DEBUG ((DEBUG_ERROR, "TpmCommHashAll Failed. %x\n", Status)); 582 goto Done; 583 } 584 } 585 586 Status = Tpm12Extend ( 587 &NewEventHdr->Digest, 588 NewEventHdr->PCRIndex, 589 NULL 590 ); 591 if (!EFI_ERROR (Status)) { 592 Status = TcgDxeLogEventI (TcgData, NewEventHdr, NewEventData); 593 } 594 595 Done: 596 if ((Status == EFI_DEVICE_ERROR) || (Status == EFI_TIMEOUT)) { 597 DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEventI - %r. Disable TPM.\n", Status)); 598 TcgData->BsCap.TPMPresentFlag = FALSE; 599 REPORT_STATUS_CODE ( 600 EFI_ERROR_CODE | EFI_ERROR_MINOR, 601 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) 602 ); 603 Status = EFI_DEVICE_ERROR; 604 } 605 606 return Status; 607 } 608 609 /** 610 This service abstracts the capability to do a hash operation on a data buffer, 611 extend a specific TPM PCR with the hash result, and add an entry to the Event Log 612 613 @param[in] This Indicates the calling context 614 @param[in] HashData Physical address of the start of the data buffer 615 to be hashed, extended, and logged. 616 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData 617 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation 618 @param[in, out] TCGLogData The physical address of the start of the data 619 buffer containing the TCG_PCR_EVENT data structure. 620 @param[in, out] EventNumber The event number of the event just logged. 621 @param[out] EventLogLastEntry Physical address of the first byte of the entry 622 just placed in the Event Log. If the Event Log was 623 empty when this function was called then this physical 624 address will be the same as the physical address of 625 the start of the Event Log. 626 627 @retval EFI_SUCCESS Operation completed successfully. 628 @retval EFI_UNSUPPORTED AlgorithmId != TPM_ALG_SHA. 629 @retval EFI_UNSUPPORTED Current TPL >= EFI_TPL_CALLBACK. 630 @retval EFI_DEVICE_ERROR The command was unsuccessful. 631 632 **/ 633 EFI_STATUS 634 EFIAPI 635 TcgDxeHashLogExtendEvent ( 636 IN EFI_TCG_PROTOCOL *This, 637 IN EFI_PHYSICAL_ADDRESS HashData, 638 IN UINT64 HashDataLen, 639 IN TPM_ALGORITHM_ID AlgorithmId, 640 IN OUT TCG_PCR_EVENT *TCGLogData, 641 IN OUT UINT32 *EventNumber, 642 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry 643 ) 644 { 645 TCG_DXE_DATA *TcgData; 646 EFI_STATUS Status; 647 648 if (TCGLogData == NULL || EventLogLastEntry == NULL){ 649 return EFI_INVALID_PARAMETER; 650 } 651 652 TcgData = TCG_DXE_DATA_FROM_THIS (This); 653 654 if (TcgData->BsCap.TPMDeactivatedFlag || (!TcgData->BsCap.TPMPresentFlag)) { 655 return EFI_DEVICE_ERROR; 656 } 657 658 if (AlgorithmId != TPM_ALG_SHA) { 659 return EFI_UNSUPPORTED; 660 } 661 662 if (HashData == 0 && HashDataLen > 0) { 663 return EFI_INVALID_PARAMETER; 664 } 665 666 Status = TcgDxeHashLogExtendEventI ( 667 TcgData, 668 (UINT8 *) (UINTN) HashData, 669 HashDataLen, 670 (TCG_PCR_EVENT_HDR*)TCGLogData, 671 TCGLogData->Event 672 ); 673 674 if (!EFI_ERROR(Status)){ 675 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN) TcgData->LastEvent; 676 } 677 678 return Status; 679 } 680 681 TCG_DXE_DATA mTcgDxeData = { 682 { 683 TcgDxeStatusCheck, 684 TcgDxeHashAll, 685 TcgDxeLogEvent, 686 TcgDxePassThroughToTpm, 687 TcgDxeHashLogExtendEvent 688 }, 689 { 690 sizeof (mTcgDxeData.BsCap), 691 { 1, 2, 0, 0 }, 692 { 1, 2, 0, 0 }, 693 1, 694 TRUE, 695 FALSE 696 }, 697 &mTcgClientAcpiTemplate, 698 &mTcgServerAcpiTemplate, 699 0, 700 NULL 701 }; 702 703 /** 704 Initialize the Event Log and log events passed from the PEI phase. 705 706 @retval EFI_SUCCESS Operation completed successfully. 707 @retval EFI_OUT_OF_RESOURCES Out of memory. 708 709 **/ 710 EFI_STATUS 711 EFIAPI 712 SetupEventLog ( 713 VOID 714 ) 715 { 716 EFI_STATUS Status; 717 TCG_PCR_EVENT *TcgEvent; 718 EFI_PEI_HOB_POINTERS GuidHob; 719 EFI_PHYSICAL_ADDRESS Lasa; 720 721 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) { 722 Lasa = mTcgClientAcpiTemplate.Lasa; 723 724 Status = gBS->AllocatePages ( 725 AllocateMaxAddress, 726 EfiACPIMemoryNVS, 727 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)), 728 &Lasa 729 ); 730 if (EFI_ERROR (Status)) { 731 return Status; 732 } 733 mTcgClientAcpiTemplate.Lasa = Lasa; 734 // 735 // To initialize them as 0xFF is recommended 736 // because the OS can know the last entry for that. 737 // 738 SetMem ((VOID *)(UINTN)mTcgClientAcpiTemplate.Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF); 739 mTcgClientAcpiTemplate.Laml = PcdGet32 (PcdTcgLogAreaMinLen); 740 741 } else { 742 Lasa = mTcgServerAcpiTemplate.Lasa; 743 744 Status = gBS->AllocatePages ( 745 AllocateMaxAddress, 746 EfiACPIMemoryNVS, 747 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)), 748 &Lasa 749 ); 750 if (EFI_ERROR (Status)) { 751 return Status; 752 } 753 mTcgServerAcpiTemplate.Lasa = Lasa; 754 // 755 // To initialize them as 0xFF is recommended 756 // because the OS can know the last entry for that. 757 // 758 SetMem ((VOID *)(UINTN)mTcgServerAcpiTemplate.Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF); 759 mTcgServerAcpiTemplate.Laml = PcdGet32 (PcdTcgLogAreaMinLen); 760 } 761 762 GuidHob.Raw = GetHobList (); 763 while (!EFI_ERROR (Status) && 764 (GuidHob.Raw = GetNextGuidHob (&gTcgEventEntryHobGuid, GuidHob.Raw)) != NULL) { 765 TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid); 766 GuidHob.Raw = GET_NEXT_HOB (GuidHob); 767 Status = TcgDxeLogEventI ( 768 &mTcgDxeData, 769 (TCG_PCR_EVENT_HDR*)TcgEvent, 770 TcgEvent->Event 771 ); 772 } 773 774 return Status; 775 } 776 777 /** 778 Measure and log an action string, and extend the measurement result into PCR[5]. 779 780 @param[in] String A specific string that indicates an Action event. 781 782 @retval EFI_SUCCESS Operation completed successfully. 783 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 784 785 **/ 786 EFI_STATUS 787 EFIAPI 788 TcgMeasureAction ( 789 IN CHAR8 *String 790 ) 791 { 792 TCG_PCR_EVENT_HDR TcgEvent; 793 794 TcgEvent.PCRIndex = 5; 795 TcgEvent.EventType = EV_EFI_ACTION; 796 TcgEvent.EventSize = (UINT32)AsciiStrLen (String); 797 return TcgDxeHashLogExtendEventI ( 798 &mTcgDxeData, 799 (UINT8*)String, 800 TcgEvent.EventSize, 801 &TcgEvent, 802 (UINT8 *) String 803 ); 804 } 805 806 /** 807 Measure and log EFI handoff tables, and extend the measurement result into PCR[1]. 808 809 @retval EFI_SUCCESS Operation completed successfully. 810 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 811 812 **/ 813 EFI_STATUS 814 EFIAPI 815 MeasureHandoffTables ( 816 VOID 817 ) 818 { 819 EFI_STATUS Status; 820 TCG_PCR_EVENT_HDR TcgEvent; 821 EFI_HANDOFF_TABLE_POINTERS HandoffTables; 822 UINTN ProcessorNum; 823 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf; 824 825 ProcessorLocBuf = NULL; 826 Status = EFI_SUCCESS; 827 828 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) { 829 // 830 // Tcg Server spec. 831 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1] 832 // 833 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum); 834 835 if (!EFI_ERROR(Status)){ 836 TcgEvent.PCRIndex = 1; 837 TcgEvent.EventType = EV_TABLE_OF_DEVICES; 838 TcgEvent.EventSize = sizeof (HandoffTables); 839 840 HandoffTables.NumberOfTables = 1; 841 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid; 842 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf; 843 844 Status = TcgDxeHashLogExtendEventI ( 845 &mTcgDxeData, 846 (UINT8*)(UINTN)ProcessorLocBuf, 847 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum, 848 &TcgEvent, 849 (UINT8*)&HandoffTables 850 ); 851 852 FreePool(ProcessorLocBuf); 853 } 854 } 855 856 return Status; 857 } 858 859 /** 860 Measure and log Separator event, and extend the measurement result into a specific PCR. 861 862 @param[in] PCRIndex PCR index. 863 864 @retval EFI_SUCCESS Operation completed successfully. 865 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 866 867 **/ 868 EFI_STATUS 869 EFIAPI 870 MeasureSeparatorEvent ( 871 IN TPM_PCRINDEX PCRIndex 872 ) 873 { 874 TCG_PCR_EVENT_HDR TcgEvent; 875 UINT32 EventData; 876 877 EventData = 0; 878 TcgEvent.PCRIndex = PCRIndex; 879 TcgEvent.EventType = EV_SEPARATOR; 880 TcgEvent.EventSize = (UINT32)sizeof (EventData); 881 return TcgDxeHashLogExtendEventI ( 882 &mTcgDxeData, 883 (UINT8 *)&EventData, 884 sizeof (EventData), 885 &TcgEvent, 886 (UINT8 *)&EventData 887 ); 888 } 889 890 /** 891 Read an EFI Variable. 892 893 This function allocates a buffer to return the contents of the variable. The caller is 894 responsible for freeing the buffer. 895 896 @param[in] VarName A Null-terminated string that is the name of the vendor's variable. 897 @param[in] VendorGuid A unique identifier for the vendor. 898 @param[out] VarSize The size of the variable data. 899 900 @return A pointer to the buffer to return the contents of the variable.Otherwise NULL. 901 902 **/ 903 VOID * 904 EFIAPI 905 ReadVariable ( 906 IN CHAR16 *VarName, 907 IN EFI_GUID *VendorGuid, 908 OUT UINTN *VarSize 909 ) 910 { 911 EFI_STATUS Status; 912 VOID *VarData; 913 914 *VarSize = 0; 915 Status = gRT->GetVariable ( 916 VarName, 917 VendorGuid, 918 NULL, 919 VarSize, 920 NULL 921 ); 922 if (Status != EFI_BUFFER_TOO_SMALL) { 923 return NULL; 924 } 925 926 VarData = AllocatePool (*VarSize); 927 if (VarData != NULL) { 928 Status = gRT->GetVariable ( 929 VarName, 930 VendorGuid, 931 NULL, 932 VarSize, 933 VarData 934 ); 935 if (EFI_ERROR (Status)) { 936 FreePool (VarData); 937 VarData = NULL; 938 *VarSize = 0; 939 } 940 } 941 return VarData; 942 } 943 944 /** 945 Measure and log an EFI variable, and extend the measurement result into a specific PCR. 946 947 @param[in] PCRIndex PCR Index. 948 @param[in] EventType Event type. 949 @param[in] VarName A Null-terminated string that is the name of the vendor's variable. 950 @param[in] VendorGuid A unique identifier for the vendor. 951 @param[in] VarData The content of the variable data. 952 @param[in] VarSize The size of the variable data. 953 954 @retval EFI_SUCCESS Operation completed successfully. 955 @retval EFI_OUT_OF_RESOURCES Out of memory. 956 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 957 958 **/ 959 EFI_STATUS 960 EFIAPI 961 MeasureVariable ( 962 IN TPM_PCRINDEX PCRIndex, 963 IN TCG_EVENTTYPE EventType, 964 IN CHAR16 *VarName, 965 IN EFI_GUID *VendorGuid, 966 IN VOID *VarData, 967 IN UINTN VarSize 968 ) 969 { 970 EFI_STATUS Status; 971 TCG_PCR_EVENT_HDR TcgEvent; 972 UINTN VarNameLength; 973 EFI_VARIABLE_DATA *VarLog; 974 975 VarNameLength = StrLen (VarName); 976 TcgEvent.PCRIndex = PCRIndex; 977 TcgEvent.EventType = EventType; 978 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize 979 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData)); 980 981 VarLog = (EFI_VARIABLE_DATA*)AllocatePool (TcgEvent.EventSize); 982 if (VarLog == NULL) { 983 return EFI_OUT_OF_RESOURCES; 984 } 985 986 VarLog->VariableName = *VendorGuid; 987 VarLog->UnicodeNameLength = VarNameLength; 988 VarLog->VariableDataLength = VarSize; 989 CopyMem ( 990 VarLog->UnicodeName, 991 VarName, 992 VarNameLength * sizeof (*VarName) 993 ); 994 CopyMem ( 995 (CHAR16 *)VarLog->UnicodeName + VarNameLength, 996 VarData, 997 VarSize 998 ); 999 1000 Status = TcgDxeHashLogExtendEventI ( 1001 &mTcgDxeData, 1002 (UINT8*)VarLog, 1003 TcgEvent.EventSize, 1004 &TcgEvent, 1005 (UINT8*)VarLog 1006 ); 1007 FreePool (VarLog); 1008 return Status; 1009 } 1010 1011 /** 1012 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5]. 1013 1014 @param[in] VarName A Null-terminated string that is the name of the vendor's variable. 1015 @param[in] VendorGuid A unique identifier for the vendor. 1016 @param[out] VarSize The size of the variable data. 1017 @param[out] VarData Pointer to the content of the variable. 1018 1019 @retval EFI_SUCCESS Operation completed successfully. 1020 @retval EFI_OUT_OF_RESOURCES Out of memory. 1021 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1022 1023 **/ 1024 EFI_STATUS 1025 EFIAPI 1026 ReadAndMeasureBootVariable ( 1027 IN CHAR16 *VarName, 1028 IN EFI_GUID *VendorGuid, 1029 OUT UINTN *VarSize, 1030 OUT VOID **VarData 1031 ) 1032 { 1033 EFI_STATUS Status; 1034 1035 *VarData = ReadVariable (VarName, VendorGuid, VarSize); 1036 if (*VarData == NULL) { 1037 return EFI_NOT_FOUND; 1038 } 1039 1040 Status = MeasureVariable ( 1041 5, 1042 EV_EFI_VARIABLE_BOOT, 1043 VarName, 1044 VendorGuid, 1045 *VarData, 1046 *VarSize 1047 ); 1048 return Status; 1049 } 1050 1051 /** 1052 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR. 1053 1054 The EFI boot variables are BootOrder and Boot#### variables. 1055 1056 @retval EFI_SUCCESS Operation completed successfully. 1057 @retval EFI_OUT_OF_RESOURCES Out of memory. 1058 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1059 1060 **/ 1061 EFI_STATUS 1062 EFIAPI 1063 MeasureAllBootVariables ( 1064 VOID 1065 ) 1066 { 1067 EFI_STATUS Status; 1068 UINT16 *BootOrder; 1069 UINTN BootCount; 1070 UINTN Index; 1071 VOID *BootVarData; 1072 UINTN Size; 1073 1074 Status = ReadAndMeasureBootVariable ( 1075 mBootVarName, 1076 &gEfiGlobalVariableGuid, 1077 &BootCount, 1078 (VOID **) &BootOrder 1079 ); 1080 if (Status == EFI_NOT_FOUND || BootOrder == NULL) { 1081 return EFI_SUCCESS; 1082 } 1083 1084 if (EFI_ERROR (Status)) { 1085 // 1086 // BootOrder can't be NULL if status is not EFI_NOT_FOUND 1087 // 1088 FreePool (BootOrder); 1089 return Status; 1090 } 1091 1092 BootCount /= sizeof (*BootOrder); 1093 for (Index = 0; Index < BootCount; Index++) { 1094 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]); 1095 Status = ReadAndMeasureBootVariable ( 1096 mBootVarName, 1097 &gEfiGlobalVariableGuid, 1098 &Size, 1099 &BootVarData 1100 ); 1101 if (!EFI_ERROR (Status)) { 1102 FreePool (BootVarData); 1103 } 1104 } 1105 1106 FreePool (BootOrder); 1107 return EFI_SUCCESS; 1108 } 1109 1110 /** 1111 Ready to Boot Event notification handler. 1112 1113 Sequence of OS boot events is measured in this event notification handler. 1114 1115 @param[in] Event Event whose notification function is being invoked 1116 @param[in] Context Pointer to the notification function's context 1117 1118 **/ 1119 VOID 1120 EFIAPI 1121 OnReadyToBoot ( 1122 IN EFI_EVENT Event, 1123 IN VOID *Context 1124 ) 1125 { 1126 EFI_STATUS Status; 1127 TPM_PCRINDEX PcrIndex; 1128 1129 if (mBootAttempts == 0) { 1130 1131 // 1132 // Measure handoff tables. 1133 // 1134 Status = MeasureHandoffTables (); 1135 if (EFI_ERROR (Status)) { 1136 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n")); 1137 } 1138 1139 // 1140 // Measure BootOrder & Boot#### variables. 1141 // 1142 Status = MeasureAllBootVariables (); 1143 if (EFI_ERROR (Status)) { 1144 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n")); 1145 } 1146 1147 // 1148 // 1. This is the first boot attempt. 1149 // 1150 Status = TcgMeasureAction ( 1151 EFI_CALLING_EFI_APPLICATION 1152 ); 1153 if (EFI_ERROR (Status)) { 1154 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION)); 1155 } 1156 1157 // 1158 // 2. Draw a line between pre-boot env and entering post-boot env. 1159 // 1160 for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) { 1161 Status = MeasureSeparatorEvent (PcrIndex); 1162 if (EFI_ERROR (Status)) { 1163 DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n")); 1164 } 1165 } 1166 1167 // 1168 // 3. Measure GPT. It would be done in SAP driver. 1169 // 1170 1171 // 1172 // 4. Measure PE/COFF OS loader. It would be done in SAP driver. 1173 // 1174 1175 // 1176 // 5. Read & Measure variable. BootOrder already measured. 1177 // 1178 } else { 1179 // 1180 // 6. Not first attempt, meaning a return from last attempt 1181 // 1182 Status = TcgMeasureAction ( 1183 EFI_RETURNING_FROM_EFI_APPLICATOIN 1184 ); 1185 if (EFI_ERROR (Status)) { 1186 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN)); 1187 } 1188 } 1189 1190 DEBUG ((EFI_D_INFO, "TPM TcgDxe Measure Data when ReadyToBoot\n")); 1191 // 1192 // Increase boot attempt counter. 1193 // 1194 mBootAttempts++; 1195 } 1196 1197 /** 1198 Install TCG ACPI Table when ACPI Table Protocol is available. 1199 1200 A system's firmware uses an ACPI table to identify the system's TCG capabilities 1201 to the Post-Boot environment. The information in this ACPI table is not guaranteed 1202 to be valid until the Host Platform transitions from pre-boot state to post-boot state. 1203 1204 @param[in] Event Event whose notification function is being invoked 1205 @param[in] Context Pointer to the notification function's context 1206 **/ 1207 VOID 1208 EFIAPI 1209 InstallAcpiTable ( 1210 IN EFI_EVENT Event, 1211 IN VOID* Context 1212 ) 1213 { 1214 UINTN TableKey; 1215 EFI_STATUS Status; 1216 EFI_ACPI_TABLE_PROTOCOL *AcpiTable; 1217 UINT8 Checksum; 1218 UINT64 OemTableId; 1219 1220 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable); 1221 if (EFI_ERROR (Status)) { 1222 return; 1223 } 1224 1225 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) { 1226 CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId)); 1227 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); 1228 CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); 1229 mTcgClientAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); 1230 mTcgClientAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); 1231 mTcgClientAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); 1232 // 1233 // The ACPI table must be checksumed before calling the InstallAcpiTable() 1234 // service of the ACPI table protocol to install it. 1235 // 1236 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate)); 1237 mTcgClientAcpiTemplate.Header.Checksum = Checksum; 1238 1239 Status = AcpiTable->InstallAcpiTable ( 1240 AcpiTable, 1241 &mTcgClientAcpiTemplate, 1242 sizeof (mTcgClientAcpiTemplate), 1243 &TableKey 1244 ); 1245 } else { 1246 CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId)); 1247 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); 1248 CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); 1249 mTcgServerAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); 1250 mTcgServerAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); 1251 mTcgServerAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); 1252 // 1253 // The ACPI table must be checksumed before calling the InstallAcpiTable() 1254 // service of the ACPI table protocol to install it. 1255 // 1256 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate)); 1257 mTcgServerAcpiTemplate.Header.Checksum = Checksum; 1258 1259 mTcgServerAcpiTemplate.BaseAddress.Address = PcdGet64 (PcdTpmBaseAddress); 1260 Status = AcpiTable->InstallAcpiTable ( 1261 AcpiTable, 1262 &mTcgServerAcpiTemplate, 1263 sizeof (mTcgServerAcpiTemplate), 1264 &TableKey 1265 ); 1266 } 1267 1268 if (EFI_ERROR (Status)) { 1269 DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure")); 1270 } 1271 } 1272 1273 /** 1274 Exit Boot Services Event notification handler. 1275 1276 Measure invocation and success of ExitBootServices. 1277 1278 @param[in] Event Event whose notification function is being invoked 1279 @param[in] Context Pointer to the notification function's context 1280 1281 **/ 1282 VOID 1283 EFIAPI 1284 OnExitBootServices ( 1285 IN EFI_EVENT Event, 1286 IN VOID *Context 1287 ) 1288 { 1289 EFI_STATUS Status; 1290 1291 // 1292 // Measure invocation of ExitBootServices, 1293 // 1294 Status = TcgMeasureAction ( 1295 EFI_EXIT_BOOT_SERVICES_INVOCATION 1296 ); 1297 if (EFI_ERROR (Status)) { 1298 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION)); 1299 } 1300 1301 // 1302 // Measure success of ExitBootServices 1303 // 1304 Status = TcgMeasureAction ( 1305 EFI_EXIT_BOOT_SERVICES_SUCCEEDED 1306 ); 1307 if (EFI_ERROR (Status)){ 1308 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED)); 1309 } 1310 } 1311 1312 /** 1313 Exit Boot Services Failed Event notification handler. 1314 1315 Measure Failure of ExitBootServices. 1316 1317 @param[in] Event Event whose notification function is being invoked 1318 @param[in] Context Pointer to the notification function's context 1319 1320 **/ 1321 VOID 1322 EFIAPI 1323 OnExitBootServicesFailed ( 1324 IN EFI_EVENT Event, 1325 IN VOID *Context 1326 ) 1327 { 1328 EFI_STATUS Status; 1329 1330 // 1331 // Measure Failure of ExitBootServices, 1332 // 1333 Status = TcgMeasureAction ( 1334 EFI_EXIT_BOOT_SERVICES_FAILED 1335 ); 1336 if (EFI_ERROR (Status)){ 1337 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED)); 1338 } 1339 } 1340 1341 /** 1342 Get TPM Deactivated state. 1343 1344 @param[out] TPMDeactivatedFlag Returns TPM Deactivated state. 1345 1346 @retval EFI_SUCCESS Operation completed successfully. 1347 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1348 1349 **/ 1350 EFI_STATUS 1351 GetTpmStatus ( 1352 OUT BOOLEAN *TPMDeactivatedFlag 1353 ) 1354 { 1355 EFI_STATUS Status; 1356 TPM_STCLEAR_FLAGS VolatileFlags; 1357 1358 Status = Tpm12GetCapabilityFlagVolatile (&VolatileFlags); 1359 if (!EFI_ERROR (Status)) { 1360 *TPMDeactivatedFlag = VolatileFlags.deactivated; 1361 } 1362 1363 return Status; 1364 } 1365 1366 /** 1367 The driver's entry point. 1368 1369 It publishes EFI TCG Protocol. 1370 1371 @param[in] ImageHandle The firmware allocated handle for the EFI image. 1372 @param[in] SystemTable A pointer to the EFI System Table. 1373 1374 @retval EFI_SUCCESS The entry point is executed successfully. 1375 @retval other Some error occurs when executing this entry point. 1376 1377 **/ 1378 EFI_STATUS 1379 EFIAPI 1380 DriverEntry ( 1381 IN EFI_HANDLE ImageHandle, 1382 IN EFI_SYSTEM_TABLE *SystemTable 1383 ) 1384 { 1385 EFI_STATUS Status; 1386 EFI_EVENT Event; 1387 VOID *Registration; 1388 1389 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){ 1390 DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n")); 1391 return EFI_UNSUPPORTED; 1392 } 1393 1394 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { 1395 DEBUG ((EFI_D_ERROR, "TPM error!\n")); 1396 return EFI_DEVICE_ERROR; 1397 } 1398 1399 Status = Tpm12RequestUseTpm (); 1400 if (EFI_ERROR (Status)) { 1401 DEBUG ((EFI_D_ERROR, "TPM not detected!\n")); 1402 return Status; 1403 } 1404 1405 Status = GetTpmStatus (&mTcgDxeData.BsCap.TPMDeactivatedFlag); 1406 if (EFI_ERROR (Status)) { 1407 DEBUG (( 1408 EFI_D_ERROR, 1409 "Line %d in file " __FILE__ ":\n " 1410 "DriverEntry: TPM not working properly\n", 1411 __LINE__ 1412 )); 1413 return Status; 1414 } 1415 1416 Status = gBS->InstallProtocolInterface ( 1417 &ImageHandle, 1418 &gEfiTcgProtocolGuid, 1419 EFI_NATIVE_INTERFACE, 1420 &mTcgDxeData.TcgProtocol 1421 ); 1422 if (!EFI_ERROR (Status) && (!mTcgDxeData.BsCap.TPMDeactivatedFlag) && mTcgDxeData.BsCap.TPMPresentFlag) { 1423 // 1424 // Setup the log area and copy event log from hob list to it 1425 // 1426 Status = SetupEventLog (); 1427 ASSERT_EFI_ERROR (Status); 1428 1429 // 1430 // Measure handoff tables, Boot#### variables etc. 1431 // 1432 Status = EfiCreateEventReadyToBootEx ( 1433 TPL_CALLBACK, 1434 OnReadyToBoot, 1435 NULL, 1436 &Event 1437 ); 1438 1439 Status = gBS->CreateEventEx ( 1440 EVT_NOTIFY_SIGNAL, 1441 TPL_NOTIFY, 1442 OnExitBootServices, 1443 NULL, 1444 &gEfiEventExitBootServicesGuid, 1445 &Event 1446 ); 1447 1448 // 1449 // Measure Exit Boot Service failed 1450 // 1451 Status = gBS->CreateEventEx ( 1452 EVT_NOTIFY_SIGNAL, 1453 TPL_NOTIFY, 1454 OnExitBootServicesFailed, 1455 NULL, 1456 &gEventExitBootServicesFailedGuid, 1457 &Event 1458 ); 1459 } 1460 1461 // 1462 // Install ACPI Table 1463 // 1464 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration); 1465 1466 return Status; 1467 } 1468