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