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