]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c
SecurityPkg: Reallocate TPM Active PCRs based on platform support
[mirror_edk2.git] / SecurityPkg / Library / HashLibBaseCryptoRouter / HashLibBaseCryptoRouterPei.c
CommitLineData
c1d93242 1/** @file\r
07309c3d 2 This library is BaseCrypto router. It will redirect hash request to each individual\r
fc70522f 3 hash handler registered, such as SHA1, SHA256.\r
c1d93242
JY
4 Platform can use PcdTpm2HashMask to mask some hash engines.\r
5\r
195f0119 6Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>\r
289b714b 7SPDX-License-Identifier: BSD-2-Clause-Patent\r
c1d93242
JY
8\r
9**/\r
10\r
11#include <PiPei.h>\r
12#include <Library/BaseLib.h>\r
13#include <Library/BaseMemoryLib.h>\r
14#include <Library/Tpm2CommandLib.h>\r
15#include <Library/DebugLib.h>\r
16#include <Library/MemoryAllocationLib.h>\r
17#include <Library/PcdLib.h>\r
18#include <Library/HobLib.h>\r
19#include <Library/HashLib.h>\r
9fe9cf9a 20#include <Guid/ZeroGuid.h>\r
c1d93242
JY
21\r
22#include "HashLibBaseCryptoRouterCommon.h"\r
23\r
24#define HASH_LIB_PEI_ROUTER_GUID \\r
25 { 0x84681c08, 0x6873, 0x46f3, { 0x8b, 0xb7, 0xab, 0x66, 0x18, 0x95, 0xa1, 0xb3 } }\r
26\r
c411b485 27EFI_GUID mHashLibPeiRouterGuid = HASH_LIB_PEI_ROUTER_GUID;\r
c1d93242
JY
28\r
29typedef struct {\r
9fe9cf9a
SZ
30 //\r
31 // If gZeroGuid, SupportedHashMask is 0 for FIRST module which consumes HashLib\r
32 // or the hash algorithm bitmap of LAST module which consumes HashLib.\r
33 // HashInterfaceCount and HashInterface are all 0.\r
34 // If gEfiCallerIdGuid, HashInterfaceCount, HashInterface and SupportedHashMask\r
35 // are the hash interface information of CURRENT module which consumes HashLib.\r
36 //\r
c411b485
MK
37 EFI_GUID Identifier;\r
38 UINTN HashInterfaceCount;\r
39 HASH_INTERFACE HashInterface[HASH_COUNT];\r
40 UINT32 SupportedHashMask;\r
c1d93242
JY
41} HASH_INTERFACE_HOB;\r
42\r
43/**\r
9fe9cf9a
SZ
44 This function gets hash interface hob.\r
45\r
46 @param Identifier Identifier to get hash interface hob.\r
47\r
48 @retval hash interface hob.\r
49**/\r
50HASH_INTERFACE_HOB *\r
51InternalGetHashInterfaceHob (\r
c411b485 52 EFI_GUID *Identifier\r
9fe9cf9a
SZ
53 )\r
54{\r
55 EFI_PEI_HOB_POINTERS Hob;\r
56 HASH_INTERFACE_HOB *HashInterfaceHob;\r
57\r
58 Hob.Raw = GetFirstGuidHob (&mHashLibPeiRouterGuid);\r
59 while (Hob.Raw != NULL) {\r
60 HashInterfaceHob = GET_GUID_HOB_DATA (Hob);\r
61 if (CompareGuid (&HashInterfaceHob->Identifier, Identifier)) {\r
62 //\r
63 // Found the matched one.\r
64 //\r
65 return HashInterfaceHob;\r
66 }\r
c411b485 67\r
9fe9cf9a
SZ
68 Hob.Raw = GET_NEXT_HOB (Hob);\r
69 Hob.Raw = GetNextGuidHob (&mHashLibPeiRouterGuid, Hob.Raw);\r
70 }\r
c411b485 71\r
9fe9cf9a
SZ
72 return NULL;\r
73}\r
74\r
75/**\r
76 This function creates hash interface hob.\r
c1d93242 77\r
9fe9cf9a
SZ
78 @param Identifier Identifier to create hash interface hob.\r
79\r
80 @retval hash interface hob.\r
c1d93242
JY
81**/\r
82HASH_INTERFACE_HOB *\r
9fe9cf9a 83InternalCreateHashInterfaceHob (\r
c411b485 84 EFI_GUID *Identifier\r
c1d93242
JY
85 )\r
86{\r
c411b485 87 HASH_INTERFACE_HOB LocalHashInterfaceHob;\r
9fe9cf9a 88\r
c411b485 89 ZeroMem (&LocalHashInterfaceHob, sizeof (LocalHashInterfaceHob));\r
9fe9cf9a 90 CopyGuid (&LocalHashInterfaceHob.Identifier, Identifier);\r
c411b485 91 return BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof (LocalHashInterfaceHob));\r
9fe9cf9a 92}\r
c1d93242 93\r
9fe9cf9a
SZ
94/**\r
95 Check mismatch of supported HashMask between modules\r
96 that may link different HashInstanceLib instances.\r
97\r
98 @param HashInterfaceHobCurrent Pointer to hash interface hob for CURRENT module.\r
99\r
100**/\r
101VOID\r
102CheckSupportedHashMaskMismatch (\r
c411b485 103 IN HASH_INTERFACE_HOB *HashInterfaceHobCurrent\r
9fe9cf9a
SZ
104 )\r
105{\r
c411b485 106 HASH_INTERFACE_HOB *HashInterfaceHobLast;\r
9fe9cf9a
SZ
107\r
108 HashInterfaceHobLast = InternalGetHashInterfaceHob (&gZeroGuid);\r
109 ASSERT (HashInterfaceHobLast != NULL);\r
110\r
111 if ((HashInterfaceHobLast->SupportedHashMask != 0) &&\r
c411b485
MK
112 (HashInterfaceHobCurrent->SupportedHashMask != HashInterfaceHobLast->SupportedHashMask))\r
113 {\r
9fe9cf9a
SZ
114 DEBUG ((\r
115 DEBUG_WARN,\r
116 "WARNING: There is mismatch of supported HashMask (0x%x - 0x%x) between modules\n",\r
117 HashInterfaceHobCurrent->SupportedHashMask,\r
118 HashInterfaceHobLast->SupportedHashMask\r
119 ));\r
120 DEBUG ((DEBUG_WARN, "that are linking different HashInstanceLib instances!\n"));\r
c1d93242 121 }\r
c1d93242
JY
122}\r
123\r
124/**\r
125 Start hash sequence.\r
126\r
127 @param HashHandle Hash handle.\r
128\r
129 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.\r
130 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
131**/\r
132EFI_STATUS\r
133EFIAPI\r
134HashStart (\r
c411b485 135 OUT HASH_HANDLE *HashHandle\r
c1d93242
JY
136 )\r
137{\r
c411b485
MK
138 HASH_INTERFACE_HOB *HashInterfaceHob;\r
139 HASH_HANDLE *HashCtx;\r
140 UINTN Index;\r
141 UINT32 HashMask;\r
c1d93242 142\r
9fe9cf9a 143 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242
JY
144 if (HashInterfaceHob == NULL) {\r
145 return EFI_UNSUPPORTED;\r
146 }\r
147\r
148 if (HashInterfaceHob->HashInterfaceCount == 0) {\r
149 return EFI_UNSUPPORTED;\r
150 }\r
151\r
9fe9cf9a
SZ
152 CheckSupportedHashMaskMismatch (HashInterfaceHob);\r
153\r
c411b485 154 HashCtx = AllocatePool (sizeof (*HashCtx) * HashInterfaceHob->HashInterfaceCount);\r
c1d93242
JY
155 ASSERT (HashCtx != NULL);\r
156\r
157 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
1abfa4ce
JY
158 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);\r
159 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
160 HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]);\r
161 }\r
c1d93242
JY
162 }\r
163\r
164 *HashHandle = (HASH_HANDLE)HashCtx;\r
165\r
166 return EFI_SUCCESS;\r
167}\r
168\r
169/**\r
170 Update hash sequence data.\r
171\r
172 @param HashHandle Hash handle.\r
173 @param DataToHash Data to be hashed.\r
174 @param DataToHashLen Data size.\r
175\r
176 @retval EFI_SUCCESS Hash sequence updated.\r
177**/\r
178EFI_STATUS\r
179EFIAPI\r
180HashUpdate (\r
c411b485
MK
181 IN HASH_HANDLE HashHandle,\r
182 IN VOID *DataToHash,\r
183 IN UINTN DataToHashLen\r
c1d93242
JY
184 )\r
185{\r
c411b485
MK
186 HASH_INTERFACE_HOB *HashInterfaceHob;\r
187 HASH_HANDLE *HashCtx;\r
188 UINTN Index;\r
189 UINT32 HashMask;\r
c1d93242 190\r
9fe9cf9a 191 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242
JY
192 if (HashInterfaceHob == NULL) {\r
193 return EFI_UNSUPPORTED;\r
194 }\r
195\r
196 if (HashInterfaceHob->HashInterfaceCount == 0) {\r
197 return EFI_UNSUPPORTED;\r
198 }\r
199\r
9fe9cf9a
SZ
200 CheckSupportedHashMaskMismatch (HashInterfaceHob);\r
201\r
c1d93242
JY
202 HashCtx = (HASH_HANDLE *)HashHandle;\r
203\r
204 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
1abfa4ce
JY
205 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);\r
206 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
207 HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
208 }\r
c1d93242
JY
209 }\r
210\r
211 return EFI_SUCCESS;\r
212}\r
213\r
214/**\r
215 Hash sequence complete and extend to PCR.\r
216\r
217 @param HashHandle Hash handle.\r
218 @param PcrIndex PCR to be extended.\r
219 @param DataToHash Data to be hashed.\r
220 @param DataToHashLen Data size.\r
221 @param DigestList Digest list.\r
222\r
223 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.\r
224**/\r
225EFI_STATUS\r
226EFIAPI\r
227HashCompleteAndExtend (\r
c411b485
MK
228 IN HASH_HANDLE HashHandle,\r
229 IN TPMI_DH_PCR PcrIndex,\r
230 IN VOID *DataToHash,\r
231 IN UINTN DataToHashLen,\r
232 OUT TPML_DIGEST_VALUES *DigestList\r
c1d93242
JY
233 )\r
234{\r
c411b485
MK
235 TPML_DIGEST_VALUES Digest;\r
236 HASH_INTERFACE_HOB *HashInterfaceHob;\r
237 HASH_HANDLE *HashCtx;\r
238 UINTN Index;\r
239 EFI_STATUS Status;\r
240 UINT32 HashMask;\r
c1d93242 241\r
9fe9cf9a 242 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242
JY
243 if (HashInterfaceHob == NULL) {\r
244 return EFI_UNSUPPORTED;\r
245 }\r
246\r
247 if (HashInterfaceHob->HashInterfaceCount == 0) {\r
248 return EFI_UNSUPPORTED;\r
249 }\r
250\r
9fe9cf9a
SZ
251 CheckSupportedHashMaskMismatch (HashInterfaceHob);\r
252\r
c1d93242 253 HashCtx = (HASH_HANDLE *)HashHandle;\r
c411b485 254 ZeroMem (DigestList, sizeof (*DigestList));\r
c1d93242
JY
255\r
256 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
1abfa4ce
JY
257 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);\r
258 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
259 HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
260 HashInterfaceHob->HashInterface[Index].HashFinal (HashCtx[Index], &Digest);\r
261 Tpm2SetHashToDigestList (DigestList, &Digest);\r
262 }\r
c1d93242
JY
263 }\r
264\r
265 FreePool (HashCtx);\r
266\r
267 Status = Tpm2PcrExtend (\r
268 PcrIndex,\r
269 DigestList\r
270 );\r
271 return Status;\r
272}\r
273\r
274/**\r
275 Hash data and extend to PCR.\r
276\r
277 @param PcrIndex PCR to be extended.\r
278 @param DataToHash Data to be hashed.\r
279 @param DataToHashLen Data size.\r
280 @param DigestList Digest list.\r
281\r
282 @retval EFI_SUCCESS Hash data and DigestList is returned.\r
283**/\r
284EFI_STATUS\r
285EFIAPI\r
286HashAndExtend (\r
c411b485
MK
287 IN TPMI_DH_PCR PcrIndex,\r
288 IN VOID *DataToHash,\r
289 IN UINTN DataToHashLen,\r
290 OUT TPML_DIGEST_VALUES *DigestList\r
c1d93242
JY
291 )\r
292{\r
c411b485
MK
293 HASH_INTERFACE_HOB *HashInterfaceHob;\r
294 HASH_HANDLE HashHandle;\r
295 EFI_STATUS Status;\r
c1d93242 296\r
9fe9cf9a 297 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242
JY
298 if (HashInterfaceHob == NULL) {\r
299 return EFI_UNSUPPORTED;\r
300 }\r
301\r
302 if (HashInterfaceHob->HashInterfaceCount == 0) {\r
303 return EFI_UNSUPPORTED;\r
304 }\r
305\r
9fe9cf9a
SZ
306 CheckSupportedHashMaskMismatch (HashInterfaceHob);\r
307\r
c1d93242
JY
308 HashStart (&HashHandle);\r
309 HashUpdate (HashHandle, DataToHash, DataToHashLen);\r
310 Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);\r
311\r
312 return Status;\r
313}\r
314\r
315/**\r
316 This service register Hash.\r
317\r
318 @param HashInterface Hash interface\r
319\r
320 @retval EFI_SUCCESS This hash interface is registered successfully.\r
321 @retval EFI_UNSUPPORTED System does not support register this interface.\r
322 @retval EFI_ALREADY_STARTED System already register this interface.\r
323**/\r
324EFI_STATUS\r
325EFIAPI\r
326RegisterHashInterfaceLib (\r
c411b485 327 IN HASH_INTERFACE *HashInterface\r
c1d93242
JY
328 )\r
329{\r
c411b485
MK
330 UINTN Index;\r
331 HASH_INTERFACE_HOB *HashInterfaceHob;\r
332 UINT32 HashMask;\r
195f0119 333 UINT32 Tpm2HashMask;\r
c411b485 334 EFI_STATUS Status;\r
c1d93242
JY
335\r
336 //\r
337 // Check allow\r
338 //\r
195f0119
RGC
339 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);\r
340 Tpm2HashMask = PcdGet32 (PcdTpm2HashMask);\r
341\r
342 if ((Tpm2HashMask != 0) &&\r
343 ((HashMask & Tpm2HashMask) == 0))\r
344 {\r
c1d93242
JY
345 return EFI_UNSUPPORTED;\r
346 }\r
347\r
9fe9cf9a 348 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242 349 if (HashInterfaceHob == NULL) {\r
9fe9cf9a 350 HashInterfaceHob = InternalCreateHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242
JY
351 if (HashInterfaceHob == NULL) {\r
352 return EFI_OUT_OF_RESOURCES;\r
353 }\r
354 }\r
355\r
356 if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {\r
357 return EFI_OUT_OF_RESOURCES;\r
358 }\r
359\r
360 //\r
361 // Check duplication\r
362 //\r
363 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
364 if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) {\r
9fe9cf9a
SZ
365 DEBUG ((DEBUG_ERROR, "Hash Interface (%g) has been registered\n", &HashInterface->HashGuid));\r
366 return EFI_ALREADY_STARTED;\r
c1d93242
JY
367 }\r
368 }\r
369\r
9fe9cf9a
SZ
370 //\r
371 // Record hash algorithm bitmap of CURRENT module which consumes HashLib.\r
372 //\r
373 HashInterfaceHob->SupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap) | HashMask;\r
c411b485 374 Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, HashInterfaceHob->SupportedHashMask);\r
9fe9cf9a
SZ
375 ASSERT_EFI_ERROR (Status);\r
376\r
c411b485
MK
377 CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof (*HashInterface));\r
378 HashInterfaceHob->HashInterfaceCount++;\r
b3548d32 379\r
c1d93242 380 return EFI_SUCCESS;\r
9fe9cf9a
SZ
381}\r
382\r
383/**\r
384 The constructor function of HashLibBaseCryptoRouterPei.\r
385\r
386 @param FileHandle The handle of FFS header the loaded driver.\r
387 @param PeiServices The pointer to the PEI services.\r
388\r
389 @retval EFI_SUCCESS The constructor executes successfully.\r
390 @retval EFI_OUT_OF_RESOURCES There is no enough resource for the constructor.\r
391\r
392**/\r
393EFI_STATUS\r
394EFIAPI\r
395HashLibBaseCryptoRouterPeiConstructor (\r
c411b485
MK
396 IN EFI_PEI_FILE_HANDLE FileHandle,\r
397 IN CONST EFI_PEI_SERVICES **PeiServices\r
9fe9cf9a
SZ
398 )\r
399{\r
c411b485
MK
400 EFI_STATUS Status;\r
401 HASH_INTERFACE_HOB *HashInterfaceHob;\r
9fe9cf9a
SZ
402\r
403 HashInterfaceHob = InternalGetHashInterfaceHob (&gZeroGuid);\r
404 if (HashInterfaceHob == NULL) {\r
405 //\r
406 // No HOB with gZeroGuid Identifier has been created,\r
407 // this is FIRST module which consumes HashLib.\r
408 // Create the HOB with gZeroGuid Identifier.\r
409 //\r
410 HashInterfaceHob = InternalCreateHashInterfaceHob (&gZeroGuid);\r
411 if (HashInterfaceHob == NULL) {\r
412 return EFI_OUT_OF_RESOURCES;\r
413 }\r
414 } else {\r
415 //\r
416 // Record hash algorithm bitmap of LAST module which also consumes HashLib.\r
417 //\r
418 HashInterfaceHob->SupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
419 }\r
420\r
421 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
422 if (HashInterfaceHob != NULL) {\r
423 //\r
424 // In PEI phase, some modules may call RegisterForShadow and will be\r
425 // shadowed and executed again after memory is discovered.\r
426 // This is the second execution of this module, clear the hash interface\r
427 // information registered at its first execution.\r
428 //\r
4cc2b63b
MAL
429 ZeroMem (&HashInterfaceHob->HashInterface, sizeof (HashInterfaceHob->HashInterface));\r
430 HashInterfaceHob->HashInterfaceCount = 0;\r
c411b485 431 HashInterfaceHob->SupportedHashMask = 0;\r
9fe9cf9a
SZ
432 }\r
433\r
434 //\r
435 // Set PcdTcg2HashAlgorithmBitmap to 0 in CONSTRUCTOR for CURRENT module.\r
436 //\r
437 Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, 0);\r
438 ASSERT_EFI_ERROR (Status);\r
439\r
440 return EFI_SUCCESS;\r
441}\r