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