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