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