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