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