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