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