2 This library is BaseCrypto router. It will redirect hash request to each individual
3 hash handler registerd, such as SHA1, SHA256.
4 Platform can use PcdTpm2HashMask to mask some hash engines.
6 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Library/BaseLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/Tpm2CommandLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/MemoryAllocationLib.h>
23 #include <Library/PcdLib.h>
24 #include <Library/HobLib.h>
25 #include <Library/HashLib.h>
26 #include <Guid/ZeroGuid.h>
28 #include "HashLibBaseCryptoRouterCommon.h"
30 #define HASH_LIB_PEI_ROUTER_GUID \
31 { 0x84681c08, 0x6873, 0x46f3, { 0x8b, 0xb7, 0xab, 0x66, 0x18, 0x95, 0xa1, 0xb3 } }
33 EFI_GUID mHashLibPeiRouterGuid
= HASH_LIB_PEI_ROUTER_GUID
;
37 // If gZeroGuid, SupportedHashMask is 0 for FIRST module which consumes HashLib
38 // or the hash algorithm bitmap of LAST module which consumes HashLib.
39 // HashInterfaceCount and HashInterface are all 0.
40 // If gEfiCallerIdGuid, HashInterfaceCount, HashInterface and SupportedHashMask
41 // are the hash interface information of CURRENT module which consumes HashLib.
44 UINTN HashInterfaceCount
;
45 HASH_INTERFACE HashInterface
[HASH_COUNT
];
46 UINT32 SupportedHashMask
;
50 This function gets hash interface hob.
52 @param Identifier Identifier to get hash interface hob.
54 @retval hash interface hob.
57 InternalGetHashInterfaceHob (
61 EFI_PEI_HOB_POINTERS Hob
;
62 HASH_INTERFACE_HOB
*HashInterfaceHob
;
64 Hob
.Raw
= GetFirstGuidHob (&mHashLibPeiRouterGuid
);
65 while (Hob
.Raw
!= NULL
) {
66 HashInterfaceHob
= GET_GUID_HOB_DATA (Hob
);
67 if (CompareGuid (&HashInterfaceHob
->Identifier
, Identifier
)) {
69 // Found the matched one.
71 return HashInterfaceHob
;
73 Hob
.Raw
= GET_NEXT_HOB (Hob
);
74 Hob
.Raw
= GetNextGuidHob (&mHashLibPeiRouterGuid
, Hob
.Raw
);
80 This function creates hash interface hob.
82 @param Identifier Identifier to create hash interface hob.
84 @retval hash interface hob.
87 InternalCreateHashInterfaceHob (
91 HASH_INTERFACE_HOB LocalHashInterfaceHob
;
93 ZeroMem (&LocalHashInterfaceHob
, sizeof(LocalHashInterfaceHob
));
94 CopyGuid (&LocalHashInterfaceHob
.Identifier
, Identifier
);
95 return BuildGuidDataHob (&mHashLibPeiRouterGuid
, &LocalHashInterfaceHob
, sizeof(LocalHashInterfaceHob
));
99 Check mismatch of supported HashMask between modules
100 that may link different HashInstanceLib instances.
102 @param HashInterfaceHobCurrent Pointer to hash interface hob for CURRENT module.
106 CheckSupportedHashMaskMismatch (
107 IN HASH_INTERFACE_HOB
*HashInterfaceHobCurrent
110 HASH_INTERFACE_HOB
*HashInterfaceHobLast
;
112 HashInterfaceHobLast
= InternalGetHashInterfaceHob (&gZeroGuid
);
113 ASSERT (HashInterfaceHobLast
!= NULL
);
115 if ((HashInterfaceHobLast
->SupportedHashMask
!= 0) &&
116 (HashInterfaceHobCurrent
->SupportedHashMask
!= HashInterfaceHobLast
->SupportedHashMask
)) {
119 "WARNING: There is mismatch of supported HashMask (0x%x - 0x%x) between modules\n",
120 HashInterfaceHobCurrent
->SupportedHashMask
,
121 HashInterfaceHobLast
->SupportedHashMask
123 DEBUG ((DEBUG_WARN
, "that are linking different HashInstanceLib instances!\n"));
130 @param HashHandle Hash handle.
132 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
133 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
138 OUT HASH_HANDLE
*HashHandle
141 HASH_INTERFACE_HOB
*HashInterfaceHob
;
142 HASH_HANDLE
*HashCtx
;
146 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
147 if (HashInterfaceHob
== NULL
) {
148 return EFI_UNSUPPORTED
;
151 if (HashInterfaceHob
->HashInterfaceCount
== 0) {
152 return EFI_UNSUPPORTED
;
155 CheckSupportedHashMaskMismatch (HashInterfaceHob
);
157 HashCtx
= AllocatePool (sizeof(*HashCtx
) * HashInterfaceHob
->HashInterfaceCount
);
158 ASSERT (HashCtx
!= NULL
);
160 for (Index
= 0; Index
< HashInterfaceHob
->HashInterfaceCount
; Index
++) {
161 HashMask
= Tpm2GetHashMaskFromAlgo (&HashInterfaceHob
->HashInterface
[Index
].HashGuid
);
162 if ((HashMask
& PcdGet32 (PcdTpm2HashMask
)) != 0) {
163 HashInterfaceHob
->HashInterface
[Index
].HashInit (&HashCtx
[Index
]);
167 *HashHandle
= (HASH_HANDLE
)HashCtx
;
173 Update hash sequence data.
175 @param HashHandle Hash handle.
176 @param DataToHash Data to be hashed.
177 @param DataToHashLen Data size.
179 @retval EFI_SUCCESS Hash sequence updated.
184 IN HASH_HANDLE HashHandle
,
186 IN UINTN DataToHashLen
189 HASH_INTERFACE_HOB
*HashInterfaceHob
;
190 HASH_HANDLE
*HashCtx
;
194 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
195 if (HashInterfaceHob
== NULL
) {
196 return EFI_UNSUPPORTED
;
199 if (HashInterfaceHob
->HashInterfaceCount
== 0) {
200 return EFI_UNSUPPORTED
;
203 CheckSupportedHashMaskMismatch (HashInterfaceHob
);
205 HashCtx
= (HASH_HANDLE
*)HashHandle
;
207 for (Index
= 0; Index
< HashInterfaceHob
->HashInterfaceCount
; Index
++) {
208 HashMask
= Tpm2GetHashMaskFromAlgo (&HashInterfaceHob
->HashInterface
[Index
].HashGuid
);
209 if ((HashMask
& PcdGet32 (PcdTpm2HashMask
)) != 0) {
210 HashInterfaceHob
->HashInterface
[Index
].HashUpdate (HashCtx
[Index
], DataToHash
, DataToHashLen
);
218 Hash sequence complete and extend to PCR.
220 @param HashHandle Hash handle.
221 @param PcrIndex PCR to be extended.
222 @param DataToHash Data to be hashed.
223 @param DataToHashLen Data size.
224 @param DigestList Digest list.
226 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
230 HashCompleteAndExtend (
231 IN HASH_HANDLE HashHandle
,
232 IN TPMI_DH_PCR PcrIndex
,
234 IN UINTN DataToHashLen
,
235 OUT TPML_DIGEST_VALUES
*DigestList
238 TPML_DIGEST_VALUES Digest
;
239 HASH_INTERFACE_HOB
*HashInterfaceHob
;
240 HASH_HANDLE
*HashCtx
;
245 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
246 if (HashInterfaceHob
== NULL
) {
247 return EFI_UNSUPPORTED
;
250 if (HashInterfaceHob
->HashInterfaceCount
== 0) {
251 return EFI_UNSUPPORTED
;
254 CheckSupportedHashMaskMismatch (HashInterfaceHob
);
256 HashCtx
= (HASH_HANDLE
*)HashHandle
;
257 ZeroMem (DigestList
, sizeof(*DigestList
));
259 for (Index
= 0; Index
< HashInterfaceHob
->HashInterfaceCount
; Index
++) {
260 HashMask
= Tpm2GetHashMaskFromAlgo (&HashInterfaceHob
->HashInterface
[Index
].HashGuid
);
261 if ((HashMask
& PcdGet32 (PcdTpm2HashMask
)) != 0) {
262 HashInterfaceHob
->HashInterface
[Index
].HashUpdate (HashCtx
[Index
], DataToHash
, DataToHashLen
);
263 HashInterfaceHob
->HashInterface
[Index
].HashFinal (HashCtx
[Index
], &Digest
);
264 Tpm2SetHashToDigestList (DigestList
, &Digest
);
270 Status
= Tpm2PcrExtend (
278 Hash data and extend to PCR.
280 @param PcrIndex PCR to be extended.
281 @param DataToHash Data to be hashed.
282 @param DataToHashLen Data size.
283 @param DigestList Digest list.
285 @retval EFI_SUCCESS Hash data and DigestList is returned.
290 IN TPMI_DH_PCR PcrIndex
,
292 IN UINTN DataToHashLen
,
293 OUT TPML_DIGEST_VALUES
*DigestList
296 HASH_INTERFACE_HOB
*HashInterfaceHob
;
297 HASH_HANDLE HashHandle
;
300 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
301 if (HashInterfaceHob
== NULL
) {
302 return EFI_UNSUPPORTED
;
305 if (HashInterfaceHob
->HashInterfaceCount
== 0) {
306 return EFI_UNSUPPORTED
;
309 CheckSupportedHashMaskMismatch (HashInterfaceHob
);
311 HashStart (&HashHandle
);
312 HashUpdate (HashHandle
, DataToHash
, DataToHashLen
);
313 Status
= HashCompleteAndExtend (HashHandle
, PcrIndex
, NULL
, 0, DigestList
);
319 This service register Hash.
321 @param HashInterface Hash interface
323 @retval EFI_SUCCESS This hash interface is registered successfully.
324 @retval EFI_UNSUPPORTED System does not support register this interface.
325 @retval EFI_ALREADY_STARTED System already register this interface.
329 RegisterHashInterfaceLib (
330 IN HASH_INTERFACE
*HashInterface
334 HASH_INTERFACE_HOB
*HashInterfaceHob
;
341 HashMask
= Tpm2GetHashMaskFromAlgo (&HashInterface
->HashGuid
);
342 if ((HashMask
& PcdGet32 (PcdTpm2HashMask
)) == 0) {
343 return EFI_UNSUPPORTED
;
346 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
347 if (HashInterfaceHob
== NULL
) {
348 HashInterfaceHob
= InternalCreateHashInterfaceHob (&gEfiCallerIdGuid
);
349 if (HashInterfaceHob
== NULL
) {
350 return EFI_OUT_OF_RESOURCES
;
354 if (HashInterfaceHob
->HashInterfaceCount
>= HASH_COUNT
) {
355 return EFI_OUT_OF_RESOURCES
;
361 for (Index
= 0; Index
< HashInterfaceHob
->HashInterfaceCount
; Index
++) {
362 if (CompareGuid (&HashInterfaceHob
->HashInterface
[Index
].HashGuid
, &HashInterface
->HashGuid
)) {
363 DEBUG ((DEBUG_ERROR
, "Hash Interface (%g) has been registered\n", &HashInterface
->HashGuid
));
364 return EFI_ALREADY_STARTED
;
369 // Record hash algorithm bitmap of CURRENT module which consumes HashLib.
371 HashInterfaceHob
->SupportedHashMask
= PcdGet32 (PcdTcg2HashAlgorithmBitmap
) | HashMask
;
372 Status
= PcdSet32S (PcdTcg2HashAlgorithmBitmap
, HashInterfaceHob
->SupportedHashMask
);
373 ASSERT_EFI_ERROR (Status
);
375 CopyMem (&HashInterfaceHob
->HashInterface
[HashInterfaceHob
->HashInterfaceCount
], HashInterface
, sizeof(*HashInterface
));
376 HashInterfaceHob
->HashInterfaceCount
++;
382 The constructor function of HashLibBaseCryptoRouterPei.
384 @param FileHandle The handle of FFS header the loaded driver.
385 @param PeiServices The pointer to the PEI services.
387 @retval EFI_SUCCESS The constructor executes successfully.
388 @retval EFI_OUT_OF_RESOURCES There is no enough resource for the constructor.
393 HashLibBaseCryptoRouterPeiConstructor (
394 IN EFI_PEI_FILE_HANDLE FileHandle
,
395 IN CONST EFI_PEI_SERVICES
**PeiServices
399 HASH_INTERFACE_HOB
*HashInterfaceHob
;
401 HashInterfaceHob
= InternalGetHashInterfaceHob (&gZeroGuid
);
402 if (HashInterfaceHob
== NULL
) {
404 // No HOB with gZeroGuid Identifier has been created,
405 // this is FIRST module which consumes HashLib.
406 // Create the HOB with gZeroGuid Identifier.
408 HashInterfaceHob
= InternalCreateHashInterfaceHob (&gZeroGuid
);
409 if (HashInterfaceHob
== NULL
) {
410 return EFI_OUT_OF_RESOURCES
;
414 // Record hash algorithm bitmap of LAST module which also consumes HashLib.
416 HashInterfaceHob
->SupportedHashMask
= PcdGet32 (PcdTcg2HashAlgorithmBitmap
);
419 HashInterfaceHob
= InternalGetHashInterfaceHob (&gEfiCallerIdGuid
);
420 if (HashInterfaceHob
!= NULL
) {
422 // In PEI phase, some modules may call RegisterForShadow and will be
423 // shadowed and executed again after memory is discovered.
424 // This is the second execution of this module, clear the hash interface
425 // information registered at its first execution.
427 ZeroMem (&HashInterfaceHob
->HashInterface
, sizeof (HashInterfaceHob
->HashInterface
));
428 HashInterfaceHob
->HashInterfaceCount
= 0;
429 HashInterfaceHob
->SupportedHashMask
= 0;
433 // Set PcdTcg2HashAlgorithmBitmap to 0 in CONSTRUCTOR for CURRENT module.
435 Status
= PcdSet32S (PcdTcg2HashAlgorithmBitmap
, 0);
436 ASSERT_EFI_ERROR (Status
);