]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
SecurityPkg: Clean up source files
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Dxe / Tcg2Dxe.c
CommitLineData
1abfa4ce
JY
1/** @file\r
2 This module implements Tcg2 Protocol.\r
b3548d32
LG
3\r
4Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
336dbfd1 5(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
b3548d32
LG
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
1abfa4ce
JY
9http://opensource.org/licenses/bsd-license.php\r
10\r
b3548d32 11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
1abfa4ce
JY
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <PiDxe.h>\r
17#include <IndustryStandard/Acpi.h>\r
18#include <IndustryStandard/PeImage.h>\r
1abfa4ce
JY
19#include <IndustryStandard/TcpaAcpi.h>\r
20\r
21#include <Guid/GlobalVariable.h>\r
1abfa4ce
JY
22#include <Guid/HobList.h>\r
23#include <Guid/TcgEventHob.h>\r
24#include <Guid/EventGroup.h>\r
25#include <Guid/EventExitBootServiceFailed.h>\r
26#include <Guid/ImageAuthentication.h>\r
27#include <Guid/TpmInstance.h>\r
28\r
29#include <Protocol/DevicePath.h>\r
30#include <Protocol/MpService.h>\r
31#include <Protocol/VariableWrite.h>\r
32#include <Protocol/Tcg2Protocol.h>\r
33#include <Protocol/TrEEProtocol.h>\r
9d5dfe9d 34#include <Protocol/ResetNotification.h>\r
1abfa4ce
JY
35\r
36#include <Library/DebugLib.h>\r
37#include <Library/BaseMemoryLib.h>\r
38#include <Library/UefiRuntimeServicesTableLib.h>\r
39#include <Library/UefiDriverEntryPoint.h>\r
40#include <Library/HobLib.h>\r
41#include <Library/UefiBootServicesTableLib.h>\r
42#include <Library/BaseLib.h>\r
43#include <Library/MemoryAllocationLib.h>\r
44#include <Library/PrintLib.h>\r
45#include <Library/Tpm2CommandLib.h>\r
46#include <Library/PcdLib.h>\r
47#include <Library/UefiLib.h>\r
48#include <Library/Tpm2DeviceLib.h>\r
49#include <Library/HashLib.h>\r
50#include <Library/PerformanceLib.h>\r
51#include <Library/ReportStatusCodeLib.h>\r
52#include <Library/Tcg2PhysicalPresenceLib.h>\r
53\r
54#define PERF_ID_TCG2_DXE 0x3120\r
55\r
56typedef struct {\r
57 CHAR16 *VariableName;\r
58 EFI_GUID *VendorGuid;\r
59} VARIABLE_TYPE;\r
60\r
1abfa4ce
JY
61#define TCG2_DEFAULT_MAX_COMMAND_SIZE 0x1000\r
62#define TCG2_DEFAULT_MAX_RESPONSE_SIZE 0x1000\r
63\r
64typedef struct {\r
65 EFI_GUID *EventGuid;\r
66 EFI_TCG2_EVENT_LOG_FORMAT LogFormat;\r
67} TCG2_EVENT_INFO_STRUCT;\r
68\r
69TCG2_EVENT_INFO_STRUCT mTcg2EventInfo[] = {\r
70 {&gTcgEventEntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2},\r
71 {&gTcgEvent2EntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2},\r
72};\r
73\r
74#define TCG_EVENT_LOG_AREA_COUNT_MAX 2\r
75\r
76typedef struct {\r
77 EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat;\r
78 EFI_PHYSICAL_ADDRESS Lasa;\r
79 UINT64 Laml;\r
80 UINTN EventLogSize;\r
81 UINT8 *LastEvent;\r
82 BOOLEAN EventLogStarted;\r
83 BOOLEAN EventLogTruncated;\r
84} TCG_EVENT_LOG_AREA_STRUCT;\r
85\r
86typedef struct _TCG_DXE_DATA {\r
87 EFI_TCG2_BOOT_SERVICE_CAPABILITY BsCap;\r
88 TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
89 BOOLEAN GetEventLogCalled[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
90 TCG_EVENT_LOG_AREA_STRUCT FinalEventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
91 EFI_TCG2_FINAL_EVENTS_TABLE *FinalEventsTable[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
92} TCG_DXE_DATA;\r
93\r
94TCG_DXE_DATA mTcgDxeData = {\r
95 {\r
96 sizeof (EFI_TCG2_BOOT_SERVICE_CAPABILITY), // Size\r
97 { 1, 1 }, // StructureVersion\r
98 { 1, 1 }, // ProtocolVersion\r
99 EFI_TCG2_BOOT_HASH_ALG_SHA1, // HashAlgorithmBitmap\r
100 EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2, // SupportedEventLogs\r
101 TRUE, // TPMPresentFlag\r
102 TCG2_DEFAULT_MAX_COMMAND_SIZE, // MaxCommandSize\r
103 TCG2_DEFAULT_MAX_RESPONSE_SIZE, // MaxResponseSize\r
104 0, // ManufacturerID\r
105 0, // NumberOfPCRBanks\r
106 0, // ActivePcrBanks\r
107 },\r
108};\r
109\r
110UINTN mBootAttempts = 0;\r
111CHAR16 mBootVarName[] = L"BootOrder";\r
112\r
113VARIABLE_TYPE mVariableType[] = {\r
114 {EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid},\r
115 {EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid},\r
116 {EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid},\r
117 {EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid},\r
118 {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid},\r
119};\r
120\r
121EFI_HANDLE mImageHandle;\r
122\r
123/**\r
124 Measure PE image into TPM log based on the authenticode image hashing in\r
125 PE/COFF Specification 8.0 Appendix A.\r
126\r
127 Caution: This function may receive untrusted input.\r
128 PE/COFF image is external input, so this function will validate its data structure\r
129 within this image buffer before use.\r
130\r
5a8eae95
LG
131 Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().\r
132\r
1abfa4ce
JY
133 @param[in] PCRIndex TPM PCR index\r
134 @param[in] ImageAddress Start address of image buffer.\r
135 @param[in] ImageSize Image size\r
136 @param[out] DigestList Digeest list of this image.\r
137\r
138 @retval EFI_SUCCESS Successfully measure image.\r
139 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.\r
140 @retval other error value\r
141**/\r
142EFI_STATUS\r
143MeasurePeImageAndExtend (\r
144 IN UINT32 PCRIndex,\r
145 IN EFI_PHYSICAL_ADDRESS ImageAddress,\r
146 IN UINTN ImageSize,\r
147 OUT TPML_DIGEST_VALUES *DigestList\r
148 );\r
149\r
150/**\r
151\r
152 This function dump raw data.\r
153\r
154 @param Data raw data\r
155 @param Size raw data size\r
156\r
157**/\r
158VOID\r
159InternalDumpData (\r
160 IN UINT8 *Data,\r
161 IN UINTN Size\r
162 )\r
163{\r
164 UINTN Index;\r
165 for (Index = 0; Index < Size; Index++) {\r
166 DEBUG ((EFI_D_INFO, "%02x", (UINTN)Data[Index]));\r
167 }\r
168}\r
169\r
a2612cf7
ZC
170/**\r
171\r
172 This function initialize TCG_PCR_EVENT2_HDR for EV_NO_ACTION Event Type other than EFI Specification ID event\r
173 The behavior is defined by TCG PC Client PFP Spec. Section 9.3.4 EV_NO_ACTION Event Types\r
174\r
175 @param[in, out] NoActionEvent Event Header of EV_NO_ACTION Event\r
176 @param[in] EventSize Event Size of the EV_NO_ACTION Event\r
177\r
178**/\r
179VOID\r
180InitNoActionEvent (\r
181 IN OUT TCG_PCR_EVENT2_HDR *NoActionEvent,\r
182 IN UINT32 EventSize\r
183 )\r
184{\r
185 UINT32 DigestListCount;\r
186 TPMI_ALG_HASH HashAlgId;\r
187 UINT8 *DigestBuffer;\r
188\r
189 DigestBuffer = (UINT8 *)NoActionEvent->Digests.digests;\r
190 DigestListCount = 0;\r
191\r
192 NoActionEvent->PCRIndex = 0;\r
193 NoActionEvent->EventType = EV_NO_ACTION;\r
194\r
195 //\r
196 // Set Hash count & hashAlg accordingly, while Digest.digests[n].digest to all 0\r
197 //\r
198 ZeroMem (&NoActionEvent->Digests, sizeof(NoActionEvent->Digests));\r
199\r
200 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
201 HashAlgId = TPM_ALG_SHA1;\r
202 CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
203 DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
204 DigestListCount++;\r
205 }\r
206\r
207 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
208 HashAlgId = TPM_ALG_SHA256;\r
209 CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
210 DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
211 DigestListCount++;\r
212 }\r
213\r
214 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
215 HashAlgId = TPM_ALG_SHA384;\r
216 CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
217 DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
218 DigestListCount++;\r
219 }\r
220\r
221 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
222 HashAlgId = TPM_ALG_SHA512;\r
223 CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
224 DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
225 DigestListCount++;\r
226 }\r
227\r
228 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
229 HashAlgId = TPM_ALG_SM3_256;\r
230 CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
231 DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
232 DigestListCount++;\r
233 }\r
234\r
235 //\r
236 // Set Digests Count\r
237 //\r
238 WriteUnaligned32 ((UINT32 *)&NoActionEvent->Digests.count, DigestListCount);\r
239\r
240 //\r
241 // Set Event Size\r
242 //\r
243 WriteUnaligned32((UINT32 *)DigestBuffer, EventSize);\r
244}\r
245\r
1abfa4ce
JY
246/**\r
247\r
248 This function dump raw data with colume format.\r
249\r
250 @param Data raw data\r
251 @param Size raw data size\r
252\r
253**/\r
254VOID\r
255InternalDumpHex (\r
256 IN UINT8 *Data,\r
257 IN UINTN Size\r
258 )\r
259{\r
260 UINTN Index;\r
261 UINTN Count;\r
262 UINTN Left;\r
263\r
264#define COLUME_SIZE (16 * 2)\r
265\r
266 Count = Size / COLUME_SIZE;\r
267 Left = Size % COLUME_SIZE;\r
268 for (Index = 0; Index < Count; Index++) {\r
269 DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));\r
270 InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);\r
271 DEBUG ((EFI_D_INFO, "\n"));\r
272 }\r
273\r
274 if (Left != 0) {\r
275 DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));\r
276 InternalDumpData (Data + Index * COLUME_SIZE, Left);\r
277 DEBUG ((EFI_D_INFO, "\n"));\r
278 }\r
279}\r
280\r
1abfa4ce
JY
281/**\r
282 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function\r
283 Caller is responsible to free LocationBuf.\r
284\r
285 @param[out] LocationBuf Returns Processor Location Buffer.\r
286 @param[out] Num Returns processor number.\r
287\r
288 @retval EFI_SUCCESS Operation completed successfully.\r
289 @retval EFI_UNSUPPORTED MpService protocol not found.\r
290\r
291**/\r
292EFI_STATUS\r
293GetProcessorsCpuLocation (\r
294 OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf,\r
295 OUT UINTN *Num\r
296 )\r
297{\r
298 EFI_STATUS Status;\r
299 EFI_MP_SERVICES_PROTOCOL *MpProtocol;\r
300 UINTN ProcessorNum;\r
301 UINTN EnabledProcessorNum;\r
302 EFI_PROCESSOR_INFORMATION ProcessorInfo;\r
303 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;\r
304 UINTN Index;\r
305\r
306 Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpProtocol);\r
307 if (EFI_ERROR (Status)) {\r
308 //\r
309 // MP protocol is not installed\r
310 //\r
311 return EFI_UNSUPPORTED;\r
312 }\r
313\r
314 Status = MpProtocol->GetNumberOfProcessors(\r
315 MpProtocol,\r
316 &ProcessorNum,\r
317 &EnabledProcessorNum\r
318 );\r
319 if (EFI_ERROR(Status)){\r
320 return Status;\r
321 }\r
322\r
323 Status = gBS->AllocatePool(\r
324 EfiBootServicesData,\r
325 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
326 (VOID **) &ProcessorLocBuf\r
327 );\r
328 if (EFI_ERROR(Status)){\r
329 return Status;\r
330 }\r
331\r
332 //\r
333 // Get each processor Location info\r
334 //\r
335 for (Index = 0; Index < ProcessorNum; Index++) {\r
336 Status = MpProtocol->GetProcessorInfo(\r
337 MpProtocol,\r
338 Index,\r
339 &ProcessorInfo\r
340 );\r
341 if (EFI_ERROR(Status)){\r
342 FreePool(ProcessorLocBuf);\r
343 return Status;\r
344 }\r
345\r
346 //\r
347 // Get all Processor Location info & measure\r
348 //\r
349 CopyMem(\r
350 &ProcessorLocBuf[Index],\r
351 &ProcessorInfo.Location,\r
352 sizeof(EFI_CPU_PHYSICAL_LOCATION)\r
353 );\r
354 }\r
355\r
356 *LocationBuf = ProcessorLocBuf;\r
357 *Num = ProcessorNum;\r
358\r
359 return Status;\r
360}\r
361\r
362/**\r
363 The EFI_TCG2_PROTOCOL GetCapability function call provides protocol\r
364 capability information and state information.\r
365\r
366 @param[in] This Indicates the calling context\r
367 @param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY\r
368 structure and sets the size field to the size of the structure allocated.\r
369 The callee fills in the fields with the EFI protocol capability information\r
370 and the current EFI TCG2 state information up to the number of fields which\r
371 fit within the size of the structure passed in.\r
372\r
373 @retval EFI_SUCCESS Operation completed successfully.\r
374 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
b3548d32 375 The ProtocolCapability variable will not be populated.\r
1abfa4ce
JY
376 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
377 The ProtocolCapability variable will not be populated.\r
378 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.\r
b3548d32 379 It will be partially populated (required Size field will be set).\r
1abfa4ce
JY
380**/\r
381EFI_STATUS\r
382EFIAPI\r
383Tcg2GetCapability (\r
384 IN EFI_TCG2_PROTOCOL *This,\r
385 IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability\r
386 )\r
387{\r
336dbfd1 388 DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability ...\n"));\r
1abfa4ce
JY
389\r
390 if ((This == NULL) || (ProtocolCapability == NULL)) {\r
391 return EFI_INVALID_PARAMETER;\r
392 }\r
b3548d32 393\r
336dbfd1
DL
394 DEBUG ((DEBUG_VERBOSE, "Size - 0x%x\n", ProtocolCapability->Size));\r
395 DEBUG ((DEBUG_VERBOSE, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)));\r
1abfa4ce
JY
396\r
397 if (ProtocolCapability->Size < mTcgDxeData.BsCap.Size) {\r
398 //\r
399 // Handle the case that firmware support 1.1 but OS only support 1.0.\r
400 //\r
b3548d32 401 if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) ||\r
1abfa4ce
JY
402 ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) {\r
403 if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) {\r
404 CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0));\r
405 ProtocolCapability->Size = sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0);\r
406 ProtocolCapability->StructureVersion.Major = 1;\r
407 ProtocolCapability->StructureVersion.Minor = 0;\r
408 ProtocolCapability->ProtocolVersion.Major = 1;\r
409 ProtocolCapability->ProtocolVersion.Minor = 0;\r
410 DEBUG ((EFI_D_ERROR, "TreeGetCapability (Compatible) - %r\n", EFI_SUCCESS));\r
411 return EFI_SUCCESS;\r
412 }\r
413 }\r
414 ProtocolCapability->Size = mTcgDxeData.BsCap.Size;\r
415 return EFI_BUFFER_TOO_SMALL;\r
416 }\r
417\r
418 CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, mTcgDxeData.BsCap.Size);\r
336dbfd1 419 DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability - %r\n", EFI_SUCCESS));\r
1abfa4ce
JY
420 return EFI_SUCCESS;\r
421}\r
422\r
423/**\r
424 This function dump PCR event.\r
425\r
426 @param[in] EventHdr TCG PCR event structure.\r
427**/\r
428VOID\r
429DumpEvent (\r
430 IN TCG_PCR_EVENT_HDR *EventHdr\r
431 )\r
432{\r
433 UINTN Index;\r
434\r
435 DEBUG ((EFI_D_INFO, " Event:\n"));\r
436 DEBUG ((EFI_D_INFO, " PCRIndex - %d\n", EventHdr->PCRIndex));\r
437 DEBUG ((EFI_D_INFO, " EventType - 0x%08x\n", EventHdr->EventType));\r
438 DEBUG ((EFI_D_INFO, " Digest - "));\r
439 for (Index = 0; Index < sizeof(TCG_DIGEST); Index++) {\r
440 DEBUG ((EFI_D_INFO, "%02x ", EventHdr->Digest.digest[Index]));\r
441 }\r
442 DEBUG ((EFI_D_INFO, "\n"));\r
443 DEBUG ((EFI_D_INFO, " EventSize - 0x%08x\n", EventHdr->EventSize));\r
444 InternalDumpHex ((UINT8 *)(EventHdr + 1), EventHdr->EventSize);\r
445}\r
446\r
447/**\r
448 This function dump TCG_EfiSpecIDEventStruct.\r
449\r
450 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.\r
451**/\r
452VOID\r
453DumpTcgEfiSpecIdEventStruct (\r
454 IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct\r
455 )\r
456{\r
a9092578 457 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
1abfa4ce 458 UINTN Index;\r
a9092578
QS
459 UINT8 *VendorInfoSize;\r
460 UINT8 *VendorInfo;\r
461 UINT32 NumberOfAlgorithms;\r
1abfa4ce
JY
462\r
463 DEBUG ((EFI_D_INFO, " TCG_EfiSpecIDEventStruct:\n"));\r
464 DEBUG ((EFI_D_INFO, " signature - '"));\r
465 for (Index = 0; Index < sizeof(TcgEfiSpecIdEventStruct->signature); Index++) {\r
466 DEBUG ((EFI_D_INFO, "%c", TcgEfiSpecIdEventStruct->signature[Index]));\r
467 }\r
468 DEBUG ((EFI_D_INFO, "'\n"));\r
469 DEBUG ((EFI_D_INFO, " platformClass - 0x%08x\n", TcgEfiSpecIdEventStruct->platformClass));\r
470 DEBUG ((EFI_D_INFO, " specVersion - %d.%d%d\n", TcgEfiSpecIdEventStruct->specVersionMajor, TcgEfiSpecIdEventStruct->specVersionMinor, TcgEfiSpecIdEventStruct->specErrata));\r
471 DEBUG ((EFI_D_INFO, " uintnSize - 0x%02x\n", TcgEfiSpecIdEventStruct->uintnSize));\r
472\r
a9092578
QS
473 CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof(NumberOfAlgorithms));\r
474 DEBUG ((EFI_D_INFO, " NumberOfAlgorithms - 0x%08x\n", NumberOfAlgorithms));\r
1abfa4ce 475\r
a9092578
QS
476 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));\r
477 for (Index = 0; Index < NumberOfAlgorithms; Index++) {\r
1abfa4ce 478 DEBUG ((EFI_D_INFO, " digest(%d)\n", Index));\r
a9092578
QS
479 DEBUG ((EFI_D_INFO, " algorithmId - 0x%04x\n", DigestSize[Index].algorithmId));\r
480 DEBUG ((EFI_D_INFO, " digestSize - 0x%04x\n", DigestSize[Index].digestSize));\r
1abfa4ce 481 }\r
a9092578
QS
482 VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];\r
483 DEBUG ((EFI_D_INFO, " VendorInfoSize - 0x%02x\n", *VendorInfoSize));\r
484 VendorInfo = VendorInfoSize + 1;\r
485 DEBUG ((EFI_D_INFO, " VendorInfo - "));\r
486 for (Index = 0; Index < *VendorInfoSize; Index++) {\r
487 DEBUG ((EFI_D_INFO, "%02x ", VendorInfo[Index]));\r
1abfa4ce
JY
488 }\r
489 DEBUG ((EFI_D_INFO, "\n"));\r
490}\r
491\r
492/**\r
493 This function get size of TCG_EfiSpecIDEventStruct.\r
494\r
495 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.\r
496**/\r
497UINTN\r
498GetTcgEfiSpecIdEventStructSize (\r
499 IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct\r
500 )\r
501{\r
a9092578
QS
502 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
503 UINT8 *VendorInfoSize;\r
504 UINT32 NumberOfAlgorithms;\r
1abfa4ce 505\r
a9092578 506 CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof(NumberOfAlgorithms));\r
1abfa4ce 507\r
a9092578
QS
508 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));\r
509 VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];\r
510 return sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (NumberOfAlgorithms * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8) + (*VendorInfoSize);\r
1abfa4ce
JY
511}\r
512\r
513/**\r
514 This function dump PCR event 2.\r
515\r
516 @param[in] TcgPcrEvent2 TCG PCR event 2 structure.\r
517**/\r
518VOID\r
519DumpEvent2 (\r
520 IN TCG_PCR_EVENT2 *TcgPcrEvent2\r
521 )\r
522{\r
523 UINTN Index;\r
524 UINT32 DigestIndex;\r
525 UINT32 DigestCount;\r
526 TPMI_ALG_HASH HashAlgo;\r
527 UINT32 DigestSize;\r
528 UINT8 *DigestBuffer;\r
529 UINT32 EventSize;\r
530 UINT8 *EventBuffer;\r
531\r
532 DEBUG ((EFI_D_INFO, " Event:\n"));\r
533 DEBUG ((EFI_D_INFO, " PCRIndex - %d\n", TcgPcrEvent2->PCRIndex));\r
534 DEBUG ((EFI_D_INFO, " EventType - 0x%08x\n", TcgPcrEvent2->EventType));\r
535\r
536 DEBUG ((EFI_D_INFO, " DigestCount: 0x%08x\n", TcgPcrEvent2->Digest.count));\r
537\r
538 DigestCount = TcgPcrEvent2->Digest.count;\r
539 HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg;\r
540 DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest;\r
541 for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {\r
542 DEBUG ((EFI_D_INFO, " HashAlgo : 0x%04x\n", HashAlgo));\r
543 DEBUG ((EFI_D_INFO, " Digest(%d): ", DigestIndex));\r
544 DigestSize = GetHashSizeFromAlgo (HashAlgo);\r
545 for (Index = 0; Index < DigestSize; Index++) {\r
546 DEBUG ((EFI_D_INFO, "%02x ", DigestBuffer[Index]));\r
547 }\r
548 DEBUG ((EFI_D_INFO, "\n"));\r
549 //\r
550 // Prepare next\r
551 //\r
552 CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof(TPMI_ALG_HASH));\r
553 DigestBuffer = DigestBuffer + DigestSize + sizeof(TPMI_ALG_HASH);\r
554 }\r
555 DEBUG ((EFI_D_INFO, "\n"));\r
556 DigestBuffer = DigestBuffer - sizeof(TPMI_ALG_HASH);\r
557\r
558 CopyMem (&EventSize, DigestBuffer, sizeof(TcgPcrEvent2->EventSize));\r
559 DEBUG ((EFI_D_INFO, " EventSize - 0x%08x\n", EventSize));\r
560 EventBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);\r
561 InternalDumpHex (EventBuffer, EventSize);\r
562}\r
563\r
564/**\r
565 This function returns size of TCG PCR event 2.\r
b3548d32 566\r
1abfa4ce
JY
567 @param[in] TcgPcrEvent2 TCG PCR event 2 structure.\r
568\r
569 @return size of TCG PCR event 2.\r
570**/\r
571UINTN\r
572GetPcrEvent2Size (\r
573 IN TCG_PCR_EVENT2 *TcgPcrEvent2\r
574 )\r
575{\r
576 UINT32 DigestIndex;\r
577 UINT32 DigestCount;\r
578 TPMI_ALG_HASH HashAlgo;\r
579 UINT32 DigestSize;\r
580 UINT8 *DigestBuffer;\r
581 UINT32 EventSize;\r
582 UINT8 *EventBuffer;\r
583\r
584 DigestCount = TcgPcrEvent2->Digest.count;\r
585 HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg;\r
586 DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest;\r
587 for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {\r
588 DigestSize = GetHashSizeFromAlgo (HashAlgo);\r
589 //\r
590 // Prepare next\r
591 //\r
592 CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof(TPMI_ALG_HASH));\r
593 DigestBuffer = DigestBuffer + DigestSize + sizeof(TPMI_ALG_HASH);\r
594 }\r
595 DigestBuffer = DigestBuffer - sizeof(TPMI_ALG_HASH);\r
596\r
597 CopyMem (&EventSize, DigestBuffer, sizeof(TcgPcrEvent2->EventSize));\r
598 EventBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);\r
599\r
600 return (UINTN)EventBuffer + EventSize - (UINTN)TcgPcrEvent2;\r
601}\r
602\r
603/**\r
604 This function dump event log.\r
605\r
606 @param[in] EventLogFormat The type of the event log for which the information is requested.\r
607 @param[in] EventLogLocation A pointer to the memory address of the event log.\r
608 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the\r
609 address of the start of the last entry in the event log in memory.\r
610 @param[in] FinalEventsTable A pointer to the memory address of the final event table.\r
611**/\r
612VOID\r
613DumpEventLog (\r
614 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,\r
615 IN EFI_PHYSICAL_ADDRESS EventLogLocation,\r
616 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry,\r
617 IN EFI_TCG2_FINAL_EVENTS_TABLE *FinalEventsTable\r
618 )\r
619{\r
620 TCG_PCR_EVENT_HDR *EventHdr;\r
621 TCG_PCR_EVENT2 *TcgPcrEvent2;\r
622 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;\r
623 UINTN NumberOfEvents;\r
624\r
625 DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));\r
b3548d32 626\r
1abfa4ce
JY
627 switch (EventLogFormat) {\r
628 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
629 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
630 while ((UINTN)EventHdr <= EventLogLastEntry) {\r
631 DumpEvent (EventHdr);\r
632 EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize);\r
633 }\r
634 if (FinalEventsTable == NULL) {\r
635 DEBUG ((EFI_D_INFO, "FinalEventsTable: NOT FOUND\n"));\r
636 } else {\r
637 DEBUG ((EFI_D_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable));\r
638 DEBUG ((EFI_D_INFO, " Version: (0x%x)\n", FinalEventsTable->Version));\r
639 DEBUG ((EFI_D_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents));\r
640\r
641 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)(FinalEventsTable + 1);\r
642 for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {\r
643 DumpEvent (EventHdr);\r
644 EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize);\r
645 }\r
646 }\r
647 break;\r
648 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
649 //\r
b3548d32 650 // Dump first event\r
1abfa4ce
JY
651 //\r
652 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
653 DumpEvent (EventHdr);\r
654\r
655 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)(EventHdr + 1);\r
656 DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct);\r
657\r
658 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgEfiSpecIdEventStruct + GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct));\r
659 while ((UINTN)TcgPcrEvent2 <= EventLogLastEntry) {\r
660 DumpEvent2 (TcgPcrEvent2);\r
661 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2));\r
662 }\r
663\r
664 if (FinalEventsTable == NULL) {\r
665 DEBUG ((EFI_D_INFO, "FinalEventsTable: NOT FOUND\n"));\r
666 } else {\r
667 DEBUG ((EFI_D_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable));\r
668 DEBUG ((EFI_D_INFO, " Version: (0x%x)\n", FinalEventsTable->Version));\r
669 DEBUG ((EFI_D_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents));\r
670\r
671 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)(UINTN)(FinalEventsTable + 1);\r
672 for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {\r
673 DumpEvent2 (TcgPcrEvent2);\r
674 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2));\r
675 }\r
676 }\r
677 break;\r
678 }\r
679\r
680 return ;\r
681}\r
682\r
683/**\r
684 The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to\r
b3548d32 685 retrieve the address of a given event log and its last entry.\r
1abfa4ce
JY
686\r
687 @param[in] This Indicates the calling context\r
688 @param[in] EventLogFormat The type of the event log for which the information is requested.\r
689 @param[out] EventLogLocation A pointer to the memory address of the event log.\r
690 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the\r
691 address of the start of the last entry in the event log in memory.\r
692 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would\r
693 have exceeded the area allocated for events, this value is set to TRUE.\r
694 Otherwise, the value will be FALSE and the Event Log will be complete.\r
695\r
696 @retval EFI_SUCCESS Operation completed successfully.\r
697 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect\r
698 (e.g. asking for an event log whose format is not supported).\r
699**/\r
700EFI_STATUS\r
701EFIAPI\r
702Tcg2GetEventLog (\r
703 IN EFI_TCG2_PROTOCOL *This,\r
704 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,\r
705 OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,\r
706 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,\r
707 OUT BOOLEAN *EventLogTruncated\r
708 )\r
709{\r
710 UINTN Index;\r
711\r
712 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog ... (0x%x)\n", EventLogFormat));\r
713\r
714 if (This == NULL) {\r
715 return EFI_INVALID_PARAMETER;\r
716 }\r
717\r
718 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
719 if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {\r
720 break;\r
721 }\r
722 }\r
723\r
724 if (Index == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])) {\r
725 return EFI_INVALID_PARAMETER;\r
726 }\r
727\r
728 if ((mTcg2EventInfo[Index].LogFormat & mTcgDxeData.BsCap.SupportedEventLogs) == 0) {\r
729 return EFI_INVALID_PARAMETER;\r
730 }\r
731\r
732 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
733 if (EventLogLocation != NULL) {\r
734 *EventLogLocation = 0;\r
735 }\r
736 if (EventLogLastEntry != NULL) {\r
737 *EventLogLastEntry = 0;\r
738 }\r
739 if (EventLogTruncated != NULL) {\r
740 *EventLogTruncated = FALSE;\r
741 }\r
742 return EFI_SUCCESS;\r
743 }\r
744\r
745 if (EventLogLocation != NULL) {\r
746 *EventLogLocation = mTcgDxeData.EventLogAreaStruct[Index].Lasa;\r
747 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogLocation - %x)\n", *EventLogLocation));\r
748 }\r
749\r
750 if (EventLogLastEntry != NULL) {\r
751 if (!mTcgDxeData.EventLogAreaStruct[Index].EventLogStarted) {\r
752 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;\r
753 } else {\r
754 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)mTcgDxeData.EventLogAreaStruct[Index].LastEvent;\r
755 }\r
756 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry));\r
757 }\r
758\r
759 if (EventLogTruncated != NULL) {\r
760 *EventLogTruncated = mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated;\r
761 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated));\r
762 }\r
763\r
764 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog - %r\n", EFI_SUCCESS));\r
765\r
766 // Dump Event Log for debug purpose\r
767 if ((EventLogLocation != NULL) && (EventLogLastEntry != NULL)) {\r
768 DumpEventLog (EventLogFormat, *EventLogLocation, *EventLogLastEntry, mTcgDxeData.FinalEventsTable[Index]);\r
769 }\r
770\r
771 //\r
772 // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored\r
773 // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID.\r
774 //\r
775 mTcgDxeData.GetEventLogCalled[Index] = TRUE;\r
776\r
777 return EFI_SUCCESS;\r
778}\r
779\r
780/**\r
781 Add a new entry to the Event Log.\r
782\r
b3548d32
LG
783 @param[in, out] EventLogPtr Pointer to the Event Log data.\r
784 @param[in, out] LogSize Size of the Event Log.\r
1abfa4ce 785 @param[in] MaxSize Maximum size of the Event Log.\r
b3548d32 786 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.\r
1abfa4ce 787 @param[in] NewEventHdrSize New event header size.\r
b3548d32 788 @param[in] NewEventData Pointer to the new event data.\r
1abfa4ce 789 @param[in] NewEventSize New event data size.\r
b3548d32 790\r
1abfa4ce
JY
791 @retval EFI_SUCCESS The new event log entry was added.\r
792 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
793\r
794**/\r
795EFI_STATUS\r
796TcgCommLogEvent (\r
797 IN OUT UINT8 **EventLogPtr,\r
798 IN OUT UINTN *LogSize,\r
799 IN UINTN MaxSize,\r
800 IN VOID *NewEventHdr,\r
801 IN UINT32 NewEventHdrSize,\r
802 IN UINT8 *NewEventData,\r
803 IN UINT32 NewEventSize\r
804 )\r
805{\r
806 UINTN NewLogSize;\r
807\r
808 if (NewEventSize > MAX_ADDRESS - NewEventHdrSize) {\r
809 return EFI_OUT_OF_RESOURCES;\r
810 }\r
811\r
812 NewLogSize = NewEventHdrSize + NewEventSize;\r
813\r
814 if (NewLogSize > MAX_ADDRESS - *LogSize) {\r
815 return EFI_OUT_OF_RESOURCES;\r
816 }\r
817\r
818 if (NewLogSize + *LogSize > MaxSize) {\r
819 DEBUG ((EFI_D_INFO, " MaxSize - 0x%x\n", MaxSize));\r
820 DEBUG ((EFI_D_INFO, " NewLogSize - 0x%x\n", NewLogSize));\r
821 DEBUG ((EFI_D_INFO, " LogSize - 0x%x\n", *LogSize));\r
822 DEBUG ((EFI_D_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));\r
823 return EFI_OUT_OF_RESOURCES;\r
824 }\r
825\r
826 *EventLogPtr += *LogSize;\r
827 *LogSize += NewLogSize;\r
828 CopyMem (*EventLogPtr, NewEventHdr, NewEventHdrSize);\r
829 CopyMem (\r
830 *EventLogPtr + NewEventHdrSize,\r
831 NewEventData,\r
832 NewEventSize\r
833 );\r
834 return EFI_SUCCESS;\r
835}\r
836\r
837/**\r
838 Add a new entry to the Event Log.\r
839\r
840 @param[in] EventLogFormat The type of the event log for which the information is requested.\r
b3548d32 841 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.\r
1abfa4ce 842 @param[in] NewEventHdrSize New event header size.\r
b3548d32 843 @param[in] NewEventData Pointer to the new event data.\r
1abfa4ce
JY
844 @param[in] NewEventSize New event data size.\r
845\r
846 @retval EFI_SUCCESS The new event log entry was added.\r
847 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
848\r
849**/\r
850EFI_STATUS\r
851TcgDxeLogEvent (\r
852 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,\r
853 IN VOID *NewEventHdr,\r
854 IN UINT32 NewEventHdrSize,\r
855 IN UINT8 *NewEventData,\r
856 IN UINT32 NewEventSize\r
857 )\r
858{\r
859 EFI_STATUS Status;\r
860 UINTN Index;\r
861 TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;\r
b3548d32 862\r
1abfa4ce
JY
863 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
864 if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {\r
865 break;\r
866 }\r
867 }\r
868\r
869 if (Index == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])) {\r
870 return EFI_INVALID_PARAMETER;\r
871 }\r
872\r
fd46e831
JY
873 //\r
874 // Record to normal event log\r
875 //\r
876 EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index];\r
1abfa4ce
JY
877\r
878 if (EventLogAreaStruct->EventLogTruncated) {\r
879 return EFI_VOLUME_FULL;\r
880 }\r
881\r
882 EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;\r
883 Status = TcgCommLogEvent (\r
884 &EventLogAreaStruct->LastEvent,\r
885 &EventLogAreaStruct->EventLogSize,\r
886 (UINTN)EventLogAreaStruct->Laml,\r
887 NewEventHdr,\r
888 NewEventHdrSize,\r
889 NewEventData,\r
890 NewEventSize\r
891 );\r
b3548d32 892\r
fd46e831 893 if (Status == EFI_OUT_OF_RESOURCES) {\r
1abfa4ce
JY
894 EventLogAreaStruct->EventLogTruncated = TRUE;\r
895 return EFI_VOLUME_FULL;\r
896 } else if (Status == EFI_SUCCESS) {\r
897 EventLogAreaStruct->EventLogStarted = TRUE;\r
fd46e831
JY
898 }\r
899\r
900 //\r
901 // If GetEventLog is called, record to FinalEventsTable, too.\r
902 //\r
903 if (mTcgDxeData.GetEventLogCalled[Index]) {\r
904 if (mTcgDxeData.FinalEventsTable[Index] == NULL) {\r
905 //\r
906 // no need for FinalEventsTable\r
907 //\r
908 return EFI_SUCCESS;\r
909 }\r
910 EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index];\r
911\r
912 if (EventLogAreaStruct->EventLogTruncated) {\r
913 return EFI_VOLUME_FULL;\r
914 }\r
915\r
916 EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;\r
917 Status = TcgCommLogEvent (\r
918 &EventLogAreaStruct->LastEvent,\r
919 &EventLogAreaStruct->EventLogSize,\r
920 (UINTN)EventLogAreaStruct->Laml,\r
921 NewEventHdr,\r
922 NewEventHdrSize,\r
923 NewEventData,\r
924 NewEventSize\r
925 );\r
926 if (Status == EFI_OUT_OF_RESOURCES) {\r
927 EventLogAreaStruct->EventLogTruncated = TRUE;\r
928 return EFI_VOLUME_FULL;\r
929 } else if (Status == EFI_SUCCESS) {\r
930 EventLogAreaStruct->EventLogStarted = TRUE;\r
931 //\r
932 // Increase the NumberOfEvents in FinalEventsTable\r
933 //\r
1abfa4ce 934 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;\r
fd46e831 935 DEBUG ((EFI_D_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents));\r
c0584d0b 936 DEBUG ((EFI_D_INFO, " Size - 0x%x\n", (UINTN)EventLogAreaStruct->EventLogSize));\r
1abfa4ce
JY
937 }\r
938 }\r
939\r
940 return Status;\r
941}\r
942\r
1abfa4ce
JY
943/**\r
944 Get TPML_DIGEST_VALUES compact binary buffer size.\r
945\r
946 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.\r
947\r
948 @return TPML_DIGEST_VALUES compact binary buffer size.\r
949**/\r
950UINT32\r
951GetDigestListBinSize (\r
952 IN VOID *DigestListBin\r
953 )\r
954{\r
955 UINTN Index;\r
956 UINT16 DigestSize;\r
957 UINT32 TotalSize;\r
958 UINT32 Count;\r
959 TPMI_ALG_HASH HashAlg;\r
960\r
961 Count = ReadUnaligned32 (DigestListBin);\r
962 TotalSize = sizeof(Count);\r
963 DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);\r
964 for (Index = 0; Index < Count; Index++) {\r
965 HashAlg = ReadUnaligned16 (DigestListBin);\r
966 TotalSize += sizeof(HashAlg);\r
967 DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);\r
968\r
969 DigestSize = GetHashSizeFromAlgo (HashAlg);\r
970 TotalSize += DigestSize;\r
971 DigestListBin = (UINT8 *)DigestListBin + DigestSize;\r
972 }\r
973\r
974 return TotalSize;\r
975}\r
976\r
ab5b1f31
SZ
977/**\r
978 Copy TPML_DIGEST_VALUES compact binary into a buffer\r
979\r
980 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.\r
981 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.\r
982 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.\r
983 @param[out] HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.\r
984\r
985 @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.\r
986**/\r
987VOID *\r
988CopyDigestListBinToBuffer (\r
989 IN OUT VOID *Buffer,\r
990 IN VOID *DigestListBin,\r
991 IN UINT32 HashAlgorithmMask,\r
992 OUT UINT32 *HashAlgorithmMaskCopied\r
993 )\r
994{\r
995 UINTN Index;\r
996 UINT16 DigestSize;\r
997 UINT32 Count;\r
998 TPMI_ALG_HASH HashAlg;\r
999 UINT32 DigestListCount;\r
1000 UINT32 *DigestListCountPtr;\r
1001\r
1002 DigestListCountPtr = (UINT32 *) Buffer;\r
1003 DigestListCount = 0;\r
1004 (*HashAlgorithmMaskCopied) = 0;\r
1005\r
1006 Count = ReadUnaligned32 (DigestListBin);\r
1007 Buffer = (UINT8 *)Buffer + sizeof(Count);\r
1008 DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);\r
1009 for (Index = 0; Index < Count; Index++) {\r
1010 HashAlg = ReadUnaligned16 (DigestListBin);\r
1011 DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);\r
1012 DigestSize = GetHashSizeFromAlgo (HashAlg);\r
1013\r
1014 if (IsHashAlgSupportedInHashAlgorithmMask(HashAlg, HashAlgorithmMask)) {\r
1015 CopyMem (Buffer, &HashAlg, sizeof(HashAlg));\r
1016 Buffer = (UINT8 *)Buffer + sizeof(HashAlg);\r
1017 CopyMem (Buffer, DigestListBin, DigestSize);\r
1018 Buffer = (UINT8 *)Buffer + DigestSize;\r
1019 DigestListCount++;\r
1020 (*HashAlgorithmMaskCopied) |= GetHashMaskFromAlgo (HashAlg);\r
1021 } else {\r
1022 DEBUG ((DEBUG_ERROR, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg));\r
1023 }\r
1024 DigestListBin = (UINT8 *)DigestListBin + DigestSize;\r
1025 }\r
1026 WriteUnaligned32 (DigestListCountPtr, DigestListCount);\r
1027\r
1028 return Buffer;\r
1029}\r
1030\r
1abfa4ce
JY
1031/**\r
1032 Add a new entry to the Event Log.\r
1033\r
1034 @param[in] DigestList A list of digest.\r
1035 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.\r
1036 @param[in] NewEventData Pointer to the new event data.\r
1037\r
1038 @retval EFI_SUCCESS The new event log entry was added.\r
1039 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
1040**/\r
1041EFI_STATUS\r
1042TcgDxeLogHashEvent (\r
1043 IN TPML_DIGEST_VALUES *DigestList,\r
1044 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,\r
1045 IN UINT8 *NewEventData\r
1046 )\r
1047{\r
1048 EFI_STATUS Status;\r
1049 EFI_TPL OldTpl;\r
1050 UINTN Index;\r
1051 EFI_STATUS RetStatus;\r
1052 TCG_PCR_EVENT2 TcgPcrEvent2;\r
1053 UINT8 *DigestBuffer;\r
a9f1b2e2 1054 UINT32 *EventSizePtr;\r
1abfa4ce
JY
1055\r
1056 DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
1057\r
1058 RetStatus = EFI_SUCCESS;\r
1059 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
1060 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
1061 DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));\r
1062 switch (mTcg2EventInfo[Index].LogFormat) {\r
1063 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
d4b9b2c3 1064 Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
1abfa4ce
JY
1065 if (!EFI_ERROR (Status)) {\r
1066 //\r
1067 // Enter critical region\r
1068 //\r
1069 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
1070 Status = TcgDxeLogEvent (\r
1071 mTcg2EventInfo[Index].LogFormat,\r
1072 NewEventHdr,\r
1073 sizeof(TCG_PCR_EVENT_HDR),\r
1074 NewEventData,\r
1075 NewEventHdr->EventSize\r
1076 );\r
1077 if (Status != EFI_SUCCESS) {\r
1078 RetStatus = Status;\r
1079 }\r
1080 gBS->RestoreTPL (OldTpl);\r
1081 //\r
1082 // Exit critical region\r
1083 //\r
1084 }\r
1085 break;\r
1086 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
1087 ZeroMem (&TcgPcrEvent2, sizeof(TcgPcrEvent2));\r
1088 TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex;\r
1089 TcgPcrEvent2.EventType = NewEventHdr->EventType;\r
1090 DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest;\r
a9f1b2e2
SZ
1091 EventSizePtr = CopyDigestListToBuffer (DigestBuffer, DigestList, mTcgDxeData.BsCap.ActivePcrBanks);\r
1092 CopyMem (EventSizePtr, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));\r
1abfa4ce
JY
1093\r
1094 //\r
1095 // Enter critical region\r
1096 //\r
1097 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
1098 Status = TcgDxeLogEvent (\r
1099 mTcg2EventInfo[Index].LogFormat,\r
1100 &TcgPcrEvent2,\r
a9f1b2e2 1101 sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListBinSize (DigestBuffer) + sizeof(TcgPcrEvent2.EventSize),\r
1abfa4ce
JY
1102 NewEventData,\r
1103 NewEventHdr->EventSize\r
1104 );\r
1105 if (Status != EFI_SUCCESS) {\r
1106 RetStatus = Status;\r
1107 }\r
1108 gBS->RestoreTPL (OldTpl);\r
1109 //\r
1110 // Exit critical region\r
1111 //\r
1112 break;\r
1113 }\r
1114 }\r
1115 }\r
1116\r
1117 return RetStatus;\r
1118}\r
1119\r
1120/**\r
1121 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
1122 and add an entry to the Event Log.\r
1123\r
1124 @param[in] Flags Bitmap providing additional information.\r
b3548d32 1125 @param[in] HashData Physical address of the start of the data buffer\r
1abfa4ce
JY
1126 to be hashed, extended, and logged.\r
1127 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData\r
b3548d32
LG
1128 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.\r
1129 @param[in] NewEventData Pointer to the new event data.\r
1abfa4ce
JY
1130\r
1131 @retval EFI_SUCCESS Operation completed successfully.\r
1132 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
1133 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
1134\r
1135**/\r
1136EFI_STATUS\r
1137TcgDxeHashLogExtendEvent (\r
1138 IN UINT64 Flags,\r
1139 IN UINT8 *HashData,\r
1140 IN UINT64 HashDataLen,\r
1141 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,\r
1142 IN UINT8 *NewEventData\r
1143 )\r
1144{\r
1145 EFI_STATUS Status;\r
1146 TPML_DIGEST_VALUES DigestList;\r
1147\r
1148 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
1149 return EFI_DEVICE_ERROR;\r
1150 }\r
1151\r
1152 Status = HashAndExtend (\r
1153 NewEventHdr->PCRIndex,\r
1154 HashData,\r
1155 (UINTN)HashDataLen,\r
1156 &DigestList\r
1157 );\r
1158 if (!EFI_ERROR (Status)) {\r
1159 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
1160 Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
1161 }\r
1162 }\r
1163\r
1164 if (Status == EFI_DEVICE_ERROR) {\r
1165 DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status));\r
1166 mTcgDxeData.BsCap.TPMPresentFlag = FALSE;\r
1167 REPORT_STATUS_CODE (\r
1168 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
1169 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
1170 );\r
1171 }\r
1172\r
1173 return Status;\r
1174}\r
1175\r
1176/**\r
1177 The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with\r
1178 an opportunity to extend and optionally log events without requiring\r
b3548d32 1179 knowledge of actual TPM commands.\r
1abfa4ce 1180 The extend operation will occur even if this function cannot create an event\r
b3548d32 1181 log entry (e.g. due to the event log being full).\r
1abfa4ce
JY
1182\r
1183 @param[in] This Indicates the calling context\r
1184 @param[in] Flags Bitmap providing additional information.\r
b3548d32 1185 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.\r
1abfa4ce
JY
1186 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.\r
1187 @param[in] Event Pointer to data buffer containing information about the event.\r
1188\r
1189 @retval EFI_SUCCESS Operation completed successfully.\r
1190 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
1191 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.\r
1192 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1193 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.\r
1194**/\r
1195EFI_STATUS\r
1196EFIAPI\r
1197Tcg2HashLogExtendEvent (\r
1198 IN EFI_TCG2_PROTOCOL *This,\r
1199 IN UINT64 Flags,\r
1200 IN EFI_PHYSICAL_ADDRESS DataToHash,\r
1201 IN UINT64 DataToHashLen,\r
1202 IN EFI_TCG2_EVENT *Event\r
1203 )\r
1204{\r
1205 EFI_STATUS Status;\r
1206 TCG_PCR_EVENT_HDR NewEventHdr;\r
1207 TPML_DIGEST_VALUES DigestList;\r
1208\r
336dbfd1 1209 DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent ...\n"));\r
1abfa4ce
JY
1210\r
1211 if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {\r
1212 return EFI_INVALID_PARAMETER;\r
1213 }\r
1214\r
1215 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
1216 return EFI_DEVICE_ERROR;\r
1217 }\r
1218\r
1219 if (Event->Size < Event->Header.HeaderSize + sizeof(UINT32)) {\r
1220 return EFI_INVALID_PARAMETER;\r
1221 }\r
1222\r
1223 if (Event->Header.PCRIndex > MAX_PCR_INDEX) {\r
1224 return EFI_INVALID_PARAMETER;\r
1225 }\r
1226\r
1227 NewEventHdr.PCRIndex = Event->Header.PCRIndex;\r
1228 NewEventHdr.EventType = Event->Header.EventType;\r
1229 NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize;\r
1230 if ((Flags & PE_COFF_IMAGE) != 0) {\r
1231 Status = MeasurePeImageAndExtend (\r
1232 NewEventHdr.PCRIndex,\r
1233 DataToHash,\r
1234 (UINTN)DataToHashLen,\r
1235 &DigestList\r
1236 );\r
1237 if (!EFI_ERROR (Status)) {\r
1238 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
1239 Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event);\r
1240 }\r
1241 }\r
1242 if (Status == EFI_DEVICE_ERROR) {\r
1243 DEBUG ((EFI_D_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status));\r
1244 mTcgDxeData.BsCap.TPMPresentFlag = FALSE;\r
1245 REPORT_STATUS_CODE (\r
1246 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
1247 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
1248 );\r
1249 }\r
1250 } else {\r
1251 Status = TcgDxeHashLogExtendEvent (\r
1252 Flags,\r
1253 (UINT8 *) (UINTN) DataToHash,\r
1254 DataToHashLen,\r
1255 &NewEventHdr,\r
1256 Event->Event\r
1257 );\r
1258 }\r
336dbfd1 1259 DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent - %r\n", Status));\r
1abfa4ce
JY
1260 return Status;\r
1261}\r
1262\r
1263/**\r
1264 This service enables the sending of commands to the TPM.\r
1265\r
1266 @param[in] This Indicates the calling context\r
1267 @param[in] InputParameterBlockSize Size of the TPM input parameter block.\r
1268 @param[in] InputParameterBlock Pointer to the TPM input parameter block.\r
1269 @param[in] OutputParameterBlockSize Size of the TPM output parameter block.\r
1270 @param[in] OutputParameterBlock Pointer to the TPM output parameter block.\r
1271\r
1272 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.\r
1273 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.\r
1274 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
b3548d32 1275 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.\r
1abfa4ce
JY
1276**/\r
1277EFI_STATUS\r
1278EFIAPI\r
1279Tcg2SubmitCommand (\r
1280 IN EFI_TCG2_PROTOCOL *This,\r
1281 IN UINT32 InputParameterBlockSize,\r
1282 IN UINT8 *InputParameterBlock,\r
1283 IN UINT32 OutputParameterBlockSize,\r
1284 IN UINT8 *OutputParameterBlock\r
1285 )\r
1286{\r
1287 EFI_STATUS Status;\r
1288\r
1289 DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand ...\n"));\r
1290\r
1291 if ((This == NULL) ||\r
1292 (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||\r
1293 (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL)) {\r
1294 return EFI_INVALID_PARAMETER;\r
1295 }\r
1296\r
1297 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
1298 return EFI_DEVICE_ERROR;\r
1299 }\r
1300\r
e1f35834 1301 if (InputParameterBlockSize > mTcgDxeData.BsCap.MaxCommandSize) {\r
1abfa4ce
JY
1302 return EFI_INVALID_PARAMETER;\r
1303 }\r
e1f35834 1304 if (OutputParameterBlockSize > mTcgDxeData.BsCap.MaxResponseSize) {\r
1abfa4ce
JY
1305 return EFI_INVALID_PARAMETER;\r
1306 }\r
1307\r
1308 Status = Tpm2SubmitCommand (\r
1309 InputParameterBlockSize,\r
1310 InputParameterBlock,\r
1311 &OutputParameterBlockSize,\r
1312 OutputParameterBlock\r
1313 );\r
1314 DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand - %r\n", Status));\r
1315 return Status;\r
1316}\r
1317\r
1318/**\r
1319 This service returns the currently active PCR banks.\r
1320\r
1321 @param[in] This Indicates the calling context\r
1322 @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.\r
1323\r
1324 @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.\r
b3548d32 1325 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1abfa4ce
JY
1326**/\r
1327EFI_STATUS\r
1328EFIAPI\r
1329Tcg2GetActivePCRBanks (\r
1330 IN EFI_TCG2_PROTOCOL *This,\r
1331 OUT UINT32 *ActivePcrBanks\r
1332 )\r
1333{\r
1334 if (ActivePcrBanks == NULL) {\r
1335 return EFI_INVALID_PARAMETER;\r
1336 }\r
1337 *ActivePcrBanks = mTcgDxeData.BsCap.ActivePcrBanks;\r
1338 return EFI_SUCCESS;\r
1339}\r
1340\r
1341/**\r
1342 This service sets the currently active PCR banks.\r
1343\r
1344 @param[in] This Indicates the calling context\r
1345 @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set.\r
1346\r
1347 @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active.\r
1348 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1349**/\r
1350EFI_STATUS\r
1351EFIAPI\r
1352Tcg2SetActivePCRBanks (\r
1353 IN EFI_TCG2_PROTOCOL *This,\r
1354 IN UINT32 ActivePcrBanks\r
1355 )\r
1356{\r
1357 EFI_STATUS Status;\r
1358 UINT32 ReturnCode;\r
1359\r
1360 DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks ... (0x%x)\n", ActivePcrBanks));\r
1361\r
1362 if (ActivePcrBanks == 0) {\r
1363 return EFI_INVALID_PARAMETER;\r
1364 }\r
1365 if ((ActivePcrBanks & (~mTcgDxeData.BsCap.HashAlgorithmBitmap)) != 0) {\r
1366 return EFI_INVALID_PARAMETER;\r
1367 }\r
1368 if (ActivePcrBanks == mTcgDxeData.BsCap.ActivePcrBanks) {\r
1369 //\r
1370 // Need clear previous SET_PCR_BANKS setting\r
1371 //\r
1372 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_NO_ACTION, 0);\r
1373 } else {\r
1374 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, ActivePcrBanks);\r
1375 }\r
1376\r
1377 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
1378 Status = EFI_SUCCESS;\r
1379 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {\r
1380 Status = EFI_OUT_OF_RESOURCES;\r
1381 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {\r
1382 Status = EFI_UNSUPPORTED;\r
1383 } else {\r
1384 Status = EFI_DEVICE_ERROR;\r
1385 }\r
1386\r
1387 DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks - %r\n", Status));\r
1388\r
1389 return Status;\r
1390}\r
1391\r
1392/**\r
1393 This service retrieves the result of a previous invocation of SetActivePcrBanks.\r
1394\r
1395 @param[in] This Indicates the calling context\r
1396 @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.\r
1397 @param[out] Response The response from the SetActivePcrBank request.\r
1398\r
1399 @retval EFI_SUCCESS The result value could be returned.\r
1400 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1401**/\r
1402EFI_STATUS\r
1403EFIAPI\r
1404Tcg2GetResultOfSetActivePcrBanks (\r
1405 IN EFI_TCG2_PROTOCOL *This,\r
1406 OUT UINT32 *OperationPresent,\r
1407 OUT UINT32 *Response\r
1408 )\r
1409{\r
1410 UINT32 ReturnCode;\r
1411\r
1412 if ((OperationPresent == NULL) || (Response == NULL)) {\r
1413 return EFI_INVALID_PARAMETER;\r
1414 }\r
b3548d32 1415\r
1abfa4ce
JY
1416 ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);\r
1417 if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {\r
1418 return EFI_SUCCESS;\r
1419 } else {\r
1420 return EFI_UNSUPPORTED;\r
1421 }\r
1422}\r
1423\r
1424EFI_TCG2_PROTOCOL mTcg2Protocol = {\r
1425 Tcg2GetCapability,\r
1426 Tcg2GetEventLog,\r
1427 Tcg2HashLogExtendEvent,\r
1428 Tcg2SubmitCommand,\r
1429 Tcg2GetActivePCRBanks,\r
1430 Tcg2SetActivePCRBanks,\r
1431 Tcg2GetResultOfSetActivePcrBanks,\r
1432};\r
1433\r
1434/**\r
1435 Initialize the Event Log and log events passed from the PEI phase.\r
1436\r
1437 @retval EFI_SUCCESS Operation completed successfully.\r
1438 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1439\r
1440**/\r
1441EFI_STATUS\r
1442SetupEventLog (\r
1443 VOID\r
1444 )\r
1445{\r
1446 EFI_STATUS Status;\r
1447 VOID *TcgEvent;\r
1448 EFI_PEI_HOB_POINTERS GuidHob;\r
1449 EFI_PHYSICAL_ADDRESS Lasa;\r
1450 UINTN Index;\r
ab5b1f31
SZ
1451 VOID *DigestListBin;\r
1452 TPML_DIGEST_VALUES TempDigestListBin;\r
1abfa4ce 1453 UINT32 DigestListBinSize;\r
ab5b1f31 1454 UINT8 *Event;\r
1abfa4ce 1455 UINT32 EventSize;\r
ab5b1f31
SZ
1456 UINT32 *EventSizePtr;\r
1457 UINT32 HashAlgorithmMaskCopied;\r
1abfa4ce 1458 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;\r
9381e149 1459 UINT8 TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];\r
a2612cf7
ZC
1460 TCG_PCR_EVENT_HDR SpecIdEvent;\r
1461 TCG_PCR_EVENT2_HDR NoActionEvent;\r
a9092578 1462 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
35e00ace 1463 TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;\r
a9092578
QS
1464 UINT8 *VendorInfoSize;\r
1465 UINT32 NumberOfAlgorithms;\r
18458db1 1466 TCG_EfiStartupLocalityEvent StartupLocalityEvent;\r
1abfa4ce
JY
1467\r
1468 DEBUG ((EFI_D_INFO, "SetupEventLog\n"));\r
1469\r
1470 //\r
1471 // 1. Create Log Area\r
1472 //\r
1473 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
1474 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
1475 mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
1abfa4ce 1476 Status = gBS->AllocatePages (\r
dc756bae 1477 AllocateAnyPages,\r
fd46e831 1478 EfiBootServicesData,\r
91e914f5 1479 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
1abfa4ce
JY
1480 &Lasa\r
1481 );\r
1482 if (EFI_ERROR (Status)) {\r
1483 return Status;\r
1484 }\r
1485 mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
91e914f5 1486 mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
1abfa4ce 1487 //\r
b3548d32 1488 // To initialize them as 0xFF is recommended\r
1abfa4ce
JY
1489 // because the OS can know the last entry for that.\r
1490 //\r
91e914f5 1491 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
1abfa4ce
JY
1492 //\r
1493 // Create first entry for Log Header Entry Data\r
1494 //\r
1495 if (mTcg2EventInfo[Index].LogFormat != EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {\r
1496 //\r
1497 // TcgEfiSpecIdEventStruct\r
1498 //\r
1499 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;\r
1500 CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof(TcgEfiSpecIdEventStruct->signature));\r
1501 TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);\r
1502 TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;\r
1503 TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;\r
1504 TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;\r
1505 TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32);\r
a9092578
QS
1506 NumberOfAlgorithms = 0;\r
1507 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));\r
1abfa4ce 1508 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
35e00ace
QS
1509 TempDigestSize = DigestSize;\r
1510 TempDigestSize += NumberOfAlgorithms;\r
1511 TempDigestSize->algorithmId = TPM_ALG_SHA1;\r
1512 TempDigestSize->digestSize = SHA1_DIGEST_SIZE;\r
a9092578 1513 NumberOfAlgorithms++;\r
1abfa4ce
JY
1514 }\r
1515 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
35e00ace
QS
1516 TempDigestSize = DigestSize;\r
1517 TempDigestSize += NumberOfAlgorithms;\r
1518 TempDigestSize->algorithmId = TPM_ALG_SHA256;\r
1519 TempDigestSize->digestSize = SHA256_DIGEST_SIZE;\r
a9092578 1520 NumberOfAlgorithms++;\r
1abfa4ce
JY
1521 }\r
1522 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
35e00ace
QS
1523 TempDigestSize = DigestSize;\r
1524 TempDigestSize += NumberOfAlgorithms;\r
1525 TempDigestSize->algorithmId = TPM_ALG_SHA384;\r
1526 TempDigestSize->digestSize = SHA384_DIGEST_SIZE;\r
a9092578 1527 NumberOfAlgorithms++;\r
1abfa4ce
JY
1528 }\r
1529 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
35e00ace
QS
1530 TempDigestSize = DigestSize;\r
1531 TempDigestSize += NumberOfAlgorithms;\r
1532 TempDigestSize->algorithmId = TPM_ALG_SHA512;\r
1533 TempDigestSize->digestSize = SHA512_DIGEST_SIZE;\r
a9092578 1534 NumberOfAlgorithms++;\r
1abfa4ce
JY
1535 }\r
1536 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
35e00ace
QS
1537 TempDigestSize = DigestSize;\r
1538 TempDigestSize += NumberOfAlgorithms;\r
1539 TempDigestSize->algorithmId = TPM_ALG_SM3_256;\r
1540 TempDigestSize->digestSize = SM3_256_DIGEST_SIZE;\r
a9092578 1541 NumberOfAlgorithms++;\r
1abfa4ce 1542 }\r
a9092578 1543 CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof(NumberOfAlgorithms));\r
35e00ace
QS
1544 TempDigestSize = DigestSize;\r
1545 TempDigestSize += NumberOfAlgorithms;\r
1546 VendorInfoSize = (UINT8 *)TempDigestSize;\r
a9092578 1547 *VendorInfoSize = 0;\r
1abfa4ce 1548\r
a2612cf7
ZC
1549 SpecIdEvent.PCRIndex = 0;\r
1550 SpecIdEvent.EventType = EV_NO_ACTION;\r
1551 ZeroMem (&SpecIdEvent.Digest, sizeof(SpecIdEvent.Digest));\r
1552 SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
1abfa4ce
JY
1553\r
1554 //\r
a2612cf7
ZC
1555 // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.\r
1556 // TCG EFI Protocol Spec. Section 5.3 Event Log Header\r
18458db1 1557 // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log\r
1abfa4ce
JY
1558 //\r
1559 Status = TcgDxeLogEvent (\r
1560 mTcg2EventInfo[Index].LogFormat,\r
a2612cf7
ZC
1561 &SpecIdEvent,\r
1562 sizeof(SpecIdEvent),\r
1abfa4ce 1563 (UINT8 *)TcgEfiSpecIdEventStruct,\r
a2612cf7 1564 SpecIdEvent.EventSize\r
1abfa4ce 1565 );\r
18458db1
ZC
1566\r
1567 //\r
a2612cf7 1568 // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2\r
18458db1
ZC
1569 //\r
1570 GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);\r
1571 if (GuidHob.Guid != NULL) {\r
1572 //\r
1573 // Get Locality Indicator from StartupLocality HOB\r
1574 //\r
1575 StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));\r
1576 CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof(StartupLocalityEvent.Signature));\r
18458db1
ZC
1577 DEBUG ((DEBUG_INFO, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent.StartupLocality));\r
1578\r
a2612cf7
ZC
1579 //\r
1580 // Initialize StartupLocalityEvent\r
1581 //\r
1582 InitNoActionEvent(&NoActionEvent, sizeof(StartupLocalityEvent));\r
1583\r
18458db1
ZC
1584 //\r
1585 // Log EfiStartupLocalityEvent as the second Event\r
1586 // TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event\r
1587 //\r
1588 Status = TcgDxeLogEvent (\r
1589 mTcg2EventInfo[Index].LogFormat,\r
1590 &NoActionEvent,\r
a2612cf7 1591 sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),\r
18458db1 1592 (UINT8 *)&StartupLocalityEvent,\r
a2612cf7 1593 sizeof(StartupLocalityEvent)\r
18458db1 1594 );\r
a2612cf7 1595\r
18458db1 1596 }\r
1abfa4ce
JY
1597 }\r
1598 }\r
1599 }\r
1600\r
1601 //\r
1602 // 2. Create Final Log Area\r
1603 //\r
1604 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
1605 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
fd46e831 1606 if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {\r
fd46e831 1607 Status = gBS->AllocatePages (\r
dc756bae 1608 AllocateAnyPages,\r
fd46e831
JY
1609 EfiACPIMemoryNVS,\r
1610 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),\r
1611 &Lasa\r
1612 );\r
1613 if (EFI_ERROR (Status)) {\r
1614 return Status;\r
1615 }\r
1616 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);\r
1abfa4ce 1617\r
fd46e831
JY
1618 //\r
1619 // Initialize\r
1620 //\r
1621 mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;\r
1622 (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;\r
1623 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;\r
1624\r
1625 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
1626 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
1627 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
1628 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
1629 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;\r
1630 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
1631 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
1abfa4ce 1632\r
1abfa4ce 1633 //\r
b3548d32 1634 // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2\r
1abfa4ce 1635 //\r
fd46e831 1636 Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);\r
1abfa4ce
JY
1637 if (EFI_ERROR (Status)) {\r
1638 return Status;\r
1639 }\r
fd46e831
JY
1640 } else {\r
1641 //\r
1642 // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2\r
1643 //\r
1644 mTcgDxeData.FinalEventsTable[Index] = NULL;\r
1645 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
1646 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = 0;\r
1647 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = 0;\r
1648 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
1649 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;\r
1650 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
1651 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
1abfa4ce
JY
1652 }\r
1653 }\r
1654 }\r
b3548d32 1655\r
1abfa4ce
JY
1656 //\r
1657 // 3. Sync data from PEI to DXE\r
1658 //\r
1659 Status = EFI_SUCCESS;\r
1660 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
1661 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
1662 GuidHob.Raw = GetHobList ();\r
1663 Status = EFI_SUCCESS;\r
b3548d32 1664 while (!EFI_ERROR (Status) &&\r
1abfa4ce 1665 (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {\r
ab5b1f31
SZ
1666 TcgEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));\r
1667 ASSERT (TcgEvent != NULL);\r
1abfa4ce
JY
1668 GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
1669 switch (mTcg2EventInfo[Index].LogFormat) {\r
1670 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
1671 Status = TcgDxeLogEvent (\r
1672 mTcg2EventInfo[Index].LogFormat,\r
1673 TcgEvent,\r
1674 sizeof(TCG_PCR_EVENT_HDR),\r
1675 ((TCG_PCR_EVENT*)TcgEvent)->Event,\r
1676 ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize\r
1677 );\r
1678 break;\r
1679 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
ab5b1f31
SZ
1680 DigestListBin = (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE);\r
1681 DigestListBinSize = GetDigestListBinSize (DigestListBin);\r
1682 //\r
1683 // Save event size.\r
1684 //\r
1685 CopyMem (&EventSize, (UINT8 *)DigestListBin + DigestListBinSize, sizeof(UINT32));\r
1686 Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32);\r
1687 //\r
1688 // Filter inactive digest in the event2 log from PEI HOB.\r
1689 //\r
1690 CopyMem (&TempDigestListBin, DigestListBin, GetDigestListBinSize (DigestListBin));\r
1691 EventSizePtr = CopyDigestListBinToBuffer (\r
1692 DigestListBin,\r
1693 &TempDigestListBin,\r
1694 mTcgDxeData.BsCap.ActivePcrBanks,\r
1695 &HashAlgorithmMaskCopied\r
1696 );\r
1697 if (HashAlgorithmMaskCopied != mTcgDxeData.BsCap.ActivePcrBanks) {\r
1698 DEBUG ((\r
1699 DEBUG_ERROR,\r
1700 "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",\r
1701 HashAlgorithmMaskCopied,\r
1702 mTcgDxeData.BsCap.ActivePcrBanks\r
1703 ));\r
1704 }\r
1705 //\r
1706 // Restore event size.\r
1707 //\r
1708 CopyMem (EventSizePtr, &EventSize, sizeof(UINT32));\r
1709 DigestListBinSize = GetDigestListBinSize (DigestListBin);\r
1710\r
1abfa4ce
JY
1711 Status = TcgDxeLogEvent (\r
1712 mTcg2EventInfo[Index].LogFormat,\r
1713 TcgEvent,\r
1714 sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
ab5b1f31 1715 Event,\r
1abfa4ce
JY
1716 EventSize\r
1717 );\r
1718 break;\r
1719 }\r
ab5b1f31 1720 FreePool (TcgEvent);\r
1abfa4ce
JY
1721 }\r
1722 }\r
1723 }\r
1724\r
1725 return Status;\r
1726}\r
1727\r
1728/**\r
c1b0828b 1729 Measure and log an action string, and extend the measurement result into PCR[PCRIndex].\r
1abfa4ce 1730\r
c1b0828b 1731 @param[in] PCRIndex PCRIndex to extend\r
b3548d32
LG
1732 @param[in] String A specific string that indicates an Action event.\r
1733\r
1abfa4ce
JY
1734 @retval EFI_SUCCESS Operation completed successfully.\r
1735 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1736\r
1737**/\r
1738EFI_STATUS\r
1739TcgMeasureAction (\r
c1b0828b
ZC
1740 IN TPM_PCRINDEX PCRIndex,\r
1741 IN CHAR8 *String\r
1abfa4ce
JY
1742 )\r
1743{\r
1744 TCG_PCR_EVENT_HDR TcgEvent;\r
1745\r
c1b0828b 1746 TcgEvent.PCRIndex = PCRIndex;\r
1abfa4ce
JY
1747 TcgEvent.EventType = EV_EFI_ACTION;\r
1748 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
1749 return TcgDxeHashLogExtendEvent (\r
1750 0,\r
1751 (UINT8*)String,\r
1752 TcgEvent.EventSize,\r
1753 &TcgEvent,\r
1754 (UINT8 *) String\r
1755 );\r
1756}\r
1757\r
1758/**\r
1759 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].\r
1760\r
1761 @retval EFI_SUCCESS Operation completed successfully.\r
1762 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1763\r
1764**/\r
1765EFI_STATUS\r
1766MeasureHandoffTables (\r
1767 VOID\r
1768 )\r
1769{\r
1770 EFI_STATUS Status;\r
1abfa4ce
JY
1771 TCG_PCR_EVENT_HDR TcgEvent;\r
1772 EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
1773 UINTN ProcessorNum;\r
1774 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;\r
1775\r
1776 ProcessorLocBuf = NULL;\r
d2de4483 1777 Status = EFI_SUCCESS;\r
1abfa4ce
JY
1778\r
1779 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
1780 //\r
b3548d32 1781 // Tcg Server spec.\r
1abfa4ce
JY
1782 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
1783 //\r
1784 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);\r
1785\r
1786 if (!EFI_ERROR(Status)){\r
1787 TcgEvent.PCRIndex = 1;\r
1788 TcgEvent.EventType = EV_TABLE_OF_DEVICES;\r
1789 TcgEvent.EventSize = sizeof (HandoffTables);\r
1790\r
1791 HandoffTables.NumberOfTables = 1;\r
1792 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;\r
1793 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;\r
1794\r
1795 Status = TcgDxeHashLogExtendEvent (\r
1796 0,\r
1797 (UINT8*)(UINTN)ProcessorLocBuf,\r
1798 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
1799 &TcgEvent,\r
1800 (UINT8*)&HandoffTables\r
1801 );\r
1802\r
1803 FreePool(ProcessorLocBuf);\r
1804 }\r
1805 }\r
1806\r
1807 return Status;\r
1808}\r
1809\r
1810/**\r
1811 Measure and log Separator event, and extend the measurement result into a specific PCR.\r
1812\r
b3548d32 1813 @param[in] PCRIndex PCR index.\r
1abfa4ce
JY
1814\r
1815 @retval EFI_SUCCESS Operation completed successfully.\r
1816 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1817\r
1818**/\r
1819EFI_STATUS\r
1820MeasureSeparatorEvent (\r
1821 IN TPM_PCRINDEX PCRIndex\r
1822 )\r
1823{\r
1824 TCG_PCR_EVENT_HDR TcgEvent;\r
1825 UINT32 EventData;\r
1826\r
1827 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));\r
1828\r
1829 EventData = 0;\r
1830 TcgEvent.PCRIndex = PCRIndex;\r
1831 TcgEvent.EventType = EV_SEPARATOR;\r
1832 TcgEvent.EventSize = (UINT32)sizeof (EventData);\r
1833 return TcgDxeHashLogExtendEvent (\r
1834 0,\r
1835 (UINT8 *)&EventData,\r
1836 sizeof (EventData),\r
1837 &TcgEvent,\r
1838 (UINT8 *)&EventData\r
1839 );\r
1840}\r
1841\r
1842/**\r
1843 Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
1844\r
b3548d32
LG
1845 @param[in] PCRIndex PCR Index.\r
1846 @param[in] EventType Event type.\r
1abfa4ce
JY
1847 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
1848 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
1849 @param[in] VarData The content of the variable data.\r
1850 @param[in] VarSize The size of the variable data.\r
1851\r
1abfa4ce
JY
1852 @retval EFI_SUCCESS Operation completed successfully.\r
1853 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1854 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1855\r
1856**/\r
1857EFI_STATUS\r
1858MeasureVariable (\r
1859 IN TPM_PCRINDEX PCRIndex,\r
1860 IN TCG_EVENTTYPE EventType,\r
1861 IN CHAR16 *VarName,\r
1862 IN EFI_GUID *VendorGuid,\r
1863 IN VOID *VarData,\r
1864 IN UINTN VarSize\r
1865 )\r
1866{\r
1867 EFI_STATUS Status;\r
1868 TCG_PCR_EVENT_HDR TcgEvent;\r
1869 UINTN VarNameLength;\r
9d77acf1 1870 UEFI_VARIABLE_DATA *VarLog;\r
1abfa4ce
JY
1871\r
1872 DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));\r
1873 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
1874\r
1875 VarNameLength = StrLen (VarName);\r
1876 TcgEvent.PCRIndex = PCRIndex;\r
1877 TcgEvent.EventType = EventType;\r
1878\r
1879 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
1880 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
1881\r
9d77acf1 1882 VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (TcgEvent.EventSize);\r
1abfa4ce
JY
1883 if (VarLog == NULL) {\r
1884 return EFI_OUT_OF_RESOURCES;\r
1885 }\r
1886\r
1887 VarLog->VariableName = *VendorGuid;\r
1888 VarLog->UnicodeNameLength = VarNameLength;\r
1889 VarLog->VariableDataLength = VarSize;\r
1890 CopyMem (\r
1891 VarLog->UnicodeName,\r
1892 VarName,\r
1893 VarNameLength * sizeof (*VarName)\r
1894 );\r
1895 if (VarSize != 0 && VarData != NULL) {\r
1896 CopyMem (\r
1897 (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
1898 VarData,\r
1899 VarSize\r
1900 );\r
1901 }\r
1902\r
1903 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
1904 //\r
9d77acf1 1905 // Digest is the event data (UEFI_VARIABLE_DATA)\r
1abfa4ce
JY
1906 //\r
1907 Status = TcgDxeHashLogExtendEvent (\r
1908 0,\r
1909 (UINT8*)VarLog,\r
1910 TcgEvent.EventSize,\r
1911 &TcgEvent,\r
1912 (UINT8*)VarLog\r
1913 );\r
1914 } else {\r
36e9e3e8 1915 ASSERT (VarData != NULL);\r
1abfa4ce
JY
1916 Status = TcgDxeHashLogExtendEvent (\r
1917 0,\r
1918 (UINT8*)VarData,\r
1919 VarSize,\r
1920 &TcgEvent,\r
1921 (UINT8*)VarLog\r
1922 );\r
1923 }\r
1924 FreePool (VarLog);\r
1925 return Status;\r
1926}\r
1927\r
1928/**\r
1929 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
1930\r
b3548d32
LG
1931 @param[in] PCRIndex PCR Index.\r
1932 @param[in] EventType Event type.\r
1abfa4ce
JY
1933 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
1934 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
1935 @param[out] VarSize The size of the variable data.\r
1936 @param[out] VarData Pointer to the content of the variable.\r
1937\r
1abfa4ce
JY
1938 @retval EFI_SUCCESS Operation completed successfully.\r
1939 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1940 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1941\r
1942**/\r
1943EFI_STATUS\r
1944ReadAndMeasureVariable (\r
1945 IN TPM_PCRINDEX PCRIndex,\r
1946 IN TCG_EVENTTYPE EventType,\r
1947 IN CHAR16 *VarName,\r
1948 IN EFI_GUID *VendorGuid,\r
1949 OUT UINTN *VarSize,\r
1950 OUT VOID **VarData\r
1951 )\r
1952{\r
1953 EFI_STATUS Status;\r
1954\r
1955 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);\r
1956 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
1957 if (EFI_ERROR (Status)) {\r
1958 //\r
1959 // It is valid case, so we need handle it.\r
1960 //\r
1961 *VarData = NULL;\r
1962 *VarSize = 0;\r
1963 }\r
1964 } else {\r
1965 //\r
1966 // if status error, VarData is freed and set NULL by GetVariable2\r
1967 //\r
1968 if (EFI_ERROR (Status)) {\r
1969 return EFI_NOT_FOUND;\r
1970 }\r
1971 }\r
1972\r
1973 Status = MeasureVariable (\r
1974 PCRIndex,\r
1975 EventType,\r
1976 VarName,\r
1977 VendorGuid,\r
1978 *VarData,\r
1979 *VarSize\r
1980 );\r
1981 return Status;\r
1982}\r
1983\r
1984/**\r
fe13f92b
ZC
1985 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].\r
1986according to TCG PC Client PFP spec 0021 Section 2.4.4.2\r
1abfa4ce
JY
1987\r
1988 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
1989 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
1990 @param[out] VarSize The size of the variable data.\r
1991 @param[out] VarData Pointer to the content of the variable.\r
1992\r
1abfa4ce
JY
1993 @retval EFI_SUCCESS Operation completed successfully.\r
1994 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1995 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1996\r
1997**/\r
1998EFI_STATUS\r
1999ReadAndMeasureBootVariable (\r
2000 IN CHAR16 *VarName,\r
2001 IN EFI_GUID *VendorGuid,\r
2002 OUT UINTN *VarSize,\r
2003 OUT VOID **VarData\r
2004 )\r
2005{\r
2006 return ReadAndMeasureVariable (\r
fe13f92b 2007 1,\r
1abfa4ce
JY
2008 EV_EFI_VARIABLE_BOOT,\r
2009 VarName,\r
2010 VendorGuid,\r
2011 VarSize,\r
2012 VarData\r
2013 );\r
2014}\r
2015\r
2016/**\r
2017 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].\r
2018\r
2019 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
2020 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
2021 @param[out] VarSize The size of the variable data.\r
2022 @param[out] VarData Pointer to the content of the variable.\r
2023\r
1abfa4ce
JY
2024 @retval EFI_SUCCESS Operation completed successfully.\r
2025 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2026 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2027\r
2028**/\r
2029EFI_STATUS\r
2030ReadAndMeasureSecureVariable (\r
2031 IN CHAR16 *VarName,\r
2032 IN EFI_GUID *VendorGuid,\r
2033 OUT UINTN *VarSize,\r
2034 OUT VOID **VarData\r
2035 )\r
2036{\r
2037 return ReadAndMeasureVariable (\r
2038 7,\r
2039 EV_EFI_VARIABLE_DRIVER_CONFIG,\r
2040 VarName,\r
2041 VendorGuid,\r
2042 VarSize,\r
2043 VarData\r
2044 );\r
2045}\r
2046\r
2047/**\r
2048 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.\r
2049\r
2050 The EFI boot variables are BootOrder and Boot#### variables.\r
2051\r
2052 @retval EFI_SUCCESS Operation completed successfully.\r
2053 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2054 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2055\r
2056**/\r
2057EFI_STATUS\r
2058MeasureAllBootVariables (\r
2059 VOID\r
2060 )\r
2061{\r
2062 EFI_STATUS Status;\r
2063 UINT16 *BootOrder;\r
2064 UINTN BootCount;\r
2065 UINTN Index;\r
2066 VOID *BootVarData;\r
2067 UINTN Size;\r
2068\r
2069 Status = ReadAndMeasureBootVariable (\r
2070 mBootVarName,\r
2071 &gEfiGlobalVariableGuid,\r
2072 &BootCount,\r
2073 (VOID **) &BootOrder\r
2074 );\r
2075 if (Status == EFI_NOT_FOUND || BootOrder == NULL) {\r
2076 return EFI_SUCCESS;\r
2077 }\r
2078\r
2079 if (EFI_ERROR (Status)) {\r
2080 //\r
2081 // BootOrder can't be NULL if status is not EFI_NOT_FOUND\r
2082 //\r
2083 FreePool (BootOrder);\r
2084 return Status;\r
2085 }\r
2086\r
2087 BootCount /= sizeof (*BootOrder);\r
2088 for (Index = 0; Index < BootCount; Index++) {\r
2089 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);\r
2090 Status = ReadAndMeasureBootVariable (\r
2091 mBootVarName,\r
2092 &gEfiGlobalVariableGuid,\r
2093 &Size,\r
2094 &BootVarData\r
2095 );\r
2096 if (!EFI_ERROR (Status)) {\r
2097 FreePool (BootVarData);\r
2098 }\r
2099 }\r
2100\r
2101 FreePool (BootOrder);\r
2102 return EFI_SUCCESS;\r
2103}\r
2104\r
2105/**\r
2106 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.\r
2107\r
2108 The EFI boot variables are BootOrder and Boot#### variables.\r
2109\r
2110 @retval EFI_SUCCESS Operation completed successfully.\r
2111 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2112 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2113\r
2114**/\r
2115EFI_STATUS\r
2116MeasureAllSecureVariables (\r
2117 VOID\r
2118 )\r
2119{\r
2120 EFI_STATUS Status;\r
2121 VOID *Data;\r
2122 UINTN DataSize;\r
2123 UINTN Index;\r
2124\r
2125 Status = EFI_NOT_FOUND;\r
2126 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
2127 Status = ReadAndMeasureSecureVariable (\r
2128 mVariableType[Index].VariableName,\r
2129 mVariableType[Index].VendorGuid,\r
2130 &DataSize,\r
2131 &Data\r
2132 );\r
2133 if (!EFI_ERROR (Status)) {\r
2134 if (Data != NULL) {\r
2135 FreePool (Data);\r
2136 }\r
2137 }\r
2138 }\r
2139\r
400b0940
ZC
2140 //\r
2141 // Measure DBT if present and not empty\r
2142 //\r
2143 Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);\r
2144 if (!EFI_ERROR(Status)) {\r
2145 Status = MeasureVariable (\r
2146 7,\r
2147 EV_EFI_VARIABLE_DRIVER_CONFIG,\r
2148 EFI_IMAGE_SECURITY_DATABASE2,\r
2149 &gEfiImageSecurityDatabaseGuid,\r
2150 Data,\r
2151 DataSize\r
2152 );\r
2153 FreePool(Data);\r
2154 } else {\r
2155 DEBUG((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));\r
2156 }\r
2157\r
1abfa4ce
JY
2158 return EFI_SUCCESS;\r
2159}\r
2160\r
2161/**\r
2162 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.\r
2163\r
2164 @retval EFI_SUCCESS Operation completed successfully.\r
2165 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2166 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2167\r
2168**/\r
2169EFI_STATUS\r
2170MeasureLaunchOfFirmwareDebugger (\r
2171 VOID\r
2172 )\r
2173{\r
2174 TCG_PCR_EVENT_HDR TcgEvent;\r
2175\r
2176 TcgEvent.PCRIndex = 7;\r
2177 TcgEvent.EventType = EV_EFI_ACTION;\r
2178 TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1;\r
2179 return TcgDxeHashLogExtendEvent (\r
2180 0,\r
2181 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,\r
2182 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1,\r
2183 &TcgEvent,\r
2184 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING\r
2185 );\r
2186}\r
2187\r
2188/**\r
2189 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.\r
2190\r
2191 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)\r
2192 - The contents of the SecureBoot variable\r
2193 - The contents of the PK variable\r
2194 - The contents of the KEK variable\r
2195 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable\r
2196 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable\r
2197 - Separator\r
2198 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path\r
2199\r
2200 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,\r
2201 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].\r
2202\r
2203 @param[in] Event Event whose notification function is being invoked\r
2204 @param[in] Context Pointer to the notification function's context\r
2205**/\r
2206VOID\r
2207EFIAPI\r
2208MeasureSecureBootPolicy (\r
2209 IN EFI_EVENT Event,\r
2210 IN VOID *Context\r
2211 )\r
2212{\r
2213 EFI_STATUS Status;\r
2214 VOID *Protocol;\r
2215\r
2216 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);\r
2217 if (EFI_ERROR (Status)) {\r
2218 return;\r
2219 }\r
2220\r
2221 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {\r
2222 Status = MeasureLaunchOfFirmwareDebugger ();\r
2223 DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));\r
2224 }\r
2225\r
2226 Status = MeasureAllSecureVariables ();\r
2227 DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status));\r
2228\r
2229 //\r
2230 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)\r
2231 // and ImageVerification (Authority)\r
2232 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So\r
2233 // the Authority measurement happen before ReadToBoot event.\r
2234 //\r
2235 Status = MeasureSeparatorEvent (7);\r
2236 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status));\r
2237 return ;\r
2238}\r
2239\r
2240/**\r
2241 Ready to Boot Event notification handler.\r
2242\r
2243 Sequence of OS boot events is measured in this event notification handler.\r
2244\r
2245 @param[in] Event Event whose notification function is being invoked\r
2246 @param[in] Context Pointer to the notification function's context\r
2247\r
2248**/\r
2249VOID\r
2250EFIAPI\r
2251OnReadyToBoot (\r
2252 IN EFI_EVENT Event,\r
2253 IN VOID *Context\r
2254 )\r
2255{\r
2256 EFI_STATUS Status;\r
2257 TPM_PCRINDEX PcrIndex;\r
2258\r
2259 PERF_START_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE);\r
2260 if (mBootAttempts == 0) {\r
2261\r
2262 //\r
2263 // Measure handoff tables.\r
2264 //\r
2265 Status = MeasureHandoffTables ();\r
2266 if (EFI_ERROR (Status)) {\r
2267 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));\r
2268 }\r
2269\r
2270 //\r
2271 // Measure BootOrder & Boot#### variables.\r
2272 //\r
2273 Status = MeasureAllBootVariables ();\r
2274 if (EFI_ERROR (Status)) {\r
2275 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));\r
2276 }\r
2277\r
2278 //\r
2279 // 1. This is the first boot attempt.\r
2280 //\r
2281 Status = TcgMeasureAction (\r
c1b0828b 2282 4,\r
1abfa4ce
JY
2283 EFI_CALLING_EFI_APPLICATION\r
2284 );\r
2285 if (EFI_ERROR (Status)) {\r
655dabe3 2286 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
1abfa4ce
JY
2287 }\r
2288\r
2289 //\r
2290 // 2. Draw a line between pre-boot env and entering post-boot env.\r
2291 // PCR[7] is already done.\r
2292 //\r
2293 for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {\r
2294 Status = MeasureSeparatorEvent (PcrIndex);\r
2295 if (EFI_ERROR (Status)) {\r
0ab475c9 2296 DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));\r
1abfa4ce
JY
2297 }\r
2298 }\r
2299\r
2300 //\r
2301 // 3. Measure GPT. It would be done in SAP driver.\r
2302 //\r
2303\r
2304 //\r
2305 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.\r
2306 //\r
2307\r
2308 //\r
2309 // 5. Read & Measure variable. BootOrder already measured.\r
2310 //\r
2311 } else {\r
2312 //\r
2313 // 6. Not first attempt, meaning a return from last attempt\r
2314 //\r
2315 Status = TcgMeasureAction (\r
c1b0828b 2316 4,\r
1abfa4ce
JY
2317 EFI_RETURNING_FROM_EFI_APPLICATOIN\r
2318 );\r
2319 if (EFI_ERROR (Status)) {\r
655dabe3 2320 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));\r
1abfa4ce 2321 }\r
c1b0828b
ZC
2322\r
2323 //\r
2324 // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again\r
2325 // TCG PC Client PFP spec Section 2.4.4.5 Step 4\r
2326 //\r
2327 Status = TcgMeasureAction (\r
2328 4,\r
2329 EFI_CALLING_EFI_APPLICATION\r
2330 );\r
2331 if (EFI_ERROR (Status)) {\r
2332 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
2333 }\r
1abfa4ce
JY
2334 }\r
2335\r
2336 DEBUG ((EFI_D_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));\r
2337 //\r
2338 // Increase boot attempt counter.\r
2339 //\r
2340 mBootAttempts++;\r
2341 PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE + 1);\r
2342}\r
2343\r
2344/**\r
2345 Exit Boot Services Event notification handler.\r
2346\r
2347 Measure invocation and success of ExitBootServices.\r
2348\r
2349 @param[in] Event Event whose notification function is being invoked\r
2350 @param[in] Context Pointer to the notification function's context\r
2351\r
2352**/\r
2353VOID\r
2354EFIAPI\r
2355OnExitBootServices (\r
2356 IN EFI_EVENT Event,\r
2357 IN VOID *Context\r
2358 )\r
2359{\r
2360 EFI_STATUS Status;\r
2361\r
2362 //\r
2363 // Measure invocation of ExitBootServices,\r
2364 //\r
2365 Status = TcgMeasureAction (\r
c1b0828b 2366 5,\r
1abfa4ce
JY
2367 EFI_EXIT_BOOT_SERVICES_INVOCATION\r
2368 );\r
2369 if (EFI_ERROR (Status)) {\r
655dabe3 2370 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));\r
1abfa4ce
JY
2371 }\r
2372\r
2373 //\r
2374 // Measure success of ExitBootServices\r
2375 //\r
2376 Status = TcgMeasureAction (\r
c1b0828b 2377 5,\r
1abfa4ce
JY
2378 EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
2379 );\r
2380 if (EFI_ERROR (Status)) {\r
655dabe3 2381 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));\r
1abfa4ce
JY
2382 }\r
2383}\r
2384\r
2385/**\r
2386 Exit Boot Services Failed Event notification handler.\r
2387\r
2388 Measure Failure of ExitBootServices.\r
2389\r
2390 @param[in] Event Event whose notification function is being invoked\r
2391 @param[in] Context Pointer to the notification function's context\r
2392\r
2393**/\r
2394VOID\r
2395EFIAPI\r
2396OnExitBootServicesFailed (\r
2397 IN EFI_EVENT Event,\r
2398 IN VOID *Context\r
2399 )\r
2400{\r
2401 EFI_STATUS Status;\r
2402\r
2403 //\r
2404 // Measure Failure of ExitBootServices,\r
2405 //\r
2406 Status = TcgMeasureAction (\r
c1b0828b 2407 5,\r
1abfa4ce
JY
2408 EFI_EXIT_BOOT_SERVICES_FAILED\r
2409 );\r
2410 if (EFI_ERROR (Status)) {\r
655dabe3 2411 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));\r
1abfa4ce
JY
2412 }\r
2413\r
2414}\r
2415\r
9d5dfe9d
RN
2416/**\r
2417 This routine is called to properly shutdown the TPM before system reset.\r
2418 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
2419 Part 1: Architecture, Revision 01.16.\r
2420\r
2421 @param[in] ResetType The type of reset to perform.\r
2422 @param[in] ResetStatus The status code for the reset.\r
2423 @param[in] DataSize The size, in bytes, of ResetData.\r
2424 @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or\r
2425 EfiResetShutdown the data buffer starts with a Null-terminated\r
2426 string, optionally followed by additional binary data.\r
2427 The string is a description that the caller may use to further\r
2428 indicate the reason for the system reset. ResetData is only\r
2429 valid if ResetStatus is something other than EFI_SUCCESS\r
2430 unless the ResetType is EfiResetPlatformSpecific\r
2431 where a minimum amount of ResetData is always required.\r
2432 For a ResetType of EfiResetPlatformSpecific the data buffer\r
2433 also starts with a Null-terminated string that is followed\r
2434 by an EFI_GUID that describes the specific type of reset to perform.\r
2435**/\r
2436VOID\r
2437EFIAPI\r
2438ShutdownTpmOnReset (\r
2439 IN EFI_RESET_TYPE ResetType,\r
2440 IN EFI_STATUS ResetStatus,\r
2441 IN UINTN DataSize,\r
2442 IN VOID *ResetData OPTIONAL\r
2443 )\r
2444{\r
2445 EFI_STATUS Status;\r
2446 Status = Tpm2Shutdown (TPM_SU_CLEAR);\r
2447 DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));\r
2448}\r
2449\r
2450/**\r
2451 Hook the system reset to properly shutdown TPM.\r
2452 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
2453 Part 1: Architecture, Revision 01.16.\r
2454\r
2455 @param[in] Event Event whose notification function is being invoked\r
2456 @param[in] Context Pointer to the notification function's context\r
2457**/\r
2458VOID\r
2459EFIAPI\r
2460OnResetNotificationInstall (\r
2461 IN EFI_EVENT Event,\r
2462 IN VOID *Context\r
2463 )\r
2464{\r
2465 EFI_STATUS Status;\r
2466 EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify;\r
2467\r
2468 Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify);\r
2469 if (!EFI_ERROR (Status)) {\r
2470 Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);\r
2471 ASSERT_EFI_ERROR (Status);\r
2472 DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));\r
2473\r
2474 gBS->CloseEvent (Event);\r
2475 }\r
2476}\r
2477\r
1abfa4ce
JY
2478/**\r
2479 The function install Tcg2 protocol.\r
b3548d32 2480\r
1abfa4ce
JY
2481 @retval EFI_SUCCESS Tcg2 protocol is installed.\r
2482 @retval other Some error occurs.\r
2483**/\r
2484EFI_STATUS\r
2485InstallTcg2 (\r
2486 VOID\r
2487 )\r
2488{\r
2489 EFI_STATUS Status;\r
2490 EFI_HANDLE Handle;\r
2491\r
2492 Handle = NULL;\r
2493 Status = gBS->InstallMultipleProtocolInterfaces (\r
2494 &Handle,\r
2495 &gEfiTcg2ProtocolGuid,\r
2496 &mTcg2Protocol,\r
2497 NULL\r
2498 );\r
2499 return Status;\r
2500}\r
2501\r
2502/**\r
2503 The driver's entry point. It publishes EFI Tcg2 Protocol.\r
2504\r
b3548d32 2505 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
1abfa4ce 2506 @param[in] SystemTable A pointer to the EFI System Table.\r
b3548d32 2507\r
1abfa4ce
JY
2508 @retval EFI_SUCCESS The entry point is executed successfully.\r
2509 @retval other Some error occurs when executing this entry point.\r
2510**/\r
2511EFI_STATUS\r
2512EFIAPI\r
2513DriverEntry (\r
2514 IN EFI_HANDLE ImageHandle,\r
2515 IN EFI_SYSTEM_TABLE *SystemTable\r
2516 )\r
2517{\r
2518 EFI_STATUS Status;\r
2519 EFI_EVENT Event;\r
2520 VOID *Registration;\r
2521 UINT32 MaxCommandSize;\r
2522 UINT32 MaxResponseSize;\r
1abfa4ce
JY
2523 UINTN Index;\r
2524 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;\r
2525 UINT32 ActivePCRBanks;\r
2526 UINT32 NumberOfPCRBanks;\r
2527\r
2528 mImageHandle = ImageHandle;\r
2529\r
2530 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
2531 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
f0f1a3cb 2532 DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));\r
1abfa4ce
JY
2533 return EFI_UNSUPPORTED;\r
2534 }\r
2535\r
2536 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
2537 DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
2538 return EFI_DEVICE_ERROR;\r
2539 }\r
b3548d32 2540\r
1abfa4ce
JY
2541 Status = Tpm2RequestUseTpm ();\r
2542 if (EFI_ERROR (Status)) {\r
2543 DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));\r
2544 return Status;\r
2545 }\r
b3548d32 2546\r
1abfa4ce
JY
2547 //\r
2548 // Fill information\r
2549 //\r
2550 ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));\r
b3548d32 2551\r
1abfa4ce
JY
2552 mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);\r
2553 mTcgDxeData.BsCap.ProtocolVersion.Major = 1;\r
2554 mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;\r
2555 mTcgDxeData.BsCap.StructureVersion.Major = 1;\r
2556 mTcgDxeData.BsCap.StructureVersion.Minor = 1;\r
2557\r
2558 DEBUG ((EFI_D_INFO, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));\r
2559 DEBUG ((EFI_D_INFO, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));\r
2560\r
2561 Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);\r
2562 if (EFI_ERROR (Status)) {\r
2563 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));\r
2564 } else {\r
2565 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));\r
2566 }\r
2567\r
2568 DEBUG_CODE (\r
2569 UINT32 FirmwareVersion1;\r
2570 UINT32 FirmwareVersion2;\r
2571\r
2572 Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);\r
2573 if (EFI_ERROR (Status)) {\r
2574 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));\r
2575 } else {\r
2576 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));\r
2577 }\r
2578 );\r
2579\r
2580 Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);\r
2581 if (EFI_ERROR (Status)) {\r
2582 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));\r
2583 } else {\r
2584 mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize;\r
2585 mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;\r
2586 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));\r
2587 }\r
2588\r
2589 //\r
2590 // Get supported PCR and current Active PCRs\r
2591 //\r
07cdba18
JY
2592 Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePCRBanks);\r
2593 ASSERT_EFI_ERROR (Status);\r
2594\r
1abfa4ce
JY
2595 mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
2596 mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
2597\r
a3cad6f8
JY
2598 //\r
2599 // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.\r
2600 //\r
2601 NumberOfPCRBanks = 0;\r
2602 for (Index = 0; Index < 32; Index++) {\r
2603 if ((mTcgDxeData.BsCap.HashAlgorithmBitmap & (1u << Index)) != 0) {\r
2604 NumberOfPCRBanks++;\r
2605 }\r
2606 }\r
2607\r
1abfa4ce
JY
2608 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) {\r
2609 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
2610 } else {\r
2611 mTcgDxeData.BsCap.NumberOfPCRBanks = PcdGet32 (PcdTcg2NumberOfPCRBanks);\r
2612 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) > NumberOfPCRBanks) {\r
2613 DEBUG ((EFI_D_ERROR, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks), NumberOfPCRBanks));\r
2614 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
2615 }\r
2616 }\r
2617\r
2618 mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;\r
87361c6a 2619 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) == 0) {\r
1abfa4ce
JY
2620 //\r
2621 // No need to expose TCG1.2 event log if SHA1 bank does not exist.\r
2622 //\r
87361c6a 2623 mTcgDxeData.BsCap.SupportedEventLogs &= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;\r
1abfa4ce
JY
2624 }\r
2625\r
2626 DEBUG ((EFI_D_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
2627 DEBUG ((EFI_D_INFO, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));\r
2628 DEBUG ((EFI_D_INFO, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData.BsCap.NumberOfPCRBanks));\r
2629 DEBUG ((EFI_D_INFO, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData.BsCap.ActivePcrBanks));\r
2630\r
2631 if (mTcgDxeData.BsCap.TPMPresentFlag) {\r
2632 //\r
2633 // Setup the log area and copy event log from hob list to it\r
2634 //\r
2635 Status = SetupEventLog ();\r
2636 ASSERT_EFI_ERROR (Status);\r
2637\r
2638 //\r
2639 // Measure handoff tables, Boot#### variables etc.\r
2640 //\r
2641 Status = EfiCreateEventReadyToBootEx (\r
2642 TPL_CALLBACK,\r
2643 OnReadyToBoot,\r
2644 NULL,\r
2645 &Event\r
2646 );\r
2647\r
2648 Status = gBS->CreateEventEx (\r
2649 EVT_NOTIFY_SIGNAL,\r
2650 TPL_NOTIFY,\r
2651 OnExitBootServices,\r
2652 NULL,\r
2653 &gEfiEventExitBootServicesGuid,\r
2654 &Event\r
2655 );\r
2656\r
2657 //\r
b3548d32 2658 // Measure Exit Boot Service failed\r
1abfa4ce
JY
2659 //\r
2660 Status = gBS->CreateEventEx (\r
2661 EVT_NOTIFY_SIGNAL,\r
2662 TPL_NOTIFY,\r
2663 OnExitBootServicesFailed,\r
2664 NULL,\r
2665 &gEventExitBootServicesFailedGuid,\r
2666 &Event\r
2667 );\r
2668\r
2669 //\r
2670 // Create event callback, because we need access variable on SecureBootPolicyVariable\r
2671 // We should use VariableWriteArch instead of VariableArch, because Variable driver\r
2672 // may update SecureBoot value based on last setting.\r
2673 //\r
2674 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
9d5dfe9d
RN
2675\r
2676 //\r
2677 // Hook the system reset to properly shutdown TPM.\r
2678 //\r
2679 EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);\r
1abfa4ce
JY
2680 }\r
2681\r
2682 //\r
2683 // Install Tcg2Protocol\r
2684 //\r
2685 Status = InstallTcg2 ();\r
2686 DEBUG ((EFI_D_INFO, "InstallTcg2 - %r\n", Status));\r
2687\r
2688 return Status;\r
2689}\r