]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c
SecurityPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2EnhancedAuthorization.c
CommitLineData
967eacca
JY
1/** @file\r
2 Implement TPM2 EnhancedAuthorization related command.\r
3\r
dd577319 4Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved. <BR>\r
289b714b 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
967eacca
JY
6\r
7**/\r
8\r
9#include <IndustryStandard/UefiTcgPlatform.h>\r
10#include <Library/Tpm2CommandLib.h>\r
11#include <Library/Tpm2DeviceLib.h>\r
12#include <Library/BaseMemoryLib.h>\r
13#include <Library/BaseLib.h>\r
14#include <Library/DebugLib.h>\r
15\r
16#pragma pack(1)\r
17\r
18typedef struct {\r
19 TPM2_COMMAND_HEADER Header;\r
20 TPMI_DH_ENTITY AuthHandle;\r
21 TPMI_SH_POLICY PolicySession;\r
22 UINT32 AuthSessionSize;\r
23 TPMS_AUTH_COMMAND AuthSession;\r
24 TPM2B_NONCE NonceTPM;\r
25 TPM2B_DIGEST CpHashA;\r
26 TPM2B_NONCE PolicyRef;\r
27 INT32 Expiration;\r
28} TPM2_POLICY_SECRET_COMMAND;\r
29\r
30typedef struct {\r
31 TPM2_RESPONSE_HEADER Header;\r
32 UINT32 AuthSessionSize;\r
33 TPM2B_TIMEOUT Timeout;\r
34 TPMT_TK_AUTH PolicyTicket;\r
35 TPMS_AUTH_RESPONSE AuthSession;\r
36} TPM2_POLICY_SECRET_RESPONSE;\r
37\r
a50e58f4
JY
38typedef struct {\r
39 TPM2_COMMAND_HEADER Header;\r
40 TPMI_SH_POLICY PolicySession;\r
41 TPML_DIGEST HashList;\r
42} TPM2_POLICY_OR_COMMAND;\r
43\r
44typedef struct {\r
45 TPM2_RESPONSE_HEADER Header;\r
46} TPM2_POLICY_OR_RESPONSE;\r
47\r
967eacca
JY
48typedef struct {\r
49 TPM2_COMMAND_HEADER Header;\r
50 TPMI_SH_POLICY PolicySession;\r
51 TPM_CC Code;\r
52} TPM2_POLICY_COMMAND_CODE_COMMAND;\r
53\r
54typedef struct {\r
55 TPM2_RESPONSE_HEADER Header;\r
56} TPM2_POLICY_COMMAND_CODE_RESPONSE;\r
57\r
58typedef struct {\r
59 TPM2_COMMAND_HEADER Header;\r
60 TPMI_SH_POLICY PolicySession;\r
61} TPM2_POLICY_GET_DIGEST_COMMAND;\r
62\r
63typedef struct {\r
64 TPM2_RESPONSE_HEADER Header;\r
65 TPM2B_DIGEST PolicyHash;\r
66} TPM2_POLICY_GET_DIGEST_RESPONSE;\r
67\r
68#pragma pack()\r
69\r
70/**\r
71 This command includes a secret-based authorization to a policy.\r
72 The caller proves knowledge of the secret value using an authorization\r
73 session using the authValue associated with authHandle.\r
74\r
75 @param[in] AuthHandle Handle for an entity providing the authorization\r
76 @param[in] PolicySession Handle for the policy session being extended.\r
77 @param[in] AuthSession Auth Session context\r
78 @param[in] NonceTPM The policy nonce for the session.\r
79 @param[in] CpHashA Digest of the command parameters to which this authorization is limited.\r
80 @param[in] PolicyRef A reference to a policy relating to the authorization.\r
81 @param[in] Expiration Time when authorization will expire, measured in seconds from the time that nonceTPM was generated.\r
82 @param[out] Timeout Time value used to indicate to the TPM when the ticket expires.\r
83 @param[out] PolicyTicket A ticket that includes a value indicating when the authorization expires.\r
b3548d32 84\r
967eacca
JY
85 @retval EFI_SUCCESS Operation completed successfully.\r
86 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
87**/\r
88EFI_STATUS\r
89EFIAPI\r
90Tpm2PolicySecret (\r
91 IN TPMI_DH_ENTITY AuthHandle,\r
92 IN TPMI_SH_POLICY PolicySession,\r
93 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL\r
94 IN TPM2B_NONCE *NonceTPM,\r
95 IN TPM2B_DIGEST *CpHashA,\r
96 IN TPM2B_NONCE *PolicyRef,\r
97 IN INT32 Expiration,\r
98 OUT TPM2B_TIMEOUT *Timeout,\r
99 OUT TPMT_TK_AUTH *PolicyTicket\r
100 )\r
101{\r
102 EFI_STATUS Status;\r
103 TPM2_POLICY_SECRET_COMMAND SendBuffer;\r
104 TPM2_POLICY_SECRET_RESPONSE RecvBuffer;\r
105 UINT32 SendBufferSize;\r
106 UINT32 RecvBufferSize;\r
107 UINT8 *Buffer;\r
108 UINT32 SessionInfoSize;\r
109\r
110 //\r
111 // Construct command\r
112 //\r
113 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
114 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicySecret);\r
115 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);\r
116 SendBuffer.PolicySession = SwapBytes32 (PolicySession);\r
b3548d32 117\r
967eacca
JY
118 //\r
119 // Add in Auth session\r
120 //\r
121 Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
122\r
123 // sessionInfoSize\r
124 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
125 Buffer += SessionInfoSize;\r
126 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
127\r
128 //\r
129 // Real data\r
130 //\r
131 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NonceTPM->size));\r
132 Buffer += sizeof(UINT16);\r
133 CopyMem (Buffer, NonceTPM->buffer, NonceTPM->size);\r
134 Buffer += NonceTPM->size;\r
135\r
136 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(CpHashA->size));\r
137 Buffer += sizeof(UINT16);\r
138 CopyMem (Buffer, CpHashA->buffer, CpHashA->size);\r
139 Buffer += CpHashA->size;\r
140\r
141 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PolicyRef->size));\r
142 Buffer += sizeof(UINT16);\r
143 CopyMem (Buffer, PolicyRef->buffer, PolicyRef->size);\r
144 Buffer += PolicyRef->size;\r
b3548d32 145\r
967eacca
JY
146 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32((UINT32)Expiration));\r
147 Buffer += sizeof(UINT32);\r
148\r
149 SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);\r
150 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
151\r
152 //\r
153 // send Tpm command\r
154 //\r
155 RecvBufferSize = sizeof (RecvBuffer);\r
156 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
157 if (EFI_ERROR (Status)) {\r
7ae130da 158 goto Done;\r
967eacca
JY
159 }\r
160\r
161 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
162 DEBUG ((EFI_D_ERROR, "Tpm2PolicySecret - RecvBufferSize Error - %x\n", RecvBufferSize));\r
7ae130da
JY
163 Status = EFI_DEVICE_ERROR;\r
164 goto Done;\r
967eacca
JY
165 }\r
166 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
167 DEBUG ((EFI_D_ERROR, "Tpm2PolicySecret - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
7ae130da
JY
168 Status = EFI_DEVICE_ERROR;\r
169 goto Done;\r
967eacca
JY
170 }\r
171\r
172 //\r
173 // Return the response\r
174 //\r
175 Buffer = (UINT8 *)&RecvBuffer.Timeout;\r
176 Timeout->size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));\r
dd577319
ZC
177 if (Timeout->size > sizeof(UINT64)) {\r
178 DEBUG ((DEBUG_ERROR, "Tpm2PolicySecret - Timeout->size error %x\n", Timeout->size));\r
179 Status = EFI_DEVICE_ERROR;\r
180 goto Done;\r
181 }\r
182\r
967eacca
JY
183 Buffer += sizeof(UINT16);\r
184 CopyMem (Timeout->buffer, Buffer, Timeout->size);\r
185\r
186 PolicyTicket->tag = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));\r
187 Buffer += sizeof(UINT16);\r
188 PolicyTicket->hierarchy = SwapBytes32(ReadUnaligned32 ((UINT32 *)Buffer));\r
189 Buffer += sizeof(UINT32);\r
190 PolicyTicket->digest.size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));\r
191 Buffer += sizeof(UINT16);\r
dd577319
ZC
192 if (PolicyTicket->digest.size > sizeof(TPMU_HA)) {\r
193 DEBUG ((DEBUG_ERROR, "Tpm2PolicySecret - digest.size error %x\n", PolicyTicket->digest.size));\r
194 Status = EFI_DEVICE_ERROR;\r
195 goto Done;\r
196 }\r
197\r
967eacca
JY
198 CopyMem (PolicyTicket->digest.buffer, Buffer, PolicyTicket->digest.size);\r
199\r
7ae130da
JY
200Done:\r
201 //\r
202 // Clear AuthSession Content\r
203 //\r
204 ZeroMem (&SendBuffer, sizeof(SendBuffer));\r
205 ZeroMem (&RecvBuffer, sizeof(RecvBuffer));\r
206 return Status;\r
967eacca
JY
207}\r
208\r
a50e58f4
JY
209/**\r
210 This command allows options in authorizations without requiring that the TPM evaluate all of the options.\r
211 If a policy may be satisfied by different sets of conditions, the TPM need only evaluate one set that\r
212 satisfies the policy. This command will indicate that one of the required sets of conditions has been\r
213 satisfied.\r
214\r
215 @param[in] PolicySession Handle for the policy session being extended.\r
216 @param[in] HashList the list of hashes to check for a match.\r
b3548d32 217\r
a50e58f4
JY
218 @retval EFI_SUCCESS Operation completed successfully.\r
219 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
220**/\r
221EFI_STATUS\r
222EFIAPI\r
223Tpm2PolicyOR (\r
224 IN TPMI_SH_POLICY PolicySession,\r
225 IN TPML_DIGEST *HashList\r
226 )\r
227{\r
228 EFI_STATUS Status;\r
229 TPM2_POLICY_OR_COMMAND SendBuffer;\r
230 TPM2_POLICY_OR_RESPONSE RecvBuffer;\r
231 UINT32 SendBufferSize;\r
232 UINT32 RecvBufferSize;\r
233 UINT8 *Buffer;\r
234 UINTN Index;\r
235\r
236 //\r
237 // Construct command\r
238 //\r
239 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
240 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyOR);\r
241\r
242 SendBuffer.PolicySession = SwapBytes32 (PolicySession);\r
243 Buffer = (UINT8 *)&SendBuffer.HashList;\r
244 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (HashList->count));\r
245 Buffer += sizeof(UINT32);\r
246 for (Index = 0; Index < HashList->count; Index++) {\r
247 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (HashList->digests[Index].size));\r
248 Buffer += sizeof(UINT16);\r
249 CopyMem (Buffer, HashList->digests[Index].buffer, HashList->digests[Index].size);\r
250 Buffer += HashList->digests[Index].size;\r
251 }\r
252\r
253 SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);\r
254 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
255\r
256 //\r
257 // send Tpm command\r
258 //\r
259 RecvBufferSize = sizeof (RecvBuffer);\r
260 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
261 if (EFI_ERROR (Status)) {\r
262 return Status;\r
263 }\r
264\r
265 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
266 DEBUG ((EFI_D_ERROR, "Tpm2PolicyOR - RecvBufferSize Error - %x\n", RecvBufferSize));\r
267 return EFI_DEVICE_ERROR;\r
268 }\r
269 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
270 DEBUG ((EFI_D_ERROR, "Tpm2PolicyOR - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
271 return EFI_DEVICE_ERROR;\r
272 }\r
273\r
274 return EFI_SUCCESS;\r
275}\r
276\r
967eacca
JY
277/**\r
278 This command indicates that the authorization will be limited to a specific command code.\r
279\r
280 @param[in] PolicySession Handle for the policy session being extended.\r
281 @param[in] Code The allowed commandCode.\r
b3548d32 282\r
967eacca
JY
283 @retval EFI_SUCCESS Operation completed successfully.\r
284 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
285**/\r
286EFI_STATUS\r
287EFIAPI\r
288Tpm2PolicyCommandCode (\r
289 IN TPMI_SH_POLICY PolicySession,\r
290 IN TPM_CC Code\r
291 )\r
292{\r
293 EFI_STATUS Status;\r
294 TPM2_POLICY_COMMAND_CODE_COMMAND SendBuffer;\r
295 TPM2_POLICY_COMMAND_CODE_RESPONSE RecvBuffer;\r
296 UINT32 SendBufferSize;\r
297 UINT32 RecvBufferSize;\r
298\r
299 //\r
300 // Construct command\r
301 //\r
302 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
303 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyCommandCode);\r
304\r
305 SendBuffer.PolicySession = SwapBytes32 (PolicySession);\r
306 SendBuffer.Code = SwapBytes32 (Code);\r
307\r
308 SendBufferSize = (UINT32) sizeof (SendBuffer);\r
309 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
310\r
311 //\r
312 // send Tpm command\r
313 //\r
314 RecvBufferSize = sizeof (RecvBuffer);\r
315 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
316 if (EFI_ERROR (Status)) {\r
317 return Status;\r
318 }\r
319\r
320 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
321 DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - RecvBufferSize Error - %x\n", RecvBufferSize));\r
322 return EFI_DEVICE_ERROR;\r
323 }\r
324 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
325 DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
326 return EFI_DEVICE_ERROR;\r
327 }\r
328\r
329 return EFI_SUCCESS;\r
330}\r
331\r
332/**\r
333 This command returns the current policyDigest of the session. This command allows the TPM\r
334 to be used to perform the actions required to precompute the authPolicy for an object.\r
335\r
336 @param[in] PolicySession Handle for the policy session.\r
337 @param[out] PolicyHash the current value of the policyHash of policySession.\r
b3548d32 338\r
967eacca
JY
339 @retval EFI_SUCCESS Operation completed successfully.\r
340 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
341**/\r
342EFI_STATUS\r
343EFIAPI\r
344Tpm2PolicyGetDigest (\r
345 IN TPMI_SH_POLICY PolicySession,\r
346 OUT TPM2B_DIGEST *PolicyHash\r
347 )\r
348{\r
349 EFI_STATUS Status;\r
350 TPM2_POLICY_GET_DIGEST_COMMAND SendBuffer;\r
351 TPM2_POLICY_GET_DIGEST_RESPONSE RecvBuffer;\r
352 UINT32 SendBufferSize;\r
353 UINT32 RecvBufferSize;\r
354\r
355 //\r
356 // Construct command\r
357 //\r
358 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
359 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyGetDigest);\r
360\r
361 SendBuffer.PolicySession = SwapBytes32 (PolicySession);\r
362\r
363 SendBufferSize = (UINT32) sizeof (SendBuffer);\r
364 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
365\r
366 //\r
367 // send Tpm command\r
368 //\r
369 RecvBufferSize = sizeof (RecvBuffer);\r
370 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
371 if (EFI_ERROR (Status)) {\r
372 return Status;\r
373 }\r
374\r
375 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
376 DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - RecvBufferSize Error - %x\n", RecvBufferSize));\r
377 return EFI_DEVICE_ERROR;\r
378 }\r
379 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
380 DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
381 return EFI_DEVICE_ERROR;\r
382 }\r
383\r
384 //\r
385 // Return the response\r
386 //\r
387 PolicyHash->size = SwapBytes16 (RecvBuffer.PolicyHash.size);\r
dd577319
ZC
388 if (PolicyHash->size > sizeof(TPMU_HA)) {\r
389 DEBUG ((DEBUG_ERROR, "Tpm2PolicyGetDigest - PolicyHash->size error %x\n", PolicyHash->size));\r
390 return EFI_DEVICE_ERROR;\r
391 }\r
392\r
967eacca
JY
393 CopyMem (PolicyHash->buffer, &RecvBuffer.PolicyHash.buffer, PolicyHash->size);\r
394\r
395 return EFI_SUCCESS;\r
396}\r