2 Implement TPM2 Object related command.
4 Copyright (c) 2017, 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 NameSize
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)((UINT8
*)&RecvBuffer
+ sizeof(TPM2_RESPONSE_HEADER
) +
113 sizeof(UINT16
) + OutPublicSize
)));
114 QualifiedNameSize
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)((UINT8
*)&RecvBuffer
+ sizeof(TPM2_RESPONSE_HEADER
) +
115 sizeof(UINT16
) + OutPublicSize
+
116 sizeof(UINT16
) + NameSize
)));
118 if (RecvBufferSize
!= sizeof(TPM2_RESPONSE_HEADER
) + sizeof(UINT16
) + OutPublicSize
+ sizeof(UINT16
) + NameSize
+ sizeof(UINT16
) + QualifiedNameSize
) {
119 DEBUG ((DEBUG_ERROR
, "Tpm2ReadPublic - RecvBufferSize %x Error - OutPublicSize %x, NameSize %x, QualifiedNameSize %x\n", RecvBufferSize
, OutPublicSize
, NameSize
, QualifiedNameSize
));
120 return EFI_DEVICE_ERROR
;
124 // Return the response
126 Buffer
= (UINT8
*)&RecvBuffer
.OutPublic
;
127 CopyMem (OutPublic
, &RecvBuffer
.OutPublic
, sizeof(UINT16
) + OutPublicSize
);
128 OutPublic
->size
= OutPublicSize
;
129 OutPublic
->publicArea
.type
= SwapBytes16 (OutPublic
->publicArea
.type
);
130 OutPublic
->publicArea
.nameAlg
= SwapBytes16 (OutPublic
->publicArea
.nameAlg
);
131 WriteUnaligned32 ((UINT32
*)&OutPublic
->publicArea
.objectAttributes
, SwapBytes32 (ReadUnaligned32 ((UINT32
*)&OutPublic
->publicArea
.objectAttributes
)));
132 Buffer
= (UINT8
*)&RecvBuffer
.OutPublic
.publicArea
.authPolicy
;
133 OutPublic
->publicArea
.authPolicy
.size
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
134 Buffer
+= sizeof(UINT16
);
135 CopyMem (OutPublic
->publicArea
.authPolicy
.buffer
, Buffer
, OutPublic
->publicArea
.authPolicy
.size
);
136 Buffer
+= OutPublic
->publicArea
.authPolicy
.size
;
139 switch (OutPublic
->publicArea
.type
) {
140 case TPM_ALG_KEYEDHASH
:
141 OutPublic
->publicArea
.parameters
.keyedHashDetail
.scheme
.scheme
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
142 Buffer
+= sizeof(UINT16
);
143 switch (OutPublic
->publicArea
.parameters
.keyedHashDetail
.scheme
.scheme
) {
145 OutPublic
->publicArea
.parameters
.keyedHashDetail
.scheme
.details
.hmac
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
146 Buffer
+= sizeof(UINT16
);
149 OutPublic
->publicArea
.parameters
.keyedHashDetail
.scheme
.details
.xor.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
150 Buffer
+= sizeof(UINT16
);
151 OutPublic
->publicArea
.parameters
.keyedHashDetail
.scheme
.details
.xor.kdf
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
152 Buffer
+= sizeof(UINT16
);
155 return EFI_UNSUPPORTED
;
157 case TPM_ALG_SYMCIPHER
:
158 OutPublic
->publicArea
.parameters
.symDetail
.algorithm
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
159 Buffer
+= sizeof(UINT16
);
160 switch (OutPublic
->publicArea
.parameters
.symDetail
.algorithm
) {
162 OutPublic
->publicArea
.parameters
.symDetail
.keyBits
.aes
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
163 Buffer
+= sizeof(UINT16
);
164 OutPublic
->publicArea
.parameters
.symDetail
.mode
.aes
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
165 Buffer
+= sizeof(UINT16
);
168 OutPublic
->publicArea
.parameters
.symDetail
.keyBits
.SM4
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
169 Buffer
+= sizeof(UINT16
);
170 OutPublic
->publicArea
.parameters
.symDetail
.mode
.SM4
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
171 Buffer
+= sizeof(UINT16
);
174 OutPublic
->publicArea
.parameters
.symDetail
.keyBits
.xor = SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
175 Buffer
+= sizeof(UINT16
);
180 return EFI_UNSUPPORTED
;
184 OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.algorithm
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
185 Buffer
+= sizeof(UINT16
);
186 switch (OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.algorithm
) {
188 OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.keyBits
.aes
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
189 Buffer
+= sizeof(UINT16
);
190 OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.mode
.aes
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
191 Buffer
+= sizeof(UINT16
);
194 OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.keyBits
.SM4
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
195 Buffer
+= sizeof(UINT16
);
196 OutPublic
->publicArea
.parameters
.rsaDetail
.symmetric
.mode
.SM4
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
197 Buffer
+= sizeof(UINT16
);
202 return EFI_UNSUPPORTED
;
204 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.scheme
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
205 Buffer
+= sizeof(UINT16
);
206 switch (OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.scheme
) {
208 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.rsassa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
209 Buffer
+= sizeof(UINT16
);
212 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.rsapss
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
213 Buffer
+= sizeof(UINT16
);
218 OutPublic
->publicArea
.parameters
.rsaDetail
.scheme
.details
.oaep
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
219 Buffer
+= sizeof(UINT16
);
224 return EFI_UNSUPPORTED
;
226 OutPublic
->publicArea
.parameters
.rsaDetail
.keyBits
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
227 Buffer
+= sizeof(UINT16
);
228 OutPublic
->publicArea
.parameters
.rsaDetail
.exponent
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
229 Buffer
+= sizeof(UINT32
);
232 OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.algorithm
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
233 Buffer
+= sizeof(UINT16
);
234 switch (OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.algorithm
) {
236 OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.keyBits
.aes
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
237 Buffer
+= sizeof(UINT16
);
238 OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.mode
.aes
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
239 Buffer
+= sizeof(UINT16
);
242 OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.keyBits
.SM4
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
243 Buffer
+= sizeof(UINT16
);
244 OutPublic
->publicArea
.parameters
.eccDetail
.symmetric
.mode
.SM4
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
245 Buffer
+= sizeof(UINT16
);
250 return EFI_UNSUPPORTED
;
252 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.scheme
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
253 Buffer
+= sizeof(UINT16
);
254 switch (OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.scheme
) {
256 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecdsa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
257 Buffer
+= sizeof(UINT16
);
260 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecdaa
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
261 Buffer
+= sizeof(UINT16
);
263 case TPM_ALG_ECSCHNORR
:
264 OutPublic
->publicArea
.parameters
.eccDetail
.scheme
.details
.ecSchnorr
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
265 Buffer
+= sizeof(UINT16
);
272 return EFI_UNSUPPORTED
;
274 OutPublic
->publicArea
.parameters
.eccDetail
.curveID
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
275 Buffer
+= sizeof(UINT16
);
276 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.scheme
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
277 Buffer
+= sizeof(UINT16
);
278 switch (OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.scheme
) {
280 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.details
.mgf1
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
281 Buffer
+= sizeof(UINT16
);
283 case TPM_ALG_KDF1_SP800_108
:
284 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.details
.kdf1_sp800_108
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
285 Buffer
+= sizeof(UINT16
);
287 case TPM_ALG_KDF1_SP800_56a
:
288 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.details
.kdf1_SP800_56a
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
289 Buffer
+= sizeof(UINT16
);
292 OutPublic
->publicArea
.parameters
.eccDetail
.kdf
.details
.kdf2
.hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
293 Buffer
+= sizeof(UINT16
);
298 return EFI_UNSUPPORTED
;
302 return EFI_UNSUPPORTED
;
306 switch (OutPublic
->publicArea
.type
) {
307 case TPM_ALG_KEYEDHASH
:
308 OutPublic
->publicArea
.unique
.keyedHash
.size
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
309 Buffer
+= sizeof(UINT16
);
310 CopyMem (OutPublic
->publicArea
.unique
.keyedHash
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.keyedHash
.size
);
311 Buffer
+= OutPublic
->publicArea
.unique
.keyedHash
.size
;
313 case TPM_ALG_SYMCIPHER
:
314 OutPublic
->publicArea
.unique
.sym
.size
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
315 Buffer
+= sizeof(UINT16
);
316 CopyMem (OutPublic
->publicArea
.unique
.sym
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.sym
.size
);
317 Buffer
+= OutPublic
->publicArea
.unique
.sym
.size
;
320 OutPublic
->publicArea
.unique
.rsa
.size
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
321 Buffer
+= sizeof(UINT16
);
322 CopyMem (OutPublic
->publicArea
.unique
.rsa
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.rsa
.size
);
323 Buffer
+= OutPublic
->publicArea
.unique
.rsa
.size
;
326 OutPublic
->publicArea
.unique
.ecc
.x
.size
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
327 Buffer
+= sizeof(UINT16
);
328 CopyMem (OutPublic
->publicArea
.unique
.ecc
.x
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.ecc
.x
.size
);
329 Buffer
+= OutPublic
->publicArea
.unique
.ecc
.x
.size
;
330 OutPublic
->publicArea
.unique
.ecc
.y
.size
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
331 Buffer
+= sizeof(UINT16
);
332 CopyMem (OutPublic
->publicArea
.unique
.ecc
.y
.buffer
, Buffer
, OutPublic
->publicArea
.unique
.ecc
.y
.size
);
333 Buffer
+= OutPublic
->publicArea
.unique
.ecc
.y
.size
;
336 return EFI_UNSUPPORTED
;
339 CopyMem (Name
->name
, (UINT8
*)&RecvBuffer
+ sizeof(TPM2_RESPONSE_HEADER
) + sizeof(UINT16
) + OutPublicSize
+ sizeof(UINT16
), NameSize
);
340 Name
->size
= NameSize
;
342 CopyMem (QualifiedName
->name
, (UINT8
*)&RecvBuffer
+ sizeof(TPM2_RESPONSE_HEADER
) + sizeof(UINT16
) + OutPublicSize
+ sizeof(UINT16
) + NameSize
+ sizeof(UINT16
), QualifiedNameSize
);
343 QualifiedName
->size
= QualifiedNameSize
;