• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Utility functions used by TPM PEI driver.
3 
4 Copyright (c) 2005 - 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 "TpmComm.h"
16 
17 /**
18   Send a command to TPM for execution and return response data.
19 
20   @param[in]      PeiServices   Describes the list of possible PEI Services.
21   @param[in]      TisReg        TPM register space base address.
22   @param[in]      BufferIn      Buffer for command data.
23   @param[in]      SizeIn        Size of command data.
24   @param[in, out] BufferOut     Buffer for response data.
25   @param[in, out] SizeOut       size of response data.
26 
27   @retval EFI_SUCCESS           Operation completed successfully.
28   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
29   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
30   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
31 
32 **/
33 EFI_STATUS
34 TisTpmCommand (
35   IN     EFI_PEI_SERVICES           **PeiServices,
36   IN     TIS_PC_REGISTERS_PTR       TisReg,
37   IN     UINT8                      *BufferIn,
38   IN     UINT32                     SizeIn,
39   IN OUT UINT8                      *BufferOut,
40   IN OUT UINT32                     *SizeOut
41   );
42 
43 /**
44   Send TPM_Startup command to TPM.
45 
46   @param[in] PeiServices        Describes the list of possible PEI Services.
47   @param[in] TpmHandle          TPM handle.
48   @param[in] BootMode           Boot mode.
49 
50   @retval EFI_SUCCESS           Operation completed successfully.
51   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
52   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
53   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
54 
55 **/
56 EFI_STATUS
TpmCommStartup(IN EFI_PEI_SERVICES ** PeiServices,IN TIS_TPM_HANDLE TpmHandle,IN EFI_BOOT_MODE BootMode)57 TpmCommStartup (
58   IN      EFI_PEI_SERVICES          **PeiServices,
59   IN      TIS_TPM_HANDLE            TpmHandle,
60   IN      EFI_BOOT_MODE             BootMode
61   )
62 {
63   EFI_STATUS                        Status;
64   TPM_STARTUP_TYPE                  TpmSt;
65   UINT32                            TpmRecvSize;
66   UINT32                            TpmSendSize;
67   TPM_CMD_START_UP                  SendBuffer;
68   UINT8                             RecvBuffer[20];
69 
70   TpmSt = TPM_ST_CLEAR;
71   if (BootMode == BOOT_ON_S3_RESUME) {
72     TpmSt = TPM_ST_STATE;
73   }
74   //
75   // send Tpm command TPM_ORD_Startup
76   //
77   TpmRecvSize               = 20;
78   TpmSendSize               = sizeof (TPM_CMD_START_UP);
79   SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
80   SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
81   SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_Startup);
82   SendBuffer.TpmSt          = SwapBytes16 (TpmSt);
83   Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
84   return Status;
85 }
86 
87 /**
88   Send TPM_ContinueSelfTest command to TPM.
89 
90   @param[in] PeiServices        Describes the list of possible PEI Services.
91   @param[in] TpmHandle          TPM handle.
92 
93   @retval EFI_SUCCESS           Operation completed successfully.
94   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
95   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
96   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
97 
98 **/
99 EFI_STATUS
TpmCommContinueSelfTest(IN EFI_PEI_SERVICES ** PeiServices,IN TIS_TPM_HANDLE TpmHandle)100 TpmCommContinueSelfTest (
101   IN      EFI_PEI_SERVICES          **PeiServices,
102   IN      TIS_TPM_HANDLE            TpmHandle
103   )
104 {
105   EFI_STATUS                        Status;
106   UINT32                            TpmRecvSize;
107   UINT32                            TpmSendSize;
108   TPM_CMD_SELF_TEST                 SendBuffer;
109   UINT8                             RecvBuffer[20];
110 
111   //
112   // send Tpm command TPM_ORD_ContinueSelfTest
113   //
114   TpmRecvSize               = 20;
115   TpmSendSize               = sizeof (TPM_CMD_SELF_TEST);
116   SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
117   SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
118   SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_ContinueSelfTest);
119   Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
120   return Status;
121 }
122 
123 /**
124   Get TPM capability flags.
125 
126   @param[in]  PeiServices       Describes the list of possible PEI Services.
127   @param[in]  TpmHandle         TPM handle.
128   @param[out] Deactivated       Returns deactivated flag.
129   @param[out] LifetimeLock      Returns physicalPresenceLifetimeLock permanent flag.
130   @param[out] CmdEnable         Returns physicalPresenceCMDEnable permanent flag.
131 
132   @retval EFI_SUCCESS           Operation completed successfully.
133   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
134   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
135   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
136 
137 **/
138 EFI_STATUS
TpmCommGetCapability(IN EFI_PEI_SERVICES ** PeiServices,IN TIS_TPM_HANDLE TpmHandle,OUT BOOLEAN * Deactivated,OPTIONAL OUT BOOLEAN * LifetimeLock,OPTIONAL OUT BOOLEAN * CmdEnable OPTIONAL)139 TpmCommGetCapability (
140   IN      EFI_PEI_SERVICES          **PeiServices,
141   IN      TIS_TPM_HANDLE            TpmHandle,
142      OUT  BOOLEAN                   *Deactivated, OPTIONAL
143      OUT  BOOLEAN                   *LifetimeLock, OPTIONAL
144      OUT  BOOLEAN                   *CmdEnable OPTIONAL
145   )
146 {
147   EFI_STATUS                        Status;
148   UINT32                            TpmRecvSize;
149   UINT32                            TpmSendSize;
150   TPM_CMD_GET_CAPABILITY            SendBuffer;
151   UINT8                             RecvBuffer[40];
152   TPM_PERMANENT_FLAGS               *TpmPermanentFlags;
153 
154   //
155   // send Tpm command TPM_ORD_GetCapability
156   //
157   TpmRecvSize                   = 40;
158   TpmSendSize                   = sizeof (TPM_CMD_GET_CAPABILITY);
159   SendBuffer.Hdr.tag            = SwapBytes16 (TPM_TAG_RQU_COMMAND);
160   SendBuffer.Hdr.paramSize      = SwapBytes32 (TpmSendSize);
161   SendBuffer.Hdr.ordinal        = SwapBytes32 (TPM_ORD_GetCapability);
162   SendBuffer.Capability         = SwapBytes32 (TPM_CAP_FLAG);
163   SendBuffer.CapabilityFlagSize = SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT));
164   SendBuffer.CapabilityFlag     = SwapBytes32 (TPM_CAP_FLAG_PERMANENT);
165   Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
166   if (EFI_ERROR (Status)) {
167     return Status;
168   }
169   TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];
170   if (Deactivated != NULL) {
171     *Deactivated      = TpmPermanentFlags->deactivated;
172   }
173 
174   if (LifetimeLock != NULL) {
175     *LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock;
176   }
177 
178   if (CmdEnable != NULL) {
179     *CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable;
180   }
181   return Status;
182 }
183 
184 /**
185   Extend a TPM PCR.
186 
187   @param[in]  PeiServices       Describes the list of possible PEI Services.
188   @param[in]  TpmHandle         TPM handle.
189   @param[in]  DigestToExtend    The 160 bit value representing the event to be recorded.
190   @param[in]  PcrIndex          The PCR to be updated.
191   @param[out] NewPcrValue       New PCR value after extend.
192 
193   @retval EFI_SUCCESS           Operation completed successfully.
194   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
195   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
196   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
197 
198 **/
199 EFI_STATUS
TpmCommExtend(IN EFI_PEI_SERVICES ** PeiServices,IN TIS_TPM_HANDLE TpmHandle,IN TPM_DIGEST * DigestToExtend,IN TPM_PCRINDEX PcrIndex,OUT TPM_DIGEST * NewPcrValue)200 TpmCommExtend (
201   IN      EFI_PEI_SERVICES          **PeiServices,
202   IN      TIS_TPM_HANDLE            TpmHandle,
203   IN      TPM_DIGEST                *DigestToExtend,
204   IN      TPM_PCRINDEX              PcrIndex,
205      OUT  TPM_DIGEST                *NewPcrValue
206   )
207 {
208   EFI_STATUS                        Status;
209   UINT32                            TpmSendSize;
210   UINT32                            TpmRecvSize;
211   TPM_CMD_EXTEND                    SendBuffer;
212   UINT8                             RecvBuffer[10 + sizeof(TPM_DIGEST)];
213 
214   //
215   // send Tpm command TPM_ORD_Extend
216   //
217   TpmRecvSize               = sizeof (TPM_RSP_COMMAND_HDR) + sizeof (TPM_DIGEST);
218   TpmSendSize               = sizeof (TPM_CMD_EXTEND);
219   SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
220   SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
221   SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_Extend);
222   SendBuffer.PcrIndex       = SwapBytes32 (PcrIndex);
223   CopyMem (&SendBuffer.TpmDigest, (UINT8 *)DigestToExtend, sizeof (TPM_DIGEST));
224   Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
225   if (EFI_ERROR (Status)) {
226     return Status;
227   }
228 
229   if(NewPcrValue != NULL) {
230     CopyMem ((UINT8*)NewPcrValue, &RecvBuffer[10], sizeof (TPM_DIGEST));
231   }
232 
233   return Status;
234 }
235 
236 
237 /**
238   Send TSC_PhysicalPresence command to TPM.
239 
240   @param[in] PeiServices        Describes the list of possible PEI Services.
241   @param[in] TpmHandle          TPM handle.
242   @param[in] PhysicalPresence   The state to set the TPMs Physical Presence flags.
243 
244   @retval EFI_SUCCESS           Operation completed successfully.
245   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
246   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
247   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
248 
249 **/
250 EFI_STATUS
TpmCommPhysicalPresence(IN EFI_PEI_SERVICES ** PeiServices,IN TIS_TPM_HANDLE TpmHandle,IN TPM_PHYSICAL_PRESENCE PhysicalPresence)251 TpmCommPhysicalPresence (
252   IN      EFI_PEI_SERVICES          **PeiServices,
253   IN      TIS_TPM_HANDLE            TpmHandle,
254   IN      TPM_PHYSICAL_PRESENCE     PhysicalPresence
255   )
256 {
257   EFI_STATUS                        Status;
258   UINT32                            TpmSendSize;
259   UINT32                            TpmRecvSize;
260   TPM_CMD_PHYSICAL_PRESENCE         SendBuffer;
261   UINT8                             RecvBuffer[10];
262 
263   //
264   // send Tpm command TSC_ORD_PhysicalPresence
265   //
266   TpmRecvSize                 = 10;
267   TpmSendSize                 = sizeof (TPM_CMD_PHYSICAL_PRESENCE);
268   SendBuffer.Hdr.tag          = SwapBytes16 (TPM_TAG_RQU_COMMAND);
269   SendBuffer.Hdr.paramSize    = SwapBytes32 (TpmSendSize);
270   SendBuffer.Hdr.ordinal      = SwapBytes32 (TSC_ORD_PhysicalPresence);
271   SendBuffer.PhysicalPresence = SwapBytes16 (PhysicalPresence);
272   Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
273   return Status;
274 }
275