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