]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c
e302d53561d95bb7f5a7d6bf58a7b6b32b778b76
[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 TPM_CC Code;
48 } TPM2_POLICY_COMMAND_CODE_COMMAND;
49
50 typedef struct {
51 TPM2_RESPONSE_HEADER Header;
52 } TPM2_POLICY_COMMAND_CODE_RESPONSE;
53
54 typedef struct {
55 TPM2_COMMAND_HEADER Header;
56 TPMI_SH_POLICY PolicySession;
57 } TPM2_POLICY_GET_DIGEST_COMMAND;
58
59 typedef struct {
60 TPM2_RESPONSE_HEADER Header;
61 TPM2B_DIGEST PolicyHash;
62 } TPM2_POLICY_GET_DIGEST_RESPONSE;
63
64 #pragma pack()
65
66 /**
67 This command includes a secret-based authorization to a policy.
68 The caller proves knowledge of the secret value using an authorization
69 session using the authValue associated with authHandle.
70
71 @param[in] AuthHandle Handle for an entity providing the authorization
72 @param[in] PolicySession Handle for the policy session being extended.
73 @param[in] AuthSession Auth Session context
74 @param[in] NonceTPM The policy nonce for the session.
75 @param[in] CpHashA Digest of the command parameters to which this authorization is limited.
76 @param[in] PolicyRef A reference to a policy relating to the authorization.
77 @param[in] Expiration Time when authorization will expire, measured in seconds from the time that nonceTPM was generated.
78 @param[out] Timeout Time value used to indicate to the TPM when the ticket expires.
79 @param[out] PolicyTicket A ticket that includes a value indicating when the authorization expires.
80
81 @retval EFI_SUCCESS Operation completed successfully.
82 @retval EFI_DEVICE_ERROR The command was unsuccessful.
83 **/
84 EFI_STATUS
85 EFIAPI
86 Tpm2PolicySecret (
87 IN TPMI_DH_ENTITY AuthHandle,
88 IN TPMI_SH_POLICY PolicySession,
89 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
90 IN TPM2B_NONCE *NonceTPM,
91 IN TPM2B_DIGEST *CpHashA,
92 IN TPM2B_NONCE *PolicyRef,
93 IN INT32 Expiration,
94 OUT TPM2B_TIMEOUT *Timeout,
95 OUT TPMT_TK_AUTH *PolicyTicket
96 )
97 {
98 EFI_STATUS Status;
99 TPM2_POLICY_SECRET_COMMAND SendBuffer;
100 TPM2_POLICY_SECRET_RESPONSE RecvBuffer;
101 UINT32 SendBufferSize;
102 UINT32 RecvBufferSize;
103 UINT8 *Buffer;
104 UINT32 SessionInfoSize;
105
106 //
107 // Construct command
108 //
109 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
110 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicySecret);
111 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
112 SendBuffer.PolicySession = SwapBytes32 (PolicySession);
113
114 //
115 // Add in Auth session
116 //
117 Buffer = (UINT8 *)&SendBuffer.AuthSession;
118
119 // sessionInfoSize
120 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
121 Buffer += SessionInfoSize;
122 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
123
124 //
125 // Real data
126 //
127 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NonceTPM->size));
128 Buffer += sizeof(UINT16);
129 CopyMem (Buffer, NonceTPM->buffer, NonceTPM->size);
130 Buffer += NonceTPM->size;
131
132 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(CpHashA->size));
133 Buffer += sizeof(UINT16);
134 CopyMem (Buffer, CpHashA->buffer, CpHashA->size);
135 Buffer += CpHashA->size;
136
137 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PolicyRef->size));
138 Buffer += sizeof(UINT16);
139 CopyMem (Buffer, PolicyRef->buffer, PolicyRef->size);
140 Buffer += PolicyRef->size;
141
142 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32((UINT32)Expiration));
143 Buffer += sizeof(UINT32);
144
145 SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
146 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
147
148 //
149 // send Tpm command
150 //
151 RecvBufferSize = sizeof (RecvBuffer);
152 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
153 if (EFI_ERROR (Status)) {
154 return Status;
155 }
156
157 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
158 DEBUG ((EFI_D_ERROR, "Tpm2PolicySecret - RecvBufferSize Error - %x\n", RecvBufferSize));
159 return EFI_DEVICE_ERROR;
160 }
161 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
162 DEBUG ((EFI_D_ERROR, "Tpm2PolicySecret - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
163 return EFI_DEVICE_ERROR;
164 }
165
166 //
167 // Return the response
168 //
169 Buffer = (UINT8 *)&RecvBuffer.Timeout;
170 Timeout->size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));
171 Buffer += sizeof(UINT16);
172 CopyMem (Timeout->buffer, Buffer, Timeout->size);
173
174 PolicyTicket->tag = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));
175 Buffer += sizeof(UINT16);
176 PolicyTicket->hierarchy = SwapBytes32(ReadUnaligned32 ((UINT32 *)Buffer));
177 Buffer += sizeof(UINT32);
178 PolicyTicket->digest.size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));
179 Buffer += sizeof(UINT16);
180 CopyMem (PolicyTicket->digest.buffer, Buffer, PolicyTicket->digest.size);
181
182 return EFI_SUCCESS;
183 }
184
185 /**
186 This command indicates that the authorization will be limited to a specific command code.
187
188 @param[in] PolicySession Handle for the policy session being extended.
189 @param[in] Code The allowed commandCode.
190
191 @retval EFI_SUCCESS Operation completed successfully.
192 @retval EFI_DEVICE_ERROR The command was unsuccessful.
193 **/
194 EFI_STATUS
195 EFIAPI
196 Tpm2PolicyCommandCode (
197 IN TPMI_SH_POLICY PolicySession,
198 IN TPM_CC Code
199 )
200 {
201 EFI_STATUS Status;
202 TPM2_POLICY_COMMAND_CODE_COMMAND SendBuffer;
203 TPM2_POLICY_COMMAND_CODE_RESPONSE RecvBuffer;
204 UINT32 SendBufferSize;
205 UINT32 RecvBufferSize;
206
207 //
208 // Construct command
209 //
210 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
211 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyCommandCode);
212
213 SendBuffer.PolicySession = SwapBytes32 (PolicySession);
214 SendBuffer.Code = SwapBytes32 (Code);
215
216 SendBufferSize = (UINT32) sizeof (SendBuffer);
217 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
218
219 //
220 // send Tpm command
221 //
222 RecvBufferSize = sizeof (RecvBuffer);
223 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
224 if (EFI_ERROR (Status)) {
225 return Status;
226 }
227
228 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
229 DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - RecvBufferSize Error - %x\n", RecvBufferSize));
230 return EFI_DEVICE_ERROR;
231 }
232 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
233 DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
234 return EFI_DEVICE_ERROR;
235 }
236
237 return EFI_SUCCESS;
238 }
239
240 /**
241 This command returns the current policyDigest of the session. This command allows the TPM
242 to be used to perform the actions required to precompute the authPolicy for an object.
243
244 @param[in] PolicySession Handle for the policy session.
245 @param[out] PolicyHash the current value of the policyHash of policySession.
246
247 @retval EFI_SUCCESS Operation completed successfully.
248 @retval EFI_DEVICE_ERROR The command was unsuccessful.
249 **/
250 EFI_STATUS
251 EFIAPI
252 Tpm2PolicyGetDigest (
253 IN TPMI_SH_POLICY PolicySession,
254 OUT TPM2B_DIGEST *PolicyHash
255 )
256 {
257 EFI_STATUS Status;
258 TPM2_POLICY_GET_DIGEST_COMMAND SendBuffer;
259 TPM2_POLICY_GET_DIGEST_RESPONSE RecvBuffer;
260 UINT32 SendBufferSize;
261 UINT32 RecvBufferSize;
262
263 //
264 // Construct command
265 //
266 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
267 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyGetDigest);
268
269 SendBuffer.PolicySession = SwapBytes32 (PolicySession);
270
271 SendBufferSize = (UINT32) sizeof (SendBuffer);
272 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
273
274 //
275 // send Tpm command
276 //
277 RecvBufferSize = sizeof (RecvBuffer);
278 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
279 if (EFI_ERROR (Status)) {
280 return Status;
281 }
282
283 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
284 DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - RecvBufferSize Error - %x\n", RecvBufferSize));
285 return EFI_DEVICE_ERROR;
286 }
287 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
288 DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
289 return EFI_DEVICE_ERROR;
290 }
291
292 //
293 // Return the response
294 //
295 PolicyHash->size = SwapBytes16 (RecvBuffer.PolicyHash.size);
296 CopyMem (PolicyHash->buffer, &RecvBuffer.PolicyHash.buffer, PolicyHash->size);
297
298 return EFI_SUCCESS;
299 }