]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/TcgDxe/TcgDxe.c
Add TPM2 implementation.
[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 - 2013, 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 //
739 // Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]
740 //
741 Status = EfiGetSystemConfigurationTable (
742 &gEfiSmbiosTableGuid,
743 (VOID **) &SmbiosTable
744 );
745
746 if (!EFI_ERROR (Status)) {
747 ASSERT (SmbiosTable != NULL);
748
749 TcgEvent.PCRIndex = 1;
750 TcgEvent.EventType = EV_EFI_HANDOFF_TABLES;
751 TcgEvent.EventSize = sizeof (HandoffTables);
752
753 HandoffTables.NumberOfTables = 1;
754 HandoffTables.TableEntry[0].VendorGuid = gEfiSmbiosTableGuid;
755 HandoffTables.TableEntry[0].VendorTable = SmbiosTable;
756
757 DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTable->TableAddress));
758 DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", SmbiosTable->TableLength));
759
760 Status = TcgDxeHashLogExtendEventI (
761 &mTcgDxeData,
762 (UINT8*)(UINTN)SmbiosTable->TableAddress,
763 SmbiosTable->TableLength,
764 &TcgEvent,
765 (UINT8*)&HandoffTables
766 );
767 }
768
769 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
770 //
771 // Tcg Server spec.
772 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
773 //
774 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);
775
776 if (!EFI_ERROR(Status)){
777 TcgEvent.PCRIndex = 1;
778 TcgEvent.EventType = EV_TABLE_OF_DEVICES;
779 TcgEvent.EventSize = sizeof (HandoffTables);
780
781 HandoffTables.NumberOfTables = 1;
782 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
783 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
784
785 Status = TcgDxeHashLogExtendEventI (
786 &mTcgDxeData,
787 (UINT8*)(UINTN)ProcessorLocBuf,
788 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
789 &TcgEvent,
790 (UINT8*)&HandoffTables
791 );
792
793 FreePool(ProcessorLocBuf);
794 }
795 }
796
797 return Status;
798 }
799
800 /**
801 Measure and log Separator event, and extend the measurement result into a specific PCR.
802
803 @param[in] PCRIndex PCR index.
804
805 @retval EFI_SUCCESS Operation completed successfully.
806 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
807
808 **/
809 EFI_STATUS
810 EFIAPI
811 MeasureSeparatorEvent (
812 IN TPM_PCRINDEX PCRIndex
813 )
814 {
815 TCG_PCR_EVENT_HDR TcgEvent;
816 UINT32 EventData;
817
818 EventData = 0;
819 TcgEvent.PCRIndex = PCRIndex;
820 TcgEvent.EventType = EV_SEPARATOR;
821 TcgEvent.EventSize = (UINT32)sizeof (EventData);
822 return TcgDxeHashLogExtendEventI (
823 &mTcgDxeData,
824 (UINT8 *)&EventData,
825 sizeof (EventData),
826 &TcgEvent,
827 (UINT8 *)&EventData
828 );
829 }
830
831 /**
832 Read an EFI Variable.
833
834 This function allocates a buffer to return the contents of the variable. The caller is
835 responsible for freeing the buffer.
836
837 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
838 @param[in] VendorGuid A unique identifier for the vendor.
839 @param[out] VarSize The size of the variable data.
840
841 @return A pointer to the buffer to return the contents of the variable.Otherwise NULL.
842
843 **/
844 VOID *
845 EFIAPI
846 ReadVariable (
847 IN CHAR16 *VarName,
848 IN EFI_GUID *VendorGuid,
849 OUT UINTN *VarSize
850 )
851 {
852 EFI_STATUS Status;
853 VOID *VarData;
854
855 *VarSize = 0;
856 Status = gRT->GetVariable (
857 VarName,
858 VendorGuid,
859 NULL,
860 VarSize,
861 NULL
862 );
863 if (Status != EFI_BUFFER_TOO_SMALL) {
864 return NULL;
865 }
866
867 VarData = AllocatePool (*VarSize);
868 if (VarData != NULL) {
869 Status = gRT->GetVariable (
870 VarName,
871 VendorGuid,
872 NULL,
873 VarSize,
874 VarData
875 );
876 if (EFI_ERROR (Status)) {
877 FreePool (VarData);
878 VarData = NULL;
879 *VarSize = 0;
880 }
881 }
882 return VarData;
883 }
884
885 /**
886 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
887
888 @param[in] PCRIndex PCR Index.
889 @param[in] EventType Event type.
890 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
891 @param[in] VendorGuid A unique identifier for the vendor.
892 @param[in] VarData The content of the variable data.
893 @param[in] VarSize The size of the variable data.
894
895 @retval EFI_SUCCESS Operation completed successfully.
896 @retval EFI_OUT_OF_RESOURCES Out of memory.
897 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
898
899 **/
900 EFI_STATUS
901 EFIAPI
902 MeasureVariable (
903 IN TPM_PCRINDEX PCRIndex,
904 IN TCG_EVENTTYPE EventType,
905 IN CHAR16 *VarName,
906 IN EFI_GUID *VendorGuid,
907 IN VOID *VarData,
908 IN UINTN VarSize
909 )
910 {
911 EFI_STATUS Status;
912 TCG_PCR_EVENT_HDR TcgEvent;
913 UINTN VarNameLength;
914 EFI_VARIABLE_DATA *VarLog;
915
916 VarNameLength = StrLen (VarName);
917 TcgEvent.PCRIndex = PCRIndex;
918 TcgEvent.EventType = EventType;
919 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
920 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
921
922 VarLog = (EFI_VARIABLE_DATA*)AllocatePool (TcgEvent.EventSize);
923 if (VarLog == NULL) {
924 return EFI_OUT_OF_RESOURCES;
925 }
926
927 VarLog->VariableName = *VendorGuid;
928 VarLog->UnicodeNameLength = VarNameLength;
929 VarLog->VariableDataLength = VarSize;
930 CopyMem (
931 VarLog->UnicodeName,
932 VarName,
933 VarNameLength * sizeof (*VarName)
934 );
935 CopyMem (
936 (CHAR16 *)VarLog->UnicodeName + VarNameLength,
937 VarData,
938 VarSize
939 );
940
941 Status = TcgDxeHashLogExtendEventI (
942 &mTcgDxeData,
943 (UINT8*)VarData,
944 VarSize,
945 &TcgEvent,
946 (UINT8*)VarLog
947 );
948 FreePool (VarLog);
949 return Status;
950 }
951
952 /**
953 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
954
955 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
956 @param[in] VendorGuid A unique identifier for the vendor.
957 @param[out] VarSize The size of the variable data.
958 @param[out] VarData Pointer to the content of the variable.
959
960 @retval EFI_SUCCESS Operation completed successfully.
961 @retval EFI_OUT_OF_RESOURCES Out of memory.
962 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
963
964 **/
965 EFI_STATUS
966 EFIAPI
967 ReadAndMeasureBootVariable (
968 IN CHAR16 *VarName,
969 IN EFI_GUID *VendorGuid,
970 OUT UINTN *VarSize,
971 OUT VOID **VarData
972 )
973 {
974 EFI_STATUS Status;
975
976 *VarData = ReadVariable (VarName, VendorGuid, VarSize);
977 if (*VarData == NULL) {
978 return EFI_NOT_FOUND;
979 }
980
981 Status = MeasureVariable (
982 5,
983 EV_EFI_VARIABLE_BOOT,
984 VarName,
985 VendorGuid,
986 *VarData,
987 *VarSize
988 );
989 return Status;
990 }
991
992 /**
993 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
994
995 The EFI boot variables are BootOrder and Boot#### variables.
996
997 @retval EFI_SUCCESS Operation completed successfully.
998 @retval EFI_OUT_OF_RESOURCES Out of memory.
999 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1000
1001 **/
1002 EFI_STATUS
1003 EFIAPI
1004 MeasureAllBootVariables (
1005 VOID
1006 )
1007 {
1008 EFI_STATUS Status;
1009 UINT16 *BootOrder;
1010 UINTN BootCount;
1011 UINTN Index;
1012 VOID *BootVarData;
1013 UINTN Size;
1014
1015 Status = ReadAndMeasureBootVariable (
1016 mBootVarName,
1017 &gEfiGlobalVariableGuid,
1018 &BootCount,
1019 (VOID **) &BootOrder
1020 );
1021 if (Status == EFI_NOT_FOUND) {
1022 return EFI_SUCCESS;
1023 }
1024 ASSERT (BootOrder != NULL);
1025
1026 if (EFI_ERROR (Status)) {
1027 FreePool (BootOrder);
1028 return Status;
1029 }
1030
1031 BootCount /= sizeof (*BootOrder);
1032 for (Index = 0; Index < BootCount; Index++) {
1033 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);
1034 Status = ReadAndMeasureBootVariable (
1035 mBootVarName,
1036 &gEfiGlobalVariableGuid,
1037 &Size,
1038 &BootVarData
1039 );
1040 if (!EFI_ERROR (Status)) {
1041 FreePool (BootVarData);
1042 }
1043 }
1044
1045 FreePool (BootOrder);
1046 return EFI_SUCCESS;
1047 }
1048
1049 /**
1050 Ready to Boot Event notification handler.
1051
1052 Sequence of OS boot events is measured in this event notification handler.
1053
1054 @param[in] Event Event whose notification function is being invoked
1055 @param[in] Context Pointer to the notification function's context
1056
1057 **/
1058 VOID
1059 EFIAPI
1060 OnReadyToBoot (
1061 IN EFI_EVENT Event,
1062 IN VOID *Context
1063 )
1064 {
1065 EFI_STATUS Status;
1066 TPM_PCRINDEX PcrIndex;
1067
1068 if (mBootAttempts == 0) {
1069
1070 //
1071 // Measure handoff tables.
1072 //
1073 Status = MeasureHandoffTables ();
1074 if (EFI_ERROR (Status)) {
1075 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));
1076 }
1077
1078 //
1079 // Measure BootOrder & Boot#### variables.
1080 //
1081 Status = MeasureAllBootVariables ();
1082 if (EFI_ERROR (Status)) {
1083 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));
1084 }
1085
1086 //
1087 // 1. This is the first boot attempt.
1088 //
1089 Status = TcgMeasureAction (
1090 EFI_CALLING_EFI_APPLICATION
1091 );
1092 ASSERT_EFI_ERROR (Status);
1093
1094 //
1095 // 2. Draw a line between pre-boot env and entering post-boot env.
1096 //
1097 for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
1098 Status = MeasureSeparatorEvent (PcrIndex);
1099 ASSERT_EFI_ERROR (Status);
1100 }
1101
1102 //
1103 // 3. Measure GPT. It would be done in SAP driver.
1104 //
1105
1106 //
1107 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
1108 //
1109
1110 //
1111 // 5. Read & Measure variable. BootOrder already measured.
1112 //
1113 } else {
1114 //
1115 // 6. Not first attempt, meaning a return from last attempt
1116 //
1117 Status = TcgMeasureAction (
1118 EFI_RETURNING_FROM_EFI_APPLICATOIN
1119 );
1120 ASSERT_EFI_ERROR (Status);
1121 }
1122
1123 DEBUG ((EFI_D_INFO, "TPM TcgDxe Measure Data when ReadyToBoot\n"));
1124 //
1125 // Increase boot attempt counter.
1126 //
1127 mBootAttempts++;
1128 }
1129
1130 /**
1131 Install TCG ACPI Table when ACPI Table Protocol is available.
1132
1133 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1134 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1135 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1136
1137 @param[in] Event Event whose notification function is being invoked
1138 @param[in] Context Pointer to the notification function's context
1139 **/
1140 VOID
1141 EFIAPI
1142 InstallAcpiTable (
1143 IN EFI_EVENT Event,
1144 IN VOID* Context
1145 )
1146 {
1147 UINTN TableKey;
1148 EFI_STATUS Status;
1149 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
1150 UINT8 Checksum;
1151 UINT64 OemTableId;
1152
1153 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
1154 if (EFI_ERROR (Status)) {
1155 return;
1156 }
1157
1158 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
1159 CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId));
1160 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
1161 CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
1162 mTcgClientAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1163 mTcgClientAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1164 mTcgClientAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1165 //
1166 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1167 // service of the ACPI table protocol to install it.
1168 //
1169 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate));
1170 mTcgClientAcpiTemplate.Header.Checksum = Checksum;
1171
1172 Status = AcpiTable->InstallAcpiTable (
1173 AcpiTable,
1174 &mTcgClientAcpiTemplate,
1175 sizeof (mTcgClientAcpiTemplate),
1176 &TableKey
1177 );
1178 } else {
1179 CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId));
1180 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
1181 CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
1182 mTcgServerAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1183 mTcgServerAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1184 mTcgServerAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1185 //
1186 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1187 // service of the ACPI table protocol to install it.
1188 //
1189 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate));
1190 mTcgServerAcpiTemplate.Header.Checksum = Checksum;
1191
1192 Status = AcpiTable->InstallAcpiTable (
1193 AcpiTable,
1194 &mTcgServerAcpiTemplate,
1195 sizeof (mTcgServerAcpiTemplate),
1196 &TableKey
1197 );
1198 }
1199 ASSERT_EFI_ERROR (Status);
1200 }
1201
1202 /**
1203 Exit Boot Services Event notification handler.
1204
1205 Measure invocation and success of ExitBootServices.
1206
1207 @param[in] Event Event whose notification function is being invoked
1208 @param[in] Context Pointer to the notification function's context
1209
1210 **/
1211 VOID
1212 EFIAPI
1213 OnExitBootServices (
1214 IN EFI_EVENT Event,
1215 IN VOID *Context
1216 )
1217 {
1218 EFI_STATUS Status;
1219
1220 //
1221 // Measure invocation of ExitBootServices,
1222 //
1223 Status = TcgMeasureAction (
1224 EFI_EXIT_BOOT_SERVICES_INVOCATION
1225 );
1226 ASSERT_EFI_ERROR (Status);
1227
1228 //
1229 // Measure success of ExitBootServices
1230 //
1231 Status = TcgMeasureAction (
1232 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1233 );
1234 ASSERT_EFI_ERROR (Status);
1235 }
1236
1237 /**
1238 Exit Boot Services Failed Event notification handler.
1239
1240 Measure Failure of ExitBootServices.
1241
1242 @param[in] Event Event whose notification function is being invoked
1243 @param[in] Context Pointer to the notification function's context
1244
1245 **/
1246 VOID
1247 EFIAPI
1248 OnExitBootServicesFailed (
1249 IN EFI_EVENT Event,
1250 IN VOID *Context
1251 )
1252 {
1253 EFI_STATUS Status;
1254
1255 //
1256 // Measure Failure of ExitBootServices,
1257 //
1258 Status = TcgMeasureAction (
1259 EFI_EXIT_BOOT_SERVICES_FAILED
1260 );
1261 ASSERT_EFI_ERROR (Status);
1262
1263 }
1264
1265 /**
1266 Get TPM Deactivated state.
1267
1268 @param[out] TPMDeactivatedFlag Returns TPM Deactivated state.
1269
1270 @retval EFI_SUCCESS Operation completed successfully.
1271 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1272
1273 **/
1274 EFI_STATUS
1275 GetTpmStatus (
1276 OUT BOOLEAN *TPMDeactivatedFlag
1277 )
1278 {
1279 EFI_STATUS Status;
1280 TPM_STCLEAR_FLAGS VFlags;
1281
1282 Status = TpmCommGetFlags (
1283 mTcgDxeData.TpmHandle,
1284 TPM_CAP_FLAG_VOLATILE,
1285 &VFlags,
1286 sizeof (VFlags)
1287 );
1288 if (!EFI_ERROR (Status)) {
1289 *TPMDeactivatedFlag = VFlags.deactivated;
1290 }
1291
1292 return Status;
1293 }
1294
1295 /**
1296 The driver's entry point.
1297
1298 It publishes EFI TCG Protocol.
1299
1300 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1301 @param[in] SystemTable A pointer to the EFI System Table.
1302
1303 @retval EFI_SUCCESS The entry point is executed successfully.
1304 @retval other Some error occurs when executing this entry point.
1305
1306 **/
1307 EFI_STATUS
1308 EFIAPI
1309 DriverEntry (
1310 IN EFI_HANDLE ImageHandle,
1311 IN EFI_SYSTEM_TABLE *SystemTable
1312 )
1313 {
1314 EFI_STATUS Status;
1315 EFI_EVENT Event;
1316 VOID *Registration;
1317
1318 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
1319 DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
1320 return EFI_UNSUPPORTED;
1321 }
1322
1323 mTcgDxeData.TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
1324 Status = TisPcRequestUseTpm (mTcgDxeData.TpmHandle);
1325 if (EFI_ERROR (Status)) {
1326 DEBUG ((EFI_D_ERROR, "TPM not detected!\n"));
1327 return Status;
1328 }
1329
1330 Status = GetTpmStatus (&mTcgDxeData.BsCap.TPMDeactivatedFlag);
1331 if (EFI_ERROR (Status)) {
1332 DEBUG ((
1333 EFI_D_ERROR,
1334 "Line %d in file " __FILE__ ":\n "
1335 "DriverEntry: TPM not working properly\n",
1336 __LINE__
1337 ));
1338 return Status;
1339 }
1340
1341 Status = gBS->InstallProtocolInterface (
1342 &ImageHandle,
1343 &gEfiTcgProtocolGuid,
1344 EFI_NATIVE_INTERFACE,
1345 &mTcgDxeData.TcgProtocol
1346 );
1347 if (!EFI_ERROR (Status) && !mTcgDxeData.BsCap.TPMDeactivatedFlag) {
1348 //
1349 // Setup the log area and copy event log from hob list to it
1350 //
1351 Status = SetupEventLog ();
1352 ASSERT_EFI_ERROR (Status);
1353
1354 //
1355 // Measure handoff tables, Boot#### variables etc.
1356 //
1357 Status = EfiCreateEventReadyToBootEx (
1358 TPL_CALLBACK,
1359 OnReadyToBoot,
1360 NULL,
1361 &Event
1362 );
1363
1364 Status = gBS->CreateEventEx (
1365 EVT_NOTIFY_SIGNAL,
1366 TPL_NOTIFY,
1367 OnExitBootServices,
1368 NULL,
1369 &gEfiEventExitBootServicesGuid,
1370 &Event
1371 );
1372
1373 //
1374 // Measure Exit Boot Service failed
1375 //
1376 Status = gBS->CreateEventEx (
1377 EVT_NOTIFY_SIGNAL,
1378 TPL_NOTIFY,
1379 OnExitBootServicesFailed,
1380 NULL,
1381 &gEventExitBootServicesFailedGuid,
1382 &Event
1383 );
1384 }
1385
1386 //
1387 // Install ACPI Table
1388 //
1389 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);
1390
1391 return Status;
1392 }