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