]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c
SecurityPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Help.c
CommitLineData
c1d93242
JY
1/** @file\r
2 Implement TPM2 help.\r
3\r
dd577319 4Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>\r
289b714b 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
c1d93242
JY
6\r
7**/\r
8\r
9#include <IndustryStandard/UefiTcgPlatform.h>\r
10#include <Library/Tpm2CommandLib.h>\r
11#include <Library/Tpm2DeviceLib.h>\r
12#include <Library/BaseMemoryLib.h>\r
13#include <Library/BaseLib.h>\r
14#include <Library/DebugLib.h>\r
15\r
16typedef struct {\r
17 TPMI_ALG_HASH HashAlgo;\r
18 UINT16 HashSize;\r
b8ae1f4d 19 UINT32 HashMask;\r
c1d93242
JY
20} INTERNAL_HASH_INFO;\r
21\r
22STATIC INTERNAL_HASH_INFO mHashInfo[] = {\r
b8ae1f4d
SZ
23 {TPM_ALG_SHA1, SHA1_DIGEST_SIZE, HASH_ALG_SHA1},\r
24 {TPM_ALG_SHA256, SHA256_DIGEST_SIZE, HASH_ALG_SHA256},\r
25 {TPM_ALG_SM3_256, SM3_256_DIGEST_SIZE, HASH_ALG_SM3_256},\r
26 {TPM_ALG_SHA384, SHA384_DIGEST_SIZE, HASH_ALG_SHA384},\r
27 {TPM_ALG_SHA512, SHA512_DIGEST_SIZE, HASH_ALG_SHA512},\r
c1d93242
JY
28};\r
29\r
30/**\r
31 Return size of digest.\r
32\r
33 @param[in] HashAlgo Hash algorithm\r
34\r
35 @return size of digest\r
36**/\r
37UINT16\r
38EFIAPI\r
39GetHashSizeFromAlgo (\r
40 IN TPMI_ALG_HASH HashAlgo\r
41 )\r
42{\r
43 UINTN Index;\r
44\r
45 for (Index = 0; Index < sizeof(mHashInfo)/sizeof(mHashInfo[0]); Index++) {\r
46 if (mHashInfo[Index].HashAlgo == HashAlgo) {\r
47 return mHashInfo[Index].HashSize;\r
48 }\r
49 }\r
50 return 0;\r
51}\r
52\r
b8ae1f4d
SZ
53/**\r
54 Get hash mask from algorithm.\r
55\r
56 @param[in] HashAlgo Hash algorithm\r
57\r
58 @return Hash mask\r
59**/\r
60UINT32\r
61EFIAPI\r
62GetHashMaskFromAlgo (\r
63 IN TPMI_ALG_HASH HashAlgo\r
64 )\r
65{\r
66 UINTN Index;\r
67\r
68 for (Index = 0; Index < sizeof(mHashInfo)/sizeof(mHashInfo[0]); Index++) {\r
69 if (mHashInfo[Index].HashAlgo == HashAlgo) {\r
70 return mHashInfo[Index].HashMask;\r
71 }\r
72 }\r
73 return 0;\r
74}\r
75\r
c1d93242
JY
76/**\r
77 Copy AuthSessionIn to TPM2 command buffer.\r
78\r
79 @param [in] AuthSessionIn Input AuthSession data\r
80 @param [out] AuthSessionOut Output AuthSession data in TPM2 command buffer\r
81\r
82 @return AuthSession size\r
83**/\r
84UINT32\r
85EFIAPI\r
86CopyAuthSessionCommand (\r
87 IN TPMS_AUTH_COMMAND *AuthSessionIn, OPTIONAL\r
88 OUT UINT8 *AuthSessionOut\r
89 )\r
90{\r
91 UINT8 *Buffer;\r
92\r
93 Buffer = (UINT8 *)AuthSessionOut;\r
b3548d32 94\r
c1d93242
JY
95 //\r
96 // Add in Auth session\r
97 //\r
98 if (AuthSessionIn != NULL) {\r
99 // sessionHandle\r
100 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(AuthSessionIn->sessionHandle));\r
101 Buffer += sizeof(UINT32);\r
102\r
103 // nonce\r
104 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthSessionIn->nonce.size));\r
105 Buffer += sizeof(UINT16);\r
106\r
107 CopyMem (Buffer, AuthSessionIn->nonce.buffer, AuthSessionIn->nonce.size);\r
108 Buffer += AuthSessionIn->nonce.size;\r
109\r
110 // sessionAttributes\r
111 *(UINT8 *)Buffer = *(UINT8 *)&AuthSessionIn->sessionAttributes;\r
58dbfc3c 112 Buffer++;\r
c1d93242
JY
113\r
114 // hmac\r
115 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthSessionIn->hmac.size));\r
116 Buffer += sizeof(UINT16);\r
117\r
118 CopyMem (Buffer, AuthSessionIn->hmac.buffer, AuthSessionIn->hmac.size);\r
119 Buffer += AuthSessionIn->hmac.size;\r
120 } else {\r
121 // sessionHandle\r
122 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(TPM_RS_PW));\r
123 Buffer += sizeof(UINT32);\r
124\r
125 // nonce = nullNonce\r
126 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(0));\r
127 Buffer += sizeof(UINT16);\r
128\r
129 // sessionAttributes = 0\r
130 *(UINT8 *)Buffer = 0x00;\r
58dbfc3c 131 Buffer++;\r
c1d93242
JY
132\r
133 // hmac = nullAuth\r
134 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(0));\r
135 Buffer += sizeof(UINT16);\r
136 }\r
137\r
4333b99d 138 return (UINT32)((UINTN)Buffer - (UINTN)AuthSessionOut);\r
c1d93242
JY
139}\r
140\r
141/**\r
142 Copy AuthSessionIn from TPM2 response buffer.\r
143\r
144 @param [in] AuthSessionIn Input AuthSession data in TPM2 response buffer\r
145 @param [out] AuthSessionOut Output AuthSession data\r
146\r
dd577319
ZC
147 @return 0 copy failed\r
148 else AuthSession size\r
c1d93242
JY
149**/\r
150UINT32\r
151EFIAPI\r
152CopyAuthSessionResponse (\r
153 IN UINT8 *AuthSessionIn,\r
154 OUT TPMS_AUTH_RESPONSE *AuthSessionOut OPTIONAL\r
155 )\r
156{\r
157 UINT8 *Buffer;\r
158 TPMS_AUTH_RESPONSE LocalAuthSessionOut;\r
159\r
160 if (AuthSessionOut == NULL) {\r
161 AuthSessionOut = &LocalAuthSessionOut;\r
162 }\r
163\r
164 Buffer = (UINT8 *)AuthSessionIn;\r
165\r
166 // nonce\r
167 AuthSessionOut->nonce.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
168 Buffer += sizeof(UINT16);\r
dd577319
ZC
169 if (AuthSessionOut->nonce.size > sizeof(TPMU_HA)) {\r
170 DEBUG ((DEBUG_ERROR, "CopyAuthSessionResponse - nonce.size error %x\n", AuthSessionOut->nonce.size));\r
171 return 0;\r
172 }\r
c1d93242
JY
173\r
174 CopyMem (AuthSessionOut->nonce.buffer, Buffer, AuthSessionOut->nonce.size);\r
175 Buffer += AuthSessionOut->nonce.size;\r
176\r
177 // sessionAttributes\r
178 *(UINT8 *)&AuthSessionOut->sessionAttributes = *(UINT8 *)Buffer;\r
58dbfc3c 179 Buffer++;\r
c1d93242
JY
180\r
181 // hmac\r
182 AuthSessionOut->hmac.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
183 Buffer += sizeof(UINT16);\r
dd577319
ZC
184 if (AuthSessionOut->hmac.size > sizeof(TPMU_HA)) {\r
185 DEBUG ((DEBUG_ERROR, "CopyAuthSessionResponse - hmac.size error %x\n", AuthSessionOut->hmac.size));\r
186 return 0;\r
187 }\r
c1d93242
JY
188\r
189 CopyMem (AuthSessionOut->hmac.buffer, Buffer, AuthSessionOut->hmac.size);\r
190 Buffer += AuthSessionOut->hmac.size;\r
191\r
4333b99d 192 return (UINT32)((UINTN)Buffer - (UINTN)AuthSessionIn);\r
c1d93242 193}\r
d4b9b2c3 194\r
f5e34e37
JY
195/**\r
196 Return if hash alg is supported in HashAlgorithmMask.\r
197\r
198 @param HashAlg Hash algorithm to be checked.\r
199 @param HashAlgorithmMask Bitfield of allowed hash algorithms.\r
200\r
201 @retval TRUE Hash algorithm is supported.\r
202 @retval FALSE Hash algorithm is not supported.\r
203**/\r
204BOOLEAN\r
697c30b1 205EFIAPI\r
f5e34e37
JY
206IsHashAlgSupportedInHashAlgorithmMask(\r
207 IN TPMI_ALG_HASH HashAlg,\r
208 IN UINT32 HashAlgorithmMask\r
209 )\r
210{\r
211 switch (HashAlg) {\r
212 case TPM_ALG_SHA1:\r
213 if ((HashAlgorithmMask & HASH_ALG_SHA1) != 0) {\r
214 return TRUE;\r
215 }\r
216 break;\r
217 case TPM_ALG_SHA256:\r
218 if ((HashAlgorithmMask & HASH_ALG_SHA256) != 0) {\r
219 return TRUE;\r
220 }\r
221 break;\r
222 case TPM_ALG_SHA384:\r
223 if ((HashAlgorithmMask & HASH_ALG_SHA384) != 0) {\r
224 return TRUE;\r
225 }\r
226 break;\r
227 case TPM_ALG_SHA512:\r
228 if ((HashAlgorithmMask & HASH_ALG_SHA512) != 0) {\r
229 return TRUE;\r
230 }\r
231 break;\r
232 case TPM_ALG_SM3_256:\r
233 if ((HashAlgorithmMask & HASH_ALG_SM3_256) != 0) {\r
234 return TRUE;\r
235 }\r
236 break;\r
237 }\r
238\r
239 return FALSE;\r
240}\r
241\r
242/**\r
243 Copy TPML_DIGEST_VALUES into a buffer\r
244\r
ae1a4284 245 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.\r
f5e34e37
JY
246 @param[in] DigestList TPML_DIGEST_VALUES to be copied.\r
247 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.\r
248\r
249 @return The end of buffer to hold TPML_DIGEST_VALUES.\r
250**/\r
251VOID *\r
252EFIAPI\r
253CopyDigestListToBuffer (\r
254 IN OUT VOID *Buffer,\r
255 IN TPML_DIGEST_VALUES *DigestList,\r
256 IN UINT32 HashAlgorithmMask\r
257 )\r
258{\r
259 UINTN Index;\r
260 UINT16 DigestSize;\r
be93a17b
SZ
261 UINT32 DigestListCount;\r
262 UINT32 *DigestListCountPtr;\r
f5e34e37 263\r
be93a17b
SZ
264 DigestListCountPtr = (UINT32 *) Buffer;\r
265 DigestListCount = 0;\r
f5e34e37
JY
266 Buffer = (UINT8 *)Buffer + sizeof(DigestList->count);\r
267 for (Index = 0; Index < DigestList->count; Index++) {\r
268 if (!IsHashAlgSupportedInHashAlgorithmMask(DigestList->digests[Index].hashAlg, HashAlgorithmMask)) {\r
269 DEBUG ((EFI_D_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n", DigestList->digests[Index].hashAlg));\r
270 continue;\r
271 }\r
272 CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof(DigestList->digests[Index].hashAlg));\r
273 Buffer = (UINT8 *)Buffer + sizeof(DigestList->digests[Index].hashAlg);\r
274 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
275 CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);\r
276 Buffer = (UINT8 *)Buffer + DigestSize;\r
be93a17b 277 DigestListCount++;\r
f5e34e37 278 }\r
be93a17b 279 WriteUnaligned32 (DigestListCountPtr, DigestListCount);\r
f5e34e37
JY
280\r
281 return Buffer;\r
282}\r
283\r
77e55cf4
JY
284/**\r
285 Get TPML_DIGEST_VALUES data size.\r
286\r
287 @param[in] DigestList TPML_DIGEST_VALUES data.\r
288\r
289 @return TPML_DIGEST_VALUES data size.\r
290**/\r
291UINT32\r
292EFIAPI\r
293GetDigestListSize (\r
294 IN TPML_DIGEST_VALUES *DigestList\r
295 )\r
296{\r
297 UINTN Index;\r
298 UINT16 DigestSize;\r
299 UINT32 TotalSize;\r
300\r
301 TotalSize = sizeof(DigestList->count);\r
302 for (Index = 0; Index < DigestList->count; Index++) {\r
303 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
304 TotalSize += sizeof(DigestList->digests[Index].hashAlg) + DigestSize;\r
305 }\r
306\r
307 return TotalSize;\r
308}\r
309\r
d4b9b2c3
JY
310/**\r
311 This function get digest from digest list.\r
312\r
f28ab849
SZ
313 @param[in] HashAlg Digest algorithm\r
314 @param[in] DigestList Digest list\r
315 @param[out] Digest Digest\r
d4b9b2c3 316\r
f28ab849
SZ
317 @retval EFI_SUCCESS Digest is found and returned.\r
318 @retval EFI_NOT_FOUND Digest is not found.\r
d4b9b2c3
JY
319**/\r
320EFI_STATUS\r
321EFIAPI\r
322GetDigestFromDigestList (\r
323 IN TPMI_ALG_HASH HashAlg,\r
324 IN TPML_DIGEST_VALUES *DigestList,\r
f28ab849 325 OUT VOID *Digest\r
d4b9b2c3
JY
326 )\r
327{\r
328 UINTN Index;\r
329 UINT16 DigestSize;\r
330\r
331 DigestSize = GetHashSizeFromAlgo (HashAlg);\r
332 for (Index = 0; Index < DigestList->count; Index++) {\r
333 if (DigestList->digests[Index].hashAlg == HashAlg) {\r
334 CopyMem (\r
335 Digest,\r
336 &DigestList->digests[Index].digest,\r
337 DigestSize\r
338 );\r
339 return EFI_SUCCESS;\r
340 }\r
341 }\r
342\r
343 return EFI_NOT_FOUND;\r
f28ab849 344}\r