2 Implement TPM2 EnhancedAuthorization related command.
4 Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
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>
19 TPM2_COMMAND_HEADER Header
;
20 TPMI_DH_ENTITY AuthHandle
;
21 TPMI_SH_POLICY PolicySession
;
22 UINT32 AuthSessionSize
;
23 TPMS_AUTH_COMMAND AuthSession
;
26 TPM2B_NONCE PolicyRef
;
28 } TPM2_POLICY_SECRET_COMMAND
;
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
;
39 TPM2_COMMAND_HEADER Header
;
40 TPMI_SH_POLICY PolicySession
;
42 } TPM2_POLICY_OR_COMMAND
;
45 TPM2_RESPONSE_HEADER Header
;
46 } TPM2_POLICY_OR_RESPONSE
;
49 TPM2_COMMAND_HEADER Header
;
50 TPMI_SH_POLICY PolicySession
;
52 } TPM2_POLICY_COMMAND_CODE_COMMAND
;
55 TPM2_RESPONSE_HEADER Header
;
56 } TPM2_POLICY_COMMAND_CODE_RESPONSE
;
59 TPM2_COMMAND_HEADER Header
;
60 TPMI_SH_POLICY PolicySession
;
61 } TPM2_POLICY_GET_DIGEST_COMMAND
;
64 TPM2_RESPONSE_HEADER Header
;
65 TPM2B_DIGEST PolicyHash
;
66 } TPM2_POLICY_GET_DIGEST_RESPONSE
;
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.
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.
85 @retval EFI_SUCCESS Operation completed successfully.
86 @retval EFI_DEVICE_ERROR The command was unsuccessful.
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
,
98 OUT TPM2B_TIMEOUT
*Timeout
,
99 OUT TPMT_TK_AUTH
*PolicyTicket
103 TPM2_POLICY_SECRET_COMMAND SendBuffer
;
104 TPM2_POLICY_SECRET_RESPONSE RecvBuffer
;
105 UINT32 SendBufferSize
;
106 UINT32 RecvBufferSize
;
108 UINT32 SessionInfoSize
;
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
);
119 // Add in Auth session
121 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
124 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
125 Buffer
+= SessionInfoSize
;
126 SendBuffer
.AuthSessionSize
= SwapBytes32(SessionInfoSize
);
131 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16(NonceTPM
->size
));
132 Buffer
+= sizeof(UINT16
);
133 CopyMem (Buffer
, NonceTPM
->buffer
, NonceTPM
->size
);
134 Buffer
+= NonceTPM
->size
;
136 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16(CpHashA
->size
));
137 Buffer
+= sizeof(UINT16
);
138 CopyMem (Buffer
, CpHashA
->buffer
, CpHashA
->size
);
139 Buffer
+= CpHashA
->size
;
141 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16(PolicyRef
->size
));
142 Buffer
+= sizeof(UINT16
);
143 CopyMem (Buffer
, PolicyRef
->buffer
, PolicyRef
->size
);
144 Buffer
+= PolicyRef
->size
;
146 WriteUnaligned32 ((UINT32
*)Buffer
, SwapBytes32((UINT32
)Expiration
));
147 Buffer
+= sizeof(UINT32
);
149 SendBufferSize
= (UINT32
)((UINTN
)Buffer
- (UINTN
)&SendBuffer
);
150 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
155 RecvBufferSize
= sizeof (RecvBuffer
);
156 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
157 if (EFI_ERROR (Status
)) {
161 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
162 DEBUG ((DEBUG_ERROR
, "Tpm2PolicySecret - RecvBufferSize Error - %x\n", RecvBufferSize
));
163 Status
= EFI_DEVICE_ERROR
;
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
;
173 // Return the response
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
;
183 Buffer
+= sizeof(UINT16
);
184 CopyMem (Timeout
->buffer
, Buffer
, Timeout
->size
);
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
;
198 CopyMem (PolicyTicket
->digest
.buffer
, Buffer
, PolicyTicket
->digest
.size
);
202 // Clear AuthSession Content
204 ZeroMem (&SendBuffer
, sizeof(SendBuffer
));
205 ZeroMem (&RecvBuffer
, sizeof(RecvBuffer
));
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
215 @param[in] PolicySession Handle for the policy session being extended.
216 @param[in] HashList the list of hashes to check for a match.
218 @retval EFI_SUCCESS Operation completed successfully.
219 @retval EFI_DEVICE_ERROR The command was unsuccessful.
224 IN TPMI_SH_POLICY PolicySession
,
225 IN TPML_DIGEST
*HashList
229 TPM2_POLICY_OR_COMMAND SendBuffer
;
230 TPM2_POLICY_OR_RESPONSE RecvBuffer
;
231 UINT32 SendBufferSize
;
232 UINT32 RecvBufferSize
;
239 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_NO_SESSIONS
);
240 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_PolicyOR
);
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
;
253 SendBufferSize
= (UINT32
)((UINTN
)Buffer
- (UINTN
)&SendBuffer
);
254 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
259 RecvBufferSize
= sizeof (RecvBuffer
);
260 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
261 if (EFI_ERROR (Status
)) {
265 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
266 DEBUG ((DEBUG_ERROR
, "Tpm2PolicyOR - RecvBufferSize Error - %x\n", RecvBufferSize
));
267 return EFI_DEVICE_ERROR
;
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
;
278 This command indicates that the authorization will be limited to a specific command code.
280 @param[in] PolicySession Handle for the policy session being extended.
281 @param[in] Code The allowed commandCode.
283 @retval EFI_SUCCESS Operation completed successfully.
284 @retval EFI_DEVICE_ERROR The command was unsuccessful.
288 Tpm2PolicyCommandCode (
289 IN TPMI_SH_POLICY PolicySession
,
294 TPM2_POLICY_COMMAND_CODE_COMMAND SendBuffer
;
295 TPM2_POLICY_COMMAND_CODE_RESPONSE RecvBuffer
;
296 UINT32 SendBufferSize
;
297 UINT32 RecvBufferSize
;
302 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_NO_SESSIONS
);
303 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_PolicyCommandCode
);
305 SendBuffer
.PolicySession
= SwapBytes32 (PolicySession
);
306 SendBuffer
.Code
= SwapBytes32 (Code
);
308 SendBufferSize
= (UINT32
) sizeof (SendBuffer
);
309 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
314 RecvBufferSize
= sizeof (RecvBuffer
);
315 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
316 if (EFI_ERROR (Status
)) {
320 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
321 DEBUG ((DEBUG_ERROR
, "Tpm2PolicyCommandCode - RecvBufferSize Error - %x\n", RecvBufferSize
));
322 return EFI_DEVICE_ERROR
;
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
;
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.
336 @param[in] PolicySession Handle for the policy session.
337 @param[out] PolicyHash the current value of the policyHash of policySession.
339 @retval EFI_SUCCESS Operation completed successfully.
340 @retval EFI_DEVICE_ERROR The command was unsuccessful.
344 Tpm2PolicyGetDigest (
345 IN TPMI_SH_POLICY PolicySession
,
346 OUT TPM2B_DIGEST
*PolicyHash
350 TPM2_POLICY_GET_DIGEST_COMMAND SendBuffer
;
351 TPM2_POLICY_GET_DIGEST_RESPONSE RecvBuffer
;
352 UINT32 SendBufferSize
;
353 UINT32 RecvBufferSize
;
358 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_NO_SESSIONS
);
359 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_PolicyGetDigest
);
361 SendBuffer
.PolicySession
= SwapBytes32 (PolicySession
);
363 SendBufferSize
= (UINT32
) sizeof (SendBuffer
);
364 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
369 RecvBufferSize
= sizeof (RecvBuffer
);
370 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
371 if (EFI_ERROR (Status
)) {
375 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
376 DEBUG ((DEBUG_ERROR
, "Tpm2PolicyGetDigest - RecvBufferSize Error - %x\n", RecvBufferSize
));
377 return EFI_DEVICE_ERROR
;
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
;
385 // Return the response
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
;
393 CopyMem (PolicyHash
->buffer
, &RecvBuffer
.PolicyHash
.buffer
, PolicyHash
->size
);