2 This library is BaseCrypto router. It will redirect hash request to each individual
3 hash handler registered, such as SHA1, SHA256.
4 Platform can use PcdTpm2HashMask to mask some hash engines.
6 Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/Tpm2CommandLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/MemoryAllocationLib.h>
17 #include <Library/PcdLib.h>
18 #include <Library/HobLib.h>
19 #include <Library/HashLib.h>
20 #include <Guid/ZeroGuid.h>
22 #include "HashLibBaseCryptoRouterCommon.h"
24 #define HASH_LIB_PEI_ROUTER_GUID \
25 { 0x84681c08, 0x6873, 0x46f3, { 0x8b, 0xb7, 0xab, 0x66, 0x18, 0x95, 0xa1, 0xb3 } }
27 EFI_GUID mHashLibPeiRouterGuid
= HASH_LIB_PEI_ROUTER_GUID
;
31 // If gZeroGuid, SupportedHashMask is 0 for FIRST module which consumes HashLib
32 // or the hash algorithm bitmap of LAST module which consumes HashLib.
33 // HashInterfaceCount and HashInterface are all 0.
34 // If gEfiCallerIdGuid, HashInterfaceCount, HashInterface and SupportedHashMask
35 // are the hash interface information of CURRENT module which consumes HashLib.
38 UINTN HashInterfaceCount
;
39 HASH_INTERFACE HashInterface
[HASH_COUNT
];
40 UINT32 SupportedHashMask
;
44 This function gets hash interface hob.
46 @param Identifier Identifier to get hash interface hob.
48 @retval hash interface hob.
51 InternalGetHashInterfaceHob (
55 EFI_PEI_HOB_POINTERS Hob
;
56 HASH_INTERFACE_HOB
*HashInterfaceHob
;
58 Hob
.Raw
= GetFirstGuidHob (&mHashLibPeiRouterGuid
);
59 while (Hob
.Raw
!= NULL
) {
60 HashInterfaceHob
= GET_GUID_HOB_DATA (Hob
);
61 if (CompareGuid (&HashInterfaceHob
->Identifier
, Identifier
)) {
63 // Found the matched one.
65 return HashInterfaceHob
;
68 Hob
.Raw
= GET_NEXT_HOB (Hob
);
69 Hob
.Raw
= GetNextGuidHob (&mHashLibPeiRouterGuid
, Hob
.Raw
);
76 This function creates hash interface hob.
78 @param Identifier Identifier to create hash interface hob.
80 @retval hash interface hob.
83 InternalCreateHashInterfaceHob (
87 HASH_INTERFACE_HOB LocalHashInterfaceHob
;
89 ZeroMem (&LocalHashInterfaceHob
, sizeof (LocalHashInterfaceHob
));
90 CopyGuid (&LocalHashInterfaceHob
.Identifier
, Identifier
);
91 return BuildGuidDataHob (&mHashLibPeiRouterGuid
, &LocalHashInterfaceHob
, sizeof (LocalHashInterfaceHob
));
95 Check mismatch of supported HashMask between modules
96 that may link different HashInstanceLib instances.
98 @param HashInterfaceHobCurrent Pointer to hash interface hob for CURRENT module.
102 CheckSupportedHashMaskMismatch (
103 IN HASH_INTERFACE_HOB
*HashInterfaceHobCurrent
106 HASH_INTERFACE_HOB
*HashInterfaceHobLast
;
108 HashInterfaceHobLast
= InternalGetHashInterfaceHob (&gZeroGuid
);
109 ASSERT (HashInterfaceHobLast
!= NULL
);
111 if ((HashInterfaceHobLast
->SupportedHashMask
!= 0) &&
112 (HashInterfaceHobCurrent
->SupportedHashMask
!= HashInterfaceHobLast
->SupportedHashMask
))
116 "WARNING: There is mismatch of supported HashMask (0x%x - 0x%x) between modules\n",
117 HashInterfaceHobCurrent
->SupportedHashMask
,
118 HashInterfaceHobLast
->SupportedHashMask
120 DEBUG ((DEBUG_WARN
, "that are linking different HashInstanceLib instances!\n"));
127 @param HashHandle Hash handle.
129 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
130 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
135 OUT HASH_HANDLE
*HashHandle
138 HASH_INTERFACE_HOB
*HashInterfaceHob
;
139 HASH_HANDLE
*HashCtx
;
143 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
144 if (HashInterfaceHob
== NULL
) {
145 return EFI_UNSUPPORTED
;
148 if (HashInterfaceHob
->HashInterfaceCount
== 0) {
149 return EFI_UNSUPPORTED
;
152 CheckSupportedHashMaskMismatch (HashInterfaceHob
);
154 HashCtx
= AllocatePool (sizeof (*HashCtx
) * HashInterfaceHob
->HashInterfaceCount
);
155 ASSERT (HashCtx
!= NULL
);
157 for (Index
= 0; Index
< HashInterfaceHob
->HashInterfaceCount
; Index
++) {
158 HashMask
= Tpm2GetHashMaskFromAlgo (&HashInterfaceHob
->HashInterface
[Index
].HashGuid
);
159 if ((HashMask
& PcdGet32 (PcdTpm2HashMask
)) != 0) {
160 HashInterfaceHob
->HashInterface
[Index
].HashInit (&HashCtx
[Index
]);
164 *HashHandle
= (HASH_HANDLE
)HashCtx
;
170 Update hash sequence data.
172 @param HashHandle Hash handle.
173 @param DataToHash Data to be hashed.
174 @param DataToHashLen Data size.
176 @retval EFI_SUCCESS Hash sequence updated.
181 IN HASH_HANDLE HashHandle
,
183 IN UINTN DataToHashLen
186 HASH_INTERFACE_HOB
*HashInterfaceHob
;
187 HASH_HANDLE
*HashCtx
;
191 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
192 if (HashInterfaceHob
== NULL
) {
193 return EFI_UNSUPPORTED
;
196 if (HashInterfaceHob
->HashInterfaceCount
== 0) {
197 return EFI_UNSUPPORTED
;
200 CheckSupportedHashMaskMismatch (HashInterfaceHob
);
202 HashCtx
= (HASH_HANDLE
*)HashHandle
;
204 for (Index
= 0; Index
< HashInterfaceHob
->HashInterfaceCount
; Index
++) {
205 HashMask
= Tpm2GetHashMaskFromAlgo (&HashInterfaceHob
->HashInterface
[Index
].HashGuid
);
206 if ((HashMask
& PcdGet32 (PcdTpm2HashMask
)) != 0) {
207 HashInterfaceHob
->HashInterface
[Index
].HashUpdate (HashCtx
[Index
], DataToHash
, DataToHashLen
);
215 Hash sequence complete and extend to PCR.
217 @param HashHandle Hash handle.
218 @param PcrIndex PCR to be extended.
219 @param DataToHash Data to be hashed.
220 @param DataToHashLen Data size.
221 @param DigestList Digest list.
223 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
227 HashCompleteAndExtend (
228 IN HASH_HANDLE HashHandle
,
229 IN TPMI_DH_PCR PcrIndex
,
231 IN UINTN DataToHashLen
,
232 OUT TPML_DIGEST_VALUES
*DigestList
235 TPML_DIGEST_VALUES Digest
;
236 HASH_INTERFACE_HOB
*HashInterfaceHob
;
237 HASH_HANDLE
*HashCtx
;
242 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
243 if (HashInterfaceHob
== NULL
) {
244 return EFI_UNSUPPORTED
;
247 if (HashInterfaceHob
->HashInterfaceCount
== 0) {
248 return EFI_UNSUPPORTED
;
251 CheckSupportedHashMaskMismatch (HashInterfaceHob
);
253 HashCtx
= (HASH_HANDLE
*)HashHandle
;
254 ZeroMem (DigestList
, sizeof (*DigestList
));
256 for (Index
= 0; Index
< HashInterfaceHob
->HashInterfaceCount
; Index
++) {
257 HashMask
= Tpm2GetHashMaskFromAlgo (&HashInterfaceHob
->HashInterface
[Index
].HashGuid
);
258 if ((HashMask
& PcdGet32 (PcdTpm2HashMask
)) != 0) {
259 HashInterfaceHob
->HashInterface
[Index
].HashUpdate (HashCtx
[Index
], DataToHash
, DataToHashLen
);
260 HashInterfaceHob
->HashInterface
[Index
].HashFinal (HashCtx
[Index
], &Digest
);
261 Tpm2SetHashToDigestList (DigestList
, &Digest
);
267 Status
= Tpm2PcrExtend (
275 Hash data and extend to PCR.
277 @param PcrIndex PCR to be extended.
278 @param DataToHash Data to be hashed.
279 @param DataToHashLen Data size.
280 @param DigestList Digest list.
282 @retval EFI_SUCCESS Hash data and DigestList is returned.
287 IN TPMI_DH_PCR PcrIndex
,
289 IN UINTN DataToHashLen
,
290 OUT TPML_DIGEST_VALUES
*DigestList
293 HASH_INTERFACE_HOB
*HashInterfaceHob
;
294 HASH_HANDLE HashHandle
;
297 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
298 if (HashInterfaceHob
== NULL
) {
299 return EFI_UNSUPPORTED
;
302 if (HashInterfaceHob
->HashInterfaceCount
== 0) {
303 return EFI_UNSUPPORTED
;
306 CheckSupportedHashMaskMismatch (HashInterfaceHob
);
308 HashStart (&HashHandle
);
309 HashUpdate (HashHandle
, DataToHash
, DataToHashLen
);
310 Status
= HashCompleteAndExtend (HashHandle
, PcrIndex
, NULL
, 0, DigestList
);
316 This service register Hash.
318 @param HashInterface Hash interface
320 @retval EFI_SUCCESS This hash interface is registered successfully.
321 @retval EFI_UNSUPPORTED System does not support register this interface.
322 @retval EFI_ALREADY_STARTED System already register this interface.
326 RegisterHashInterfaceLib (
327 IN HASH_INTERFACE
*HashInterface
331 HASH_INTERFACE_HOB
*HashInterfaceHob
;
339 HashMask
= Tpm2GetHashMaskFromAlgo (&HashInterface
->HashGuid
);
340 Tpm2HashMask
= PcdGet32 (PcdTpm2HashMask
);
342 if ((Tpm2HashMask
!= 0) &&
343 ((HashMask
& Tpm2HashMask
) == 0))
345 return EFI_UNSUPPORTED
;
348 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
349 if (HashInterfaceHob
== NULL
) {
350 HashInterfaceHob
= InternalCreateHashInterfaceHob (&gEfiCallerIdGuid
);
351 if (HashInterfaceHob
== NULL
) {
352 return EFI_OUT_OF_RESOURCES
;
356 if (HashInterfaceHob
->HashInterfaceCount
>= HASH_COUNT
) {
357 return EFI_OUT_OF_RESOURCES
;
363 for (Index
= 0; Index
< HashInterfaceHob
->HashInterfaceCount
; Index
++) {
364 if (CompareGuid (&HashInterfaceHob
->HashInterface
[Index
].HashGuid
, &HashInterface
->HashGuid
)) {
365 DEBUG ((DEBUG_ERROR
, "Hash Interface (%g) has been registered\n", &HashInterface
->HashGuid
));
366 return EFI_ALREADY_STARTED
;
371 // Record hash algorithm bitmap of CURRENT module which consumes HashLib.
373 HashInterfaceHob
->SupportedHashMask
= PcdGet32 (PcdTcg2HashAlgorithmBitmap
) | HashMask
;
374 Status
= PcdSet32S (PcdTcg2HashAlgorithmBitmap
, HashInterfaceHob
->SupportedHashMask
);
375 ASSERT_EFI_ERROR (Status
);
377 CopyMem (&HashInterfaceHob
->HashInterface
[HashInterfaceHob
->HashInterfaceCount
], HashInterface
, sizeof (*HashInterface
));
378 HashInterfaceHob
->HashInterfaceCount
++;
384 The constructor function of HashLibBaseCryptoRouterPei.
386 @param FileHandle The handle of FFS header the loaded driver.
387 @param PeiServices The pointer to the PEI services.
389 @retval EFI_SUCCESS The constructor executes successfully.
390 @retval EFI_OUT_OF_RESOURCES There is no enough resource for the constructor.
395 HashLibBaseCryptoRouterPeiConstructor (
396 IN EFI_PEI_FILE_HANDLE FileHandle
,
397 IN CONST EFI_PEI_SERVICES
**PeiServices
401 HASH_INTERFACE_HOB
*HashInterfaceHob
;
403 HashInterfaceHob
= InternalGetHashInterfaceHob (&gZeroGuid
);
404 if (HashInterfaceHob
== NULL
) {
406 // No HOB with gZeroGuid Identifier has been created,
407 // this is FIRST module which consumes HashLib.
408 // Create the HOB with gZeroGuid Identifier.
410 HashInterfaceHob
= InternalCreateHashInterfaceHob (&gZeroGuid
);
411 if (HashInterfaceHob
== NULL
) {
412 return EFI_OUT_OF_RESOURCES
;
416 // Record hash algorithm bitmap of LAST module which also consumes HashLib.
418 HashInterfaceHob
->SupportedHashMask
= PcdGet32 (PcdTcg2HashAlgorithmBitmap
);
421 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
422 if (HashInterfaceHob
!= NULL
) {
424 // In PEI phase, some modules may call RegisterForShadow and will be
425 // shadowed and executed again after memory is discovered.
426 // This is the second execution of this module, clear the hash interface
427 // information registered at its first execution.
429 ZeroMem (&HashInterfaceHob
->HashInterface
, sizeof (HashInterfaceHob
->HashInterface
));
430 HashInterfaceHob
->HashInterfaceCount
= 0;
431 HashInterfaceHob
->SupportedHashMask
= 0;
435 // Set PcdTcg2HashAlgorithmBitmap to 0 in CONSTRUCTOR for CURRENT module.
437 Status
= PcdSet32S (PcdTcg2HashAlgorithmBitmap
, 0);
438 ASSERT_EFI_ERROR (Status
);