2 Implement TPM2 Object related command.
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
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.
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>
25 TPM2_COMMAND_HEADER Header
;
26 TPMI_DH_OBJECT ObjectHandle
;
27 } TPM2_READ_PUBLIC_COMMAND
;
30 TPM2_RESPONSE_HEADER Header
;
31 TPM2B_PUBLIC OutPublic
;
33 TPM2B_NAME QualifiedName
;
34 } TPM2_READ_PUBLIC_RESPONSE
;
39 This command allows access to the public area of a loaded object.
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
46 @retval EFI_SUCCESS Operation completed successfully.
47 @retval EFI_DEVICE_ERROR Unexpected device behavior.
52 IN TPMI_DH_OBJECT ObjectHandle
,
53 OUT TPM2B_PUBLIC
*OutPublic
,
55 OUT TPM2B_NAME
*QualifiedName
59 TPM2_READ_PUBLIC_COMMAND SendBuffer
;
60 TPM2_READ_PUBLIC_RESPONSE RecvBuffer
;
61 UINT32 SendBufferSize
;
62 UINT32 RecvBufferSize
;
67 UINT16 QualifiedNameSize
;
72 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_NO_SESSIONS
);
73 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_ReadPublic
);
75 SendBuffer
.ObjectHandle
= SwapBytes32 (ObjectHandle
);
77 SendBufferSize
= (UINT32
) sizeof (SendBuffer
);
78 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
83 RecvBufferSize
= sizeof (RecvBuffer
);
84 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
85 if (EFI_ERROR (Status
)) {
89 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
90 DEBUG ((DEBUG_ERROR
, "Tpm2ReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize
));
91 return EFI_DEVICE_ERROR
;
93 ResponseCode
= SwapBytes32(RecvBuffer
.Header
.responseCode
);
94 if (ResponseCode
!= TPM_RC_SUCCESS
) {
95 DEBUG ((DEBUG_ERROR
, "Tpm2ReadPublic - responseCode - %x\n", SwapBytes32(RecvBuffer
.Header
.responseCode
)));
97 switch (ResponseCode
) {
101 case TPM_RC_SEQUENCE
:
102 // objectHandle references a sequence object
103 return EFI_INVALID_PARAMETER
;
105 return EFI_DEVICE_ERROR
;
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
;
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
;
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
;
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
;
138 // Return the response
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
;
154 CopyMem (OutPublic
->publicArea
.authPolicy
.buffer
, Buffer
, OutPublic
->publicArea
.authPolicy
.size
);
155 Buffer
+= OutPublic
->publicArea
.authPolicy
.size
;
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
) {
164 OutPublic
->publicArea
.parameters
.keyedHashDetail
.scheme
.details
.hmac
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
165 Buffer
+= sizeof(UINT16
);
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
);
174 return EFI_UNSUPPORTED
;
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
) {
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
);
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
);
193 OutPublic
->publicArea
.parameters
.symDetail
.keyBits
.xor = SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
194 Buffer
+= sizeof(UINT16
);
199 return EFI_UNSUPPORTED
;
203 OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.algorithm
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
204 Buffer
+= sizeof(UINT16
);
205 switch (OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.algorithm
) {
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
);
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
);
221 return EFI_UNSUPPORTED
;
223 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.scheme
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
224 Buffer
+= sizeof(UINT16
);
225 switch (OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.scheme
) {
227 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.rsassa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
228 Buffer
+= sizeof(UINT16
);
231 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.rsapss
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
232 Buffer
+= sizeof(UINT16
);
237 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.oaep
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
238 Buffer
+= sizeof(UINT16
);
243 return EFI_UNSUPPORTED
;
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
);
251 OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.algorithm
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
252 Buffer
+= sizeof(UINT16
);
253 switch (OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.algorithm
) {
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
);
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
);
269 return EFI_UNSUPPORTED
;
271 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.scheme
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
272 Buffer
+= sizeof(UINT16
);
273 switch (OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.scheme
) {
275 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecdsa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
276 Buffer
+= sizeof(UINT16
);
279 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecdaa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
280 Buffer
+= sizeof(UINT16
);
282 case TPM_ALG_ECSCHNORR
:
283 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecSchnorr
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
284 Buffer
+= sizeof(UINT16
);
291 return EFI_UNSUPPORTED
;
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
) {
299 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.details
.mgf1
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
300 Buffer
+= sizeof(UINT16
);
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
);
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
);
311 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.details
.kdf2
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
312 Buffer
+= sizeof(UINT16
);
317 return EFI_UNSUPPORTED
;
321 return EFI_UNSUPPORTED
;
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
;
333 CopyMem (OutPublic
->publicArea
.unique
.keyedHash
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.keyedHash
.size
);
334 Buffer
+= OutPublic
->publicArea
.unique
.keyedHash
.size
;
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
;
343 CopyMem (OutPublic
->publicArea
.unique
.sym
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.sym
.size
);
344 Buffer
+= OutPublic
->publicArea
.unique
.sym
.size
;
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
;
353 CopyMem (OutPublic
->publicArea
.unique
.rsa
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.rsa
.size
);
354 Buffer
+= OutPublic
->publicArea
.unique
.rsa
.size
;
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
;
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
;
371 CopyMem (OutPublic
->publicArea
.unique
.ecc
.y
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.ecc
.y
.size
);
372 Buffer
+= OutPublic
->publicArea
.unique
.ecc
.y
.size
;
375 return EFI_UNSUPPORTED
;
378 CopyMem (Name
->name
, (UINT8
*)&RecvBuffer
+ sizeof(TPM2_RESPONSE_HEADER
) + sizeof(UINT16
) + OutPublicSize
+ sizeof(UINT16
), NameSize
);
379 Name
->size
= NameSize
;
381 CopyMem (QualifiedName
->name
, (UINT8
*)&RecvBuffer
+ sizeof(TPM2_RESPONSE_HEADER
) + sizeof(UINT16
) + OutPublicSize
+ sizeof(UINT16
) + NameSize
+ sizeof(UINT16
), QualifiedNameSize
);
382 QualifiedName
->size
= QualifiedNameSize
;