1 /** @file 2 This module implements Tcg2 Protocol. 3 4 Copyright (c) 2015 - 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 <PiDxe.h> 16 #include <IndustryStandard/Acpi.h> 17 #include <IndustryStandard/PeImage.h> 18 #include <IndustryStandard/TcpaAcpi.h> 19 20 #include <Guid/GlobalVariable.h> 21 #include <Guid/HobList.h> 22 #include <Guid/TcgEventHob.h> 23 #include <Guid/EventGroup.h> 24 #include <Guid/EventExitBootServiceFailed.h> 25 #include <Guid/ImageAuthentication.h> 26 #include <Guid/TpmInstance.h> 27 28 #include <Protocol/DevicePath.h> 29 #include <Protocol/MpService.h> 30 #include <Protocol/VariableWrite.h> 31 #include <Protocol/Tcg2Protocol.h> 32 #include <Protocol/TrEEProtocol.h> 33 34 #include <Library/DebugLib.h> 35 #include <Library/BaseMemoryLib.h> 36 #include <Library/UefiRuntimeServicesTableLib.h> 37 #include <Library/UefiDriverEntryPoint.h> 38 #include <Library/HobLib.h> 39 #include <Library/UefiBootServicesTableLib.h> 40 #include <Library/BaseLib.h> 41 #include <Library/MemoryAllocationLib.h> 42 #include <Library/PrintLib.h> 43 #include <Library/Tpm2CommandLib.h> 44 #include <Library/PcdLib.h> 45 #include <Library/UefiLib.h> 46 #include <Library/Tpm2DeviceLib.h> 47 #include <Library/HashLib.h> 48 #include <Library/PerformanceLib.h> 49 #include <Library/ReportStatusCodeLib.h> 50 #include <Library/Tcg2PhysicalPresenceLib.h> 51 52 #define PERF_ID_TCG2_DXE 0x3120 53 54 typedef struct { 55 CHAR16 *VariableName; 56 EFI_GUID *VendorGuid; 57 } VARIABLE_TYPE; 58 59 #define EFI_TCG_LOG_AREA_SIZE 0x10000 60 #define EFI_TCG_FINAL_LOG_AREA_SIZE 0x1000 61 62 #define TCG2_DEFAULT_MAX_COMMAND_SIZE 0x1000 63 #define TCG2_DEFAULT_MAX_RESPONSE_SIZE 0x1000 64 65 typedef struct { 66 EFI_GUID *EventGuid; 67 EFI_TCG2_EVENT_LOG_FORMAT LogFormat; 68 } TCG2_EVENT_INFO_STRUCT; 69 70 TCG2_EVENT_INFO_STRUCT mTcg2EventInfo[] = { 71 {&gTcgEventEntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2}, 72 {&gTcgEvent2EntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2}, 73 }; 74 75 #define TCG_EVENT_LOG_AREA_COUNT_MAX 2 76 77 typedef struct { 78 EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat; 79 EFI_PHYSICAL_ADDRESS Lasa; 80 UINT64 Laml; 81 UINTN EventLogSize; 82 UINT8 *LastEvent; 83 BOOLEAN EventLogStarted; 84 BOOLEAN EventLogTruncated; 85 } TCG_EVENT_LOG_AREA_STRUCT; 86 87 typedef struct _TCG_DXE_DATA { 88 EFI_TCG2_BOOT_SERVICE_CAPABILITY BsCap; 89 TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX]; 90 BOOLEAN GetEventLogCalled[TCG_EVENT_LOG_AREA_COUNT_MAX]; 91 TCG_EVENT_LOG_AREA_STRUCT FinalEventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX]; 92 EFI_TCG2_FINAL_EVENTS_TABLE *FinalEventsTable[TCG_EVENT_LOG_AREA_COUNT_MAX]; 93 } TCG_DXE_DATA; 94 95 TCG_DXE_DATA mTcgDxeData = { 96 { 97 sizeof (EFI_TCG2_BOOT_SERVICE_CAPABILITY), // Size 98 { 1, 1 }, // StructureVersion 99 { 1, 1 }, // ProtocolVersion 100 EFI_TCG2_BOOT_HASH_ALG_SHA1, // HashAlgorithmBitmap 101 EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2, // SupportedEventLogs 102 TRUE, // TPMPresentFlag 103 TCG2_DEFAULT_MAX_COMMAND_SIZE, // MaxCommandSize 104 TCG2_DEFAULT_MAX_RESPONSE_SIZE, // MaxResponseSize 105 0, // ManufacturerID 106 0, // NumberOfPCRBanks 107 0, // ActivePcrBanks 108 }, 109 }; 110 111 UINTN mBootAttempts = 0; 112 CHAR16 mBootVarName[] = L"BootOrder"; 113 114 VARIABLE_TYPE mVariableType[] = { 115 {EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid}, 116 {EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid}, 117 {EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid}, 118 {EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid}, 119 {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid}, 120 }; 121 122 EFI_HANDLE mImageHandle; 123 124 /** 125 Measure PE image into TPM log based on the authenticode image hashing in 126 PE/COFF Specification 8.0 Appendix A. 127 128 Caution: This function may receive untrusted input. 129 PE/COFF image is external input, so this function will validate its data structure 130 within this image buffer before use. 131 132 @param[in] PCRIndex TPM PCR index 133 @param[in] ImageAddress Start address of image buffer. 134 @param[in] ImageSize Image size 135 @param[out] DigestList Digeest list of this image. 136 137 @retval EFI_SUCCESS Successfully measure image. 138 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image. 139 @retval other error value 140 **/ 141 EFI_STATUS 142 MeasurePeImageAndExtend ( 143 IN UINT32 PCRIndex, 144 IN EFI_PHYSICAL_ADDRESS ImageAddress, 145 IN UINTN ImageSize, 146 OUT TPML_DIGEST_VALUES *DigestList 147 ); 148 149 /** 150 151 This function dump raw data. 152 153 @param Data raw data 154 @param Size raw data size 155 156 **/ 157 VOID 158 InternalDumpData ( 159 IN UINT8 *Data, 160 IN UINTN Size 161 ) 162 { 163 UINTN Index; 164 for (Index = 0; Index < Size; Index++) { 165 DEBUG ((EFI_D_INFO, "%02x", (UINTN)Data[Index])); 166 } 167 } 168 169 /** 170 171 This function dump raw data with colume format. 172 173 @param Data raw data 174 @param Size raw data size 175 176 **/ 177 VOID 178 InternalDumpHex ( 179 IN UINT8 *Data, 180 IN UINTN Size 181 ) 182 { 183 UINTN Index; 184 UINTN Count; 185 UINTN Left; 186 187 #define COLUME_SIZE (16 * 2) 188 189 Count = Size / COLUME_SIZE; 190 Left = Size % COLUME_SIZE; 191 for (Index = 0; Index < Count; Index++) { 192 DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE)); 193 InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE); 194 DEBUG ((EFI_D_INFO, "\n")); 195 } 196 197 if (Left != 0) { 198 DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE)); 199 InternalDumpData (Data + Index * COLUME_SIZE, Left); 200 DEBUG ((EFI_D_INFO, "\n")); 201 } 202 } 203 204 /** 205 Check if buffer is all zero. 206 207 @param[in] Buffer Buffer to be checked. 208 @param[in] BufferSize Size of buffer to be checked. 209 210 @retval TRUE Buffer is all zero. 211 @retval FALSE Buffer is not all zero. 212 **/ 213 BOOLEAN 214 IsZeroBuffer ( 215 IN VOID *Buffer, 216 IN UINTN BufferSize 217 ) 218 { 219 UINT8 *BufferData; 220 UINTN Index; 221 222 BufferData = Buffer; 223 for (Index = 0; Index < BufferSize; Index++) { 224 if (BufferData[Index] != 0) { 225 return FALSE; 226 } 227 } 228 return TRUE; 229 } 230 231 /** 232 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function 233 Caller is responsible to free LocationBuf. 234 235 @param[out] LocationBuf Returns Processor Location Buffer. 236 @param[out] Num Returns processor number. 237 238 @retval EFI_SUCCESS Operation completed successfully. 239 @retval EFI_UNSUPPORTED MpService protocol not found. 240 241 **/ 242 EFI_STATUS 243 GetProcessorsCpuLocation ( 244 OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf, 245 OUT UINTN *Num 246 ) 247 { 248 EFI_STATUS Status; 249 EFI_MP_SERVICES_PROTOCOL *MpProtocol; 250 UINTN ProcessorNum; 251 UINTN EnabledProcessorNum; 252 EFI_PROCESSOR_INFORMATION ProcessorInfo; 253 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf; 254 UINTN Index; 255 256 Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpProtocol); 257 if (EFI_ERROR (Status)) { 258 // 259 // MP protocol is not installed 260 // 261 return EFI_UNSUPPORTED; 262 } 263 264 Status = MpProtocol->GetNumberOfProcessors( 265 MpProtocol, 266 &ProcessorNum, 267 &EnabledProcessorNum 268 ); 269 if (EFI_ERROR(Status)){ 270 return Status; 271 } 272 273 Status = gBS->AllocatePool( 274 EfiBootServicesData, 275 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum, 276 (VOID **) &ProcessorLocBuf 277 ); 278 if (EFI_ERROR(Status)){ 279 return Status; 280 } 281 282 // 283 // Get each processor Location info 284 // 285 for (Index = 0; Index < ProcessorNum; Index++) { 286 Status = MpProtocol->GetProcessorInfo( 287 MpProtocol, 288 Index, 289 &ProcessorInfo 290 ); 291 if (EFI_ERROR(Status)){ 292 FreePool(ProcessorLocBuf); 293 return Status; 294 } 295 296 // 297 // Get all Processor Location info & measure 298 // 299 CopyMem( 300 &ProcessorLocBuf[Index], 301 &ProcessorInfo.Location, 302 sizeof(EFI_CPU_PHYSICAL_LOCATION) 303 ); 304 } 305 306 *LocationBuf = ProcessorLocBuf; 307 *Num = ProcessorNum; 308 309 return Status; 310 } 311 312 /** 313 The EFI_TCG2_PROTOCOL GetCapability function call provides protocol 314 capability information and state information. 315 316 @param[in] This Indicates the calling context 317 @param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY 318 structure and sets the size field to the size of the structure allocated. 319 The callee fills in the fields with the EFI protocol capability information 320 and the current EFI TCG2 state information up to the number of fields which 321 fit within the size of the structure passed in. 322 323 @retval EFI_SUCCESS Operation completed successfully. 324 @retval EFI_DEVICE_ERROR The command was unsuccessful. 325 The ProtocolCapability variable will not be populated. 326 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. 327 The ProtocolCapability variable will not be populated. 328 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response. 329 It will be partially populated (required Size field will be set). 330 **/ 331 EFI_STATUS 332 EFIAPI 333 Tcg2GetCapability ( 334 IN EFI_TCG2_PROTOCOL *This, 335 IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability 336 ) 337 { 338 DEBUG ((EFI_D_INFO, "Tcg2GetCapability ...\n")); 339 340 if ((This == NULL) || (ProtocolCapability == NULL)) { 341 return EFI_INVALID_PARAMETER; 342 } 343 344 DEBUG ((EFI_D_INFO, "Size - 0x%x\n", ProtocolCapability->Size)); 345 DEBUG ((EFI_D_INFO, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0))); 346 347 if (ProtocolCapability->Size < mTcgDxeData.BsCap.Size) { 348 // 349 // Handle the case that firmware support 1.1 but OS only support 1.0. 350 // 351 if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) || 352 ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) { 353 if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) { 354 CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)); 355 ProtocolCapability->Size = sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0); 356 ProtocolCapability->StructureVersion.Major = 1; 357 ProtocolCapability->StructureVersion.Minor = 0; 358 ProtocolCapability->ProtocolVersion.Major = 1; 359 ProtocolCapability->ProtocolVersion.Minor = 0; 360 DEBUG ((EFI_D_ERROR, "TreeGetCapability (Compatible) - %r\n", EFI_SUCCESS)); 361 return EFI_SUCCESS; 362 } 363 } 364 ProtocolCapability->Size = mTcgDxeData.BsCap.Size; 365 return EFI_BUFFER_TOO_SMALL; 366 } 367 368 CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, mTcgDxeData.BsCap.Size); 369 DEBUG ((EFI_D_INFO, "Tcg2GetCapability - %r\n", EFI_SUCCESS)); 370 return EFI_SUCCESS; 371 } 372 373 /** 374 This function dump PCR event. 375 376 @param[in] EventHdr TCG PCR event structure. 377 **/ 378 VOID 379 DumpEvent ( 380 IN TCG_PCR_EVENT_HDR *EventHdr 381 ) 382 { 383 UINTN Index; 384 385 DEBUG ((EFI_D_INFO, " Event:\n")); 386 DEBUG ((EFI_D_INFO, " PCRIndex - %d\n", EventHdr->PCRIndex)); 387 DEBUG ((EFI_D_INFO, " EventType - 0x%08x\n", EventHdr->EventType)); 388 DEBUG ((EFI_D_INFO, " Digest - ")); 389 for (Index = 0; Index < sizeof(TCG_DIGEST); Index++) { 390 DEBUG ((EFI_D_INFO, "%02x ", EventHdr->Digest.digest[Index])); 391 } 392 DEBUG ((EFI_D_INFO, "\n")); 393 DEBUG ((EFI_D_INFO, " EventSize - 0x%08x\n", EventHdr->EventSize)); 394 InternalDumpHex ((UINT8 *)(EventHdr + 1), EventHdr->EventSize); 395 } 396 397 /** 398 This function dump TCG_EfiSpecIDEventStruct. 399 400 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct. 401 **/ 402 VOID 403 DumpTcgEfiSpecIdEventStruct ( 404 IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct 405 ) 406 { 407 TCG_EfiSpecIdEventAlgorithmSize *DigestSize; 408 UINTN Index; 409 UINT8 *VendorInfoSize; 410 UINT8 *VendorInfo; 411 UINT32 NumberOfAlgorithms; 412 413 DEBUG ((EFI_D_INFO, " TCG_EfiSpecIDEventStruct:\n")); 414 DEBUG ((EFI_D_INFO, " signature - '")); 415 for (Index = 0; Index < sizeof(TcgEfiSpecIdEventStruct->signature); Index++) { 416 DEBUG ((EFI_D_INFO, "%c", TcgEfiSpecIdEventStruct->signature[Index])); 417 } 418 DEBUG ((EFI_D_INFO, "'\n")); 419 DEBUG ((EFI_D_INFO, " platformClass - 0x%08x\n", TcgEfiSpecIdEventStruct->platformClass)); 420 DEBUG ((EFI_D_INFO, " specVersion - %d.%d%d\n", TcgEfiSpecIdEventStruct->specVersionMajor, TcgEfiSpecIdEventStruct->specVersionMinor, TcgEfiSpecIdEventStruct->specErrata)); 421 DEBUG ((EFI_D_INFO, " uintnSize - 0x%02x\n", TcgEfiSpecIdEventStruct->uintnSize)); 422 423 CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof(NumberOfAlgorithms)); 424 DEBUG ((EFI_D_INFO, " NumberOfAlgorithms - 0x%08x\n", NumberOfAlgorithms)); 425 426 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms)); 427 for (Index = 0; Index < NumberOfAlgorithms; Index++) { 428 DEBUG ((EFI_D_INFO, " digest(%d)\n", Index)); 429 DEBUG ((EFI_D_INFO, " algorithmId - 0x%04x\n", DigestSize[Index].algorithmId)); 430 DEBUG ((EFI_D_INFO, " digestSize - 0x%04x\n", DigestSize[Index].digestSize)); 431 } 432 VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms]; 433 DEBUG ((EFI_D_INFO, " VendorInfoSize - 0x%02x\n", *VendorInfoSize)); 434 VendorInfo = VendorInfoSize + 1; 435 DEBUG ((EFI_D_INFO, " VendorInfo - ")); 436 for (Index = 0; Index < *VendorInfoSize; Index++) { 437 DEBUG ((EFI_D_INFO, "%02x ", VendorInfo[Index])); 438 } 439 DEBUG ((EFI_D_INFO, "\n")); 440 } 441 442 /** 443 This function get size of TCG_EfiSpecIDEventStruct. 444 445 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct. 446 **/ 447 UINTN 448 GetTcgEfiSpecIdEventStructSize ( 449 IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct 450 ) 451 { 452 TCG_EfiSpecIdEventAlgorithmSize *DigestSize; 453 UINT8 *VendorInfoSize; 454 UINT32 NumberOfAlgorithms; 455 456 CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof(NumberOfAlgorithms)); 457 458 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms)); 459 VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms]; 460 return sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (NumberOfAlgorithms * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8) + (*VendorInfoSize); 461 } 462 463 /** 464 This function dump PCR event 2. 465 466 @param[in] TcgPcrEvent2 TCG PCR event 2 structure. 467 **/ 468 VOID 469 DumpEvent2 ( 470 IN TCG_PCR_EVENT2 *TcgPcrEvent2 471 ) 472 { 473 UINTN Index; 474 UINT32 DigestIndex; 475 UINT32 DigestCount; 476 TPMI_ALG_HASH HashAlgo; 477 UINT32 DigestSize; 478 UINT8 *DigestBuffer; 479 UINT32 EventSize; 480 UINT8 *EventBuffer; 481 482 DEBUG ((EFI_D_INFO, " Event:\n")); 483 DEBUG ((EFI_D_INFO, " PCRIndex - %d\n", TcgPcrEvent2->PCRIndex)); 484 DEBUG ((EFI_D_INFO, " EventType - 0x%08x\n", TcgPcrEvent2->EventType)); 485 486 DEBUG ((EFI_D_INFO, " DigestCount: 0x%08x\n", TcgPcrEvent2->Digest.count)); 487 488 DigestCount = TcgPcrEvent2->Digest.count; 489 HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg; 490 DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest; 491 for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) { 492 DEBUG ((EFI_D_INFO, " HashAlgo : 0x%04x\n", HashAlgo)); 493 DEBUG ((EFI_D_INFO, " Digest(%d): ", DigestIndex)); 494 DigestSize = GetHashSizeFromAlgo (HashAlgo); 495 for (Index = 0; Index < DigestSize; Index++) { 496 DEBUG ((EFI_D_INFO, "%02x ", DigestBuffer[Index])); 497 } 498 DEBUG ((EFI_D_INFO, "\n")); 499 // 500 // Prepare next 501 // 502 CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof(TPMI_ALG_HASH)); 503 DigestBuffer = DigestBuffer + DigestSize + sizeof(TPMI_ALG_HASH); 504 } 505 DEBUG ((EFI_D_INFO, "\n")); 506 DigestBuffer = DigestBuffer - sizeof(TPMI_ALG_HASH); 507 508 CopyMem (&EventSize, DigestBuffer, sizeof(TcgPcrEvent2->EventSize)); 509 DEBUG ((EFI_D_INFO, " EventSize - 0x%08x\n", EventSize)); 510 EventBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize); 511 InternalDumpHex (EventBuffer, EventSize); 512 } 513 514 /** 515 This function returns size of TCG PCR event 2. 516 517 @param[in] TcgPcrEvent2 TCG PCR event 2 structure. 518 519 @return size of TCG PCR event 2. 520 **/ 521 UINTN 522 GetPcrEvent2Size ( 523 IN TCG_PCR_EVENT2 *TcgPcrEvent2 524 ) 525 { 526 UINT32 DigestIndex; 527 UINT32 DigestCount; 528 TPMI_ALG_HASH HashAlgo; 529 UINT32 DigestSize; 530 UINT8 *DigestBuffer; 531 UINT32 EventSize; 532 UINT8 *EventBuffer; 533 534 DigestCount = TcgPcrEvent2->Digest.count; 535 HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg; 536 DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest; 537 for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) { 538 DigestSize = GetHashSizeFromAlgo (HashAlgo); 539 // 540 // Prepare next 541 // 542 CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof(TPMI_ALG_HASH)); 543 DigestBuffer = DigestBuffer + DigestSize + sizeof(TPMI_ALG_HASH); 544 } 545 DigestBuffer = DigestBuffer - sizeof(TPMI_ALG_HASH); 546 547 CopyMem (&EventSize, DigestBuffer, sizeof(TcgPcrEvent2->EventSize)); 548 EventBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize); 549 550 return (UINTN)EventBuffer + EventSize - (UINTN)TcgPcrEvent2; 551 } 552 553 /** 554 This function dump event log. 555 556 @param[in] EventLogFormat The type of the event log for which the information is requested. 557 @param[in] EventLogLocation A pointer to the memory address of the event log. 558 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the 559 address of the start of the last entry in the event log in memory. 560 @param[in] FinalEventsTable A pointer to the memory address of the final event table. 561 **/ 562 VOID 563 DumpEventLog ( 564 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat, 565 IN EFI_PHYSICAL_ADDRESS EventLogLocation, 566 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry, 567 IN EFI_TCG2_FINAL_EVENTS_TABLE *FinalEventsTable 568 ) 569 { 570 TCG_PCR_EVENT_HDR *EventHdr; 571 TCG_PCR_EVENT2 *TcgPcrEvent2; 572 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct; 573 UINTN NumberOfEvents; 574 575 DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat)); 576 577 switch (EventLogFormat) { 578 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2: 579 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation; 580 while ((UINTN)EventHdr <= EventLogLastEntry) { 581 DumpEvent (EventHdr); 582 EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize); 583 } 584 if (FinalEventsTable == NULL) { 585 DEBUG ((EFI_D_INFO, "FinalEventsTable: NOT FOUND\n")); 586 } else { 587 DEBUG ((EFI_D_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable)); 588 DEBUG ((EFI_D_INFO, " Version: (0x%x)\n", FinalEventsTable->Version)); 589 DEBUG ((EFI_D_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents)); 590 591 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)(FinalEventsTable + 1); 592 for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) { 593 DumpEvent (EventHdr); 594 EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize); 595 } 596 } 597 break; 598 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2: 599 // 600 // Dump first event 601 // 602 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation; 603 DumpEvent (EventHdr); 604 605 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)(EventHdr + 1); 606 DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct); 607 608 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgEfiSpecIdEventStruct + GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct)); 609 while ((UINTN)TcgPcrEvent2 <= EventLogLastEntry) { 610 DumpEvent2 (TcgPcrEvent2); 611 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2)); 612 } 613 614 if (FinalEventsTable == NULL) { 615 DEBUG ((EFI_D_INFO, "FinalEventsTable: NOT FOUND\n")); 616 } else { 617 DEBUG ((EFI_D_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable)); 618 DEBUG ((EFI_D_INFO, " Version: (0x%x)\n", FinalEventsTable->Version)); 619 DEBUG ((EFI_D_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents)); 620 621 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)(UINTN)(FinalEventsTable + 1); 622 for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) { 623 DumpEvent2 (TcgPcrEvent2); 624 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2)); 625 } 626 } 627 break; 628 } 629 630 return ; 631 } 632 633 /** 634 The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to 635 retrieve the address of a given event log and its last entry. 636 637 @param[in] This Indicates the calling context 638 @param[in] EventLogFormat The type of the event log for which the information is requested. 639 @param[out] EventLogLocation A pointer to the memory address of the event log. 640 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the 641 address of the start of the last entry in the event log in memory. 642 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would 643 have exceeded the area allocated for events, this value is set to TRUE. 644 Otherwise, the value will be FALSE and the Event Log will be complete. 645 646 @retval EFI_SUCCESS Operation completed successfully. 647 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect 648 (e.g. asking for an event log whose format is not supported). 649 **/ 650 EFI_STATUS 651 EFIAPI 652 Tcg2GetEventLog ( 653 IN EFI_TCG2_PROTOCOL *This, 654 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat, 655 OUT EFI_PHYSICAL_ADDRESS *EventLogLocation, 656 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry, 657 OUT BOOLEAN *EventLogTruncated 658 ) 659 { 660 UINTN Index; 661 662 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog ... (0x%x)\n", EventLogFormat)); 663 664 if (This == NULL) { 665 return EFI_INVALID_PARAMETER; 666 } 667 668 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) { 669 if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) { 670 break; 671 } 672 } 673 674 if (Index == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])) { 675 return EFI_INVALID_PARAMETER; 676 } 677 678 if ((mTcg2EventInfo[Index].LogFormat & mTcgDxeData.BsCap.SupportedEventLogs) == 0) { 679 return EFI_INVALID_PARAMETER; 680 } 681 682 if (!mTcgDxeData.BsCap.TPMPresentFlag) { 683 if (EventLogLocation != NULL) { 684 *EventLogLocation = 0; 685 } 686 if (EventLogLastEntry != NULL) { 687 *EventLogLastEntry = 0; 688 } 689 if (EventLogTruncated != NULL) { 690 *EventLogTruncated = FALSE; 691 } 692 return EFI_SUCCESS; 693 } 694 695 if (EventLogLocation != NULL) { 696 *EventLogLocation = mTcgDxeData.EventLogAreaStruct[Index].Lasa; 697 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogLocation - %x)\n", *EventLogLocation)); 698 } 699 700 if (EventLogLastEntry != NULL) { 701 if (!mTcgDxeData.EventLogAreaStruct[Index].EventLogStarted) { 702 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0; 703 } else { 704 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)mTcgDxeData.EventLogAreaStruct[Index].LastEvent; 705 } 706 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry)); 707 } 708 709 if (EventLogTruncated != NULL) { 710 *EventLogTruncated = mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated; 711 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated)); 712 } 713 714 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog - %r\n", EFI_SUCCESS)); 715 716 // Dump Event Log for debug purpose 717 if ((EventLogLocation != NULL) && (EventLogLastEntry != NULL)) { 718 DumpEventLog (EventLogFormat, *EventLogLocation, *EventLogLastEntry, mTcgDxeData.FinalEventsTable[Index]); 719 } 720 721 // 722 // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored 723 // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID. 724 // 725 mTcgDxeData.GetEventLogCalled[Index] = TRUE; 726 727 return EFI_SUCCESS; 728 } 729 730 /** 731 Add a new entry to the Event Log. 732 733 @param[in, out] EventLogPtr Pointer to the Event Log data. 734 @param[in, out] LogSize Size of the Event Log. 735 @param[in] MaxSize Maximum size of the Event Log. 736 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure. 737 @param[in] NewEventHdrSize New event header size. 738 @param[in] NewEventData Pointer to the new event data. 739 @param[in] NewEventSize New event data size. 740 741 @retval EFI_SUCCESS The new event log entry was added. 742 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. 743 744 **/ 745 EFI_STATUS 746 TcgCommLogEvent ( 747 IN OUT UINT8 **EventLogPtr, 748 IN OUT UINTN *LogSize, 749 IN UINTN MaxSize, 750 IN VOID *NewEventHdr, 751 IN UINT32 NewEventHdrSize, 752 IN UINT8 *NewEventData, 753 IN UINT32 NewEventSize 754 ) 755 { 756 UINTN NewLogSize; 757 758 if (NewEventSize > MAX_ADDRESS - NewEventHdrSize) { 759 return EFI_OUT_OF_RESOURCES; 760 } 761 762 NewLogSize = NewEventHdrSize + NewEventSize; 763 764 if (NewLogSize > MAX_ADDRESS - *LogSize) { 765 return EFI_OUT_OF_RESOURCES; 766 } 767 768 if (NewLogSize + *LogSize > MaxSize) { 769 DEBUG ((EFI_D_INFO, " MaxSize - 0x%x\n", MaxSize)); 770 DEBUG ((EFI_D_INFO, " NewLogSize - 0x%x\n", NewLogSize)); 771 DEBUG ((EFI_D_INFO, " LogSize - 0x%x\n", *LogSize)); 772 DEBUG ((EFI_D_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES)); 773 return EFI_OUT_OF_RESOURCES; 774 } 775 776 *EventLogPtr += *LogSize; 777 *LogSize += NewLogSize; 778 CopyMem (*EventLogPtr, NewEventHdr, NewEventHdrSize); 779 CopyMem ( 780 *EventLogPtr + NewEventHdrSize, 781 NewEventData, 782 NewEventSize 783 ); 784 return EFI_SUCCESS; 785 } 786 787 /** 788 Add a new entry to the Event Log. 789 790 @param[in] EventLogFormat The type of the event log for which the information is requested. 791 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure. 792 @param[in] NewEventHdrSize New event header size. 793 @param[in] NewEventData Pointer to the new event data. 794 @param[in] NewEventSize New event data size. 795 796 @retval EFI_SUCCESS The new event log entry was added. 797 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. 798 799 **/ 800 EFI_STATUS 801 TcgDxeLogEvent ( 802 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat, 803 IN VOID *NewEventHdr, 804 IN UINT32 NewEventHdrSize, 805 IN UINT8 *NewEventData, 806 IN UINT32 NewEventSize 807 ) 808 { 809 EFI_STATUS Status; 810 UINTN Index; 811 TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct; 812 813 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) { 814 if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) { 815 break; 816 } 817 } 818 819 if (Index == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])) { 820 return EFI_INVALID_PARAMETER; 821 } 822 823 if (!mTcgDxeData.GetEventLogCalled[Index]) { 824 EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index]; 825 } else { 826 EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index]; 827 } 828 829 if (EventLogAreaStruct->EventLogTruncated) { 830 return EFI_VOLUME_FULL; 831 } 832 833 EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa; 834 Status = TcgCommLogEvent ( 835 &EventLogAreaStruct->LastEvent, 836 &EventLogAreaStruct->EventLogSize, 837 (UINTN)EventLogAreaStruct->Laml, 838 NewEventHdr, 839 NewEventHdrSize, 840 NewEventData, 841 NewEventSize 842 ); 843 844 if (Status == EFI_DEVICE_ERROR) { 845 return EFI_DEVICE_ERROR; 846 } else if (Status == EFI_OUT_OF_RESOURCES) { 847 EventLogAreaStruct->EventLogTruncated = TRUE; 848 return EFI_VOLUME_FULL; 849 } else if (Status == EFI_SUCCESS) { 850 EventLogAreaStruct->EventLogStarted = TRUE; 851 if (mTcgDxeData.GetEventLogCalled[Index]) { 852 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++; 853 } 854 } 855 856 return Status; 857 } 858 859 /** 860 This function get digest from digest list. 861 862 @param HashAlg digest algorithm 863 @param DigestList digest list 864 @param Digest digest 865 866 @retval EFI_SUCCESS Sha1Digest is found and returned. 867 @retval EFI_NOT_FOUND Sha1Digest is not found. 868 **/ 869 EFI_STATUS 870 Tpm2GetDigestFromDigestList ( 871 IN TPMI_ALG_HASH HashAlg, 872 IN TPML_DIGEST_VALUES *DigestList, 873 IN VOID *Digest 874 ) 875 { 876 UINTN Index; 877 UINT16 DigestSize; 878 879 DigestSize = GetHashSizeFromAlgo (HashAlg); 880 for (Index = 0; Index < DigestList->count; Index++) { 881 if (DigestList->digests[Index].hashAlg == HashAlg) { 882 CopyMem ( 883 Digest, 884 &DigestList->digests[Index].digest, 885 DigestSize 886 ); 887 return EFI_SUCCESS; 888 } 889 } 890 891 return EFI_NOT_FOUND; 892 } 893 894 /** 895 Get TPML_DIGEST_VALUES data size. 896 897 @param[in] DigestList TPML_DIGEST_VALUES data. 898 899 @return TPML_DIGEST_VALUES data size. 900 **/ 901 UINT32 902 GetDigestListSize ( 903 IN TPML_DIGEST_VALUES *DigestList 904 ) 905 { 906 UINTN Index; 907 UINT16 DigestSize; 908 UINT32 TotalSize; 909 910 TotalSize = sizeof(DigestList->count); 911 for (Index = 0; Index < DigestList->count; Index++) { 912 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg); 913 TotalSize += sizeof(DigestList->digests[Index].hashAlg) + DigestSize; 914 } 915 916 return TotalSize; 917 } 918 919 /** 920 Get TPML_DIGEST_VALUES compact binary buffer size. 921 922 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer. 923 924 @return TPML_DIGEST_VALUES compact binary buffer size. 925 **/ 926 UINT32 927 GetDigestListBinSize ( 928 IN VOID *DigestListBin 929 ) 930 { 931 UINTN Index; 932 UINT16 DigestSize; 933 UINT32 TotalSize; 934 UINT32 Count; 935 TPMI_ALG_HASH HashAlg; 936 937 Count = ReadUnaligned32 (DigestListBin); 938 TotalSize = sizeof(Count); 939 DigestListBin = (UINT8 *)DigestListBin + sizeof(Count); 940 for (Index = 0; Index < Count; Index++) { 941 HashAlg = ReadUnaligned16 (DigestListBin); 942 TotalSize += sizeof(HashAlg); 943 DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg); 944 945 DigestSize = GetHashSizeFromAlgo (HashAlg); 946 TotalSize += DigestSize; 947 DigestListBin = (UINT8 *)DigestListBin + DigestSize; 948 } 949 950 return TotalSize; 951 } 952 953 /** 954 Return if hash alg is supported in TPM PCR bank. 955 956 @param HashAlg Hash algorithm to be checked. 957 958 @retval TRUE Hash algorithm is supported. 959 @retval FALSE Hash algorithm is not supported. 960 **/ 961 BOOLEAN 962 IsHashAlgSupportedInPcrBank ( 963 IN TPMI_ALG_HASH HashAlg 964 ) 965 { 966 switch (HashAlg) { 967 case TPM_ALG_SHA1: 968 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) { 969 return TRUE; 970 } 971 break; 972 case TPM_ALG_SHA256: 973 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) { 974 return TRUE; 975 } 976 break; 977 case TPM_ALG_SHA384: 978 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) { 979 return TRUE; 980 } 981 break; 982 case TPM_ALG_SHA512: 983 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) { 984 return TRUE; 985 } 986 break; 987 case TPM_ALG_SM3_256: 988 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) { 989 return TRUE; 990 } 991 break; 992 } 993 994 return FALSE; 995 } 996 997 /** 998 Copy TPML_DIGEST_VALUES into a buffer 999 1000 @param[in,out] Buffer Buffer to hold TPML_DIGEST_VALUES. 1001 @param[in] DigestList TPML_DIGEST_VALUES to be copied. 1002 1003 @return The end of buffer to hold TPML_DIGEST_VALUES. 1004 **/ 1005 VOID * 1006 CopyDigestListToBuffer ( 1007 IN OUT VOID *Buffer, 1008 IN TPML_DIGEST_VALUES *DigestList 1009 ) 1010 { 1011 UINTN Index; 1012 UINT16 DigestSize; 1013 1014 CopyMem (Buffer, &DigestList->count, sizeof(DigestList->count)); 1015 Buffer = (UINT8 *)Buffer + sizeof(DigestList->count); 1016 for (Index = 0; Index < DigestList->count; Index++) { 1017 if (!IsHashAlgSupportedInPcrBank (DigestList->digests[Index].hashAlg)) { 1018 DEBUG ((EFI_D_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n", DigestList->digests[Index].hashAlg)); 1019 continue; 1020 } 1021 CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof(DigestList->digests[Index].hashAlg)); 1022 Buffer = (UINT8 *)Buffer + sizeof(DigestList->digests[Index].hashAlg); 1023 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg); 1024 CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize); 1025 Buffer = (UINT8 *)Buffer + DigestSize; 1026 } 1027 1028 return Buffer; 1029 } 1030 1031 /** 1032 Add a new entry to the Event Log. 1033 1034 @param[in] DigestList A list of digest. 1035 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. 1036 @param[in] NewEventData Pointer to the new event data. 1037 1038 @retval EFI_SUCCESS The new event log entry was added. 1039 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. 1040 **/ 1041 EFI_STATUS 1042 TcgDxeLogHashEvent ( 1043 IN TPML_DIGEST_VALUES *DigestList, 1044 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr, 1045 IN UINT8 *NewEventData 1046 ) 1047 { 1048 EFI_STATUS Status; 1049 EFI_TPL OldTpl; 1050 UINTN Index; 1051 EFI_STATUS RetStatus; 1052 TCG_PCR_EVENT2 TcgPcrEvent2; 1053 UINT8 *DigestBuffer; 1054 1055 DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs)); 1056 1057 RetStatus = EFI_SUCCESS; 1058 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) { 1059 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) { 1060 DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat)); 1061 switch (mTcg2EventInfo[Index].LogFormat) { 1062 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2: 1063 Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest); 1064 if (!EFI_ERROR (Status)) { 1065 // 1066 // Enter critical region 1067 // 1068 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); 1069 Status = TcgDxeLogEvent ( 1070 mTcg2EventInfo[Index].LogFormat, 1071 NewEventHdr, 1072 sizeof(TCG_PCR_EVENT_HDR), 1073 NewEventData, 1074 NewEventHdr->EventSize 1075 ); 1076 if (Status != EFI_SUCCESS) { 1077 RetStatus = Status; 1078 } 1079 gBS->RestoreTPL (OldTpl); 1080 // 1081 // Exit critical region 1082 // 1083 } 1084 break; 1085 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2: 1086 ZeroMem (&TcgPcrEvent2, sizeof(TcgPcrEvent2)); 1087 TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex; 1088 TcgPcrEvent2.EventType = NewEventHdr->EventType; 1089 DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest; 1090 DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList); 1091 CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize)); 1092 DigestBuffer = DigestBuffer + sizeof(NewEventHdr->EventSize); 1093 1094 // 1095 // Enter critical region 1096 // 1097 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); 1098 Status = TcgDxeLogEvent ( 1099 mTcg2EventInfo[Index].LogFormat, 1100 &TcgPcrEvent2, 1101 sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2.EventSize), 1102 NewEventData, 1103 NewEventHdr->EventSize 1104 ); 1105 if (Status != EFI_SUCCESS) { 1106 RetStatus = Status; 1107 } 1108 gBS->RestoreTPL (OldTpl); 1109 // 1110 // Exit critical region 1111 // 1112 break; 1113 } 1114 } 1115 } 1116 1117 return RetStatus; 1118 } 1119 1120 /** 1121 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result, 1122 and add an entry to the Event Log. 1123 1124 @param[in] Flags Bitmap providing additional information. 1125 @param[in] HashData Physical address of the start of the data buffer 1126 to be hashed, extended, and logged. 1127 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData 1128 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. 1129 @param[in] NewEventData Pointer to the new event data. 1130 1131 @retval EFI_SUCCESS Operation completed successfully. 1132 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. 1133 @retval EFI_DEVICE_ERROR The command was unsuccessful. 1134 1135 **/ 1136 EFI_STATUS 1137 TcgDxeHashLogExtendEvent ( 1138 IN UINT64 Flags, 1139 IN UINT8 *HashData, 1140 IN UINT64 HashDataLen, 1141 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr, 1142 IN UINT8 *NewEventData 1143 ) 1144 { 1145 EFI_STATUS Status; 1146 TPML_DIGEST_VALUES DigestList; 1147 1148 if (!mTcgDxeData.BsCap.TPMPresentFlag) { 1149 return EFI_DEVICE_ERROR; 1150 } 1151 1152 Status = HashAndExtend ( 1153 NewEventHdr->PCRIndex, 1154 HashData, 1155 (UINTN)HashDataLen, 1156 &DigestList 1157 ); 1158 if (!EFI_ERROR (Status)) { 1159 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) { 1160 Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData); 1161 } 1162 } 1163 1164 if (Status == EFI_DEVICE_ERROR) { 1165 DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status)); 1166 mTcgDxeData.BsCap.TPMPresentFlag = FALSE; 1167 REPORT_STATUS_CODE ( 1168 EFI_ERROR_CODE | EFI_ERROR_MINOR, 1169 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) 1170 ); 1171 } 1172 1173 return Status; 1174 } 1175 1176 /** 1177 The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with 1178 an opportunity to extend and optionally log events without requiring 1179 knowledge of actual TPM commands. 1180 The extend operation will occur even if this function cannot create an event 1181 log entry (e.g. due to the event log being full). 1182 1183 @param[in] This Indicates the calling context 1184 @param[in] Flags Bitmap providing additional information. 1185 @param[in] DataToHash Physical address of the start of the data buffer to be hashed. 1186 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash. 1187 @param[in] Event Pointer to data buffer containing information about the event. 1188 1189 @retval EFI_SUCCESS Operation completed successfully. 1190 @retval EFI_DEVICE_ERROR The command was unsuccessful. 1191 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs. 1192 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. 1193 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported. 1194 **/ 1195 EFI_STATUS 1196 EFIAPI 1197 Tcg2HashLogExtendEvent ( 1198 IN EFI_TCG2_PROTOCOL *This, 1199 IN UINT64 Flags, 1200 IN EFI_PHYSICAL_ADDRESS DataToHash, 1201 IN UINT64 DataToHashLen, 1202 IN EFI_TCG2_EVENT *Event 1203 ) 1204 { 1205 EFI_STATUS Status; 1206 TCG_PCR_EVENT_HDR NewEventHdr; 1207 TPML_DIGEST_VALUES DigestList; 1208 1209 DEBUG ((EFI_D_INFO, "Tcg2HashLogExtendEvent ...\n")); 1210 1211 if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) { 1212 return EFI_INVALID_PARAMETER; 1213 } 1214 1215 if (!mTcgDxeData.BsCap.TPMPresentFlag) { 1216 return EFI_DEVICE_ERROR; 1217 } 1218 1219 if (Event->Size < Event->Header.HeaderSize + sizeof(UINT32)) { 1220 return EFI_INVALID_PARAMETER; 1221 } 1222 1223 if (Event->Header.PCRIndex > MAX_PCR_INDEX) { 1224 return EFI_INVALID_PARAMETER; 1225 } 1226 1227 NewEventHdr.PCRIndex = Event->Header.PCRIndex; 1228 NewEventHdr.EventType = Event->Header.EventType; 1229 NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize; 1230 if ((Flags & PE_COFF_IMAGE) != 0) { 1231 Status = MeasurePeImageAndExtend ( 1232 NewEventHdr.PCRIndex, 1233 DataToHash, 1234 (UINTN)DataToHashLen, 1235 &DigestList 1236 ); 1237 if (!EFI_ERROR (Status)) { 1238 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) { 1239 Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event); 1240 } 1241 } 1242 if (Status == EFI_DEVICE_ERROR) { 1243 DEBUG ((EFI_D_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status)); 1244 mTcgDxeData.BsCap.TPMPresentFlag = FALSE; 1245 REPORT_STATUS_CODE ( 1246 EFI_ERROR_CODE | EFI_ERROR_MINOR, 1247 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) 1248 ); 1249 } 1250 } else { 1251 Status = TcgDxeHashLogExtendEvent ( 1252 Flags, 1253 (UINT8 *) (UINTN) DataToHash, 1254 DataToHashLen, 1255 &NewEventHdr, 1256 Event->Event 1257 ); 1258 } 1259 DEBUG ((EFI_D_INFO, "Tcg2HashLogExtendEvent - %r\n", Status)); 1260 return Status; 1261 } 1262 1263 /** 1264 This service enables the sending of commands to the TPM. 1265 1266 @param[in] This Indicates the calling context 1267 @param[in] InputParameterBlockSize Size of the TPM input parameter block. 1268 @param[in] InputParameterBlock Pointer to the TPM input parameter block. 1269 @param[in] OutputParameterBlockSize Size of the TPM output parameter block. 1270 @param[in] OutputParameterBlock Pointer to the TPM output parameter block. 1271 1272 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received. 1273 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device. 1274 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. 1275 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. 1276 **/ 1277 EFI_STATUS 1278 EFIAPI 1279 Tcg2SubmitCommand ( 1280 IN EFI_TCG2_PROTOCOL *This, 1281 IN UINT32 InputParameterBlockSize, 1282 IN UINT8 *InputParameterBlock, 1283 IN UINT32 OutputParameterBlockSize, 1284 IN UINT8 *OutputParameterBlock 1285 ) 1286 { 1287 EFI_STATUS Status; 1288 1289 DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand ...\n")); 1290 1291 if ((This == NULL) || 1292 (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) || 1293 (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL)) { 1294 return EFI_INVALID_PARAMETER; 1295 } 1296 1297 if (!mTcgDxeData.BsCap.TPMPresentFlag) { 1298 return EFI_DEVICE_ERROR; 1299 } 1300 1301 if (InputParameterBlockSize >= mTcgDxeData.BsCap.MaxCommandSize) { 1302 return EFI_INVALID_PARAMETER; 1303 } 1304 if (OutputParameterBlockSize >= mTcgDxeData.BsCap.MaxResponseSize) { 1305 return EFI_INVALID_PARAMETER; 1306 } 1307 1308 Status = Tpm2SubmitCommand ( 1309 InputParameterBlockSize, 1310 InputParameterBlock, 1311 &OutputParameterBlockSize, 1312 OutputParameterBlock 1313 ); 1314 DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand - %r\n", Status)); 1315 return Status; 1316 } 1317 1318 /** 1319 This service returns the currently active PCR banks. 1320 1321 @param[in] This Indicates the calling context 1322 @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks. 1323 1324 @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter. 1325 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. 1326 **/ 1327 EFI_STATUS 1328 EFIAPI 1329 Tcg2GetActivePCRBanks ( 1330 IN EFI_TCG2_PROTOCOL *This, 1331 OUT UINT32 *ActivePcrBanks 1332 ) 1333 { 1334 if (ActivePcrBanks == NULL) { 1335 return EFI_INVALID_PARAMETER; 1336 } 1337 *ActivePcrBanks = mTcgDxeData.BsCap.ActivePcrBanks; 1338 return EFI_SUCCESS; 1339 } 1340 1341 /** 1342 This service sets the currently active PCR banks. 1343 1344 @param[in] This Indicates the calling context 1345 @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set. 1346 1347 @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active. 1348 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. 1349 **/ 1350 EFI_STATUS 1351 EFIAPI 1352 Tcg2SetActivePCRBanks ( 1353 IN EFI_TCG2_PROTOCOL *This, 1354 IN UINT32 ActivePcrBanks 1355 ) 1356 { 1357 EFI_STATUS Status; 1358 UINT32 ReturnCode; 1359 1360 DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks ... (0x%x)\n", ActivePcrBanks)); 1361 1362 if (ActivePcrBanks == 0) { 1363 return EFI_INVALID_PARAMETER; 1364 } 1365 if ((ActivePcrBanks & (~mTcgDxeData.BsCap.HashAlgorithmBitmap)) != 0) { 1366 return EFI_INVALID_PARAMETER; 1367 } 1368 if (ActivePcrBanks == mTcgDxeData.BsCap.ActivePcrBanks) { 1369 // 1370 // Need clear previous SET_PCR_BANKS setting 1371 // 1372 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_NO_ACTION, 0); 1373 } else { 1374 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, ActivePcrBanks); 1375 } 1376 1377 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) { 1378 Status = EFI_SUCCESS; 1379 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) { 1380 Status = EFI_OUT_OF_RESOURCES; 1381 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) { 1382 Status = EFI_UNSUPPORTED; 1383 } else { 1384 Status = EFI_DEVICE_ERROR; 1385 } 1386 1387 DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks - %r\n", Status)); 1388 1389 return Status; 1390 } 1391 1392 /** 1393 This service retrieves the result of a previous invocation of SetActivePcrBanks. 1394 1395 @param[in] This Indicates the calling context 1396 @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot. 1397 @param[out] Response The response from the SetActivePcrBank request. 1398 1399 @retval EFI_SUCCESS The result value could be returned. 1400 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. 1401 **/ 1402 EFI_STATUS 1403 EFIAPI 1404 Tcg2GetResultOfSetActivePcrBanks ( 1405 IN EFI_TCG2_PROTOCOL *This, 1406 OUT UINT32 *OperationPresent, 1407 OUT UINT32 *Response 1408 ) 1409 { 1410 UINT32 ReturnCode; 1411 1412 if ((OperationPresent == NULL) || (Response == NULL)) { 1413 return EFI_INVALID_PARAMETER; 1414 } 1415 1416 ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response); 1417 if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) { 1418 return EFI_SUCCESS; 1419 } else { 1420 return EFI_UNSUPPORTED; 1421 } 1422 } 1423 1424 EFI_TCG2_PROTOCOL mTcg2Protocol = { 1425 Tcg2GetCapability, 1426 Tcg2GetEventLog, 1427 Tcg2HashLogExtendEvent, 1428 Tcg2SubmitCommand, 1429 Tcg2GetActivePCRBanks, 1430 Tcg2SetActivePCRBanks, 1431 Tcg2GetResultOfSetActivePcrBanks, 1432 }; 1433 1434 /** 1435 Initialize the Event Log and log events passed from the PEI phase. 1436 1437 @retval EFI_SUCCESS Operation completed successfully. 1438 @retval EFI_OUT_OF_RESOURCES Out of memory. 1439 1440 **/ 1441 EFI_STATUS 1442 SetupEventLog ( 1443 VOID 1444 ) 1445 { 1446 EFI_STATUS Status; 1447 VOID *TcgEvent; 1448 EFI_PEI_HOB_POINTERS GuidHob; 1449 EFI_PHYSICAL_ADDRESS Lasa; 1450 UINTN Index; 1451 UINT32 DigestListBinSize; 1452 UINT32 EventSize; 1453 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct; 1454 UINT8 TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)]; 1455 TCG_PCR_EVENT_HDR FirstPcrEvent; 1456 TCG_EfiSpecIdEventAlgorithmSize *DigestSize; 1457 TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize; 1458 UINT8 *VendorInfoSize; 1459 UINT32 NumberOfAlgorithms; 1460 1461 DEBUG ((EFI_D_INFO, "SetupEventLog\n")); 1462 1463 // 1464 // 1. Create Log Area 1465 // 1466 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) { 1467 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) { 1468 mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat; 1469 Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1); 1470 Status = gBS->AllocatePages ( 1471 AllocateMaxAddress, 1472 EfiACPIMemoryNVS, 1473 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE), 1474 &Lasa 1475 ); 1476 if (EFI_ERROR (Status)) { 1477 return Status; 1478 } 1479 mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa; 1480 mTcgDxeData.EventLogAreaStruct[Index].Laml = EFI_TCG_LOG_AREA_SIZE; 1481 // 1482 // To initialize them as 0xFF is recommended 1483 // because the OS can know the last entry for that. 1484 // 1485 SetMem ((VOID *)(UINTN)Lasa, EFI_TCG_LOG_AREA_SIZE, 0xFF); 1486 // 1487 // Create first entry for Log Header Entry Data 1488 // 1489 if (mTcg2EventInfo[Index].LogFormat != EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) { 1490 // 1491 // TcgEfiSpecIdEventStruct 1492 // 1493 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf; 1494 CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof(TcgEfiSpecIdEventStruct->signature)); 1495 TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass); 1496 TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2; 1497 TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2; 1498 TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2; 1499 TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32); 1500 NumberOfAlgorithms = 0; 1501 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms)); 1502 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) { 1503 TempDigestSize = DigestSize; 1504 TempDigestSize += NumberOfAlgorithms; 1505 TempDigestSize->algorithmId = TPM_ALG_SHA1; 1506 TempDigestSize->digestSize = SHA1_DIGEST_SIZE; 1507 NumberOfAlgorithms++; 1508 } 1509 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) { 1510 TempDigestSize = DigestSize; 1511 TempDigestSize += NumberOfAlgorithms; 1512 TempDigestSize->algorithmId = TPM_ALG_SHA256; 1513 TempDigestSize->digestSize = SHA256_DIGEST_SIZE; 1514 NumberOfAlgorithms++; 1515 } 1516 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) { 1517 TempDigestSize = DigestSize; 1518 TempDigestSize += NumberOfAlgorithms; 1519 TempDigestSize->algorithmId = TPM_ALG_SHA384; 1520 TempDigestSize->digestSize = SHA384_DIGEST_SIZE; 1521 NumberOfAlgorithms++; 1522 } 1523 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) { 1524 TempDigestSize = DigestSize; 1525 TempDigestSize += NumberOfAlgorithms; 1526 TempDigestSize->algorithmId = TPM_ALG_SHA512; 1527 TempDigestSize->digestSize = SHA512_DIGEST_SIZE; 1528 NumberOfAlgorithms++; 1529 } 1530 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) { 1531 TempDigestSize = DigestSize; 1532 TempDigestSize += NumberOfAlgorithms; 1533 TempDigestSize->algorithmId = TPM_ALG_SM3_256; 1534 TempDigestSize->digestSize = SM3_256_DIGEST_SIZE; 1535 NumberOfAlgorithms++; 1536 } 1537 CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof(NumberOfAlgorithms)); 1538 TempDigestSize = DigestSize; 1539 TempDigestSize += NumberOfAlgorithms; 1540 VendorInfoSize = (UINT8 *)TempDigestSize; 1541 *VendorInfoSize = 0; 1542 1543 // 1544 // FirstPcrEvent 1545 // 1546 FirstPcrEvent.PCRIndex = 0; 1547 FirstPcrEvent.EventType = EV_NO_ACTION; 1548 ZeroMem (&FirstPcrEvent.Digest, sizeof(FirstPcrEvent.Digest)); 1549 FirstPcrEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct); 1550 1551 // 1552 // Record 1553 // 1554 Status = TcgDxeLogEvent ( 1555 mTcg2EventInfo[Index].LogFormat, 1556 &FirstPcrEvent, 1557 sizeof(FirstPcrEvent), 1558 (UINT8 *)TcgEfiSpecIdEventStruct, 1559 FirstPcrEvent.EventSize 1560 ); 1561 } 1562 } 1563 } 1564 1565 // 1566 // 2. Create Final Log Area 1567 // 1568 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) { 1569 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) { 1570 Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1); 1571 Status = gBS->AllocatePages ( 1572 AllocateMaxAddress, 1573 EfiACPIMemoryNVS, 1574 EFI_SIZE_TO_PAGES (EFI_TCG_FINAL_LOG_AREA_SIZE), 1575 &Lasa 1576 ); 1577 if (EFI_ERROR (Status)) { 1578 return Status; 1579 } 1580 SetMem ((VOID *)(UINTN)Lasa, EFI_TCG_FINAL_LOG_AREA_SIZE, 0xFF); 1581 1582 // 1583 // Initialize 1584 // 1585 mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa; 1586 (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION; 1587 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0; 1588 1589 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat; 1590 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE); 1591 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = EFI_TCG_FINAL_LOG_AREA_SIZE - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE); 1592 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0; 1593 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa; 1594 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE; 1595 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE; 1596 1597 if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { 1598 // 1599 // Install to configuration table 1600 // 1601 Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[1]); 1602 if (EFI_ERROR (Status)) { 1603 return Status; 1604 } 1605 } 1606 } 1607 } 1608 1609 // 1610 // 3. Sync data from PEI to DXE 1611 // 1612 Status = EFI_SUCCESS; 1613 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) { 1614 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) { 1615 GuidHob.Raw = GetHobList (); 1616 Status = EFI_SUCCESS; 1617 while (!EFI_ERROR (Status) && 1618 (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) { 1619 TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid); 1620 GuidHob.Raw = GET_NEXT_HOB (GuidHob); 1621 switch (mTcg2EventInfo[Index].LogFormat) { 1622 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2: 1623 Status = TcgDxeLogEvent ( 1624 mTcg2EventInfo[Index].LogFormat, 1625 TcgEvent, 1626 sizeof(TCG_PCR_EVENT_HDR), 1627 ((TCG_PCR_EVENT*)TcgEvent)->Event, 1628 ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize 1629 ); 1630 break; 1631 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2: 1632 DigestListBinSize = GetDigestListBinSize ((UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE)); 1633 CopyMem (&EventSize, (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize, sizeof(UINT32)); 1634 Status = TcgDxeLogEvent ( 1635 mTcg2EventInfo[Index].LogFormat, 1636 TcgEvent, 1637 sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32), 1638 (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32), 1639 EventSize 1640 ); 1641 break; 1642 } 1643 } 1644 } 1645 } 1646 1647 return Status; 1648 } 1649 1650 /** 1651 Measure and log an action string, and extend the measurement result into PCR[5]. 1652 1653 @param[in] String A specific string that indicates an Action event. 1654 1655 @retval EFI_SUCCESS Operation completed successfully. 1656 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1657 1658 **/ 1659 EFI_STATUS 1660 TcgMeasureAction ( 1661 IN CHAR8 *String 1662 ) 1663 { 1664 TCG_PCR_EVENT_HDR TcgEvent; 1665 1666 TcgEvent.PCRIndex = 5; 1667 TcgEvent.EventType = EV_EFI_ACTION; 1668 TcgEvent.EventSize = (UINT32)AsciiStrLen (String); 1669 return TcgDxeHashLogExtendEvent ( 1670 0, 1671 (UINT8*)String, 1672 TcgEvent.EventSize, 1673 &TcgEvent, 1674 (UINT8 *) String 1675 ); 1676 } 1677 1678 /** 1679 Measure and log EFI handoff tables, and extend the measurement result into PCR[1]. 1680 1681 @retval EFI_SUCCESS Operation completed successfully. 1682 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1683 1684 **/ 1685 EFI_STATUS 1686 MeasureHandoffTables ( 1687 VOID 1688 ) 1689 { 1690 EFI_STATUS Status; 1691 TCG_PCR_EVENT_HDR TcgEvent; 1692 EFI_HANDOFF_TABLE_POINTERS HandoffTables; 1693 UINTN ProcessorNum; 1694 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf; 1695 1696 ProcessorLocBuf = NULL; 1697 Status = EFI_SUCCESS; 1698 1699 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) { 1700 // 1701 // Tcg Server spec. 1702 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1] 1703 // 1704 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum); 1705 1706 if (!EFI_ERROR(Status)){ 1707 TcgEvent.PCRIndex = 1; 1708 TcgEvent.EventType = EV_TABLE_OF_DEVICES; 1709 TcgEvent.EventSize = sizeof (HandoffTables); 1710 1711 HandoffTables.NumberOfTables = 1; 1712 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid; 1713 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf; 1714 1715 Status = TcgDxeHashLogExtendEvent ( 1716 0, 1717 (UINT8*)(UINTN)ProcessorLocBuf, 1718 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum, 1719 &TcgEvent, 1720 (UINT8*)&HandoffTables 1721 ); 1722 1723 FreePool(ProcessorLocBuf); 1724 } 1725 } 1726 1727 return Status; 1728 } 1729 1730 /** 1731 Measure and log Separator event, and extend the measurement result into a specific PCR. 1732 1733 @param[in] PCRIndex PCR index. 1734 1735 @retval EFI_SUCCESS Operation completed successfully. 1736 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1737 1738 **/ 1739 EFI_STATUS 1740 MeasureSeparatorEvent ( 1741 IN TPM_PCRINDEX PCRIndex 1742 ) 1743 { 1744 TCG_PCR_EVENT_HDR TcgEvent; 1745 UINT32 EventData; 1746 1747 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex)); 1748 1749 EventData = 0; 1750 TcgEvent.PCRIndex = PCRIndex; 1751 TcgEvent.EventType = EV_SEPARATOR; 1752 TcgEvent.EventSize = (UINT32)sizeof (EventData); 1753 return TcgDxeHashLogExtendEvent ( 1754 0, 1755 (UINT8 *)&EventData, 1756 sizeof (EventData), 1757 &TcgEvent, 1758 (UINT8 *)&EventData 1759 ); 1760 } 1761 1762 /** 1763 Measure and log an EFI variable, and extend the measurement result into a specific PCR. 1764 1765 @param[in] PCRIndex PCR Index. 1766 @param[in] EventType Event type. 1767 @param[in] VarName A Null-terminated string that is the name of the vendor's variable. 1768 @param[in] VendorGuid A unique identifier for the vendor. 1769 @param[in] VarData The content of the variable data. 1770 @param[in] VarSize The size of the variable data. 1771 1772 @retval EFI_SUCCESS Operation completed successfully. 1773 @retval EFI_OUT_OF_RESOURCES Out of memory. 1774 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1775 1776 **/ 1777 EFI_STATUS 1778 MeasureVariable ( 1779 IN TPM_PCRINDEX PCRIndex, 1780 IN TCG_EVENTTYPE EventType, 1781 IN CHAR16 *VarName, 1782 IN EFI_GUID *VendorGuid, 1783 IN VOID *VarData, 1784 IN UINTN VarSize 1785 ) 1786 { 1787 EFI_STATUS Status; 1788 TCG_PCR_EVENT_HDR TcgEvent; 1789 UINTN VarNameLength; 1790 EFI_VARIABLE_DATA_TREE *VarLog; 1791 1792 DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType)); 1793 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid)); 1794 1795 VarNameLength = StrLen (VarName); 1796 TcgEvent.PCRIndex = PCRIndex; 1797 TcgEvent.EventType = EventType; 1798 1799 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize 1800 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData)); 1801 1802 VarLog = (EFI_VARIABLE_DATA_TREE *)AllocatePool (TcgEvent.EventSize); 1803 if (VarLog == NULL) { 1804 return EFI_OUT_OF_RESOURCES; 1805 } 1806 1807 VarLog->VariableName = *VendorGuid; 1808 VarLog->UnicodeNameLength = VarNameLength; 1809 VarLog->VariableDataLength = VarSize; 1810 CopyMem ( 1811 VarLog->UnicodeName, 1812 VarName, 1813 VarNameLength * sizeof (*VarName) 1814 ); 1815 if (VarSize != 0 && VarData != NULL) { 1816 CopyMem ( 1817 (CHAR16 *)VarLog->UnicodeName + VarNameLength, 1818 VarData, 1819 VarSize 1820 ); 1821 } 1822 1823 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) { 1824 // 1825 // Digest is the event data (EFI_VARIABLE_DATA) 1826 // 1827 Status = TcgDxeHashLogExtendEvent ( 1828 0, 1829 (UINT8*)VarLog, 1830 TcgEvent.EventSize, 1831 &TcgEvent, 1832 (UINT8*)VarLog 1833 ); 1834 } else { 1835 Status = TcgDxeHashLogExtendEvent ( 1836 0, 1837 (UINT8*)VarData, 1838 VarSize, 1839 &TcgEvent, 1840 (UINT8*)VarLog 1841 ); 1842 } 1843 FreePool (VarLog); 1844 return Status; 1845 } 1846 1847 /** 1848 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR. 1849 1850 @param[in] PCRIndex PCR Index. 1851 @param[in] EventType Event type. 1852 @param[in] VarName A Null-terminated string that is the name of the vendor's variable. 1853 @param[in] VendorGuid A unique identifier for the vendor. 1854 @param[out] VarSize The size of the variable data. 1855 @param[out] VarData Pointer to the content of the variable. 1856 1857 @retval EFI_SUCCESS Operation completed successfully. 1858 @retval EFI_OUT_OF_RESOURCES Out of memory. 1859 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1860 1861 **/ 1862 EFI_STATUS 1863 ReadAndMeasureVariable ( 1864 IN TPM_PCRINDEX PCRIndex, 1865 IN TCG_EVENTTYPE EventType, 1866 IN CHAR16 *VarName, 1867 IN EFI_GUID *VendorGuid, 1868 OUT UINTN *VarSize, 1869 OUT VOID **VarData 1870 ) 1871 { 1872 EFI_STATUS Status; 1873 1874 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize); 1875 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) { 1876 if (EFI_ERROR (Status)) { 1877 // 1878 // It is valid case, so we need handle it. 1879 // 1880 *VarData = NULL; 1881 *VarSize = 0; 1882 } 1883 } else { 1884 // 1885 // if status error, VarData is freed and set NULL by GetVariable2 1886 // 1887 if (EFI_ERROR (Status)) { 1888 return EFI_NOT_FOUND; 1889 } 1890 } 1891 1892 Status = MeasureVariable ( 1893 PCRIndex, 1894 EventType, 1895 VarName, 1896 VendorGuid, 1897 *VarData, 1898 *VarSize 1899 ); 1900 return Status; 1901 } 1902 1903 /** 1904 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5]. 1905 1906 @param[in] VarName A Null-terminated string that is the name of the vendor's variable. 1907 @param[in] VendorGuid A unique identifier for the vendor. 1908 @param[out] VarSize The size of the variable data. 1909 @param[out] VarData Pointer to the content of the variable. 1910 1911 @retval EFI_SUCCESS Operation completed successfully. 1912 @retval EFI_OUT_OF_RESOURCES Out of memory. 1913 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1914 1915 **/ 1916 EFI_STATUS 1917 ReadAndMeasureBootVariable ( 1918 IN CHAR16 *VarName, 1919 IN EFI_GUID *VendorGuid, 1920 OUT UINTN *VarSize, 1921 OUT VOID **VarData 1922 ) 1923 { 1924 return ReadAndMeasureVariable ( 1925 5, 1926 EV_EFI_VARIABLE_BOOT, 1927 VarName, 1928 VendorGuid, 1929 VarSize, 1930 VarData 1931 ); 1932 } 1933 1934 /** 1935 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7]. 1936 1937 @param[in] VarName A Null-terminated string that is the name of the vendor's variable. 1938 @param[in] VendorGuid A unique identifier for the vendor. 1939 @param[out] VarSize The size of the variable data. 1940 @param[out] VarData Pointer to the content of the variable. 1941 1942 @retval EFI_SUCCESS Operation completed successfully. 1943 @retval EFI_OUT_OF_RESOURCES Out of memory. 1944 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1945 1946 **/ 1947 EFI_STATUS 1948 ReadAndMeasureSecureVariable ( 1949 IN CHAR16 *VarName, 1950 IN EFI_GUID *VendorGuid, 1951 OUT UINTN *VarSize, 1952 OUT VOID **VarData 1953 ) 1954 { 1955 return ReadAndMeasureVariable ( 1956 7, 1957 EV_EFI_VARIABLE_DRIVER_CONFIG, 1958 VarName, 1959 VendorGuid, 1960 VarSize, 1961 VarData 1962 ); 1963 } 1964 1965 /** 1966 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR. 1967 1968 The EFI boot variables are BootOrder and Boot#### variables. 1969 1970 @retval EFI_SUCCESS Operation completed successfully. 1971 @retval EFI_OUT_OF_RESOURCES Out of memory. 1972 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 1973 1974 **/ 1975 EFI_STATUS 1976 MeasureAllBootVariables ( 1977 VOID 1978 ) 1979 { 1980 EFI_STATUS Status; 1981 UINT16 *BootOrder; 1982 UINTN BootCount; 1983 UINTN Index; 1984 VOID *BootVarData; 1985 UINTN Size; 1986 1987 Status = ReadAndMeasureBootVariable ( 1988 mBootVarName, 1989 &gEfiGlobalVariableGuid, 1990 &BootCount, 1991 (VOID **) &BootOrder 1992 ); 1993 if (Status == EFI_NOT_FOUND || BootOrder == NULL) { 1994 return EFI_SUCCESS; 1995 } 1996 1997 if (EFI_ERROR (Status)) { 1998 // 1999 // BootOrder can't be NULL if status is not EFI_NOT_FOUND 2000 // 2001 FreePool (BootOrder); 2002 return Status; 2003 } 2004 2005 BootCount /= sizeof (*BootOrder); 2006 for (Index = 0; Index < BootCount; Index++) { 2007 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]); 2008 Status = ReadAndMeasureBootVariable ( 2009 mBootVarName, 2010 &gEfiGlobalVariableGuid, 2011 &Size, 2012 &BootVarData 2013 ); 2014 if (!EFI_ERROR (Status)) { 2015 FreePool (BootVarData); 2016 } 2017 } 2018 2019 FreePool (BootOrder); 2020 return EFI_SUCCESS; 2021 } 2022 2023 /** 2024 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR. 2025 2026 The EFI boot variables are BootOrder and Boot#### variables. 2027 2028 @retval EFI_SUCCESS Operation completed successfully. 2029 @retval EFI_OUT_OF_RESOURCES Out of memory. 2030 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 2031 2032 **/ 2033 EFI_STATUS 2034 MeasureAllSecureVariables ( 2035 VOID 2036 ) 2037 { 2038 EFI_STATUS Status; 2039 VOID *Data; 2040 UINTN DataSize; 2041 UINTN Index; 2042 2043 Status = EFI_NOT_FOUND; 2044 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) { 2045 Status = ReadAndMeasureSecureVariable ( 2046 mVariableType[Index].VariableName, 2047 mVariableType[Index].VendorGuid, 2048 &DataSize, 2049 &Data 2050 ); 2051 if (!EFI_ERROR (Status)) { 2052 if (Data != NULL) { 2053 FreePool (Data); 2054 } 2055 } 2056 } 2057 2058 return EFI_SUCCESS; 2059 } 2060 2061 /** 2062 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR. 2063 2064 @retval EFI_SUCCESS Operation completed successfully. 2065 @retval EFI_OUT_OF_RESOURCES Out of memory. 2066 @retval EFI_DEVICE_ERROR The operation was unsuccessful. 2067 2068 **/ 2069 EFI_STATUS 2070 MeasureLaunchOfFirmwareDebugger ( 2071 VOID 2072 ) 2073 { 2074 TCG_PCR_EVENT_HDR TcgEvent; 2075 2076 TcgEvent.PCRIndex = 7; 2077 TcgEvent.EventType = EV_EFI_ACTION; 2078 TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1; 2079 return TcgDxeHashLogExtendEvent ( 2080 0, 2081 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING, 2082 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1, 2083 &TcgEvent, 2084 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING 2085 ); 2086 } 2087 2088 /** 2089 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR. 2090 2091 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed) 2092 - The contents of the SecureBoot variable 2093 - The contents of the PK variable 2094 - The contents of the KEK variable 2095 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable 2096 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable 2097 - Separator 2098 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path 2099 2100 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE, 2101 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3]. 2102 2103 @param[in] Event Event whose notification function is being invoked 2104 @param[in] Context Pointer to the notification function's context 2105 **/ 2106 VOID 2107 EFIAPI 2108 MeasureSecureBootPolicy ( 2109 IN EFI_EVENT Event, 2110 IN VOID *Context 2111 ) 2112 { 2113 EFI_STATUS Status; 2114 VOID *Protocol; 2115 2116 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol); 2117 if (EFI_ERROR (Status)) { 2118 return; 2119 } 2120 2121 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) { 2122 Status = MeasureLaunchOfFirmwareDebugger (); 2123 DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status)); 2124 } 2125 2126 Status = MeasureAllSecureVariables (); 2127 DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status)); 2128 2129 // 2130 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure) 2131 // and ImageVerification (Authority) 2132 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So 2133 // the Authority measurement happen before ReadToBoot event. 2134 // 2135 Status = MeasureSeparatorEvent (7); 2136 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status)); 2137 return ; 2138 } 2139 2140 /** 2141 Ready to Boot Event notification handler. 2142 2143 Sequence of OS boot events is measured in this event notification handler. 2144 2145 @param[in] Event Event whose notification function is being invoked 2146 @param[in] Context Pointer to the notification function's context 2147 2148 **/ 2149 VOID 2150 EFIAPI 2151 OnReadyToBoot ( 2152 IN EFI_EVENT Event, 2153 IN VOID *Context 2154 ) 2155 { 2156 EFI_STATUS Status; 2157 TPM_PCRINDEX PcrIndex; 2158 2159 PERF_START_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE); 2160 if (mBootAttempts == 0) { 2161 2162 // 2163 // Measure handoff tables. 2164 // 2165 Status = MeasureHandoffTables (); 2166 if (EFI_ERROR (Status)) { 2167 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n")); 2168 } 2169 2170 // 2171 // Measure BootOrder & Boot#### variables. 2172 // 2173 Status = MeasureAllBootVariables (); 2174 if (EFI_ERROR (Status)) { 2175 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n")); 2176 } 2177 2178 // 2179 // 1. This is the first boot attempt. 2180 // 2181 Status = TcgMeasureAction ( 2182 EFI_CALLING_EFI_APPLICATION 2183 ); 2184 if (EFI_ERROR (Status)) { 2185 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION)); 2186 } 2187 2188 // 2189 // 2. Draw a line between pre-boot env and entering post-boot env. 2190 // PCR[7] is already done. 2191 // 2192 for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) { 2193 Status = MeasureSeparatorEvent (PcrIndex); 2194 if (EFI_ERROR (Status)) { 2195 DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n")); 2196 } 2197 } 2198 2199 // 2200 // 3. Measure GPT. It would be done in SAP driver. 2201 // 2202 2203 // 2204 // 4. Measure PE/COFF OS loader. It would be done in SAP driver. 2205 // 2206 2207 // 2208 // 5. Read & Measure variable. BootOrder already measured. 2209 // 2210 } else { 2211 // 2212 // 6. Not first attempt, meaning a return from last attempt 2213 // 2214 Status = TcgMeasureAction ( 2215 EFI_RETURNING_FROM_EFI_APPLICATOIN 2216 ); 2217 if (EFI_ERROR (Status)) { 2218 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN)); 2219 } 2220 } 2221 2222 DEBUG ((EFI_D_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n")); 2223 // 2224 // Increase boot attempt counter. 2225 // 2226 mBootAttempts++; 2227 PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE + 1); 2228 } 2229 2230 /** 2231 Exit Boot Services Event notification handler. 2232 2233 Measure invocation and success of ExitBootServices. 2234 2235 @param[in] Event Event whose notification function is being invoked 2236 @param[in] Context Pointer to the notification function's context 2237 2238 **/ 2239 VOID 2240 EFIAPI 2241 OnExitBootServices ( 2242 IN EFI_EVENT Event, 2243 IN VOID *Context 2244 ) 2245 { 2246 EFI_STATUS Status; 2247 2248 // 2249 // Measure invocation of ExitBootServices, 2250 // 2251 Status = TcgMeasureAction ( 2252 EFI_EXIT_BOOT_SERVICES_INVOCATION 2253 ); 2254 if (EFI_ERROR (Status)) { 2255 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION)); 2256 } 2257 2258 // 2259 // Measure success of ExitBootServices 2260 // 2261 Status = TcgMeasureAction ( 2262 EFI_EXIT_BOOT_SERVICES_SUCCEEDED 2263 ); 2264 if (EFI_ERROR (Status)) { 2265 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED)); 2266 } 2267 } 2268 2269 /** 2270 Exit Boot Services Failed Event notification handler. 2271 2272 Measure Failure of ExitBootServices. 2273 2274 @param[in] Event Event whose notification function is being invoked 2275 @param[in] Context Pointer to the notification function's context 2276 2277 **/ 2278 VOID 2279 EFIAPI 2280 OnExitBootServicesFailed ( 2281 IN EFI_EVENT Event, 2282 IN VOID *Context 2283 ) 2284 { 2285 EFI_STATUS Status; 2286 2287 // 2288 // Measure Failure of ExitBootServices, 2289 // 2290 Status = TcgMeasureAction ( 2291 EFI_EXIT_BOOT_SERVICES_FAILED 2292 ); 2293 if (EFI_ERROR (Status)) { 2294 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED)); 2295 } 2296 2297 } 2298 2299 /** 2300 The function install Tcg2 protocol. 2301 2302 @retval EFI_SUCCESS Tcg2 protocol is installed. 2303 @retval other Some error occurs. 2304 **/ 2305 EFI_STATUS 2306 InstallTcg2 ( 2307 VOID 2308 ) 2309 { 2310 EFI_STATUS Status; 2311 EFI_HANDLE Handle; 2312 2313 Handle = NULL; 2314 Status = gBS->InstallMultipleProtocolInterfaces ( 2315 &Handle, 2316 &gEfiTcg2ProtocolGuid, 2317 &mTcg2Protocol, 2318 NULL 2319 ); 2320 return Status; 2321 } 2322 2323 /** 2324 The driver's entry point. It publishes EFI Tcg2 Protocol. 2325 2326 @param[in] ImageHandle The firmware allocated handle for the EFI image. 2327 @param[in] SystemTable A pointer to the EFI System Table. 2328 2329 @retval EFI_SUCCESS The entry point is executed successfully. 2330 @retval other Some error occurs when executing this entry point. 2331 **/ 2332 EFI_STATUS 2333 EFIAPI 2334 DriverEntry ( 2335 IN EFI_HANDLE ImageHandle, 2336 IN EFI_SYSTEM_TABLE *SystemTable 2337 ) 2338 { 2339 EFI_STATUS Status; 2340 EFI_EVENT Event; 2341 VOID *Registration; 2342 UINT32 MaxCommandSize; 2343 UINT32 MaxResponseSize; 2344 TPML_PCR_SELECTION Pcrs; 2345 UINTN Index; 2346 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap; 2347 UINT32 ActivePCRBanks; 2348 UINT32 NumberOfPCRBanks; 2349 2350 mImageHandle = ImageHandle; 2351 2352 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) || 2353 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){ 2354 DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n")); 2355 return EFI_UNSUPPORTED; 2356 } 2357 2358 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { 2359 DEBUG ((EFI_D_ERROR, "TPM2 error!\n")); 2360 return EFI_DEVICE_ERROR; 2361 } 2362 2363 Status = Tpm2RequestUseTpm (); 2364 if (EFI_ERROR (Status)) { 2365 DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n")); 2366 return Status; 2367 } 2368 2369 // 2370 // Fill information 2371 // 2372 ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])); 2373 2374 mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY); 2375 mTcgDxeData.BsCap.ProtocolVersion.Major = 1; 2376 mTcgDxeData.BsCap.ProtocolVersion.Minor = 1; 2377 mTcgDxeData.BsCap.StructureVersion.Major = 1; 2378 mTcgDxeData.BsCap.StructureVersion.Minor = 1; 2379 2380 DEBUG ((EFI_D_INFO, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor)); 2381 DEBUG ((EFI_D_INFO, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor)); 2382 2383 Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID); 2384 if (EFI_ERROR (Status)) { 2385 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n")); 2386 } else { 2387 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID)); 2388 } 2389 2390 DEBUG_CODE ( 2391 UINT32 FirmwareVersion1; 2392 UINT32 FirmwareVersion2; 2393 2394 Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2); 2395 if (EFI_ERROR (Status)) { 2396 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n")); 2397 } else { 2398 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2)); 2399 } 2400 ); 2401 2402 Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize); 2403 if (EFI_ERROR (Status)) { 2404 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n")); 2405 } else { 2406 mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize; 2407 mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize; 2408 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize)); 2409 } 2410 2411 // 2412 // Get supported PCR and current Active PCRs 2413 // 2414 Status = Tpm2GetCapabilityPcrs (&Pcrs); 2415 if (EFI_ERROR (Status)) { 2416 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n")); 2417 TpmHashAlgorithmBitmap = EFI_TCG2_BOOT_HASH_ALG_SHA1; 2418 NumberOfPCRBanks = 1; 2419 ActivePCRBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1; 2420 } else { 2421 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count)); 2422 NumberOfPCRBanks = 0; 2423 TpmHashAlgorithmBitmap = 0; 2424 ActivePCRBanks = 0; 2425 for (Index = 0; Index < Pcrs.count; Index++) { 2426 DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash)); 2427 switch (Pcrs.pcrSelections[Index].hash) { 2428 case TPM_ALG_SHA1: 2429 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA1; 2430 NumberOfPCRBanks ++; 2431 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { 2432 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA1; 2433 } 2434 break; 2435 case TPM_ALG_SHA256: 2436 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA256; 2437 NumberOfPCRBanks ++; 2438 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { 2439 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA256; 2440 } 2441 break; 2442 case TPM_ALG_SHA384: 2443 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA384; 2444 NumberOfPCRBanks ++; 2445 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { 2446 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA384; 2447 } 2448 break; 2449 case TPM_ALG_SHA512: 2450 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA512; 2451 NumberOfPCRBanks ++; 2452 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { 2453 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA512; 2454 } 2455 break; 2456 case TPM_ALG_SM3_256: 2457 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SM3_256; 2458 NumberOfPCRBanks ++; 2459 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { 2460 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SM3_256; 2461 } 2462 break; 2463 } 2464 } 2465 } 2466 mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap); 2467 mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap); 2468 2469 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) { 2470 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks; 2471 } else { 2472 mTcgDxeData.BsCap.NumberOfPCRBanks = PcdGet32 (PcdTcg2NumberOfPCRBanks); 2473 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) > NumberOfPCRBanks) { 2474 DEBUG ((EFI_D_ERROR, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks), NumberOfPCRBanks)); 2475 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks; 2476 } 2477 } 2478 2479 mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; 2480 if ((mTcgDxeData.BsCap.ActivePcrBanks & TREE_BOOT_HASH_ALG_SHA1) == 0) { 2481 // 2482 // No need to expose TCG1.2 event log if SHA1 bank does not exist. 2483 // 2484 mTcgDxeData.BsCap.SupportedEventLogs &= ~TREE_EVENT_LOG_FORMAT_TCG_1_2; 2485 } 2486 2487 DEBUG ((EFI_D_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs)); 2488 DEBUG ((EFI_D_INFO, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap)); 2489 DEBUG ((EFI_D_INFO, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData.BsCap.NumberOfPCRBanks)); 2490 DEBUG ((EFI_D_INFO, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData.BsCap.ActivePcrBanks)); 2491 2492 if (mTcgDxeData.BsCap.TPMPresentFlag) { 2493 // 2494 // Setup the log area and copy event log from hob list to it 2495 // 2496 Status = SetupEventLog (); 2497 ASSERT_EFI_ERROR (Status); 2498 2499 // 2500 // Measure handoff tables, Boot#### variables etc. 2501 // 2502 Status = EfiCreateEventReadyToBootEx ( 2503 TPL_CALLBACK, 2504 OnReadyToBoot, 2505 NULL, 2506 &Event 2507 ); 2508 2509 Status = gBS->CreateEventEx ( 2510 EVT_NOTIFY_SIGNAL, 2511 TPL_NOTIFY, 2512 OnExitBootServices, 2513 NULL, 2514 &gEfiEventExitBootServicesGuid, 2515 &Event 2516 ); 2517 2518 // 2519 // Measure Exit Boot Service failed 2520 // 2521 Status = gBS->CreateEventEx ( 2522 EVT_NOTIFY_SIGNAL, 2523 TPL_NOTIFY, 2524 OnExitBootServicesFailed, 2525 NULL, 2526 &gEventExitBootServicesFailedGuid, 2527 &Event 2528 ); 2529 2530 // 2531 // Create event callback, because we need access variable on SecureBootPolicyVariable 2532 // We should use VariableWriteArch instead of VariableArch, because Variable driver 2533 // may update SecureBoot value based on last setting. 2534 // 2535 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration); 2536 } 2537 2538 // 2539 // Install Tcg2Protocol 2540 // 2541 Status = InstallTcg2 (); 2542 DEBUG ((EFI_D_INFO, "InstallTcg2 - %r\n", Status)); 2543 2544 return Status; 2545 } 2546