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