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