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