]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c
MdePkg/TrEEProtocol.h: Fix typo 'Ihis' with 'This' in comment
[mirror_edk2.git] / SecurityPkg / Library / HashLibBaseCryptoRouter / HashLibBaseCryptoRouterPei.c
... / ...
CommitLineData
1/** @file\r
2 Ihis library is BaseCrypto router. It will redirect hash request to each individual\r
3 hash handler registerd, such as SHA1, SHA256.\r
4 Platform can use PcdTpm2HashMask to mask some hash engines.\r
5\r
6Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved. <BR>\r
7This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include <PiPei.h>\r
18#include <Library/BaseLib.h>\r
19#include <Library/BaseMemoryLib.h>\r
20#include <Library/Tpm2CommandLib.h>\r
21#include <Library/DebugLib.h>\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Library/PcdLib.h>\r
24#include <Library/HobLib.h>\r
25#include <Library/HashLib.h>\r
26\r
27#include "HashLibBaseCryptoRouterCommon.h"\r
28\r
29#define HASH_LIB_PEI_ROUTER_GUID \\r
30 { 0x84681c08, 0x6873, 0x46f3, { 0x8b, 0xb7, 0xab, 0x66, 0x18, 0x95, 0xa1, 0xb3 } }\r
31\r
32EFI_GUID mHashLibPeiRouterGuid = HASH_LIB_PEI_ROUTER_GUID;\r
33\r
34typedef struct {\r
35 UINTN HashInterfaceCount;\r
36 HASH_INTERFACE HashInterface[HASH_COUNT];\r
37} HASH_INTERFACE_HOB;\r
38\r
39/**\r
40 This function get hash interface.\r
41\r
42 @retval hash interface.\r
43**/\r
44HASH_INTERFACE_HOB *\r
45InternalGetHashInterface (\r
46 VOID\r
47 )\r
48{\r
49 EFI_HOB_GUID_TYPE *Hob;\r
50\r
51 Hob = GetFirstGuidHob (&mHashLibPeiRouterGuid);\r
52 if (Hob == NULL) {\r
53 return NULL;\r
54 }\r
55 return (HASH_INTERFACE_HOB *)(Hob + 1);\r
56}\r
57\r
58/**\r
59 Start hash sequence.\r
60\r
61 @param HashHandle Hash handle.\r
62\r
63 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.\r
64 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
65**/\r
66EFI_STATUS\r
67EFIAPI\r
68HashStart (\r
69 OUT HASH_HANDLE *HashHandle\r
70 )\r
71{\r
72 HASH_INTERFACE_HOB *HashInterfaceHob;\r
73 HASH_HANDLE *HashCtx;\r
74 UINTN Index;\r
75 UINT32 HashMask;\r
76\r
77 HashInterfaceHob = InternalGetHashInterface ();\r
78 if (HashInterfaceHob == NULL) {\r
79 return EFI_UNSUPPORTED;\r
80 }\r
81\r
82 if (HashInterfaceHob->HashInterfaceCount == 0) {\r
83 return EFI_UNSUPPORTED;\r
84 }\r
85\r
86 HashCtx = AllocatePool (sizeof(*HashCtx) * HashInterfaceHob->HashInterfaceCount);\r
87 ASSERT (HashCtx != NULL);\r
88\r
89 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
90 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);\r
91 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
92 HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]);\r
93 }\r
94 }\r
95\r
96 *HashHandle = (HASH_HANDLE)HashCtx;\r
97\r
98 return EFI_SUCCESS;\r
99}\r
100\r
101/**\r
102 Update hash sequence data.\r
103\r
104 @param HashHandle Hash handle.\r
105 @param DataToHash Data to be hashed.\r
106 @param DataToHashLen Data size.\r
107\r
108 @retval EFI_SUCCESS Hash sequence updated.\r
109**/\r
110EFI_STATUS\r
111EFIAPI\r
112HashUpdate (\r
113 IN HASH_HANDLE HashHandle,\r
114 IN VOID *DataToHash,\r
115 IN UINTN DataToHashLen\r
116 )\r
117{\r
118 HASH_INTERFACE_HOB *HashInterfaceHob;\r
119 HASH_HANDLE *HashCtx;\r
120 UINTN Index;\r
121 UINT32 HashMask;\r
122\r
123 HashInterfaceHob = InternalGetHashInterface ();\r
124 if (HashInterfaceHob == NULL) {\r
125 return EFI_UNSUPPORTED;\r
126 }\r
127\r
128 if (HashInterfaceHob->HashInterfaceCount == 0) {\r
129 return EFI_UNSUPPORTED;\r
130 }\r
131\r
132 HashCtx = (HASH_HANDLE *)HashHandle;\r
133\r
134 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
135 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);\r
136 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
137 HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
138 }\r
139 }\r
140\r
141 return EFI_SUCCESS;\r
142}\r
143\r
144/**\r
145 Hash sequence complete and extend to PCR.\r
146\r
147 @param HashHandle Hash handle.\r
148 @param PcrIndex PCR to be extended.\r
149 @param DataToHash Data to be hashed.\r
150 @param DataToHashLen Data size.\r
151 @param DigestList Digest list.\r
152\r
153 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.\r
154**/\r
155EFI_STATUS\r
156EFIAPI\r
157HashCompleteAndExtend (\r
158 IN HASH_HANDLE HashHandle,\r
159 IN TPMI_DH_PCR PcrIndex,\r
160 IN VOID *DataToHash,\r
161 IN UINTN DataToHashLen,\r
162 OUT TPML_DIGEST_VALUES *DigestList\r
163 )\r
164{\r
165 TPML_DIGEST_VALUES Digest;\r
166 HASH_INTERFACE_HOB *HashInterfaceHob;\r
167 HASH_HANDLE *HashCtx;\r
168 UINTN Index;\r
169 EFI_STATUS Status;\r
170 UINT32 HashMask;\r
171\r
172 HashInterfaceHob = InternalGetHashInterface ();\r
173 if (HashInterfaceHob == NULL) {\r
174 return EFI_UNSUPPORTED;\r
175 }\r
176\r
177 if (HashInterfaceHob->HashInterfaceCount == 0) {\r
178 return EFI_UNSUPPORTED;\r
179 }\r
180\r
181 HashCtx = (HASH_HANDLE *)HashHandle;\r
182 ZeroMem (DigestList, sizeof(*DigestList));\r
183\r
184 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
185 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);\r
186 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
187 HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
188 HashInterfaceHob->HashInterface[Index].HashFinal (HashCtx[Index], &Digest);\r
189 Tpm2SetHashToDigestList (DigestList, &Digest);\r
190 }\r
191 }\r
192\r
193 FreePool (HashCtx);\r
194\r
195 Status = Tpm2PcrExtend (\r
196 PcrIndex,\r
197 DigestList\r
198 );\r
199 return Status;\r
200}\r
201\r
202/**\r
203 Hash data and extend to PCR.\r
204\r
205 @param PcrIndex PCR to be extended.\r
206 @param DataToHash Data to be hashed.\r
207 @param DataToHashLen Data size.\r
208 @param DigestList Digest list.\r
209\r
210 @retval EFI_SUCCESS Hash data and DigestList is returned.\r
211**/\r
212EFI_STATUS\r
213EFIAPI\r
214HashAndExtend (\r
215 IN TPMI_DH_PCR PcrIndex,\r
216 IN VOID *DataToHash,\r
217 IN UINTN DataToHashLen,\r
218 OUT TPML_DIGEST_VALUES *DigestList\r
219 )\r
220{\r
221 HASH_INTERFACE_HOB *HashInterfaceHob;\r
222 HASH_HANDLE HashHandle;\r
223 EFI_STATUS Status;\r
224\r
225 HashInterfaceHob = InternalGetHashInterface ();\r
226 if (HashInterfaceHob == NULL) {\r
227 return EFI_UNSUPPORTED;\r
228 }\r
229\r
230 if (HashInterfaceHob->HashInterfaceCount == 0) {\r
231 return EFI_UNSUPPORTED;\r
232 }\r
233\r
234 HashStart (&HashHandle);\r
235 HashUpdate (HashHandle, DataToHash, DataToHashLen);\r
236 Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);\r
237\r
238 return Status;\r
239}\r
240\r
241/**\r
242 This service register Hash.\r
243\r
244 @param HashInterface Hash interface\r
245\r
246 @retval EFI_SUCCESS This hash interface is registered successfully.\r
247 @retval EFI_UNSUPPORTED System does not support register this interface.\r
248 @retval EFI_ALREADY_STARTED System already register this interface.\r
249**/\r
250EFI_STATUS\r
251EFIAPI\r
252RegisterHashInterfaceLib (\r
253 IN HASH_INTERFACE *HashInterface\r
254 )\r
255{\r
256 UINTN Index;\r
257 HASH_INTERFACE_HOB *HashInterfaceHob;\r
258 HASH_INTERFACE_HOB LocalHashInterfaceHob;\r
259 UINT32 HashMask;\r
260 UINT32 BiosSupportedHashMask;\r
261 EFI_STATUS Status;\r
262\r
263 //\r
264 // Check allow\r
265 //\r
266 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);\r
267 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {\r
268 return EFI_UNSUPPORTED;\r
269 }\r
270\r
271 HashInterfaceHob = InternalGetHashInterface ();\r
272 if (HashInterfaceHob == NULL) {\r
273 ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));\r
274 HashInterfaceHob = BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));\r
275 if (HashInterfaceHob == NULL) {\r
276 return EFI_OUT_OF_RESOURCES;\r
277 }\r
278 }\r
279\r
280 if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {\r
281 return EFI_OUT_OF_RESOURCES;\r
282 }\r
283 BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
284 Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask);\r
285 ASSERT_EFI_ERROR (Status);\r
286\r
287 //\r
288 // Check duplication\r
289 //\r
290 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
291 if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) {\r
292 //\r
293 // In PEI phase, there will be shadow driver dispatched again.\r
294 //\r
295 DEBUG ((EFI_D_INFO, "RegisterHashInterfaceLib - Override\n"));\r
296 CopyMem (&HashInterfaceHob->HashInterface[Index], HashInterface, sizeof(*HashInterface));\r
297 return EFI_SUCCESS;\r
298 }\r
299 }\r
300\r
301 CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface));\r
302 HashInterfaceHob->HashInterfaceCount ++;\r
303 \r
304 return EFI_SUCCESS;\r
305}