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