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