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