1/** @file
2  This library is used by other modules to measure data to TPM.
3
4Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved. <BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution.  The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT 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**/
46EFI_STATUS
47Tpm12MeasureAndLogData (
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**/
112EFI_STATUS
113Tpm20MeasureAndLogData (
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**/
173EFI_STATUS
174EFIAPI
175TpmMeasureAndLogData (
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