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