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