]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/TcgPei/TpmComm.c
fb5011ee9d8b406bf87084d1af999ae78932d520
[mirror_edk2.git] / SecurityPkg / Tcg / TcgPei / TpmComm.c
1 /** @file
2 Utility functions used by TPM PEI driver.
3
4 Copyright (c) 2005 - 2011, 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
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
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
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
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 ASSERT_EFI_ERROR (Status);
226
227 if(NewPcrValue != NULL) {
228 CopyMem ((UINT8*)NewPcrValue, &RecvBuffer[10], sizeof (TPM_DIGEST));
229 }
230
231 return Status;
232 }
233
234
235 /**
236 Send TSC_PhysicalPresence command to TPM.
237
238 @param[in] PeiServices Describes the list of possible PEI Services.
239 @param[in] TpmHandle TPM handle.
240 @param[in] PhysicalPresence The state to set the TPMs Physical Presence flags.
241
242 @retval EFI_SUCCESS Operation completed successfully.
243 @retval EFI_TIMEOUT The register can't run into the expected status in time.
244 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
245 @retval EFI_DEVICE_ERROR Unexpected device behavior.
246
247 **/
248 EFI_STATUS
249 TpmCommPhysicalPresence (
250 IN EFI_PEI_SERVICES **PeiServices,
251 IN TIS_TPM_HANDLE TpmHandle,
252 IN TPM_PHYSICAL_PRESENCE PhysicalPresence
253 )
254 {
255 EFI_STATUS Status;
256 UINT32 TpmSendSize;
257 UINT32 TpmRecvSize;
258 TPM_CMD_PHYSICAL_PRESENCE SendBuffer;
259 UINT8 RecvBuffer[10];
260
261 //
262 // send Tpm command TSC_ORD_PhysicalPresence
263 //
264 TpmRecvSize = 10;
265 TpmSendSize = sizeof (TPM_CMD_PHYSICAL_PRESENCE);
266 SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
267 SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
268 SendBuffer.Hdr.ordinal = SwapBytes32 (TSC_ORD_PhysicalPresence);
269 SendBuffer.PhysicalPresence = SwapBytes16 (PhysicalPresence);
270 Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
271 return Status;
272 }