]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SecurityPkg / Library / HashLibBaseCryptoRouter / HashLibBaseCryptoRouterPei.c
1 /** @file
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.
5
6 Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include <PiPei.h>
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>
21
22 #include "HashLibBaseCryptoRouterCommon.h"
23
24 #define HASH_LIB_PEI_ROUTER_GUID \
25 { 0x84681c08, 0x6873, 0x46f3, { 0x8b, 0xb7, 0xab, 0x66, 0x18, 0x95, 0xa1, 0xb3 } }
26
27 EFI_GUID mHashLibPeiRouterGuid = HASH_LIB_PEI_ROUTER_GUID;
28
29 typedef struct {
30 //
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.
36 //
37 EFI_GUID Identifier;
38 UINTN HashInterfaceCount;
39 HASH_INTERFACE HashInterface[HASH_COUNT];
40 UINT32 SupportedHashMask;
41 } HASH_INTERFACE_HOB;
42
43 /**
44 This function gets hash interface hob.
45
46 @param Identifier Identifier to get hash interface hob.
47
48 @retval hash interface hob.
49 **/
50 HASH_INTERFACE_HOB *
51 InternalGetHashInterfaceHob (
52 EFI_GUID *Identifier
53 )
54 {
55 EFI_PEI_HOB_POINTERS Hob;
56 HASH_INTERFACE_HOB *HashInterfaceHob;
57
58 Hob.Raw = GetFirstGuidHob (&mHashLibPeiRouterGuid);
59 while (Hob.Raw != NULL) {
60 HashInterfaceHob = GET_GUID_HOB_DATA (Hob);
61 if (CompareGuid (&HashInterfaceHob->Identifier, Identifier)) {
62 //
63 // Found the matched one.
64 //
65 return HashInterfaceHob;
66 }
67
68 Hob.Raw = GET_NEXT_HOB (Hob);
69 Hob.Raw = GetNextGuidHob (&mHashLibPeiRouterGuid, Hob.Raw);
70 }
71
72 return NULL;
73 }
74
75 /**
76 This function creates hash interface hob.
77
78 @param Identifier Identifier to create hash interface hob.
79
80 @retval hash interface hob.
81 **/
82 HASH_INTERFACE_HOB *
83 InternalCreateHashInterfaceHob (
84 EFI_GUID *Identifier
85 )
86 {
87 HASH_INTERFACE_HOB LocalHashInterfaceHob;
88
89 ZeroMem (&LocalHashInterfaceHob, sizeof (LocalHashInterfaceHob));
90 CopyGuid (&LocalHashInterfaceHob.Identifier, Identifier);
91 return BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof (LocalHashInterfaceHob));
92 }
93
94 /**
95 Check mismatch of supported HashMask between modules
96 that may link different HashInstanceLib instances.
97
98 @param HashInterfaceHobCurrent Pointer to hash interface hob for CURRENT module.
99
100 **/
101 VOID
102 CheckSupportedHashMaskMismatch (
103 IN HASH_INTERFACE_HOB *HashInterfaceHobCurrent
104 )
105 {
106 HASH_INTERFACE_HOB *HashInterfaceHobLast;
107
108 HashInterfaceHobLast = InternalGetHashInterfaceHob (&gZeroGuid);
109 ASSERT (HashInterfaceHobLast != NULL);
110
111 if ((HashInterfaceHobLast->SupportedHashMask != 0) &&
112 (HashInterfaceHobCurrent->SupportedHashMask != HashInterfaceHobLast->SupportedHashMask))
113 {
114 DEBUG ((
115 DEBUG_WARN,
116 "WARNING: There is mismatch of supported HashMask (0x%x - 0x%x) between modules\n",
117 HashInterfaceHobCurrent->SupportedHashMask,
118 HashInterfaceHobLast->SupportedHashMask
119 ));
120 DEBUG ((DEBUG_WARN, "that are linking different HashInstanceLib instances!\n"));
121 }
122 }
123
124 /**
125 Start hash sequence.
126
127 @param HashHandle Hash handle.
128
129 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
130 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
131 **/
132 EFI_STATUS
133 EFIAPI
134 HashStart (
135 OUT HASH_HANDLE *HashHandle
136 )
137 {
138 HASH_INTERFACE_HOB *HashInterfaceHob;
139 HASH_HANDLE *HashCtx;
140 UINTN Index;
141 UINT32 HashMask;
142
143 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
144 if (HashInterfaceHob == NULL) {
145 return EFI_UNSUPPORTED;
146 }
147
148 if (HashInterfaceHob->HashInterfaceCount == 0) {
149 return EFI_UNSUPPORTED;
150 }
151
152 CheckSupportedHashMaskMismatch (HashInterfaceHob);
153
154 HashCtx = AllocatePool (sizeof (*HashCtx) * HashInterfaceHob->HashInterfaceCount);
155 ASSERT (HashCtx != NULL);
156
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]);
161 }
162 }
163
164 *HashHandle = (HASH_HANDLE)HashCtx;
165
166 return EFI_SUCCESS;
167 }
168
169 /**
170 Update hash sequence data.
171
172 @param HashHandle Hash handle.
173 @param DataToHash Data to be hashed.
174 @param DataToHashLen Data size.
175
176 @retval EFI_SUCCESS Hash sequence updated.
177 **/
178 EFI_STATUS
179 EFIAPI
180 HashUpdate (
181 IN HASH_HANDLE HashHandle,
182 IN VOID *DataToHash,
183 IN UINTN DataToHashLen
184 )
185 {
186 HASH_INTERFACE_HOB *HashInterfaceHob;
187 HASH_HANDLE *HashCtx;
188 UINTN Index;
189 UINT32 HashMask;
190
191 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
192 if (HashInterfaceHob == NULL) {
193 return EFI_UNSUPPORTED;
194 }
195
196 if (HashInterfaceHob->HashInterfaceCount == 0) {
197 return EFI_UNSUPPORTED;
198 }
199
200 CheckSupportedHashMaskMismatch (HashInterfaceHob);
201
202 HashCtx = (HASH_HANDLE *)HashHandle;
203
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);
208 }
209 }
210
211 return EFI_SUCCESS;
212 }
213
214 /**
215 Hash sequence complete and extend to PCR.
216
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.
222
223 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
224 **/
225 EFI_STATUS
226 EFIAPI
227 HashCompleteAndExtend (
228 IN HASH_HANDLE HashHandle,
229 IN TPMI_DH_PCR PcrIndex,
230 IN VOID *DataToHash,
231 IN UINTN DataToHashLen,
232 OUT TPML_DIGEST_VALUES *DigestList
233 )
234 {
235 TPML_DIGEST_VALUES Digest;
236 HASH_INTERFACE_HOB *HashInterfaceHob;
237 HASH_HANDLE *HashCtx;
238 UINTN Index;
239 EFI_STATUS Status;
240 UINT32 HashMask;
241
242 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
243 if (HashInterfaceHob == NULL) {
244 return EFI_UNSUPPORTED;
245 }
246
247 if (HashInterfaceHob->HashInterfaceCount == 0) {
248 return EFI_UNSUPPORTED;
249 }
250
251 CheckSupportedHashMaskMismatch (HashInterfaceHob);
252
253 HashCtx = (HASH_HANDLE *)HashHandle;
254 ZeroMem (DigestList, sizeof (*DigestList));
255
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);
262 }
263 }
264
265 FreePool (HashCtx);
266
267 Status = Tpm2PcrExtend (
268 PcrIndex,
269 DigestList
270 );
271 return Status;
272 }
273
274 /**
275 Hash data and extend to PCR.
276
277 @param PcrIndex PCR to be extended.
278 @param DataToHash Data to be hashed.
279 @param DataToHashLen Data size.
280 @param DigestList Digest list.
281
282 @retval EFI_SUCCESS Hash data and DigestList is returned.
283 **/
284 EFI_STATUS
285 EFIAPI
286 HashAndExtend (
287 IN TPMI_DH_PCR PcrIndex,
288 IN VOID *DataToHash,
289 IN UINTN DataToHashLen,
290 OUT TPML_DIGEST_VALUES *DigestList
291 )
292 {
293 HASH_INTERFACE_HOB *HashInterfaceHob;
294 HASH_HANDLE HashHandle;
295 EFI_STATUS Status;
296
297 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
298 if (HashInterfaceHob == NULL) {
299 return EFI_UNSUPPORTED;
300 }
301
302 if (HashInterfaceHob->HashInterfaceCount == 0) {
303 return EFI_UNSUPPORTED;
304 }
305
306 CheckSupportedHashMaskMismatch (HashInterfaceHob);
307
308 HashStart (&HashHandle);
309 HashUpdate (HashHandle, DataToHash, DataToHashLen);
310 Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
311
312 return Status;
313 }
314
315 /**
316 This service register Hash.
317
318 @param HashInterface Hash interface
319
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.
323 **/
324 EFI_STATUS
325 EFIAPI
326 RegisterHashInterfaceLib (
327 IN HASH_INTERFACE *HashInterface
328 )
329 {
330 UINTN Index;
331 HASH_INTERFACE_HOB *HashInterfaceHob;
332 UINT32 HashMask;
333 UINT32 Tpm2HashMask;
334 EFI_STATUS Status;
335
336 //
337 // Check allow
338 //
339 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
340 Tpm2HashMask = PcdGet32 (PcdTpm2HashMask);
341
342 if ((Tpm2HashMask != 0) &&
343 ((HashMask & Tpm2HashMask) == 0))
344 {
345 return EFI_UNSUPPORTED;
346 }
347
348 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
349 if (HashInterfaceHob == NULL) {
350 HashInterfaceHob = InternalCreateHashInterfaceHob (&gEfiCallerIdGuid);
351 if (HashInterfaceHob == NULL) {
352 return EFI_OUT_OF_RESOURCES;
353 }
354 }
355
356 if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {
357 return EFI_OUT_OF_RESOURCES;
358 }
359
360 //
361 // Check duplication
362 //
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;
367 }
368 }
369
370 //
371 // Record hash algorithm bitmap of CURRENT module which consumes HashLib.
372 //
373 HashInterfaceHob->SupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap) | HashMask;
374 Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, HashInterfaceHob->SupportedHashMask);
375 ASSERT_EFI_ERROR (Status);
376
377 CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof (*HashInterface));
378 HashInterfaceHob->HashInterfaceCount++;
379
380 return EFI_SUCCESS;
381 }
382
383 /**
384 The constructor function of HashLibBaseCryptoRouterPei.
385
386 @param FileHandle The handle of FFS header the loaded driver.
387 @param PeiServices The pointer to the PEI services.
388
389 @retval EFI_SUCCESS The constructor executes successfully.
390 @retval EFI_OUT_OF_RESOURCES There is no enough resource for the constructor.
391
392 **/
393 EFI_STATUS
394 EFIAPI
395 HashLibBaseCryptoRouterPeiConstructor (
396 IN EFI_PEI_FILE_HANDLE FileHandle,
397 IN CONST EFI_PEI_SERVICES **PeiServices
398 )
399 {
400 EFI_STATUS Status;
401 HASH_INTERFACE_HOB *HashInterfaceHob;
402
403 HashInterfaceHob = InternalGetHashInterfaceHob (&gZeroGuid);
404 if (HashInterfaceHob == NULL) {
405 //
406 // No HOB with gZeroGuid Identifier has been created,
407 // this is FIRST module which consumes HashLib.
408 // Create the HOB with gZeroGuid Identifier.
409 //
410 HashInterfaceHob = InternalCreateHashInterfaceHob (&gZeroGuid);
411 if (HashInterfaceHob == NULL) {
412 return EFI_OUT_OF_RESOURCES;
413 }
414 } else {
415 //
416 // Record hash algorithm bitmap of LAST module which also consumes HashLib.
417 //
418 HashInterfaceHob->SupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);
419 }
420
421 HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
422 if (HashInterfaceHob != NULL) {
423 //
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.
428 //
429 ZeroMem (&HashInterfaceHob->HashInterface, sizeof (HashInterfaceHob->HashInterface));
430 HashInterfaceHob->HashInterfaceCount = 0;
431 HashInterfaceHob->SupportedHashMask = 0;
432 }
433
434 //
435 // Set PcdTcg2HashAlgorithmBitmap to 0 in CONSTRUCTOR for CURRENT module.
436 //
437 Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, 0);
438 ASSERT_EFI_ERROR (Status);
439
440 return EFI_SUCCESS;
441 }