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