]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c
SecurityPkg/TpmCommandLib: Add Tpm2ReadPublic.
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Object.c
CommitLineData
087132a8
JY
1/** @file\r
2 Implement TPM2 Object related command.\r
3\r
4Copyright (c) 2017, Intel Corporation. All rights reserved. <BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <IndustryStandard/UefiTcgPlatform.h>\r
16#include <Library/Tpm2CommandLib.h>\r
17#include <Library/Tpm2DeviceLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/BaseLib.h>\r
20#include <Library/DebugLib.h>\r
21\r
22#pragma pack(1)\r
23\r
24typedef struct {\r
25 TPM2_COMMAND_HEADER Header;\r
26 TPMI_DH_OBJECT ObjectHandle;\r
27} TPM2_READ_PUBLIC_COMMAND;\r
28\r
29typedef struct {\r
30 TPM2_RESPONSE_HEADER Header;\r
31 TPM2B_PUBLIC OutPublic;\r
32 TPM2B_NAME Name;\r
33 TPM2B_NAME QualifiedName;\r
34} TPM2_READ_PUBLIC_RESPONSE;\r
35\r
36#pragma pack()\r
37\r
38/**\r
39 This command allows access to the public area of a loaded object.\r
40\r
41 @param[in] ObjectHandle TPM handle of an object\r
42 @param[out] OutPublic Structure containing the public area of an object\r
43 @param[out] Name Name of the object\r
44 @param[out] QualifiedName The Qualified Name of the object\r
45\r
46 @retval EFI_SUCCESS Operation completed successfully.\r
47 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
48**/\r
49EFI_STATUS\r
50EFIAPI\r
51Tpm2ReadPublic (\r
52 IN TPMI_DH_OBJECT ObjectHandle,\r
53 OUT TPM2B_PUBLIC *OutPublic,\r
54 OUT TPM2B_NAME *Name,\r
55 OUT TPM2B_NAME *QualifiedName\r
56 )\r
57{\r
58 EFI_STATUS Status;\r
59 TPM2_READ_PUBLIC_COMMAND SendBuffer;\r
60 TPM2_READ_PUBLIC_RESPONSE RecvBuffer;\r
61 UINT32 SendBufferSize;\r
62 UINT32 RecvBufferSize;\r
63 TPM_RC ResponseCode;\r
64 UINT8 *Buffer;\r
65 UINT16 OutPublicSize;\r
66 UINT16 NameSize;\r
67 UINT16 QualifiedNameSize;\r
68\r
69 //\r
70 // Construct command\r
71 //\r
72 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
73 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_ReadPublic);\r
74\r
75 SendBuffer.ObjectHandle = SwapBytes32 (ObjectHandle);\r
76\r
77 SendBufferSize = (UINT32) sizeof (SendBuffer);\r
78 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
79\r
80 //\r
81 // send Tpm command\r
82 //\r
83 RecvBufferSize = sizeof (RecvBuffer);\r
84 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
85 if (EFI_ERROR (Status)) {\r
86 return Status;\r
87 }\r
88\r
89 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
90 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize));\r
91 return EFI_DEVICE_ERROR;\r
92 }\r
93 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);\r
94 if (ResponseCode != TPM_RC_SUCCESS) {\r
95 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
96 }\r
97 switch (ResponseCode) {\r
98 case TPM_RC_SUCCESS:\r
99 // return data\r
100 break;\r
101 case TPM_RC_SEQUENCE:\r
102 // objectHandle references a sequence object\r
103 return EFI_INVALID_PARAMETER;\r
104 default:\r
105 return EFI_DEVICE_ERROR;\r
106 }\r
107\r
108 //\r
109 // Basic check\r
110 //\r
111 OutPublicSize = SwapBytes16 (RecvBuffer.OutPublic.size);\r
112 NameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) +\r
113 sizeof(UINT16) + OutPublicSize)));\r
114 QualifiedNameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) +\r
115 sizeof(UINT16) + OutPublicSize +\r
116 sizeof(UINT16) + NameSize)));\r
117\r
118 if (RecvBufferSize != sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16) + NameSize + sizeof(UINT16) + QualifiedNameSize) {\r
119 DEBUG ((DEBUG_ERROR, "Tpm2ReadPublic - RecvBufferSize %x Error - OutPublicSize %x, NameSize %x, QualifiedNameSize %x\n", RecvBufferSize, OutPublicSize, NameSize, QualifiedNameSize));\r
120 return EFI_DEVICE_ERROR;\r
121 }\r
122\r
123 //\r
124 // Return the response\r
125 //\r
126 Buffer = (UINT8 *)&RecvBuffer.OutPublic;\r
127 CopyMem (OutPublic, &RecvBuffer.OutPublic, sizeof(UINT16) + OutPublicSize);\r
128 OutPublic->size = OutPublicSize;\r
129 OutPublic->publicArea.type = SwapBytes16 (OutPublic->publicArea.type);\r
130 OutPublic->publicArea.nameAlg = SwapBytes16 (OutPublic->publicArea.nameAlg);\r
131 WriteUnaligned32 ((UINT32 *)&OutPublic->publicArea.objectAttributes, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&OutPublic->publicArea.objectAttributes)));\r
132 Buffer = (UINT8 *)&RecvBuffer.OutPublic.publicArea.authPolicy;\r
133 OutPublic->publicArea.authPolicy.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
134 Buffer += sizeof(UINT16);\r
135 CopyMem (OutPublic->publicArea.authPolicy.buffer, Buffer, OutPublic->publicArea.authPolicy.size);\r
136 Buffer += OutPublic->publicArea.authPolicy.size;\r
137\r
138 // TPMU_PUBLIC_PARMS\r
139 switch (OutPublic->publicArea.type) {\r
140 case TPM_ALG_KEYEDHASH:\r
141 OutPublic->publicArea.parameters.keyedHashDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
142 Buffer += sizeof(UINT16);\r
143 switch (OutPublic->publicArea.parameters.keyedHashDetail.scheme.scheme) {\r
144 case TPM_ALG_HMAC:\r
145 OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
146 Buffer += sizeof(UINT16);\r
147 break;\r
148 case TPM_ALG_XOR:\r
149 OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.xor.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
150 Buffer += sizeof(UINT16);\r
151 OutPublic->publicArea.parameters.keyedHashDetail.scheme.details.xor.kdf = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
152 Buffer += sizeof(UINT16);\r
153 break;\r
154 default:\r
155 return EFI_UNSUPPORTED;\r
156 }\r
157 case TPM_ALG_SYMCIPHER:\r
158 OutPublic->publicArea.parameters.symDetail.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
159 Buffer += sizeof(UINT16);\r
160 switch (OutPublic->publicArea.parameters.symDetail.algorithm) {\r
161 case TPM_ALG_AES:\r
162 OutPublic->publicArea.parameters.symDetail.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
163 Buffer += sizeof(UINT16);\r
164 OutPublic->publicArea.parameters.symDetail.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
165 Buffer += sizeof(UINT16);\r
166 break;\r
167 case TPM_ALG_SM4:\r
168 OutPublic->publicArea.parameters.symDetail.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
169 Buffer += sizeof(UINT16);\r
170 OutPublic->publicArea.parameters.symDetail.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
171 Buffer += sizeof(UINT16);\r
172 break;\r
173 case TPM_ALG_XOR:\r
174 OutPublic->publicArea.parameters.symDetail.keyBits.xor = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
175 Buffer += sizeof(UINT16);\r
176 break;\r
177 case TPM_ALG_NULL:\r
178 break;\r
179 default:\r
180 return EFI_UNSUPPORTED;\r
181 }\r
182 break;\r
183 case TPM_ALG_RSA:\r
184 OutPublic->publicArea.parameters.rsaDetail.symmetric.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
185 Buffer += sizeof(UINT16);\r
186 switch (OutPublic->publicArea.parameters.rsaDetail.symmetric.algorithm) {\r
187 case TPM_ALG_AES:\r
188 OutPublic->publicArea.parameters.rsaDetail.symmetric.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
189 Buffer += sizeof(UINT16);\r
190 OutPublic->publicArea.parameters.rsaDetail.symmetric.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
191 Buffer += sizeof(UINT16);\r
192 break;\r
193 case TPM_ALG_SM4:\r
194 OutPublic->publicArea.parameters.rsaDetail.symmetric.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
195 Buffer += sizeof(UINT16);\r
196 OutPublic->publicArea.parameters.rsaDetail.symmetric.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
197 Buffer += sizeof(UINT16);\r
198 break;\r
199 case TPM_ALG_NULL:\r
200 break;\r
201 default:\r
202 return EFI_UNSUPPORTED;\r
203 }\r
204 OutPublic->publicArea.parameters.rsaDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
205 Buffer += sizeof(UINT16);\r
206 switch (OutPublic->publicArea.parameters.rsaDetail.scheme.scheme) {\r
207 case TPM_ALG_RSASSA:\r
208 OutPublic->publicArea.parameters.rsaDetail.scheme.details.rsassa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
209 Buffer += sizeof(UINT16);\r
210 break;\r
211 case TPM_ALG_RSAPSS:\r
212 OutPublic->publicArea.parameters.rsaDetail.scheme.details.rsapss.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
213 Buffer += sizeof(UINT16);\r
214 break;\r
215 case TPM_ALG_RSAES:\r
216 break;\r
217 case TPM_ALG_OAEP:\r
218 OutPublic->publicArea.parameters.rsaDetail.scheme.details.oaep.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
219 Buffer += sizeof(UINT16);\r
220 break;\r
221 case TPM_ALG_NULL:\r
222 break;\r
223 default:\r
224 return EFI_UNSUPPORTED;\r
225 }\r
226 OutPublic->publicArea.parameters.rsaDetail.keyBits = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
227 Buffer += sizeof(UINT16);\r
228 OutPublic->publicArea.parameters.rsaDetail.exponent = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
229 Buffer += sizeof(UINT32);\r
230 break;\r
231 case TPM_ALG_ECC:\r
232 OutPublic->publicArea.parameters.eccDetail.symmetric.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
233 Buffer += sizeof(UINT16);\r
234 switch (OutPublic->publicArea.parameters.eccDetail.symmetric.algorithm) {\r
235 case TPM_ALG_AES:\r
236 OutPublic->publicArea.parameters.eccDetail.symmetric.keyBits.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
237 Buffer += sizeof(UINT16);\r
238 OutPublic->publicArea.parameters.eccDetail.symmetric.mode.aes = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
239 Buffer += sizeof(UINT16);\r
240 break;\r
241 case TPM_ALG_SM4:\r
242 OutPublic->publicArea.parameters.eccDetail.symmetric.keyBits.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
243 Buffer += sizeof(UINT16);\r
244 OutPublic->publicArea.parameters.eccDetail.symmetric.mode.SM4 = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
245 Buffer += sizeof(UINT16);\r
246 break;\r
247 case TPM_ALG_NULL:\r
248 break;\r
249 default:\r
250 return EFI_UNSUPPORTED;\r
251 }\r
252 OutPublic->publicArea.parameters.eccDetail.scheme.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
253 Buffer += sizeof(UINT16);\r
254 switch (OutPublic->publicArea.parameters.eccDetail.scheme.scheme) {\r
255 case TPM_ALG_ECDSA:\r
256 OutPublic->publicArea.parameters.eccDetail.scheme.details.ecdsa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
257 Buffer += sizeof(UINT16);\r
258 break;\r
259 case TPM_ALG_ECDAA:\r
260 OutPublic->publicArea.parameters.eccDetail.scheme.details.ecdaa.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
261 Buffer += sizeof(UINT16);\r
262 break;\r
263 case TPM_ALG_ECSCHNORR:\r
264 OutPublic->publicArea.parameters.eccDetail.scheme.details.ecSchnorr.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
265 Buffer += sizeof(UINT16);\r
266 break;\r
267 case TPM_ALG_ECDH:\r
268 break;\r
269 case TPM_ALG_NULL:\r
270 break;\r
271 default:\r
272 return EFI_UNSUPPORTED;\r
273 }\r
274 OutPublic->publicArea.parameters.eccDetail.curveID = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
275 Buffer += sizeof(UINT16);\r
276 OutPublic->publicArea.parameters.eccDetail.kdf.scheme = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
277 Buffer += sizeof(UINT16);\r
278 switch (OutPublic->publicArea.parameters.eccDetail.kdf.scheme) {\r
279 case TPM_ALG_MGF1:\r
280 OutPublic->publicArea.parameters.eccDetail.kdf.details.mgf1.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
281 Buffer += sizeof(UINT16);\r
282 break;\r
283 case TPM_ALG_KDF1_SP800_108:\r
284 OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf1_sp800_108.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
285 Buffer += sizeof(UINT16);\r
286 break;\r
287 case TPM_ALG_KDF1_SP800_56a:\r
288 OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf1_SP800_56a.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
289 Buffer += sizeof(UINT16);\r
290 break;\r
291 case TPM_ALG_KDF2:\r
292 OutPublic->publicArea.parameters.eccDetail.kdf.details.kdf2.hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
293 Buffer += sizeof(UINT16);\r
294 break;\r
295 case TPM_ALG_NULL:\r
296 break;\r
297 default:\r
298 return EFI_UNSUPPORTED;\r
299 }\r
300 break;\r
301 default:\r
302 return EFI_UNSUPPORTED;\r
303 }\r
304\r
305 // TPMU_PUBLIC_ID\r
306 switch (OutPublic->publicArea.type) {\r
307 case TPM_ALG_KEYEDHASH:\r
308 OutPublic->publicArea.unique.keyedHash.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
309 Buffer += sizeof(UINT16);\r
310 CopyMem (OutPublic->publicArea.unique.keyedHash.buffer, Buffer, OutPublic->publicArea.unique.keyedHash.size);\r
311 Buffer += OutPublic->publicArea.unique.keyedHash.size;\r
312 break;\r
313 case TPM_ALG_SYMCIPHER:\r
314 OutPublic->publicArea.unique.sym.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
315 Buffer += sizeof(UINT16);\r
316 CopyMem (OutPublic->publicArea.unique.sym.buffer, Buffer, OutPublic->publicArea.unique.sym.size);\r
317 Buffer += OutPublic->publicArea.unique.sym.size;\r
318 break;\r
319 case TPM_ALG_RSA:\r
320 OutPublic->publicArea.unique.rsa.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
321 Buffer += sizeof(UINT16);\r
322 CopyMem (OutPublic->publicArea.unique.rsa.buffer, Buffer, OutPublic->publicArea.unique.rsa.size);\r
323 Buffer += OutPublic->publicArea.unique.rsa.size;\r
324 break;\r
325 case TPM_ALG_ECC:\r
326 OutPublic->publicArea.unique.ecc.x.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
327 Buffer += sizeof(UINT16);\r
328 CopyMem (OutPublic->publicArea.unique.ecc.x.buffer, Buffer, OutPublic->publicArea.unique.ecc.x.size);\r
329 Buffer += OutPublic->publicArea.unique.ecc.x.size;\r
330 OutPublic->publicArea.unique.ecc.y.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
331 Buffer += sizeof(UINT16);\r
332 CopyMem (OutPublic->publicArea.unique.ecc.y.buffer, Buffer, OutPublic->publicArea.unique.ecc.y.size);\r
333 Buffer += OutPublic->publicArea.unique.ecc.y.size;\r
334 break;\r
335 default:\r
336 return EFI_UNSUPPORTED;\r
337 }\r
338\r
339 CopyMem (Name->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16), NameSize);\r
340 Name->size = NameSize;\r
341\r
342 CopyMem (QualifiedName->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + OutPublicSize + sizeof(UINT16) + NameSize + sizeof(UINT16), QualifiedNameSize);\r
343 QualifiedName->size = QualifiedNameSize;\r
344\r
345 return EFI_SUCCESS;\r
346}\r