282505dbc77b477c766a46c3bca07365ac5f005a
[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 if (EFI_ERROR(Status)) {
509 DEBUG ((DEBUG_ERROR, "TpmCommHashAll Failed. %x\n", Status));
510 return Status;
511 }
512 }
513
514 Status = TpmCommExtend (
515 TcgData->TpmHandle,
516 &NewEventHdr->Digest,
517 NewEventHdr->PCRIndex,
518 NULL
519 );
520 if (!EFI_ERROR (Status)) {
521 Status = TcgDxeLogEventI (TcgData, NewEventHdr, NewEventData);
522 }
523
524 return Status;
525 }
526
527 /**
528 This service abstracts the capability to do a hash operation on a data buffer,
529 extend a specific TPM PCR with the hash result, and add an entry to the Event Log
530
531 @param[in] This Indicates the calling context
532 @param[in] HashData Physical address of the start of the data buffer
533 to be hashed, extended, and logged.
534 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
535 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation
536 @param[in, out] TCGLogData The physical address of the start of the data
537 buffer containing the TCG_PCR_EVENT data structure.
538 @param[in, out] EventNumber The event number of the event just logged.
539 @param[out] EventLogLastEntry Physical address of the first byte of the entry
540 just placed in the Event Log. If the Event Log was
541 empty when this function was called then this physical
542 address will be the same as the physical address of
543 the start of the Event Log.
544
545 @retval EFI_SUCCESS Operation completed successfully.
546 @retval EFI_UNSUPPORTED AlgorithmId != TPM_ALG_SHA.
547 @retval EFI_UNSUPPORTED Current TPL >= EFI_TPL_CALLBACK.
548 @retval EFI_DEVICE_ERROR The command was unsuccessful.
549
550 **/
551 EFI_STATUS
552 EFIAPI
553 TcgDxeHashLogExtendEvent (
554 IN EFI_TCG_PROTOCOL *This,
555 IN EFI_PHYSICAL_ADDRESS HashData,
556 IN UINT64 HashDataLen,
557 IN TPM_ALGORITHM_ID AlgorithmId,
558 IN OUT TCG_PCR_EVENT *TCGLogData,
559 IN OUT UINT32 *EventNumber,
560 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry
561 )
562 {
563 TCG_DXE_DATA *TcgData;
564 EFI_STATUS Status;
565
566 if (TCGLogData == NULL || EventLogLastEntry == NULL){
567 return EFI_INVALID_PARAMETER;
568 }
569
570 TcgData = TCG_DXE_DATA_FROM_THIS (This);
571
572 if (TcgData->BsCap.TPMDeactivatedFlag) {
573 return EFI_DEVICE_ERROR;
574 }
575
576 if (AlgorithmId != TPM_ALG_SHA) {
577 return EFI_UNSUPPORTED;
578 }
579
580 Status = TcgDxeHashLogExtendEventI (
581 TcgData,
582 (UINT8 *) (UINTN) HashData,
583 HashDataLen,
584 (TCG_PCR_EVENT_HDR*)TCGLogData,
585 TCGLogData->Event
586 );
587
588 if (!EFI_ERROR(Status)){
589 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN) TcgData->LastEvent;
590 }
591
592 return Status;
593 }
594
595 TCG_DXE_DATA mTcgDxeData = {
596 {
597 TcgDxeStatusCheck,
598 TcgDxeHashAll,
599 TcgDxeLogEvent,
600 TcgDxePassThroughToTpm,
601 TcgDxeHashLogExtendEvent
602 },
603 {
604 sizeof (mTcgDxeData.BsCap),
605 { 1, 2, 0, 0 },
606 { 1, 2, 0, 0 },
607 1,
608 TRUE,
609 FALSE
610 },
611 &mTcgClientAcpiTemplate,
612 &mTcgServerAcpiTemplate,
613 0,
614 NULL,
615 NULL
616 };
617
618 /**
619 Initialize the Event Log and log events passed from the PEI phase.
620
621 @retval EFI_SUCCESS Operation completed successfully.
622 @retval EFI_OUT_OF_RESOURCES Out of memory.
623
624 **/
625 EFI_STATUS
626 EFIAPI
627 SetupEventLog (
628 VOID
629 )
630 {
631 EFI_STATUS Status;
632 TCG_PCR_EVENT *TcgEvent;
633 EFI_PEI_HOB_POINTERS GuidHob;
634 EFI_PHYSICAL_ADDRESS Lasa;
635
636 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
637 Lasa = mTcgClientAcpiTemplate.Lasa;
638
639 Status = gBS->AllocatePages (
640 AllocateMaxAddress,
641 EfiACPIMemoryNVS,
642 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE),
643 &Lasa
644 );
645 if (EFI_ERROR (Status)) {
646 return Status;
647 }
648 mTcgClientAcpiTemplate.Lasa = Lasa;
649 //
650 // To initialize them as 0xFF is recommended
651 // because the OS can know the last entry for that.
652 //
653 SetMem ((VOID *)(UINTN)mTcgClientAcpiTemplate.Lasa, EFI_TCG_LOG_AREA_SIZE, 0xFF);
654 mTcgClientAcpiTemplate.Laml = EFI_TCG_LOG_AREA_SIZE;
655
656 } else {
657 Lasa = mTcgServerAcpiTemplate.Lasa;
658
659 Status = gBS->AllocatePages (
660 AllocateMaxAddress,
661 EfiACPIMemoryNVS,
662 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE),
663 &Lasa
664 );
665 if (EFI_ERROR (Status)) {
666 return Status;
667 }
668 mTcgServerAcpiTemplate.Lasa = Lasa;
669 //
670 // To initialize them as 0xFF is recommended
671 // because the OS can know the last entry for that.
672 //
673 SetMem ((VOID *)(UINTN)mTcgServerAcpiTemplate.Lasa, EFI_TCG_LOG_AREA_SIZE, 0xFF);
674 mTcgServerAcpiTemplate.Laml = EFI_TCG_LOG_AREA_SIZE;
675 }
676
677 GuidHob.Raw = GetHobList ();
678 while (!EFI_ERROR (Status) &&
679 (GuidHob.Raw = GetNextGuidHob (&gTcgEventEntryHobGuid, GuidHob.Raw)) != NULL) {
680 TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid);
681 GuidHob.Raw = GET_NEXT_HOB (GuidHob);
682 Status = TcgDxeLogEventI (
683 &mTcgDxeData,
684 (TCG_PCR_EVENT_HDR*)TcgEvent,
685 TcgEvent->Event
686 );
687 }
688
689 return Status;
690 }
691
692 /**
693 Measure and log an action string, and extend the measurement result into PCR[5].
694
695 @param[in] String A specific string that indicates an Action event.
696
697 @retval EFI_SUCCESS Operation completed successfully.
698 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
699
700 **/
701 EFI_STATUS
702 EFIAPI
703 TcgMeasureAction (
704 IN CHAR8 *String
705 )
706 {
707 TCG_PCR_EVENT_HDR TcgEvent;
708
709 TcgEvent.PCRIndex = 5;
710 TcgEvent.EventType = EV_EFI_ACTION;
711 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);
712 return TcgDxeHashLogExtendEventI (
713 &mTcgDxeData,
714 (UINT8*)String,
715 TcgEvent.EventSize,
716 &TcgEvent,
717 (UINT8 *) String
718 );
719 }
720
721 /**
722 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
723
724 @retval EFI_SUCCESS Operation completed successfully.
725 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
726
727 **/
728 EFI_STATUS
729 EFIAPI
730 MeasureHandoffTables (
731 VOID
732 )
733 {
734 EFI_STATUS Status;
735 SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;
736 TCG_PCR_EVENT_HDR TcgEvent;
737 EFI_HANDOFF_TABLE_POINTERS HandoffTables;
738 UINTN ProcessorNum;
739 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
740
741 ProcessorLocBuf = NULL;
742
743 //
744 // Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]
745 //
746 Status = EfiGetSystemConfigurationTable (
747 &gEfiSmbiosTableGuid,
748 (VOID **) &SmbiosTable
749 );
750
751 if (!EFI_ERROR (Status) && SmbiosTable != NULL) {
752 TcgEvent.PCRIndex = 1;
753 TcgEvent.EventType = EV_EFI_HANDOFF_TABLES;
754 TcgEvent.EventSize = sizeof (HandoffTables);
755
756 HandoffTables.NumberOfTables = 1;
757 HandoffTables.TableEntry[0].VendorGuid = gEfiSmbiosTableGuid;
758 HandoffTables.TableEntry[0].VendorTable = SmbiosTable;
759
760 DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTable->TableAddress));
761 DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", SmbiosTable->TableLength));
762
763 Status = TcgDxeHashLogExtendEventI (
764 &mTcgDxeData,
765 (UINT8*)(UINTN)SmbiosTable->TableAddress,
766 SmbiosTable->TableLength,
767 &TcgEvent,
768 (UINT8*)&HandoffTables
769 );
770 }
771
772 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
773 //
774 // Tcg Server spec.
775 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
776 //
777 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);
778
779 if (!EFI_ERROR(Status)){
780 TcgEvent.PCRIndex = 1;
781 TcgEvent.EventType = EV_TABLE_OF_DEVICES;
782 TcgEvent.EventSize = sizeof (HandoffTables);
783
784 HandoffTables.NumberOfTables = 1;
785 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
786 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
787
788 Status = TcgDxeHashLogExtendEventI (
789 &mTcgDxeData,
790 (UINT8*)(UINTN)ProcessorLocBuf,
791 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
792 &TcgEvent,
793 (UINT8*)&HandoffTables
794 );
795
796 FreePool(ProcessorLocBuf);
797 }
798 }
799
800 return Status;
801 }
802
803 /**
804 Measure and log Separator event, and extend the measurement result into a specific PCR.
805
806 @param[in] PCRIndex PCR index.
807
808 @retval EFI_SUCCESS Operation completed successfully.
809 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
810
811 **/
812 EFI_STATUS
813 EFIAPI
814 MeasureSeparatorEvent (
815 IN TPM_PCRINDEX PCRIndex
816 )
817 {
818 TCG_PCR_EVENT_HDR TcgEvent;
819 UINT32 EventData;
820
821 EventData = 0;
822 TcgEvent.PCRIndex = PCRIndex;
823 TcgEvent.EventType = EV_SEPARATOR;
824 TcgEvent.EventSize = (UINT32)sizeof (EventData);
825 return TcgDxeHashLogExtendEventI (
826 &mTcgDxeData,
827 (UINT8 *)&EventData,
828 sizeof (EventData),
829 &TcgEvent,
830 (UINT8 *)&EventData
831 );
832 }
833
834 /**
835 Read an EFI Variable.
836
837 This function allocates a buffer to return the contents of the variable. The caller is
838 responsible for freeing the buffer.
839
840 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
841 @param[in] VendorGuid A unique identifier for the vendor.
842 @param[out] VarSize The size of the variable data.
843
844 @return A pointer to the buffer to return the contents of the variable.Otherwise NULL.
845
846 **/
847 VOID *
848 EFIAPI
849 ReadVariable (
850 IN CHAR16 *VarName,
851 IN EFI_GUID *VendorGuid,
852 OUT UINTN *VarSize
853 )
854 {
855 EFI_STATUS Status;
856 VOID *VarData;
857
858 *VarSize = 0;
859 Status = gRT->GetVariable (
860 VarName,
861 VendorGuid,
862 NULL,
863 VarSize,
864 NULL
865 );
866 if (Status != EFI_BUFFER_TOO_SMALL) {
867 return NULL;
868 }
869
870 VarData = AllocatePool (*VarSize);
871 if (VarData != NULL) {
872 Status = gRT->GetVariable (
873 VarName,
874 VendorGuid,
875 NULL,
876 VarSize,
877 VarData
878 );
879 if (EFI_ERROR (Status)) {
880 FreePool (VarData);
881 VarData = NULL;
882 *VarSize = 0;
883 }
884 }
885 return VarData;
886 }
887
888 /**
889 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
890
891 @param[in] PCRIndex PCR Index.
892 @param[in] EventType Event type.
893 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
894 @param[in] VendorGuid A unique identifier for the vendor.
895 @param[in] VarData The content of the variable data.
896 @param[in] VarSize The size of the variable data.
897
898 @retval EFI_SUCCESS Operation completed successfully.
899 @retval EFI_OUT_OF_RESOURCES Out of memory.
900 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
901
902 **/
903 EFI_STATUS
904 EFIAPI
905 MeasureVariable (
906 IN TPM_PCRINDEX PCRIndex,
907 IN TCG_EVENTTYPE EventType,
908 IN CHAR16 *VarName,
909 IN EFI_GUID *VendorGuid,
910 IN VOID *VarData,
911 IN UINTN VarSize
912 )
913 {
914 EFI_STATUS Status;
915 TCG_PCR_EVENT_HDR TcgEvent;
916 UINTN VarNameLength;
917 EFI_VARIABLE_DATA *VarLog;
918
919 VarNameLength = StrLen (VarName);
920 TcgEvent.PCRIndex = PCRIndex;
921 TcgEvent.EventType = EventType;
922 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
923 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
924
925 VarLog = (EFI_VARIABLE_DATA*)AllocatePool (TcgEvent.EventSize);
926 if (VarLog == NULL) {
927 return EFI_OUT_OF_RESOURCES;
928 }
929
930 VarLog->VariableName = *VendorGuid;
931 VarLog->UnicodeNameLength = VarNameLength;
932 VarLog->VariableDataLength = VarSize;
933 CopyMem (
934 VarLog->UnicodeName,
935 VarName,
936 VarNameLength * sizeof (*VarName)
937 );
938 CopyMem (
939 (CHAR16 *)VarLog->UnicodeName + VarNameLength,
940 VarData,
941 VarSize
942 );
943
944 Status = TcgDxeHashLogExtendEventI (
945 &mTcgDxeData,
946 (UINT8*)VarData,
947 VarSize,
948 &TcgEvent,
949 (UINT8*)VarLog
950 );
951 FreePool (VarLog);
952 return Status;
953 }
954
955 /**
956 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
957
958 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
959 @param[in] VendorGuid A unique identifier for the vendor.
960 @param[out] VarSize The size of the variable data.
961 @param[out] VarData Pointer to the content of the variable.
962
963 @retval EFI_SUCCESS Operation completed successfully.
964 @retval EFI_OUT_OF_RESOURCES Out of memory.
965 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
966
967 **/
968 EFI_STATUS
969 EFIAPI
970 ReadAndMeasureBootVariable (
971 IN CHAR16 *VarName,
972 IN EFI_GUID *VendorGuid,
973 OUT UINTN *VarSize,
974 OUT VOID **VarData
975 )
976 {
977 EFI_STATUS Status;
978
979 *VarData = ReadVariable (VarName, VendorGuid, VarSize);
980 if (*VarData == NULL) {
981 return EFI_NOT_FOUND;
982 }
983
984 Status = MeasureVariable (
985 5,
986 EV_EFI_VARIABLE_BOOT,
987 VarName,
988 VendorGuid,
989 *VarData,
990 *VarSize
991 );
992 return Status;
993 }
994
995 /**
996 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
997
998 The EFI boot variables are BootOrder and Boot#### variables.
999
1000 @retval EFI_SUCCESS Operation completed successfully.
1001 @retval EFI_OUT_OF_RESOURCES Out of memory.
1002 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1003
1004 **/
1005 EFI_STATUS
1006 EFIAPI
1007 MeasureAllBootVariables (
1008 VOID
1009 )
1010 {
1011 EFI_STATUS Status;
1012 UINT16 *BootOrder;
1013 UINTN BootCount;
1014 UINTN Index;
1015 VOID *BootVarData;
1016 UINTN Size;
1017
1018 Status = ReadAndMeasureBootVariable (
1019 mBootVarName,
1020 &gEfiGlobalVariableGuid,
1021 &BootCount,
1022 (VOID **) &BootOrder
1023 );
1024 if (Status == EFI_NOT_FOUND || BootOrder == NULL) {
1025 return EFI_SUCCESS;
1026 }
1027
1028 if (EFI_ERROR (Status)) {
1029 //
1030 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1031 //
1032 FreePool (BootOrder);
1033 return Status;
1034 }
1035
1036 BootCount /= sizeof (*BootOrder);
1037 for (Index = 0; Index < BootCount; Index++) {
1038 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);
1039 Status = ReadAndMeasureBootVariable (
1040 mBootVarName,
1041 &gEfiGlobalVariableGuid,
1042 &Size,
1043 &BootVarData
1044 );
1045 if (!EFI_ERROR (Status)) {
1046 FreePool (BootVarData);
1047 }
1048 }
1049
1050 FreePool (BootOrder);
1051 return EFI_SUCCESS;
1052 }
1053
1054 /**
1055 Ready to Boot Event notification handler.
1056
1057 Sequence of OS boot events is measured in this event notification handler.
1058
1059 @param[in] Event Event whose notification function is being invoked
1060 @param[in] Context Pointer to the notification function's context
1061
1062 **/
1063 VOID
1064 EFIAPI
1065 OnReadyToBoot (
1066 IN EFI_EVENT Event,
1067 IN VOID *Context
1068 )
1069 {
1070 EFI_STATUS Status;
1071 TPM_PCRINDEX PcrIndex;
1072
1073 if (mBootAttempts == 0) {
1074
1075 //
1076 // Measure handoff tables.
1077 //
1078 Status = MeasureHandoffTables ();
1079 if (EFI_ERROR (Status)) {
1080 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));
1081 }
1082
1083 //
1084 // Measure BootOrder & Boot#### variables.
1085 //
1086 Status = MeasureAllBootVariables ();
1087 if (EFI_ERROR (Status)) {
1088 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));
1089 }
1090
1091 //
1092 // 1. This is the first boot attempt.
1093 //
1094 Status = TcgMeasureAction (
1095 EFI_CALLING_EFI_APPLICATION
1096 );
1097 if (EFI_ERROR (Status)) {
1098 DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
1099 }
1100
1101 //
1102 // 2. Draw a line between pre-boot env and entering post-boot env.
1103 //
1104 for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
1105 Status = MeasureSeparatorEvent (PcrIndex);
1106 if (EFI_ERROR (Status)) {
1107 DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));
1108 }
1109 }
1110
1111 //
1112 // 3. Measure GPT. It would be done in SAP driver.
1113 //
1114
1115 //
1116 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
1117 //
1118
1119 //
1120 // 5. Read & Measure variable. BootOrder already measured.
1121 //
1122 } else {
1123 //
1124 // 6. Not first attempt, meaning a return from last attempt
1125 //
1126 Status = TcgMeasureAction (
1127 EFI_RETURNING_FROM_EFI_APPLICATOIN
1128 );
1129 if (EFI_ERROR (Status)) {
1130 DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));
1131 }
1132 }
1133
1134 DEBUG ((EFI_D_INFO, "TPM TcgDxe Measure Data when ReadyToBoot\n"));
1135 //
1136 // Increase boot attempt counter.
1137 //
1138 mBootAttempts++;
1139 }
1140
1141 /**
1142 Install TCG ACPI Table when ACPI Table Protocol is available.
1143
1144 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1145 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1146 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1147
1148 @param[in] Event Event whose notification function is being invoked
1149 @param[in] Context Pointer to the notification function's context
1150 **/
1151 VOID
1152 EFIAPI
1153 InstallAcpiTable (
1154 IN EFI_EVENT Event,
1155 IN VOID* Context
1156 )
1157 {
1158 UINTN TableKey;
1159 EFI_STATUS Status;
1160 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
1161 UINT8 Checksum;
1162 UINT64 OemTableId;
1163
1164 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
1165 if (EFI_ERROR (Status)) {
1166 return;
1167 }
1168
1169 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
1170 CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId));
1171 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
1172 CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
1173 mTcgClientAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1174 mTcgClientAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1175 mTcgClientAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1176 //
1177 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1178 // service of the ACPI table protocol to install it.
1179 //
1180 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate));
1181 mTcgClientAcpiTemplate.Header.Checksum = Checksum;
1182
1183 Status = AcpiTable->InstallAcpiTable (
1184 AcpiTable,
1185 &mTcgClientAcpiTemplate,
1186 sizeof (mTcgClientAcpiTemplate),
1187 &TableKey
1188 );
1189 } else {
1190 CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId));
1191 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
1192 CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
1193 mTcgServerAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1194 mTcgServerAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1195 mTcgServerAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1196 //
1197 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1198 // service of the ACPI table protocol to install it.
1199 //
1200 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate));
1201 mTcgServerAcpiTemplate.Header.Checksum = Checksum;
1202
1203 Status = AcpiTable->InstallAcpiTable (
1204 AcpiTable,
1205 &mTcgServerAcpiTemplate,
1206 sizeof (mTcgServerAcpiTemplate),
1207 &TableKey
1208 );
1209 }
1210
1211 if (EFI_ERROR (Status)) {
1212 DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure"));
1213 }
1214 }
1215
1216 /**
1217 Exit Boot Services Event notification handler.
1218
1219 Measure invocation and success of ExitBootServices.
1220
1221 @param[in] Event Event whose notification function is being invoked
1222 @param[in] Context Pointer to the notification function's context
1223
1224 **/
1225 VOID
1226 EFIAPI
1227 OnExitBootServices (
1228 IN EFI_EVENT Event,
1229 IN VOID *Context
1230 )
1231 {
1232 EFI_STATUS Status;
1233
1234 //
1235 // Measure invocation of ExitBootServices,
1236 //
1237 Status = TcgMeasureAction (
1238 EFI_EXIT_BOOT_SERVICES_INVOCATION
1239 );
1240 if (EFI_ERROR (Status)) {
1241 DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));
1242 }
1243
1244 //
1245 // Measure success of ExitBootServices
1246 //
1247 Status = TcgMeasureAction (
1248 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1249 );
1250 if (EFI_ERROR (Status)){
1251 DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));
1252 }
1253 }
1254
1255 /**
1256 Exit Boot Services Failed Event notification handler.
1257
1258 Measure Failure of ExitBootServices.
1259
1260 @param[in] Event Event whose notification function is being invoked
1261 @param[in] Context Pointer to the notification function's context
1262
1263 **/
1264 VOID
1265 EFIAPI
1266 OnExitBootServicesFailed (
1267 IN EFI_EVENT Event,
1268 IN VOID *Context
1269 )
1270 {
1271 EFI_STATUS Status;
1272
1273 //
1274 // Measure Failure of ExitBootServices,
1275 //
1276 Status = TcgMeasureAction (
1277 EFI_EXIT_BOOT_SERVICES_FAILED
1278 );
1279 if (EFI_ERROR (Status)){
1280 DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));
1281 }
1282 }
1283
1284 /**
1285 Get TPM Deactivated state.
1286
1287 @param[out] TPMDeactivatedFlag Returns TPM Deactivated state.
1288
1289 @retval EFI_SUCCESS Operation completed successfully.
1290 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1291
1292 **/
1293 EFI_STATUS
1294 GetTpmStatus (
1295 OUT BOOLEAN *TPMDeactivatedFlag
1296 )
1297 {
1298 EFI_STATUS Status;
1299 TPM_STCLEAR_FLAGS VFlags;
1300
1301 Status = TpmCommGetFlags (
1302 mTcgDxeData.TpmHandle,
1303 TPM_CAP_FLAG_VOLATILE,
1304 &VFlags,
1305 sizeof (VFlags)
1306 );
1307 if (!EFI_ERROR (Status)) {
1308 *TPMDeactivatedFlag = VFlags.deactivated;
1309 }
1310
1311 return Status;
1312 }
1313
1314 /**
1315 The driver's entry point.
1316
1317 It publishes EFI TCG Protocol.
1318
1319 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1320 @param[in] SystemTable A pointer to the EFI System Table.
1321
1322 @retval EFI_SUCCESS The entry point is executed successfully.
1323 @retval other Some error occurs when executing this entry point.
1324
1325 **/
1326 EFI_STATUS
1327 EFIAPI
1328 DriverEntry (
1329 IN EFI_HANDLE ImageHandle,
1330 IN EFI_SYSTEM_TABLE *SystemTable
1331 )
1332 {
1333 EFI_STATUS Status;
1334 EFI_EVENT Event;
1335 VOID *Registration;
1336
1337 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
1338 DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
1339 return EFI_UNSUPPORTED;
1340 }
1341
1342 mTcgDxeData.TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
1343 Status = TisPcRequestUseTpm (mTcgDxeData.TpmHandle);
1344 if (EFI_ERROR (Status)) {
1345 DEBUG ((EFI_D_ERROR, "TPM not detected!\n"));
1346 return Status;
1347 }
1348
1349 Status = GetTpmStatus (&mTcgDxeData.BsCap.TPMDeactivatedFlag);
1350 if (EFI_ERROR (Status)) {
1351 DEBUG ((
1352 EFI_D_ERROR,
1353 "Line %d in file " __FILE__ ":\n "
1354 "DriverEntry: TPM not working properly\n",
1355 __LINE__
1356 ));
1357 return Status;
1358 }
1359
1360 Status = gBS->InstallProtocolInterface (
1361 &ImageHandle,
1362 &gEfiTcgProtocolGuid,
1363 EFI_NATIVE_INTERFACE,
1364 &mTcgDxeData.TcgProtocol
1365 );
1366 if (!EFI_ERROR (Status) && !mTcgDxeData.BsCap.TPMDeactivatedFlag) {
1367 //
1368 // Setup the log area and copy event log from hob list to it
1369 //
1370 Status = SetupEventLog ();
1371 ASSERT_EFI_ERROR (Status);
1372
1373 //
1374 // Measure handoff tables, Boot#### variables etc.
1375 //
1376 Status = EfiCreateEventReadyToBootEx (
1377 TPL_CALLBACK,
1378 OnReadyToBoot,
1379 NULL,
1380 &Event
1381 );
1382
1383 Status = gBS->CreateEventEx (
1384 EVT_NOTIFY_SIGNAL,
1385 TPL_NOTIFY,
1386 OnExitBootServices,
1387 NULL,
1388 &gEfiEventExitBootServicesGuid,
1389 &Event
1390 );
1391
1392 //
1393 // Measure Exit Boot Service failed
1394 //
1395 Status = gBS->CreateEventEx (
1396 EVT_NOTIFY_SIGNAL,
1397 TPL_NOTIFY,
1398 OnExitBootServicesFailed,
1399 NULL,
1400 &gEventExitBootServicesFailedGuid,
1401 &Event
1402 );
1403 }
1404
1405 //
1406 // Install ACPI Table
1407 //
1408 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);
1409
1410 return Status;
1411 }