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