]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c
Add TPM2 commands which might be used in field upgrade.
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2EnhancedAuthorization.c
CommitLineData
967eacca
JY
1/** @file\r
2 Implement TPM2 EnhancedAuthorization related command.\r
3\r
4Copyright (c) 2014, Intel Corporation. All rights reserved. <BR>\r
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 <IndustryStandard/UefiTcgPlatform.h>\r
16#include <Library/Tpm2CommandLib.h>\r
17#include <Library/Tpm2DeviceLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/BaseLib.h>\r
20#include <Library/DebugLib.h>\r
21\r
22#pragma pack(1)\r
23\r
24typedef struct {\r
25 TPM2_COMMAND_HEADER Header;\r
26 TPMI_DH_ENTITY AuthHandle;\r
27 TPMI_SH_POLICY PolicySession;\r
28 UINT32 AuthSessionSize;\r
29 TPMS_AUTH_COMMAND AuthSession;\r
30 TPM2B_NONCE NonceTPM;\r
31 TPM2B_DIGEST CpHashA;\r
32 TPM2B_NONCE PolicyRef;\r
33 INT32 Expiration;\r
34} TPM2_POLICY_SECRET_COMMAND;\r
35\r
36typedef struct {\r
37 TPM2_RESPONSE_HEADER Header;\r
38 UINT32 AuthSessionSize;\r
39 TPM2B_TIMEOUT Timeout;\r
40 TPMT_TK_AUTH PolicyTicket;\r
41 TPMS_AUTH_RESPONSE AuthSession;\r
42} TPM2_POLICY_SECRET_RESPONSE;\r
43\r
44typedef struct {\r
45 TPM2_COMMAND_HEADER Header;\r
46 TPMI_SH_POLICY PolicySession;\r
47 TPM_CC Code;\r
48} TPM2_POLICY_COMMAND_CODE_COMMAND;\r
49\r
50typedef struct {\r
51 TPM2_RESPONSE_HEADER Header;\r
52} TPM2_POLICY_COMMAND_CODE_RESPONSE;\r
53\r
54typedef struct {\r
55 TPM2_COMMAND_HEADER Header;\r
56 TPMI_SH_POLICY PolicySession;\r
57} TPM2_POLICY_GET_DIGEST_COMMAND;\r
58\r
59typedef struct {\r
60 TPM2_RESPONSE_HEADER Header;\r
61 TPM2B_DIGEST PolicyHash;\r
62} TPM2_POLICY_GET_DIGEST_RESPONSE;\r
63\r
64#pragma pack()\r
65\r
66/**\r
67 This command includes a secret-based authorization to a policy.\r
68 The caller proves knowledge of the secret value using an authorization\r
69 session using the authValue associated with authHandle.\r
70\r
71 @param[in] AuthHandle Handle for an entity providing the authorization\r
72 @param[in] PolicySession Handle for the policy session being extended.\r
73 @param[in] AuthSession Auth Session context\r
74 @param[in] NonceTPM The policy nonce for the session.\r
75 @param[in] CpHashA Digest of the command parameters to which this authorization is limited.\r
76 @param[in] PolicyRef A reference to a policy relating to the authorization.\r
77 @param[in] Expiration Time when authorization will expire, measured in seconds from the time that nonceTPM was generated.\r
78 @param[out] Timeout Time value used to indicate to the TPM when the ticket expires.\r
79 @param[out] PolicyTicket A ticket that includes a value indicating when the authorization expires.\r
80 \r
81 @retval EFI_SUCCESS Operation completed successfully.\r
82 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
83**/\r
84EFI_STATUS\r
85EFIAPI\r
86Tpm2PolicySecret (\r
87 IN TPMI_DH_ENTITY AuthHandle,\r
88 IN TPMI_SH_POLICY PolicySession,\r
89 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL\r
90 IN TPM2B_NONCE *NonceTPM,\r
91 IN TPM2B_DIGEST *CpHashA,\r
92 IN TPM2B_NONCE *PolicyRef,\r
93 IN INT32 Expiration,\r
94 OUT TPM2B_TIMEOUT *Timeout,\r
95 OUT TPMT_TK_AUTH *PolicyTicket\r
96 )\r
97{\r
98 EFI_STATUS Status;\r
99 TPM2_POLICY_SECRET_COMMAND SendBuffer;\r
100 TPM2_POLICY_SECRET_RESPONSE RecvBuffer;\r
101 UINT32 SendBufferSize;\r
102 UINT32 RecvBufferSize;\r
103 UINT8 *Buffer;\r
104 UINT32 SessionInfoSize;\r
105\r
106 //\r
107 // Construct command\r
108 //\r
109 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
110 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicySecret);\r
111 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);\r
112 SendBuffer.PolicySession = SwapBytes32 (PolicySession);\r
113 \r
114 //\r
115 // Add in Auth session\r
116 //\r
117 Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
118\r
119 // sessionInfoSize\r
120 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
121 Buffer += SessionInfoSize;\r
122 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
123\r
124 //\r
125 // Real data\r
126 //\r
127 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NonceTPM->size));\r
128 Buffer += sizeof(UINT16);\r
129 CopyMem (Buffer, NonceTPM->buffer, NonceTPM->size);\r
130 Buffer += NonceTPM->size;\r
131\r
132 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(CpHashA->size));\r
133 Buffer += sizeof(UINT16);\r
134 CopyMem (Buffer, CpHashA->buffer, CpHashA->size);\r
135 Buffer += CpHashA->size;\r
136\r
137 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PolicyRef->size));\r
138 Buffer += sizeof(UINT16);\r
139 CopyMem (Buffer, PolicyRef->buffer, PolicyRef->size);\r
140 Buffer += PolicyRef->size;\r
141 \r
142 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32((UINT32)Expiration));\r
143 Buffer += sizeof(UINT32);\r
144\r
145 SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);\r
146 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
147\r
148 //\r
149 // send Tpm command\r
150 //\r
151 RecvBufferSize = sizeof (RecvBuffer);\r
152 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
153 if (EFI_ERROR (Status)) {\r
154 return Status;\r
155 }\r
156\r
157 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
158 DEBUG ((EFI_D_ERROR, "Tpm2PolicySecret - RecvBufferSize Error - %x\n", RecvBufferSize));\r
159 return EFI_DEVICE_ERROR;\r
160 }\r
161 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
162 DEBUG ((EFI_D_ERROR, "Tpm2PolicySecret - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
163 return EFI_DEVICE_ERROR;\r
164 }\r
165\r
166 //\r
167 // Return the response\r
168 //\r
169 Buffer = (UINT8 *)&RecvBuffer.Timeout;\r
170 Timeout->size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));\r
171 Buffer += sizeof(UINT16);\r
172 CopyMem (Timeout->buffer, Buffer, Timeout->size);\r
173\r
174 PolicyTicket->tag = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));\r
175 Buffer += sizeof(UINT16);\r
176 PolicyTicket->hierarchy = SwapBytes32(ReadUnaligned32 ((UINT32 *)Buffer));\r
177 Buffer += sizeof(UINT32);\r
178 PolicyTicket->digest.size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));\r
179 Buffer += sizeof(UINT16);\r
180 CopyMem (PolicyTicket->digest.buffer, Buffer, PolicyTicket->digest.size);\r
181\r
182 return EFI_SUCCESS;\r
183}\r
184\r
185/**\r
186 This command indicates that the authorization will be limited to a specific command code.\r
187\r
188 @param[in] PolicySession Handle for the policy session being extended.\r
189 @param[in] Code The allowed commandCode.\r
190 \r
191 @retval EFI_SUCCESS Operation completed successfully.\r
192 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
193**/\r
194EFI_STATUS\r
195EFIAPI\r
196Tpm2PolicyCommandCode (\r
197 IN TPMI_SH_POLICY PolicySession,\r
198 IN TPM_CC Code\r
199 )\r
200{\r
201 EFI_STATUS Status;\r
202 TPM2_POLICY_COMMAND_CODE_COMMAND SendBuffer;\r
203 TPM2_POLICY_COMMAND_CODE_RESPONSE RecvBuffer;\r
204 UINT32 SendBufferSize;\r
205 UINT32 RecvBufferSize;\r
206\r
207 //\r
208 // Construct command\r
209 //\r
210 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
211 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyCommandCode);\r
212\r
213 SendBuffer.PolicySession = SwapBytes32 (PolicySession);\r
214 SendBuffer.Code = SwapBytes32 (Code);\r
215\r
216 SendBufferSize = (UINT32) sizeof (SendBuffer);\r
217 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
218\r
219 //\r
220 // send Tpm command\r
221 //\r
222 RecvBufferSize = sizeof (RecvBuffer);\r
223 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
224 if (EFI_ERROR (Status)) {\r
225 return Status;\r
226 }\r
227\r
228 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
229 DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - RecvBufferSize Error - %x\n", RecvBufferSize));\r
230 return EFI_DEVICE_ERROR;\r
231 }\r
232 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
233 DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
234 return EFI_DEVICE_ERROR;\r
235 }\r
236\r
237 return EFI_SUCCESS;\r
238}\r
239\r
240/**\r
241 This command returns the current policyDigest of the session. This command allows the TPM\r
242 to be used to perform the actions required to precompute the authPolicy for an object.\r
243\r
244 @param[in] PolicySession Handle for the policy session.\r
245 @param[out] PolicyHash the current value of the policyHash of policySession.\r
246 \r
247 @retval EFI_SUCCESS Operation completed successfully.\r
248 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
249**/\r
250EFI_STATUS\r
251EFIAPI\r
252Tpm2PolicyGetDigest (\r
253 IN TPMI_SH_POLICY PolicySession,\r
254 OUT TPM2B_DIGEST *PolicyHash\r
255 )\r
256{\r
257 EFI_STATUS Status;\r
258 TPM2_POLICY_GET_DIGEST_COMMAND SendBuffer;\r
259 TPM2_POLICY_GET_DIGEST_RESPONSE RecvBuffer;\r
260 UINT32 SendBufferSize;\r
261 UINT32 RecvBufferSize;\r
262\r
263 //\r
264 // Construct command\r
265 //\r
266 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
267 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyGetDigest);\r
268\r
269 SendBuffer.PolicySession = SwapBytes32 (PolicySession);\r
270\r
271 SendBufferSize = (UINT32) sizeof (SendBuffer);\r
272 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
273\r
274 //\r
275 // send Tpm command\r
276 //\r
277 RecvBufferSize = sizeof (RecvBuffer);\r
278 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
279 if (EFI_ERROR (Status)) {\r
280 return Status;\r
281 }\r
282\r
283 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
284 DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - RecvBufferSize Error - %x\n", RecvBufferSize));\r
285 return EFI_DEVICE_ERROR;\r
286 }\r
287 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
288 DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
289 return EFI_DEVICE_ERROR;\r
290 }\r
291\r
292 //\r
293 // Return the response\r
294 //\r
295 PolicyHash->size = SwapBytes16 (RecvBuffer.PolicyHash.size);\r
296 CopyMem (PolicyHash->buffer, &RecvBuffer.PolicyHash.buffer, PolicyHash->size);\r
297\r
298 return EFI_SUCCESS;\r
299}\r