1 /** @file
2   Utility functions used by TPM Dxe driver.
3 
4 Copyright (c) 2005 - 2013, 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 <IndustryStandard/Tpm12.h>
16 #include <IndustryStandard/UefiTcgPlatform.h>
17 #include <Library/TpmCommLib.h>
18 #include <Library/BaseMemoryLib.h>
19 
20 #include "TpmComm.h"
21 
22 /**
23   Extend a TPM PCR.
24 
25   @param[in]  TpmHandle       TPM handle.
26   @param[in]  DigestToExtend  The 160 bit value representing the event to be recorded.
27   @param[in]  PcrIndex        The PCR to be updated.
28   @param[out] NewPcrValue     New PCR value after extend.
29 
30   @retval EFI_SUCCESS         Operation completed successfully.
31   @retval EFI_DEVICE_ERROR    The command was unsuccessful.
32 
33 **/
34 EFI_STATUS
TpmCommExtend(IN TIS_TPM_HANDLE TpmHandle,IN TPM_DIGEST * DigestToExtend,IN TPM_PCRINDEX PcrIndex,OUT TPM_DIGEST * NewPcrValue)35 TpmCommExtend (
36   IN      TIS_TPM_HANDLE            TpmHandle,
37   IN      TPM_DIGEST                *DigestToExtend,
38   IN      TPM_PCRINDEX              PcrIndex,
39      OUT  TPM_DIGEST                *NewPcrValue
40   )
41 {
42   EFI_STATUS                        Status;
43   TPM_DIGEST                        NewValue;
44   TPM_RQU_COMMAND_HDR               CmdHdr;
45   TPM_RSP_COMMAND_HDR               RspHdr;
46 
47   if (NewPcrValue == NULL) {
48     NewPcrValue = &NewValue;
49   }
50 
51   CmdHdr.tag = TPM_TAG_RQU_COMMAND;
52   CmdHdr.paramSize =
53     sizeof (CmdHdr) + sizeof (PcrIndex) + sizeof (*DigestToExtend);
54   CmdHdr.ordinal = TPM_ORD_Extend;
55   Status = TisPcExecute (
56              TpmHandle,
57              "%h%d%r%/%h%r",
58              &CmdHdr,
59              PcrIndex,
60              DigestToExtend,
61              (UINTN)sizeof (*DigestToExtend),
62              &RspHdr,
63              NewPcrValue,
64              (UINTN)sizeof (*NewPcrValue)
65              );
66   if (EFI_ERROR (Status)) {
67     return Status;
68   }
69   if (RspHdr.returnCode != 0) {
70     return EFI_DEVICE_ERROR;
71   }
72   return EFI_SUCCESS;
73 }
74 
75 /**
76   Get TPM capability flags.
77 
78   @param[in]  TpmHandle    TPM handle.
79   @param[in]  FlagSubcap   Flag subcap.
80   @param[out] FlagBuffer   Pointer to the buffer for returned flag structure.
81   @param[in]  FlagSize     Size of the buffer.
82 
83   @retval EFI_SUCCESS      Operation completed successfully.
84   @retval EFI_DEVICE_ERROR The command was unsuccessful.
85 
86 **/
87 EFI_STATUS
TpmCommGetFlags(IN TIS_TPM_HANDLE TpmHandle,IN UINT32 FlagSubcap,OUT VOID * FlagBuffer,IN UINTN FlagSize)88 TpmCommGetFlags (
89   IN      TIS_TPM_HANDLE            TpmHandle,
90   IN      UINT32                    FlagSubcap,
91      OUT  VOID                      *FlagBuffer,
92   IN      UINTN                     FlagSize
93   )
94 {
95   EFI_STATUS                        Status;
96   TPM_RQU_COMMAND_HDR               CmdHdr;
97   TPM_RSP_COMMAND_HDR               RspHdr;
98   UINT32                            Size;
99 
100   CmdHdr.tag = TPM_TAG_RQU_COMMAND;
101   CmdHdr.paramSize = sizeof (CmdHdr) + sizeof (UINT32) * 3;
102   CmdHdr.ordinal = TPM_ORD_GetCapability;
103 
104   Status = TisPcExecute (
105              TpmHandle,
106              "%h%d%d%d%/%h%d%r",
107              &CmdHdr,
108              TPM_CAP_FLAG,
109              sizeof (FlagSubcap),
110              FlagSubcap,
111              &RspHdr,
112              &Size,
113              FlagBuffer,
114              FlagSize
115              );
116   if (EFI_ERROR (Status)) {
117     return Status;
118   }
119   if (RspHdr.returnCode != 0) {
120     return EFI_DEVICE_ERROR;
121   }
122   return EFI_SUCCESS;
123 }
124 
125 /**
126   Add a new entry to the Event Log.
127 
128   @param[in, out] EventLogPtr   Pointer to the Event Log data.
129   @param[in, out] LogSize       Size of the Event Log.
130   @param[in]      MaxSize       Maximum size of the Event Log.
131   @param[in]      NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.
132   @param[in]      NewEventData  Pointer to the new event data.
133 
134   @retval EFI_SUCCESS           The new event log entry was added.
135   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.
136 
137 **/
138 EFI_STATUS
TpmCommLogEvent(IN OUT UINT8 ** EventLogPtr,IN OUT UINTN * LogSize,IN UINTN MaxSize,IN TCG_PCR_EVENT_HDR * NewEventHdr,IN UINT8 * NewEventData)139 TpmCommLogEvent (
140   IN OUT  UINT8                     **EventLogPtr,
141   IN OUT  UINTN                     *LogSize,
142   IN      UINTN                     MaxSize,
143   IN      TCG_PCR_EVENT_HDR         *NewEventHdr,
144   IN      UINT8                     *NewEventData
145   )
146 {
147   UINTN                            NewLogSize;
148 
149   //
150   // Prevent Event Overflow
151   //
152   if (NewEventHdr->EventSize > (UINTN)(~0) - sizeof (*NewEventHdr)) {
153     return EFI_OUT_OF_RESOURCES;
154   }
155 
156   NewLogSize = sizeof (*NewEventHdr) + NewEventHdr->EventSize;
157   if (NewLogSize > MaxSize - *LogSize) {
158     return EFI_OUT_OF_RESOURCES;
159   }
160 
161   *EventLogPtr += *LogSize;
162   *LogSize += NewLogSize;
163   CopyMem (*EventLogPtr, NewEventHdr, sizeof (*NewEventHdr));
164   CopyMem (
165     *EventLogPtr + sizeof (*NewEventHdr),
166     NewEventData,
167     NewEventHdr->EventSize
168     );
169   return EFI_SUCCESS;
170 }
171