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