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
;
88 ResponseCode
= SwapBytes32 (RecvBuffer
.Header
.responseCode
);
89 if (ResponseCode
!= TPM_RC_SUCCESS
) {
90 DEBUG ((DEBUG_ERROR
, "Tpm2ReadPublic - responseCode - %x\n", SwapBytes32 (RecvBuffer
.Header
.responseCode
)));
93 switch (ResponseCode
) {
98 // objectHandle references a sequence object
99 return EFI_INVALID_PARAMETER
;
101 return EFI_DEVICE_ERROR
;
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
;
113 NameSize
= SwapBytes16 (
115 (UINT16
*)((UINT8
*)&RecvBuffer
+ sizeof (TPM2_RESPONSE_HEADER
) +
116 sizeof (UINT16
) + OutPublicSize
)
119 if (NameSize
> sizeof (TPMU_NAME
)) {
120 DEBUG ((DEBUG_ERROR
, "Tpm2ReadPublic - NameSize error %x\n", NameSize
));
121 return EFI_DEVICE_ERROR
;
124 QualifiedNameSize
= SwapBytes16 (
126 (UINT16
*)((UINT8
*)&RecvBuffer
+ sizeof (TPM2_RESPONSE_HEADER
) +
127 sizeof (UINT16
) + OutPublicSize
+
128 sizeof (UINT16
) + NameSize
)
131 if (QualifiedNameSize
> sizeof (TPMU_NAME
)) {
132 DEBUG ((DEBUG_ERROR
, "Tpm2ReadPublic - QualifiedNameSize error %x\n", QualifiedNameSize
));
133 return EFI_DEVICE_ERROR
;
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
;
142 // Return the response
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
;
158 CopyMem (OutPublic
->publicArea
.authPolicy
.buffer
, Buffer
, OutPublic
->publicArea
.authPolicy
.size
);
159 Buffer
+= OutPublic
->publicArea
.authPolicy
.size
;
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
) {
168 OutPublic
->publicArea
.parameters
.keyedHashDetail
.scheme
.details
.hmac
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
169 Buffer
+= sizeof (UINT16
);
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
);
178 return EFI_UNSUPPORTED
;
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
) {
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
);
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
);
198 OutPublic
->publicArea
.parameters
.symDetail
.keyBits
.xor = SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
199 Buffer
+= sizeof (UINT16
);
204 return EFI_UNSUPPORTED
;
209 OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.algorithm
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
210 Buffer
+= sizeof (UINT16
);
211 switch (OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.algorithm
) {
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
);
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
);
227 return EFI_UNSUPPORTED
;
230 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.scheme
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
231 Buffer
+= sizeof (UINT16
);
232 switch (OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.scheme
) {
234 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.rsassa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
235 Buffer
+= sizeof (UINT16
);
238 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.rsapss
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
239 Buffer
+= sizeof (UINT16
);
244 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.oaep
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
245 Buffer
+= sizeof (UINT16
);
250 return EFI_UNSUPPORTED
;
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
);
259 OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.algorithm
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
260 Buffer
+= sizeof (UINT16
);
261 switch (OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.algorithm
) {
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
);
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
);
277 return EFI_UNSUPPORTED
;
280 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.scheme
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
281 Buffer
+= sizeof (UINT16
);
282 switch (OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.scheme
) {
284 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecdsa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
285 Buffer
+= sizeof (UINT16
);
288 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecdaa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
289 Buffer
+= sizeof (UINT16
);
291 case TPM_ALG_ECSCHNORR
:
292 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecSchnorr
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
293 Buffer
+= sizeof (UINT16
);
300 return EFI_UNSUPPORTED
;
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
) {
309 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.details
.mgf1
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
310 Buffer
+= sizeof (UINT16
);
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
);
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
);
321 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.details
.kdf2
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
322 Buffer
+= sizeof (UINT16
);
327 return EFI_UNSUPPORTED
;
332 return EFI_UNSUPPORTED
;
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
;
345 CopyMem (OutPublic
->publicArea
.unique
.keyedHash
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.keyedHash
.size
);
346 Buffer
+= OutPublic
->publicArea
.unique
.keyedHash
.size
;
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
;
356 CopyMem (OutPublic
->publicArea
.unique
.sym
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.sym
.size
);
357 Buffer
+= OutPublic
->publicArea
.unique
.sym
.size
;
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
;
367 CopyMem (OutPublic
->publicArea
.unique
.rsa
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.rsa
.size
);
368 Buffer
+= OutPublic
->publicArea
.unique
.rsa
.size
;
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
;
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
;
387 CopyMem (OutPublic
->publicArea
.unique
.ecc
.y
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.ecc
.y
.size
);
388 Buffer
+= OutPublic
->publicArea
.unique
.ecc
.y
.size
;
391 return EFI_UNSUPPORTED
;
394 CopyMem (Name
->name
, (UINT8
*)&RecvBuffer
+ sizeof (TPM2_RESPONSE_HEADER
) + sizeof (UINT16
) + OutPublicSize
+ sizeof (UINT16
), NameSize
);
395 Name
->size
= NameSize
;
397 CopyMem (QualifiedName
->name
, (UINT8
*)&RecvBuffer
+ sizeof (TPM2_RESPONSE_HEADER
) + sizeof (UINT16
) + OutPublicSize
+ sizeof (UINT16
) + NameSize
+ sizeof (UINT16
), QualifiedNameSize
);
398 QualifiedName
->size
= QualifiedNameSize
;