]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
SecurityPkg: Fix few typos
[mirror_edk2.git] / SecurityPkg / Library / HashLibBaseCryptoRouter / HashLibBaseCryptoRouterDxe.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 - 2018, 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/HashLib.h>
19
20 #include "HashLibBaseCryptoRouterCommon.h"
21
22 HASH_INTERFACE mHashInterface[HASH_COUNT] = {{{0}, NULL, NULL, NULL}};
23 UINTN mHashInterfaceCount = 0;
24
25 UINT32 mSupportedHashMaskLast = 0;
26 UINT32 mSupportedHashMaskCurrent = 0;
27
28 /**
29 Check mismatch of supported HashMask between modules
30 that may link different HashInstanceLib instances.
31
32 **/
33 VOID
34 CheckSupportedHashMaskMismatch (
35 VOID
36 )
37 {
38 if (mSupportedHashMaskCurrent != mSupportedHashMaskLast) {
39 DEBUG ((
40 DEBUG_WARN,
41 "WARNING: There is mismatch of supported HashMask (0x%x - 0x%x) between modules\n",
42 mSupportedHashMaskCurrent,
43 mSupportedHashMaskLast
44 ));
45 DEBUG ((DEBUG_WARN, "that are linking different HashInstanceLib instances!\n"));
46 }
47 }
48
49 /**
50 Start hash sequence.
51
52 @param HashHandle Hash handle.
53
54 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
55 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
56 **/
57 EFI_STATUS
58 EFIAPI
59 HashStart (
60 OUT HASH_HANDLE *HashHandle
61 )
62 {
63 HASH_HANDLE *HashCtx;
64 UINTN Index;
65 UINT32 HashMask;
66
67 if (mHashInterfaceCount == 0) {
68 return EFI_UNSUPPORTED;
69 }
70
71 CheckSupportedHashMaskMismatch ();
72
73 HashCtx = AllocatePool (sizeof(*HashCtx) * mHashInterfaceCount);
74 ASSERT (HashCtx != NULL);
75
76 for (Index = 0; Index < mHashInterfaceCount; Index++) {
77 HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
78 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
79 mHashInterface[Index].HashInit (&HashCtx[Index]);
80 }
81 }
82
83 *HashHandle = (HASH_HANDLE)HashCtx;
84
85 return EFI_SUCCESS;
86 }
87
88 /**
89 Update hash sequence data.
90
91 @param HashHandle Hash handle.
92 @param DataToHash Data to be hashed.
93 @param DataToHashLen Data size.
94
95 @retval EFI_SUCCESS Hash sequence updated.
96 **/
97 EFI_STATUS
98 EFIAPI
99 HashUpdate (
100 IN HASH_HANDLE HashHandle,
101 IN VOID *DataToHash,
102 IN UINTN DataToHashLen
103 )
104 {
105 HASH_HANDLE *HashCtx;
106 UINTN Index;
107 UINT32 HashMask;
108
109 if (mHashInterfaceCount == 0) {
110 return EFI_UNSUPPORTED;
111 }
112
113 CheckSupportedHashMaskMismatch ();
114
115 HashCtx = (HASH_HANDLE *)HashHandle;
116
117 for (Index = 0; Index < mHashInterfaceCount; Index++) {
118 HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
119 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
120 mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
121 }
122 }
123
124 return EFI_SUCCESS;
125 }
126
127 /**
128 Hash sequence complete and extend to PCR.
129
130 @param HashHandle Hash handle.
131 @param PcrIndex PCR to be extended.
132 @param DataToHash Data to be hashed.
133 @param DataToHashLen Data size.
134 @param DigestList Digest list.
135
136 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
137 **/
138 EFI_STATUS
139 EFIAPI
140 HashCompleteAndExtend (
141 IN HASH_HANDLE HashHandle,
142 IN TPMI_DH_PCR PcrIndex,
143 IN VOID *DataToHash,
144 IN UINTN DataToHashLen,
145 OUT TPML_DIGEST_VALUES *DigestList
146 )
147 {
148 TPML_DIGEST_VALUES Digest;
149 HASH_HANDLE *HashCtx;
150 UINTN Index;
151 EFI_STATUS Status;
152 UINT32 HashMask;
153
154 if (mHashInterfaceCount == 0) {
155 return EFI_UNSUPPORTED;
156 }
157
158 CheckSupportedHashMaskMismatch ();
159
160 HashCtx = (HASH_HANDLE *)HashHandle;
161 ZeroMem (DigestList, sizeof(*DigestList));
162
163 for (Index = 0; Index < mHashInterfaceCount; Index++) {
164 HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
165 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
166 mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
167 mHashInterface[Index].HashFinal (HashCtx[Index], &Digest);
168 Tpm2SetHashToDigestList (DigestList, &Digest);
169 }
170 }
171
172 FreePool (HashCtx);
173
174 Status = Tpm2PcrExtend (
175 PcrIndex,
176 DigestList
177 );
178 return Status;
179 }
180
181 /**
182 Hash data and extend to PCR.
183
184 @param PcrIndex PCR to be extended.
185 @param DataToHash Data to be hashed.
186 @param DataToHashLen Data size.
187 @param DigestList Digest list.
188
189 @retval EFI_SUCCESS Hash data and DigestList is returned.
190 **/
191 EFI_STATUS
192 EFIAPI
193 HashAndExtend (
194 IN TPMI_DH_PCR PcrIndex,
195 IN VOID *DataToHash,
196 IN UINTN DataToHashLen,
197 OUT TPML_DIGEST_VALUES *DigestList
198 )
199 {
200 HASH_HANDLE HashHandle;
201 EFI_STATUS Status;
202
203 if (mHashInterfaceCount == 0) {
204 return EFI_UNSUPPORTED;
205 }
206
207 CheckSupportedHashMaskMismatch ();
208
209 HashStart (&HashHandle);
210 HashUpdate (HashHandle, DataToHash, DataToHashLen);
211 Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
212
213 return Status;
214 }
215
216 /**
217 This service register Hash.
218
219 @param HashInterface Hash interface
220
221 @retval EFI_SUCCESS This hash interface is registered successfully.
222 @retval EFI_UNSUPPORTED System does not support register this interface.
223 @retval EFI_ALREADY_STARTED System already register this interface.
224 **/
225 EFI_STATUS
226 EFIAPI
227 RegisterHashInterfaceLib (
228 IN HASH_INTERFACE *HashInterface
229 )
230 {
231 UINTN Index;
232 UINT32 HashMask;
233 EFI_STATUS Status;
234
235 //
236 // Check allow
237 //
238 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
239 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
240 return EFI_UNSUPPORTED;
241 }
242
243 if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) {
244 return EFI_OUT_OF_RESOURCES;
245 }
246
247 //
248 // Check duplication
249 //
250 for (Index = 0; Index < mHashInterfaceCount; Index++) {
251 if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
252 DEBUG ((DEBUG_ERROR, "Hash Interface (%g) has been registered\n", &HashInterface->HashGuid));
253 return EFI_ALREADY_STARTED;
254 }
255 }
256
257 //
258 // Record hash algorithm bitmap of CURRENT module which consumes HashLib.
259 //
260 mSupportedHashMaskCurrent = PcdGet32 (PcdTcg2HashAlgorithmBitmap) | HashMask;
261 Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, mSupportedHashMaskCurrent);
262 ASSERT_EFI_ERROR (Status);
263
264 CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface));
265 mHashInterfaceCount ++;
266
267 return EFI_SUCCESS;
268 }
269
270 /**
271 The constructor function of HashLibBaseCryptoRouterDxe.
272
273 @param ImageHandle The firmware allocated handle for the EFI image.
274 @param SystemTable A pointer to the EFI System Table.
275
276 @retval EFI_SUCCESS The constructor executed correctly.
277
278 **/
279 EFI_STATUS
280 EFIAPI
281 HashLibBaseCryptoRouterDxeConstructor (
282 IN EFI_HANDLE ImageHandle,
283 IN EFI_SYSTEM_TABLE *SystemTable
284 )
285 {
286 EFI_STATUS Status;
287
288 //
289 // Record hash algorithm bitmap of LAST module which also consumes HashLib.
290 //
291 mSupportedHashMaskLast = PcdGet32 (PcdTcg2HashAlgorithmBitmap);
292
293 //
294 // Set PcdTcg2HashAlgorithmBitmap to 0 in CONSTRUCTOR for CURRENT module.
295 //
296 Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, 0);
297 ASSERT_EFI_ERROR (Status);
298
299 return EFI_SUCCESS;
300 }