]> git.proxmox.com Git - mirror_edk2.git/blame - 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
c1d93242 1/** @file\r
07309c3d 2 This library is BaseCrypto router. It will redirect hash request to each individual\r
c1d93242
JY
3 hash handler registerd, such as SHA1, SHA256.\r
4 Platform can use PcdTpm2HashMask to mask some hash engines.\r
5\r
9fe9cf9a 6Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved. <BR>\r
c1d93242
JY
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
9fe9cf9a 26#include <Guid/ZeroGuid.h>\r
c1d93242
JY
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
9fe9cf9a
SZ
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
c1d93242
JY
44 UINTN HashInterfaceCount;\r
45 HASH_INTERFACE HashInterface[HASH_COUNT];\r
9fe9cf9a 46 UINT32 SupportedHashMask;\r
c1d93242
JY
47} HASH_INTERFACE_HOB;\r
48\r
49/**\r
9fe9cf9a
SZ
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
c1d93242 81\r
9fe9cf9a
SZ
82 @param Identifier Identifier to create hash interface hob.\r
83\r
84 @retval hash interface hob.\r
c1d93242
JY
85**/\r
86HASH_INTERFACE_HOB *\r
9fe9cf9a
SZ
87InternalCreateHashInterfaceHob (\r
88 EFI_GUID *Identifier\r
c1d93242
JY
89 )\r
90{\r
9fe9cf9a
SZ
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
c1d93242 97\r
9fe9cf9a
SZ
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
c1d93242 124 }\r
c1d93242
JY
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
1abfa4ce 144 UINT32 HashMask;\r
c1d93242 145\r
9fe9cf9a 146 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242
JY
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
9fe9cf9a
SZ
155 CheckSupportedHashMaskMismatch (HashInterfaceHob);\r
156\r
c1d93242
JY
157 HashCtx = AllocatePool (sizeof(*HashCtx) * HashInterfaceHob->HashInterfaceCount);\r
158 ASSERT (HashCtx != NULL);\r
159\r
160 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
1abfa4ce
JY
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
c1d93242
JY
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
1abfa4ce 192 UINT32 HashMask;\r
c1d93242 193\r
9fe9cf9a 194 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242
JY
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
9fe9cf9a
SZ
203 CheckSupportedHashMaskMismatch (HashInterfaceHob);\r
204\r
c1d93242
JY
205 HashCtx = (HASH_HANDLE *)HashHandle;\r
206\r
207 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
1abfa4ce
JY
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
c1d93242
JY
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
1abfa4ce 243 UINT32 HashMask;\r
c1d93242 244\r
9fe9cf9a 245 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242
JY
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
9fe9cf9a
SZ
254 CheckSupportedHashMaskMismatch (HashInterfaceHob);\r
255\r
c1d93242
JY
256 HashCtx = (HASH_HANDLE *)HashHandle;\r
257 ZeroMem (DigestList, sizeof(*DigestList));\r
258\r
259 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
1abfa4ce
JY
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
c1d93242
JY
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
9fe9cf9a 300 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242
JY
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
9fe9cf9a
SZ
309 CheckSupportedHashMaskMismatch (HashInterfaceHob);\r
310\r
c1d93242
JY
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
c1d93242 335 UINT32 HashMask;\r
fe3ca12d 336 EFI_STATUS Status;\r
c1d93242
JY
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
9fe9cf9a 346 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242 347 if (HashInterfaceHob == NULL) {\r
9fe9cf9a 348 HashInterfaceHob = InternalCreateHashInterfaceHob (&gEfiCallerIdGuid);\r
c1d93242
JY
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
9fe9cf9a
SZ
363 DEBUG ((DEBUG_ERROR, "Hash Interface (%g) has been registered\n", &HashInterface->HashGuid));\r
364 return EFI_ALREADY_STARTED;\r
c1d93242
JY
365 }\r
366 }\r
367\r
9fe9cf9a
SZ
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
c1d93242
JY
375 CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface));\r
376 HashInterfaceHob->HashInterfaceCount ++;\r
377 \r
378 return EFI_SUCCESS;\r
9fe9cf9a
SZ
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
4cc2b63b
MAL
427 ZeroMem (&HashInterfaceHob->HashInterface, sizeof (HashInterfaceHob->HashInterface));\r
428 HashInterfaceHob->HashInterfaceCount = 0;\r
73ee3aba 429 HashInterfaceHob->SupportedHashMask = 0;\r
9fe9cf9a
SZ
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