1 /** @file
2   This library is used by other modules to measure data to TPM.
3 
4 Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved. <BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include <PiDxe.h>
16 
17 #include <Protocol/TcgService.h>
18 #include <Protocol/Tcg2Protocol.h>
19 
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/MemoryAllocationLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/TpmMeasurementLib.h>
25 
26 #include <Guid/Acpi.h>
27 #include <IndustryStandard/Acpi.h>
28 
29 
30 
31 /**
32   Tpm12 measure and log data, and extend the measurement result into a specific PCR.
33 
34   @param[in]  PcrIndex         PCR Index.
35   @param[in]  EventType        Event type.
36   @param[in]  EventLog         Measurement event log.
37   @param[in]  LogLen           Event log length in bytes.
38   @param[in]  HashData         The start of the data buffer to be hashed, extended.
39   @param[in]  HashDataLen      The length, in bytes, of the buffer referenced by HashData
40 
41   @retval EFI_SUCCESS           Operation completed successfully.
42   @retval EFI_UNSUPPORTED       TPM device not available.
43   @retval EFI_OUT_OF_RESOURCES  Out of memory.
44   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
45 **/
46 EFI_STATUS
Tpm12MeasureAndLogData(IN UINT32 PcrIndex,IN UINT32 EventType,IN VOID * EventLog,IN UINT32 LogLen,IN VOID * HashData,IN UINT64 HashDataLen)47 Tpm12MeasureAndLogData (
48   IN UINT32             PcrIndex,
49   IN UINT32             EventType,
50   IN VOID               *EventLog,
51   IN UINT32             LogLen,
52   IN VOID               *HashData,
53   IN UINT64             HashDataLen
54   )
55 {
56   EFI_STATUS                Status;
57   EFI_TCG_PROTOCOL          *TcgProtocol;
58   TCG_PCR_EVENT             *TcgEvent;
59   EFI_PHYSICAL_ADDRESS      EventLogLastEntry;
60   UINT32                    EventNumber;
61 
62   TcgEvent = NULL;
63 
64   //
65   // Tpm active/deactive state is checked in HashLogExtendEvent
66   //
67   Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);
68   if (EFI_ERROR(Status)){
69     return Status;
70   }
71 
72   TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (sizeof (TCG_PCR_EVENT_HDR) + LogLen);
73   if(TcgEvent == NULL) {
74     return EFI_OUT_OF_RESOURCES;
75   }
76 
77   TcgEvent->PCRIndex  = PcrIndex;
78   TcgEvent->EventType = EventType;
79   TcgEvent->EventSize = LogLen;
80   CopyMem (&TcgEvent->Event[0], EventLog, LogLen);
81   EventNumber = 1;
82   Status = TcgProtocol->HashLogExtendEvent (
83                           TcgProtocol,
84                           (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
85                           HashDataLen,
86                           TPM_ALG_SHA,
87                           TcgEvent,
88                           &EventNumber,
89                           &EventLogLastEntry
90                           );
91 
92   FreePool (TcgEvent);
93 
94   return Status;
95 }
96 
97 /**
98   Tpm20 measure and log data, and extend the measurement result into a specific PCR.
99 
100   @param[in]  PcrIndex         PCR Index.
101   @param[in]  EventType        Event type.
102   @param[in]  EventLog         Measurement event log.
103   @param[in]  LogLen           Event log length in bytes.
104   @param[in]  HashData         The start of the data buffer to be hashed, extended.
105   @param[in]  HashDataLen      The length, in bytes, of the buffer referenced by HashData
106 
107   @retval EFI_SUCCESS           Operation completed successfully.
108   @retval EFI_UNSUPPORTED       TPM device not available.
109   @retval EFI_OUT_OF_RESOURCES  Out of memory.
110   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
111 **/
112 EFI_STATUS
Tpm20MeasureAndLogData(IN UINT32 PcrIndex,IN UINT32 EventType,IN VOID * EventLog,IN UINT32 LogLen,IN VOID * HashData,IN UINT64 HashDataLen)113 Tpm20MeasureAndLogData (
114   IN UINT32             PcrIndex,
115   IN UINT32             EventType,
116   IN VOID               *EventLog,
117   IN UINT32             LogLen,
118   IN VOID               *HashData,
119   IN UINT64             HashDataLen
120   )
121 {
122   EFI_STATUS                Status;
123   EFI_TCG2_PROTOCOL         *Tcg2Protocol;
124   EFI_TCG2_EVENT            *Tcg2Event;
125 
126   //
127   // TPMPresentFlag is checked in HashLogExtendEvent
128   //
129   Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);
130   if (EFI_ERROR (Status)) {
131     return Status;
132   }
133 
134   Tcg2Event = (EFI_TCG2_EVENT *) AllocateZeroPool (LogLen + sizeof (EFI_TCG2_EVENT));
135   if(Tcg2Event == NULL) {
136     return EFI_OUT_OF_RESOURCES;
137   }
138 
139   Tcg2Event->Size = (UINT32)LogLen + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event);
140   Tcg2Event->Header.HeaderSize    = sizeof(EFI_TCG2_EVENT_HEADER);
141   Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
142   Tcg2Event->Header.PCRIndex      = PcrIndex;
143   Tcg2Event->Header.EventType     = EventType;
144   CopyMem (&Tcg2Event->Event[0], EventLog, LogLen);
145 
146   Status = Tcg2Protocol->HashLogExtendEvent (
147                            Tcg2Protocol,
148                            0,
149                            (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
150                            HashDataLen,
151                            Tcg2Event
152                            );
153   FreePool (Tcg2Event);
154 
155   return Status;
156 }
157 
158 /**
159   Tpm measure and log data, and extend the measurement result into a specific PCR.
160 
161   @param[in]  PcrIndex         PCR Index.
162   @param[in]  EventType        Event type.
163   @param[in]  EventLog         Measurement event log.
164   @param[in]  LogLen           Event log length in bytes.
165   @param[in]  HashData         The start of the data buffer to be hashed, extended.
166   @param[in]  HashDataLen      The length, in bytes, of the buffer referenced by HashData
167 
168   @retval EFI_SUCCESS               Operation completed successfully.
169   @retval EFI_UNSUPPORTED       TPM device not available.
170   @retval EFI_OUT_OF_RESOURCES  Out of memory.
171   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
172 **/
173 EFI_STATUS
174 EFIAPI
TpmMeasureAndLogData(IN UINT32 PcrIndex,IN UINT32 EventType,IN VOID * EventLog,IN UINT32 LogLen,IN VOID * HashData,IN UINT64 HashDataLen)175 TpmMeasureAndLogData (
176   IN UINT32             PcrIndex,
177   IN UINT32             EventType,
178   IN VOID               *EventLog,
179   IN UINT32             LogLen,
180   IN VOID               *HashData,
181   IN UINT64             HashDataLen
182   )
183 {
184   EFI_STATUS  Status;
185 
186   //
187   // Try to measure using Tpm1.2 protocol
188   //
189   Status = Tpm12MeasureAndLogData(
190                PcrIndex,
191                EventType,
192                EventLog,
193                LogLen,
194                HashData,
195                HashDataLen
196                );
197   if (EFI_ERROR (Status)) {
198     //
199     // Try to measure using Tpm20 protocol
200     //
201     Status = Tpm20MeasureAndLogData(
202                PcrIndex,
203                EventType,
204                EventLog,
205                LogLen,
206                HashData,
207                HashDataLen
208                );
209   }
210 
211   return Status;
212 }
213