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