]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c
SecurityPkg: Clean up source files
[mirror_edk2.git] / SecurityPkg / Library / HashLibTpm2 / HashLibTpm2.c
CommitLineData
c1d93242 1/** @file\r
07309c3d 2 This library uses TPM2 device to calculation hash.\r
c1d93242 3\r
b3548d32 4Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>\r
6aaac383 5(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
c1d93242
JY
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <PiPei.h>\r
17#include <Library/BaseLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/Tpm2CommandLib.h>\r
20#include <Library/DebugLib.h>\r
21#include <Library/MemoryAllocationLib.h>\r
22#include <Library/HashLib.h>\r
23#include <Library/PcdLib.h>\r
c1d93242
JY
24\r
25typedef struct {\r
26 TPM_ALG_ID AlgoId;\r
27 UINT32 Mask;\r
28} TPM2_HASH_MASK;\r
29\r
30TPM2_HASH_MASK mTpm2HashMask[] = {\r
1abfa4ce
JY
31 {TPM_ALG_SHA1, HASH_ALG_SHA1},\r
32 {TPM_ALG_SHA256, HASH_ALG_SHA256},\r
33 {TPM_ALG_SHA384, HASH_ALG_SHA384},\r
34 {TPM_ALG_SHA512, HASH_ALG_SHA512},\r
c1d93242
JY
35};\r
36\r
37/**\r
38 The function get algorith from hash mask info.\r
39\r
40 @return Hash algorithm\r
41**/\r
42TPM_ALG_ID\r
43Tpm2GetAlgoFromHashMask (\r
44 VOID\r
45 )\r
46{\r
47 UINT32 HashMask;\r
48 UINTN Index;\r
49\r
50 HashMask = PcdGet32 (PcdTpm2HashMask);\r
51 for (Index = 0; Index < sizeof(mTpm2HashMask)/sizeof(mTpm2HashMask[0]); Index++) {\r
52 if (mTpm2HashMask[Index].Mask == HashMask) {\r
53 return mTpm2HashMask[Index].AlgoId;\r
54 }\r
55 }\r
56\r
57 return TPM_ALG_NULL;\r
58}\r
59\r
60/**\r
61 Start hash sequence.\r
62\r
63 @param HashHandle Hash handle.\r
64\r
65 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.\r
66 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
67**/\r
68EFI_STATUS\r
69EFIAPI\r
70HashStart (\r
71 OUT HASH_HANDLE *HashHandle\r
72 )\r
73{\r
74 TPMI_DH_OBJECT SequenceHandle;\r
75 EFI_STATUS Status;\r
76 TPM_ALG_ID AlgoId;\r
77\r
78 AlgoId = Tpm2GetAlgoFromHashMask ();\r
79\r
80 Status = Tpm2HashSequenceStart (AlgoId, &SequenceHandle);\r
81 if (!EFI_ERROR (Status)) {\r
82 *HashHandle = (HASH_HANDLE)SequenceHandle;\r
83 }\r
84 return Status;\r
85}\r
86\r
87/**\r
88 Update hash sequence data.\r
89\r
90 @param HashHandle Hash handle.\r
91 @param DataToHash Data to be hashed.\r
92 @param DataToHashLen Data size.\r
93\r
94 @retval EFI_SUCCESS Hash sequence updated.\r
95**/\r
96EFI_STATUS\r
97EFIAPI\r
98HashUpdate (\r
99 IN HASH_HANDLE HashHandle,\r
100 IN VOID *DataToHash,\r
101 IN UINTN DataToHashLen\r
102 )\r
103{\r
104 UINT8 *Buffer;\r
105 UINT64 HashLen;\r
106 TPM2B_MAX_BUFFER HashBuffer;\r
107 EFI_STATUS Status;\r
108\r
109 Buffer = (UINT8 *)(UINTN)DataToHash;\r
110 for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {\r
111\r
112 HashBuffer.size = sizeof(HashBuffer.buffer);\r
113 CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));\r
114 Buffer += sizeof(HashBuffer.buffer);\r
115\r
116 Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
117 if (EFI_ERROR(Status)) {\r
118 return EFI_DEVICE_ERROR;\r
119 }\r
120 }\r
121\r
122 //\r
123 // Last one\r
124 //\r
125 HashBuffer.size = (UINT16)HashLen;\r
126 CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
127 Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
128 if (EFI_ERROR(Status)) {\r
129 return EFI_DEVICE_ERROR;\r
130 }\r
131\r
132 return EFI_SUCCESS;\r
133}\r
134\r
135/**\r
136 Hash sequence complete and extend to PCR.\r
137\r
138 @param HashHandle Hash handle.\r
139 @param PcrIndex PCR to be extended.\r
140 @param DataToHash Data to be hashed.\r
141 @param DataToHashLen Data size.\r
142 @param DigestList Digest list.\r
143\r
144 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.\r
145**/\r
146EFI_STATUS\r
147EFIAPI\r
148HashCompleteAndExtend (\r
149 IN HASH_HANDLE HashHandle,\r
150 IN TPMI_DH_PCR PcrIndex,\r
151 IN VOID *DataToHash,\r
152 IN UINTN DataToHashLen,\r
153 OUT TPML_DIGEST_VALUES *DigestList\r
154 )\r
155{\r
156 UINT8 *Buffer;\r
157 UINT64 HashLen;\r
158 TPM2B_MAX_BUFFER HashBuffer;\r
159 EFI_STATUS Status;\r
160 TPM_ALG_ID AlgoId;\r
161 TPM2B_DIGEST Result;\r
162\r
163 AlgoId = Tpm2GetAlgoFromHashMask ();\r
164\r
165 Buffer = (UINT8 *)(UINTN)DataToHash;\r
166 for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {\r
167\r
168 HashBuffer.size = sizeof(HashBuffer.buffer);\r
169 CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));\r
170 Buffer += sizeof(HashBuffer.buffer);\r
171\r
172 Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
173 if (EFI_ERROR(Status)) {\r
174 return EFI_DEVICE_ERROR;\r
175 }\r
176 }\r
177\r
178 //\r
179 // Last one\r
180 //\r
181 HashBuffer.size = (UINT16)HashLen;\r
182 CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
183\r
184 ZeroMem(DigestList, sizeof(*DigestList));\r
185 DigestList->count = HASH_COUNT;\r
186\r
187 if (AlgoId == TPM_ALG_NULL) {\r
188 Status = Tpm2EventSequenceComplete (\r
189 PcrIndex,\r
190 (TPMI_DH_OBJECT)HashHandle,\r
191 &HashBuffer,\r
192 DigestList\r
193 );\r
194 } else {\r
195 Status = Tpm2SequenceComplete (\r
196 (TPMI_DH_OBJECT)HashHandle,\r
197 &HashBuffer,\r
198 &Result\r
199 );\r
200 if (EFI_ERROR(Status)) {\r
201 return EFI_DEVICE_ERROR;\r
202 }\r
203\r
204 DigestList->count = 1;\r
205 DigestList->digests[0].hashAlg = AlgoId;\r
206 CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);\r
207 Status = Tpm2PcrExtend (\r
208 PcrIndex,\r
209 DigestList\r
210 );\r
211 }\r
212 if (EFI_ERROR(Status)) {\r
213 return EFI_DEVICE_ERROR;\r
214 }\r
215 return EFI_SUCCESS;\r
216}\r
217\r
218/**\r
219 Hash data and extend to PCR.\r
220\r
221 @param PcrIndex PCR to be extended.\r
222 @param DataToHash Data to be hashed.\r
223 @param DataToHashLen Data size.\r
224 @param DigestList Digest list.\r
225\r
226 @retval EFI_SUCCESS Hash data and DigestList is returned.\r
227**/\r
228EFI_STATUS\r
229EFIAPI\r
230HashAndExtend (\r
231 IN TPMI_DH_PCR PcrIndex,\r
232 IN VOID *DataToHash,\r
233 IN UINTN DataToHashLen,\r
234 OUT TPML_DIGEST_VALUES *DigestList\r
235 )\r
236{\r
237 EFI_STATUS Status;\r
238 UINT8 *Buffer;\r
239 UINT64 HashLen;\r
240 TPMI_DH_OBJECT SequenceHandle;\r
241 TPM2B_MAX_BUFFER HashBuffer;\r
242 TPM_ALG_ID AlgoId;\r
243 TPM2B_EVENT EventData;\r
244 TPM2B_DIGEST Result;\r
245\r
6aaac383 246 DEBUG((EFI_D_VERBOSE, "\n HashAndExtend Entry \n"));\r
c1d93242
JY
247\r
248 SequenceHandle = 0xFFFFFFFF; // Know bad value\r
249\r
250 AlgoId = Tpm2GetAlgoFromHashMask ();\r
251\r
252 if ((AlgoId == TPM_ALG_NULL) && (DataToHashLen <= sizeof(EventData.buffer))) {\r
253 EventData.size = (UINT16)DataToHashLen;\r
254 CopyMem (EventData.buffer, DataToHash, DataToHashLen);\r
255 Status = Tpm2PcrEvent (PcrIndex, &EventData, DigestList);\r
256 if (EFI_ERROR(Status)) {\r
257 return EFI_DEVICE_ERROR;\r
258 }\r
259 return EFI_SUCCESS;\r
260 }\r
261\r
262 Status = Tpm2HashSequenceStart(AlgoId, &SequenceHandle);\r
263 if (EFI_ERROR(Status)) {\r
264 return EFI_DEVICE_ERROR;\r
265 }\r
6aaac383 266 DEBUG((EFI_D_VERBOSE, "\n Tpm2HashSequenceStart Success \n"));\r
c1d93242
JY
267\r
268 Buffer = (UINT8 *)(UINTN)DataToHash;\r
269 for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {\r
270\r
271 HashBuffer.size = sizeof(HashBuffer.buffer);\r
272 CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));\r
273 Buffer += sizeof(HashBuffer.buffer);\r
274\r
275 Status = Tpm2SequenceUpdate(SequenceHandle, &HashBuffer);\r
276 if (EFI_ERROR(Status)) {\r
277 return EFI_DEVICE_ERROR;\r
278 }\r
279 }\r
6aaac383 280 DEBUG((EFI_D_VERBOSE, "\n Tpm2SequenceUpdate Success \n"));\r
c1d93242
JY
281\r
282 HashBuffer.size = (UINT16)HashLen;\r
283 CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
284\r
285 ZeroMem(DigestList, sizeof(*DigestList));\r
286 DigestList->count = HASH_COUNT;\r
287\r
288 if (AlgoId == TPM_ALG_NULL) {\r
289 Status = Tpm2EventSequenceComplete (\r
290 PcrIndex,\r
291 SequenceHandle,\r
292 &HashBuffer,\r
293 DigestList\r
294 );\r
295 if (EFI_ERROR(Status)) {\r
296 return EFI_DEVICE_ERROR;\r
297 }\r
6aaac383 298 DEBUG((EFI_D_VERBOSE, "\n Tpm2EventSequenceComplete Success \n"));\r
c1d93242
JY
299 } else {\r
300 Status = Tpm2SequenceComplete (\r
301 SequenceHandle,\r
302 &HashBuffer,\r
303 &Result\r
304 );\r
305 if (EFI_ERROR(Status)) {\r
306 return EFI_DEVICE_ERROR;\r
307 }\r
6aaac383 308 DEBUG((EFI_D_VERBOSE, "\n Tpm2SequenceComplete Success \n"));\r
c1d93242
JY
309\r
310 DigestList->count = 1;\r
311 DigestList->digests[0].hashAlg = AlgoId;\r
312 CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);\r
313 Status = Tpm2PcrExtend (\r
314 PcrIndex,\r
315 DigestList\r
316 );\r
317 if (EFI_ERROR(Status)) {\r
318 return EFI_DEVICE_ERROR;\r
319 }\r
6aaac383 320 DEBUG((EFI_D_VERBOSE, "\n Tpm2PcrExtend Success \n"));\r
c1d93242
JY
321 }\r
322\r
323 return EFI_SUCCESS;\r
324}\r
325\r
326/**\r
327 This service register Hash.\r
328\r
329 @param HashInterface Hash interface\r
330\r
331 @retval EFI_SUCCESS This hash interface is registered successfully.\r
332 @retval EFI_UNSUPPORTED System does not support register this interface.\r
333 @retval EFI_ALREADY_STARTED System already register this interface.\r
334**/\r
335EFI_STATUS\r
336EFIAPI\r
337RegisterHashInterfaceLib (\r
338 IN HASH_INTERFACE *HashInterface\r
339 )\r
340{\r
341 return EFI_UNSUPPORTED;\r
b3548d32 342}\r