2 Implement TPM2 Object related command.
4 Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
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>
19 TPM2_COMMAND_HEADER Header
;
20 TPMI_DH_OBJECT ObjectHandle
;
21 } TPM2_READ_PUBLIC_COMMAND
;
24 TPM2_RESPONSE_HEADER Header
;
25 TPM2B_PUBLIC OutPublic
;
27 TPM2B_NAME QualifiedName
;
28 } TPM2_READ_PUBLIC_RESPONSE
;
33 This command allows access to the public area of a loaded object.
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
40 @retval EFI_SUCCESS Operation completed successfully.
41 @retval EFI_DEVICE_ERROR Unexpected device behavior.
46 IN TPMI_DH_OBJECT ObjectHandle
,
47 OUT TPM2B_PUBLIC
*OutPublic
,
49 OUT TPM2B_NAME
*QualifiedName
53 TPM2_READ_PUBLIC_COMMAND SendBuffer
;
54 TPM2_READ_PUBLIC_RESPONSE RecvBuffer
;
55 UINT32 SendBufferSize
;
56 UINT32 RecvBufferSize
;
61 UINT16 QualifiedNameSize
;
66 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_NO_SESSIONS
);
67 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_ReadPublic
);
69 SendBuffer
.ObjectHandle
= SwapBytes32 (ObjectHandle
);
71 SendBufferSize
= (UINT32
) sizeof (SendBuffer
);
72 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
77 RecvBufferSize
= sizeof (RecvBuffer
);
78 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
79 if (EFI_ERROR (Status
)) {
83 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
84 DEBUG ((DEBUG_ERROR
, "Tpm2ReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize
));
85 return EFI_DEVICE_ERROR
;
87 ResponseCode
= SwapBytes32(RecvBuffer
.Header
.responseCode
);
88 if (ResponseCode
!= TPM_RC_SUCCESS
) {
89 DEBUG ((DEBUG_ERROR
, "Tpm2ReadPublic - responseCode - %x\n", SwapBytes32(RecvBuffer
.Header
.responseCode
)));
91 switch (ResponseCode
) {
96 // objectHandle references a sequence object
97 return EFI_INVALID_PARAMETER
;
99 return EFI_DEVICE_ERROR
;
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
;
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
;
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
;
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
;
132 // Return the response
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
;
148 CopyMem (OutPublic
->publicArea
.authPolicy
.buffer
, Buffer
, OutPublic
->publicArea
.authPolicy
.size
);
149 Buffer
+= OutPublic
->publicArea
.authPolicy
.size
;
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
) {
158 OutPublic
->publicArea
.parameters
.keyedHashDetail
.scheme
.details
.hmac
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
159 Buffer
+= sizeof(UINT16
);
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
);
168 return EFI_UNSUPPORTED
;
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
) {
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
);
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
);
187 OutPublic
->publicArea
.parameters
.symDetail
.keyBits
.xor = SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
188 Buffer
+= sizeof(UINT16
);
193 return EFI_UNSUPPORTED
;
197 OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.algorithm
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
198 Buffer
+= sizeof(UINT16
);
199 switch (OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.algorithm
) {
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
);
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
);
215 return EFI_UNSUPPORTED
;
217 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.scheme
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
218 Buffer
+= sizeof(UINT16
);
219 switch (OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.scheme
) {
221 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.rsassa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
222 Buffer
+= sizeof(UINT16
);
225 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.rsapss
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
226 Buffer
+= sizeof(UINT16
);
231 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.oaep
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
232 Buffer
+= sizeof(UINT16
);
237 return EFI_UNSUPPORTED
;
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
);
245 OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.algorithm
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
246 Buffer
+= sizeof(UINT16
);
247 switch (OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.algorithm
) {
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
);
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
);
263 return EFI_UNSUPPORTED
;
265 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.scheme
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
266 Buffer
+= sizeof(UINT16
);
267 switch (OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.scheme
) {
269 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecdsa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
270 Buffer
+= sizeof(UINT16
);
273 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecdaa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
274 Buffer
+= sizeof(UINT16
);
276 case TPM_ALG_ECSCHNORR
:
277 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecSchnorr
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
278 Buffer
+= sizeof(UINT16
);
285 return EFI_UNSUPPORTED
;
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
) {
293 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.details
.mgf1
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
294 Buffer
+= sizeof(UINT16
);
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
);
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
);
305 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.details
.kdf2
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
306 Buffer
+= sizeof(UINT16
);
311 return EFI_UNSUPPORTED
;
315 return EFI_UNSUPPORTED
;
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
;
327 CopyMem (OutPublic
->publicArea
.unique
.keyedHash
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.keyedHash
.size
);
328 Buffer
+= OutPublic
->publicArea
.unique
.keyedHash
.size
;
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
;
337 CopyMem (OutPublic
->publicArea
.unique
.sym
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.sym
.size
);
338 Buffer
+= OutPublic
->publicArea
.unique
.sym
.size
;
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
;
347 CopyMem (OutPublic
->publicArea
.unique
.rsa
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.rsa
.size
);
348 Buffer
+= OutPublic
->publicArea
.unique
.rsa
.size
;
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
;
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
;
365 CopyMem (OutPublic
->publicArea
.unique
.ecc
.y
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.ecc
.y
.size
);
366 Buffer
+= OutPublic
->publicArea
.unique
.ecc
.y
.size
;
369 return EFI_UNSUPPORTED
;
372 CopyMem (Name
->name
, (UINT8
*)&RecvBuffer
+ sizeof(TPM2_RESPONSE_HEADER
) + sizeof(UINT16
) + OutPublicSize
+ sizeof(UINT16
), NameSize
);
373 Name
->size
= NameSize
;
375 CopyMem (QualifiedName
->name
, (UINT8
*)&RecvBuffer
+ sizeof(TPM2_RESPONSE_HEADER
) + sizeof(UINT16
) + OutPublicSize
+ sizeof(UINT16
) + NameSize
+ sizeof(UINT16
), QualifiedNameSize
);
376 QualifiedName
->size
= QualifiedNameSize
;