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