]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c
SecurityPkg Tpm2DeviceLibDTpm: Update enum type name to match the one in lib
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Object.c
1 /** @file
2 Implement TPM2 Object related command.
3
4 Copyright (c) 2017 - 2018, 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 if (OutPublicSize > sizeof(TPMT_PUBLIC)) {
113 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - OutPublicSize error %x\n", OutPublicSize));
114 return EFI_DEVICE_ERROR;
115 }
116
117 NameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) +
118 sizeof(UINT16) + OutPublicSize)));
119 if (NameSize > sizeof(TPMU_NAME)) {
120 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - NameSize error %x\n", NameSize));
121 return EFI_DEVICE_ERROR;
122 }
123
124 QualifiedNameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) +
125 sizeof(UINT16) + OutPublicSize +
126 sizeof(UINT16) + NameSize)));
127 if (QualifiedNameSize > sizeof(TPMU_NAME)) {
128 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - QualifiedNameSize error %x\n", QualifiedNameSize));
129 return EFI_DEVICE_ERROR;
130 }
131
132 if (RecvBufferSize != sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16) + NameSize + sizeof(UINT16) + QualifiedNameSize) {
133 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - RecvBufferSize %x Error - OutPublicSize %x, NameSize %x, QualifiedNameSize %x\n", RecvBufferSize, OutPublicSize, NameSize, QualifiedNameSize));
134 return EFI_DEVICE_ERROR;
135 }
136
137 //
138 // Return the response
139 //
140 Buffer = (UINT8 *)&RecvBuffer.OutPublic;
141 CopyMem (OutPublic, &RecvBuffer.OutPublic, sizeof(UINT16) + OutPublicSize);
142 OutPublic->size = OutPublicSize;
143 OutPublic->publicArea.type = SwapBytes16 (OutPublic->publicArea.type);
144 OutPublic->publicArea.nameAlg = SwapBytes16 (OutPublic->publicArea.nameAlg);
145 WriteUnaligned32 ((UINT32 *)&OutPublic->publicArea.objectAttributes, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&OutPublic->publicArea.objectAttributes)));
146 Buffer = (UINT8 *)&RecvBuffer.OutPublic.publicArea.authPolicy;
147 OutPublic->publicArea.authPolicy.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
148 Buffer += sizeof(UINT16);
149 if (OutPublic->publicArea.authPolicy.size > sizeof(TPMU_HA)) {
150 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - authPolicy.size error %x\n", OutPublic->publicArea.authPolicy.size));
151 return EFI_DEVICE_ERROR;
152 }
153
154 CopyMem (OutPublic->publicArea.authPolicy.buffer, Buffer, OutPublic->publicArea.authPolicy.size);
155 Buffer += OutPublic->publicArea.authPolicy.size;
156
157 // TPMU_PUBLIC_PARMS
158 switch (OutPublic->publicArea.type) {
159 case TPM_ALG_KEYEDHASH:
160 OutPublic->publicArea.parameters.keyedHashDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
161 Buffer += sizeof(UINT16);
162 switch (OutPublic->publicArea.parameters.keyedHashDetail.scheme.scheme) {
163 case TPM_ALG_HMAC:
164 OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
165 Buffer += sizeof(UINT16);
166 break;
167 case TPM_ALG_XOR:
168 OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.xor.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
169 Buffer += sizeof(UINT16);
170 OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.xor.kdf = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
171 Buffer += sizeof(UINT16);
172 break;
173 default:
174 return EFI_UNSUPPORTED;
175 }
176 case TPM_ALG_SYMCIPHER:
177 OutPublic->publicArea.parameters.symDetail.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
178 Buffer += sizeof(UINT16);
179 switch (OutPublic->publicArea.parameters.symDetail.algorithm) {
180 case TPM_ALG_AES:
181 OutPublic->publicArea.parameters.symDetail.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
182 Buffer += sizeof(UINT16);
183 OutPublic->publicArea.parameters.symDetail.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
184 Buffer += sizeof(UINT16);
185 break;
186 case TPM_ALG_SM4:
187 OutPublic->publicArea.parameters.symDetail.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
188 Buffer += sizeof(UINT16);
189 OutPublic->publicArea.parameters.symDetail.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
190 Buffer += sizeof(UINT16);
191 break;
192 case TPM_ALG_XOR:
193 OutPublic->publicArea.parameters.symDetail.keyBits.xor = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
194 Buffer += sizeof(UINT16);
195 break;
196 case TPM_ALG_NULL:
197 break;
198 default:
199 return EFI_UNSUPPORTED;
200 }
201 break;
202 case TPM_ALG_RSA:
203 OutPublic->publicArea.parameters.rsaDetail.symmetric.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
204 Buffer += sizeof(UINT16);
205 switch (OutPublic->publicArea.parameters.rsaDetail.symmetric.algorithm) {
206 case TPM_ALG_AES:
207 OutPublic->publicArea.parameters.rsaDetail.symmetric.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
208 Buffer += sizeof(UINT16);
209 OutPublic->publicArea.parameters.rsaDetail.symmetric.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
210 Buffer += sizeof(UINT16);
211 break;
212 case TPM_ALG_SM4:
213 OutPublic->publicArea.parameters.rsaDetail.symmetric.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
214 Buffer += sizeof(UINT16);
215 OutPublic->publicArea.parameters.rsaDetail.symmetric.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
216 Buffer += sizeof(UINT16);
217 break;
218 case TPM_ALG_NULL:
219 break;
220 default:
221 return EFI_UNSUPPORTED;
222 }
223 OutPublic->publicArea.parameters.rsaDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
224 Buffer += sizeof(UINT16);
225 switch (OutPublic->publicArea.parameters.rsaDetail.scheme.scheme) {
226 case TPM_ALG_RSASSA:
227 OutPublic->publicArea.parameters.rsaDetail.scheme.details.rsassa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
228 Buffer += sizeof(UINT16);
229 break;
230 case TPM_ALG_RSAPSS:
231 OutPublic->publicArea.parameters.rsaDetail.scheme.details.rsapss.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
232 Buffer += sizeof(UINT16);
233 break;
234 case TPM_ALG_RSAES:
235 break;
236 case TPM_ALG_OAEP:
237 OutPublic->publicArea.parameters.rsaDetail.scheme.details.oaep.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
238 Buffer += sizeof(UINT16);
239 break;
240 case TPM_ALG_NULL:
241 break;
242 default:
243 return EFI_UNSUPPORTED;
244 }
245 OutPublic->publicArea.parameters.rsaDetail.keyBits = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
246 Buffer += sizeof(UINT16);
247 OutPublic->publicArea.parameters.rsaDetail.exponent = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
248 Buffer += sizeof(UINT32);
249 break;
250 case TPM_ALG_ECC:
251 OutPublic->publicArea.parameters.eccDetail.symmetric.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
252 Buffer += sizeof(UINT16);
253 switch (OutPublic->publicArea.parameters.eccDetail.symmetric.algorithm) {
254 case TPM_ALG_AES:
255 OutPublic->publicArea.parameters.eccDetail.symmetric.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
256 Buffer += sizeof(UINT16);
257 OutPublic->publicArea.parameters.eccDetail.symmetric.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
258 Buffer += sizeof(UINT16);
259 break;
260 case TPM_ALG_SM4:
261 OutPublic->publicArea.parameters.eccDetail.symmetric.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
262 Buffer += sizeof(UINT16);
263 OutPublic->publicArea.parameters.eccDetail.symmetric.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
264 Buffer += sizeof(UINT16);
265 break;
266 case TPM_ALG_NULL:
267 break;
268 default:
269 return EFI_UNSUPPORTED;
270 }
271 OutPublic->publicArea.parameters.eccDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
272 Buffer += sizeof(UINT16);
273 switch (OutPublic->publicArea.parameters.eccDetail.scheme.scheme) {
274 case TPM_ALG_ECDSA:
275 OutPublic->publicArea.parameters.eccDetail.scheme.details.ecdsa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
276 Buffer += sizeof(UINT16);
277 break;
278 case TPM_ALG_ECDAA:
279 OutPublic->publicArea.parameters.eccDetail.scheme.details.ecdaa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
280 Buffer += sizeof(UINT16);
281 break;
282 case TPM_ALG_ECSCHNORR:
283 OutPublic->publicArea.parameters.eccDetail.scheme.details.ecSchnorr.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
284 Buffer += sizeof(UINT16);
285 break;
286 case TPM_ALG_ECDH:
287 break;
288 case TPM_ALG_NULL:
289 break;
290 default:
291 return EFI_UNSUPPORTED;
292 }
293 OutPublic->publicArea.parameters.eccDetail.curveID = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
294 Buffer += sizeof(UINT16);
295 OutPublic->publicArea.parameters.eccDetail.kdf.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
296 Buffer += sizeof(UINT16);
297 switch (OutPublic->publicArea.parameters.eccDetail.kdf.scheme) {
298 case TPM_ALG_MGF1:
299 OutPublic->publicArea.parameters.eccDetail.kdf.details.mgf1.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
300 Buffer += sizeof(UINT16);
301 break;
302 case TPM_ALG_KDF1_SP800_108:
303 OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf1_sp800_108.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
304 Buffer += sizeof(UINT16);
305 break;
306 case TPM_ALG_KDF1_SP800_56a:
307 OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf1_SP800_56a.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
308 Buffer += sizeof(UINT16);
309 break;
310 case TPM_ALG_KDF2:
311 OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf2.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
312 Buffer += sizeof(UINT16);
313 break;
314 case TPM_ALG_NULL:
315 break;
316 default:
317 return EFI_UNSUPPORTED;
318 }
319 break;
320 default:
321 return EFI_UNSUPPORTED;
322 }
323
324 // TPMU_PUBLIC_ID
325 switch (OutPublic->publicArea.type) {
326 case TPM_ALG_KEYEDHASH:
327 OutPublic->publicArea.unique.keyedHash.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
328 Buffer += sizeof(UINT16);
329 if(OutPublic->publicArea.unique.keyedHash.size > sizeof(TPMU_HA)) {
330 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - keyedHash.size error %x\n", OutPublic->publicArea.unique.keyedHash.size));
331 return EFI_DEVICE_ERROR;
332 }
333 CopyMem (OutPublic->publicArea.unique.keyedHash.buffer, Buffer, OutPublic->publicArea.unique.keyedHash.size);
334 Buffer += OutPublic->publicArea.unique.keyedHash.size;
335 break;
336 case TPM_ALG_SYMCIPHER:
337 OutPublic->publicArea.unique.sym.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
338 Buffer += sizeof(UINT16);
339 if(OutPublic->publicArea.unique.sym.size > sizeof(TPMU_HA)) {
340 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - sym.size error %x\n", OutPublic->publicArea.unique.sym.size));
341 return EFI_DEVICE_ERROR;
342 }
343 CopyMem (OutPublic->publicArea.unique.sym.buffer, Buffer, OutPublic->publicArea.unique.sym.size);
344 Buffer += OutPublic->publicArea.unique.sym.size;
345 break;
346 case TPM_ALG_RSA:
347 OutPublic->publicArea.unique.rsa.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
348 Buffer += sizeof(UINT16);
349 if(OutPublic->publicArea.unique.rsa.size > MAX_RSA_KEY_BYTES) {
350 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - rsa.size error %x\n", OutPublic->publicArea.unique.rsa.size));
351 return EFI_DEVICE_ERROR;
352 }
353 CopyMem (OutPublic->publicArea.unique.rsa.buffer, Buffer, OutPublic->publicArea.unique.rsa.size);
354 Buffer += OutPublic->publicArea.unique.rsa.size;
355 break;
356 case TPM_ALG_ECC:
357 OutPublic->publicArea.unique.ecc.x.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
358 Buffer += sizeof(UINT16);
359 if (OutPublic->publicArea.unique.ecc.x.size > MAX_ECC_KEY_BYTES) {
360 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - ecc.x.size error %x\n", OutPublic->publicArea.unique.ecc.x.size));
361 return EFI_DEVICE_ERROR;
362 }
363 CopyMem (OutPublic->publicArea.unique.ecc.x.buffer, Buffer, OutPublic->publicArea.unique.ecc.x.size);
364 Buffer += OutPublic->publicArea.unique.ecc.x.size;
365 OutPublic->publicArea.unique.ecc.y.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
366 Buffer += sizeof(UINT16);
367 if (OutPublic->publicArea.unique.ecc.y.size > MAX_ECC_KEY_BYTES) {
368 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - ecc.y.size error %x\n", OutPublic->publicArea.unique.ecc.y.size));
369 return EFI_DEVICE_ERROR;
370 }
371 CopyMem (OutPublic->publicArea.unique.ecc.y.buffer, Buffer, OutPublic->publicArea.unique.ecc.y.size);
372 Buffer += OutPublic->publicArea.unique.ecc.y.size;
373 break;
374 default:
375 return EFI_UNSUPPORTED;
376 }
377
378 CopyMem (Name->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16), NameSize);
379 Name->size = NameSize;
380
381 CopyMem (QualifiedName->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16) + NameSize + sizeof(UINT16), QualifiedNameSize);
382 QualifiedName->size = QualifiedNameSize;
383
384 return EFI_SUCCESS;
385 }