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