]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c
e070ff2f74a4f13a46648983a5c152af0becb737
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Object.c
1 /** @file
2 Implement TPM2 Object related command.
3
4 Copyright (c) 2017, 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_OBJECT ObjectHandle;
27 } TPM2_READ_PUBLIC_COMMAND;
28
29 typedef struct {
30 TPM2_RESPONSE_HEADER Header;
31 TPM2B_PUBLIC OutPublic;
32 TPM2B_NAME Name;
33 TPM2B_NAME QualifiedName;
34 } TPM2_READ_PUBLIC_RESPONSE;
35
36 #pragma pack()
37
38 /**
39 This command allows access to the public area of a loaded object.
40
41 @param[in] ObjectHandle TPM handle of an object
42 @param[out] OutPublic Structure containing the public area of an object
43 @param[out] Name Name of the object
44 @param[out] QualifiedName The Qualified Name of the object
45
46 @retval EFI_SUCCESS Operation completed successfully.
47 @retval EFI_DEVICE_ERROR Unexpected device behavior.
48 **/
49 EFI_STATUS
50 EFIAPI
51 Tpm2ReadPublic (
52 IN TPMI_DH_OBJECT ObjectHandle,
53 OUT TPM2B_PUBLIC *OutPublic,
54 OUT TPM2B_NAME *Name,
55 OUT TPM2B_NAME *QualifiedName
56 )
57 {
58 EFI_STATUS Status;
59 TPM2_READ_PUBLIC_COMMAND SendBuffer;
60 TPM2_READ_PUBLIC_RESPONSE RecvBuffer;
61 UINT32 SendBufferSize;
62 UINT32 RecvBufferSize;
63 TPM_RC ResponseCode;
64 UINT8 *Buffer;
65 UINT16 OutPublicSize;
66 UINT16 NameSize;
67 UINT16 QualifiedNameSize;
68
69 //
70 // Construct command
71 //
72 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
73 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_ReadPublic);
74
75 SendBuffer.ObjectHandle = SwapBytes32 (ObjectHandle);
76
77 SendBufferSize = (UINT32) sizeof (SendBuffer);
78 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
79
80 //
81 // send Tpm command
82 //
83 RecvBufferSize = sizeof (RecvBuffer);
84 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
85 if (EFI_ERROR (Status)) {
86 return Status;
87 }
88
89 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
90 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize));
91 return EFI_DEVICE_ERROR;
92 }
93 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
94 if (ResponseCode != TPM_RC_SUCCESS) {
95 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
96 }
97 switch (ResponseCode) {
98 case TPM_RC_SUCCESS:
99 // return data
100 break;
101 case TPM_RC_SEQUENCE:
102 // objectHandle references a sequence object
103 return EFI_INVALID_PARAMETER;
104 default:
105 return EFI_DEVICE_ERROR;
106 }
107
108 //
109 // Basic check
110 //
111 OutPublicSize = SwapBytes16 (RecvBuffer.OutPublic.size);
112 NameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) +
113 sizeof(UINT16) + OutPublicSize)));
114 QualifiedNameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) +
115 sizeof(UINT16) + OutPublicSize +
116 sizeof(UINT16) + NameSize)));
117
118 if (RecvBufferSize != sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16) + NameSize + sizeof(UINT16) + QualifiedNameSize) {
119 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - RecvBufferSize %x Error - OutPublicSize %x, NameSize %x, QualifiedNameSize %x\n", RecvBufferSize, OutPublicSize, NameSize, QualifiedNameSize));
120 return EFI_DEVICE_ERROR;
121 }
122
123 //
124 // Return the response
125 //
126 Buffer = (UINT8 *)&RecvBuffer.OutPublic;
127 CopyMem (OutPublic, &RecvBuffer.OutPublic, sizeof(UINT16) + OutPublicSize);
128 OutPublic->size = OutPublicSize;
129 OutPublic->publicArea.type = SwapBytes16 (OutPublic->publicArea.type);
130 OutPublic->publicArea.nameAlg = SwapBytes16 (OutPublic->publicArea.nameAlg);
131 WriteUnaligned32 ((UINT32 *)&OutPublic->publicArea.objectAttributes, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&OutPublic->publicArea.objectAttributes)));
132 Buffer = (UINT8 *)&RecvBuffer.OutPublic.publicArea.authPolicy;
133 OutPublic->publicArea.authPolicy.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
134 Buffer += sizeof(UINT16);
135 CopyMem (OutPublic->publicArea.authPolicy.buffer, Buffer, OutPublic->publicArea.authPolicy.size);
136 Buffer += OutPublic->publicArea.authPolicy.size;
137
138 // TPMU_PUBLIC_PARMS
139 switch (OutPublic->publicArea.type) {
140 case TPM_ALG_KEYEDHASH:
141 OutPublic->publicArea.parameters.keyedHashDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
142 Buffer += sizeof(UINT16);
143 switch (OutPublic->publicArea.parameters.keyedHashDetail.scheme.scheme) {
144 case TPM_ALG_HMAC:
145 OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
146 Buffer += sizeof(UINT16);
147 break;
148 case TPM_ALG_XOR:
149 OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.xor.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
150 Buffer += sizeof(UINT16);
151 OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.xor.kdf = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
152 Buffer += sizeof(UINT16);
153 break;
154 default:
155 return EFI_UNSUPPORTED;
156 }
157 case TPM_ALG_SYMCIPHER:
158 OutPublic->publicArea.parameters.symDetail.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
159 Buffer += sizeof(UINT16);
160 switch (OutPublic->publicArea.parameters.symDetail.algorithm) {
161 case TPM_ALG_AES:
162 OutPublic->publicArea.parameters.symDetail.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
163 Buffer += sizeof(UINT16);
164 OutPublic->publicArea.parameters.symDetail.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
165 Buffer += sizeof(UINT16);
166 break;
167 case TPM_ALG_SM4:
168 OutPublic->publicArea.parameters.symDetail.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
169 Buffer += sizeof(UINT16);
170 OutPublic->publicArea.parameters.symDetail.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
171 Buffer += sizeof(UINT16);
172 break;
173 case TPM_ALG_XOR:
174 OutPublic->publicArea.parameters.symDetail.keyBits.xor = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
175 Buffer += sizeof(UINT16);
176 break;
177 case TPM_ALG_NULL:
178 break;
179 default:
180 return EFI_UNSUPPORTED;
181 }
182 break;
183 case TPM_ALG_RSA:
184 OutPublic->publicArea.parameters.rsaDetail.symmetric.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
185 Buffer += sizeof(UINT16);
186 switch (OutPublic->publicArea.parameters.rsaDetail.symmetric.algorithm) {
187 case TPM_ALG_AES:
188 OutPublic->publicArea.parameters.rsaDetail.symmetric.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
189 Buffer += sizeof(UINT16);
190 OutPublic->publicArea.parameters.rsaDetail.symmetric.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
191 Buffer += sizeof(UINT16);
192 break;
193 case TPM_ALG_SM4:
194 OutPublic->publicArea.parameters.rsaDetail.symmetric.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
195 Buffer += sizeof(UINT16);
196 OutPublic->publicArea.parameters.rsaDetail.symmetric.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
197 Buffer += sizeof(UINT16);
198 break;
199 case TPM_ALG_NULL:
200 break;
201 default:
202 return EFI_UNSUPPORTED;
203 }
204 OutPublic->publicArea.parameters.rsaDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
205 Buffer += sizeof(UINT16);
206 switch (OutPublic->publicArea.parameters.rsaDetail.scheme.scheme) {
207 case TPM_ALG_RSASSA:
208 OutPublic->publicArea.parameters.rsaDetail.scheme.details.rsassa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
209 Buffer += sizeof(UINT16);
210 break;
211 case TPM_ALG_RSAPSS:
212 OutPublic->publicArea.parameters.rsaDetail.scheme.details.rsapss.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
213 Buffer += sizeof(UINT16);
214 break;
215 case TPM_ALG_RSAES:
216 break;
217 case TPM_ALG_OAEP:
218 OutPublic->publicArea.parameters.rsaDetail.scheme.details.oaep.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
219 Buffer += sizeof(UINT16);
220 break;
221 case TPM_ALG_NULL:
222 break;
223 default:
224 return EFI_UNSUPPORTED;
225 }
226 OutPublic->publicArea.parameters.rsaDetail.keyBits = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
227 Buffer += sizeof(UINT16);
228 OutPublic->publicArea.parameters.rsaDetail.exponent = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
229 Buffer += sizeof(UINT32);
230 break;
231 case TPM_ALG_ECC:
232 OutPublic->publicArea.parameters.eccDetail.symmetric.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
233 Buffer += sizeof(UINT16);
234 switch (OutPublic->publicArea.parameters.eccDetail.symmetric.algorithm) {
235 case TPM_ALG_AES:
236 OutPublic->publicArea.parameters.eccDetail.symmetric.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
237 Buffer += sizeof(UINT16);
238 OutPublic->publicArea.parameters.eccDetail.symmetric.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
239 Buffer += sizeof(UINT16);
240 break;
241 case TPM_ALG_SM4:
242 OutPublic->publicArea.parameters.eccDetail.symmetric.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
243 Buffer += sizeof(UINT16);
244 OutPublic->publicArea.parameters.eccDetail.symmetric.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
245 Buffer += sizeof(UINT16);
246 break;
247 case TPM_ALG_NULL:
248 break;
249 default:
250 return EFI_UNSUPPORTED;
251 }
252 OutPublic->publicArea.parameters.eccDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
253 Buffer += sizeof(UINT16);
254 switch (OutPublic->publicArea.parameters.eccDetail.scheme.scheme) {
255 case TPM_ALG_ECDSA:
256 OutPublic->publicArea.parameters.eccDetail.scheme.details.ecdsa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
257 Buffer += sizeof(UINT16);
258 break;
259 case TPM_ALG_ECDAA:
260 OutPublic->publicArea.parameters.eccDetail.scheme.details.ecdaa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
261 Buffer += sizeof(UINT16);
262 break;
263 case TPM_ALG_ECSCHNORR:
264 OutPublic->publicArea.parameters.eccDetail.scheme.details.ecSchnorr.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
265 Buffer += sizeof(UINT16);
266 break;
267 case TPM_ALG_ECDH:
268 break;
269 case TPM_ALG_NULL:
270 break;
271 default:
272 return EFI_UNSUPPORTED;
273 }
274 OutPublic->publicArea.parameters.eccDetail.curveID = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
275 Buffer += sizeof(UINT16);
276 OutPublic->publicArea.parameters.eccDetail.kdf.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
277 Buffer += sizeof(UINT16);
278 switch (OutPublic->publicArea.parameters.eccDetail.kdf.scheme) {
279 case TPM_ALG_MGF1:
280 OutPublic->publicArea.parameters.eccDetail.kdf.details.mgf1.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
281 Buffer += sizeof(UINT16);
282 break;
283 case TPM_ALG_KDF1_SP800_108:
284 OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf1_sp800_108.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
285 Buffer += sizeof(UINT16);
286 break;
287 case TPM_ALG_KDF1_SP800_56a:
288 OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf1_SP800_56a.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
289 Buffer += sizeof(UINT16);
290 break;
291 case TPM_ALG_KDF2:
292 OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf2.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
293 Buffer += sizeof(UINT16);
294 break;
295 case TPM_ALG_NULL:
296 break;
297 default:
298 return EFI_UNSUPPORTED;
299 }
300 break;
301 default:
302 return EFI_UNSUPPORTED;
303 }
304
305 // TPMU_PUBLIC_ID
306 switch (OutPublic->publicArea.type) {
307 case TPM_ALG_KEYEDHASH:
308 OutPublic->publicArea.unique.keyedHash.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
309 Buffer += sizeof(UINT16);
310 CopyMem (OutPublic->publicArea.unique.keyedHash.buffer, Buffer, OutPublic->publicArea.unique.keyedHash.size);
311 Buffer += OutPublic->publicArea.unique.keyedHash.size;
312 break;
313 case TPM_ALG_SYMCIPHER:
314 OutPublic->publicArea.unique.sym.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
315 Buffer += sizeof(UINT16);
316 CopyMem (OutPublic->publicArea.unique.sym.buffer, Buffer, OutPublic->publicArea.unique.sym.size);
317 Buffer += OutPublic->publicArea.unique.sym.size;
318 break;
319 case TPM_ALG_RSA:
320 OutPublic->publicArea.unique.rsa.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
321 Buffer += sizeof(UINT16);
322 CopyMem (OutPublic->publicArea.unique.rsa.buffer, Buffer, OutPublic->publicArea.unique.rsa.size);
323 Buffer += OutPublic->publicArea.unique.rsa.size;
324 break;
325 case TPM_ALG_ECC:
326 OutPublic->publicArea.unique.ecc.x.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
327 Buffer += sizeof(UINT16);
328 CopyMem (OutPublic->publicArea.unique.ecc.x.buffer, Buffer, OutPublic->publicArea.unique.ecc.x.size);
329 Buffer += OutPublic->publicArea.unique.ecc.x.size;
330 OutPublic->publicArea.unique.ecc.y.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
331 Buffer += sizeof(UINT16);
332 CopyMem (OutPublic->publicArea.unique.ecc.y.buffer, Buffer, OutPublic->publicArea.unique.ecc.y.size);
333 Buffer += OutPublic->publicArea.unique.ecc.y.size;
334 break;
335 default:
336 return EFI_UNSUPPORTED;
337 }
338
339 CopyMem (Name->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16), NameSize);
340 Name->size = NameSize;
341
342 CopyMem (QualifiedName->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16) + NameSize + sizeof(UINT16), QualifiedNameSize);
343 QualifiedName->size = QualifiedNameSize;
344
345 return EFI_SUCCESS;
346 }