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