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