]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c
SecurityPkg: Apply uncrustify changes
[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
289b714b 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
c1d93242
JY
7\r
8**/\r
9\r
10#include <PiPei.h>\r
11#include <Library/BaseLib.h>\r
12#include <Library/BaseMemoryLib.h>\r
13#include <Library/Tpm2CommandLib.h>\r
14#include <Library/DebugLib.h>\r
15#include <Library/MemoryAllocationLib.h>\r
16#include <Library/HashLib.h>\r
17#include <Library/PcdLib.h>\r
c1d93242
JY
18\r
19typedef struct {\r
c411b485
MK
20 TPM_ALG_ID AlgoId;\r
21 UINT32 Mask;\r
c1d93242
JY
22} TPM2_HASH_MASK;\r
23\r
c411b485
MK
24TPM2_HASH_MASK mTpm2HashMask[] = {\r
25 { TPM_ALG_SHA1, HASH_ALG_SHA1 },\r
26 { TPM_ALG_SHA256, HASH_ALG_SHA256 },\r
27 { TPM_ALG_SHA384, HASH_ALG_SHA384 },\r
28 { TPM_ALG_SHA512, HASH_ALG_SHA512 },\r
c1d93242
JY
29};\r
30\r
31/**\r
d6b926e7 32 The function get algorithm from hash mask info.\r
c1d93242
JY
33\r
34 @return Hash algorithm\r
35**/\r
36TPM_ALG_ID\r
37Tpm2GetAlgoFromHashMask (\r
38 VOID\r
39 )\r
40{\r
c411b485
MK
41 UINT32 HashMask;\r
42 UINTN Index;\r
c1d93242
JY
43\r
44 HashMask = PcdGet32 (PcdTpm2HashMask);\r
c411b485 45 for (Index = 0; Index < sizeof (mTpm2HashMask)/sizeof (mTpm2HashMask[0]); Index++) {\r
c1d93242
JY
46 if (mTpm2HashMask[Index].Mask == HashMask) {\r
47 return mTpm2HashMask[Index].AlgoId;\r
48 }\r
49 }\r
50\r
51 return TPM_ALG_NULL;\r
52}\r
53\r
54/**\r
55 Start hash sequence.\r
56\r
57 @param HashHandle Hash handle.\r
58\r
59 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.\r
60 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
61**/\r
62EFI_STATUS\r
63EFIAPI\r
64HashStart (\r
c411b485 65 OUT HASH_HANDLE *HashHandle\r
c1d93242
JY
66 )\r
67{\r
c411b485
MK
68 TPMI_DH_OBJECT SequenceHandle;\r
69 EFI_STATUS Status;\r
70 TPM_ALG_ID AlgoId;\r
c1d93242
JY
71\r
72 AlgoId = Tpm2GetAlgoFromHashMask ();\r
73\r
74 Status = Tpm2HashSequenceStart (AlgoId, &SequenceHandle);\r
75 if (!EFI_ERROR (Status)) {\r
76 *HashHandle = (HASH_HANDLE)SequenceHandle;\r
77 }\r
c411b485 78\r
c1d93242
JY
79 return Status;\r
80}\r
81\r
82/**\r
83 Update hash sequence data.\r
84\r
85 @param HashHandle Hash handle.\r
86 @param DataToHash Data to be hashed.\r
87 @param DataToHashLen Data size.\r
88\r
89 @retval EFI_SUCCESS Hash sequence updated.\r
90**/\r
91EFI_STATUS\r
92EFIAPI\r
93HashUpdate (\r
c411b485
MK
94 IN HASH_HANDLE HashHandle,\r
95 IN VOID *DataToHash,\r
96 IN UINTN DataToHashLen\r
c1d93242
JY
97 )\r
98{\r
c411b485
MK
99 UINT8 *Buffer;\r
100 UINT64 HashLen;\r
101 TPM2B_MAX_BUFFER HashBuffer;\r
102 EFI_STATUS Status;\r
c1d93242
JY
103\r
104 Buffer = (UINT8 *)(UINTN)DataToHash;\r
c411b485
MK
105 for (HashLen = DataToHashLen; HashLen > sizeof (HashBuffer.buffer); HashLen -= sizeof (HashBuffer.buffer)) {\r
106 HashBuffer.size = sizeof (HashBuffer.buffer);\r
107 CopyMem (HashBuffer.buffer, Buffer, sizeof (HashBuffer.buffer));\r
108 Buffer += sizeof (HashBuffer.buffer);\r
c1d93242 109\r
c411b485
MK
110 Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
111 if (EFI_ERROR (Status)) {\r
c1d93242
JY
112 return EFI_DEVICE_ERROR;\r
113 }\r
114 }\r
115\r
116 //\r
117 // Last one\r
118 //\r
119 HashBuffer.size = (UINT16)HashLen;\r
c411b485
MK
120 CopyMem (HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
121 Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
122 if (EFI_ERROR (Status)) {\r
c1d93242
JY
123 return EFI_DEVICE_ERROR;\r
124 }\r
125\r
126 return EFI_SUCCESS;\r
127}\r
128\r
129/**\r
130 Hash sequence complete and extend to PCR.\r
131\r
132 @param HashHandle Hash handle.\r
133 @param PcrIndex PCR to be extended.\r
134 @param DataToHash Data to be hashed.\r
135 @param DataToHashLen Data size.\r
136 @param DigestList Digest list.\r
137\r
138 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.\r
139**/\r
140EFI_STATUS\r
141EFIAPI\r
142HashCompleteAndExtend (\r
c411b485
MK
143 IN HASH_HANDLE HashHandle,\r
144 IN TPMI_DH_PCR PcrIndex,\r
145 IN VOID *DataToHash,\r
146 IN UINTN DataToHashLen,\r
147 OUT TPML_DIGEST_VALUES *DigestList\r
c1d93242
JY
148 )\r
149{\r
c411b485
MK
150 UINT8 *Buffer;\r
151 UINT64 HashLen;\r
152 TPM2B_MAX_BUFFER HashBuffer;\r
153 EFI_STATUS Status;\r
154 TPM_ALG_ID AlgoId;\r
155 TPM2B_DIGEST Result;\r
c1d93242
JY
156\r
157 AlgoId = Tpm2GetAlgoFromHashMask ();\r
158\r
159 Buffer = (UINT8 *)(UINTN)DataToHash;\r
c411b485
MK
160 for (HashLen = DataToHashLen; HashLen > sizeof (HashBuffer.buffer); HashLen -= sizeof (HashBuffer.buffer)) {\r
161 HashBuffer.size = sizeof (HashBuffer.buffer);\r
162 CopyMem (HashBuffer.buffer, Buffer, sizeof (HashBuffer.buffer));\r
163 Buffer += sizeof (HashBuffer.buffer);\r
c1d93242 164\r
c411b485
MK
165 Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
166 if (EFI_ERROR (Status)) {\r
c1d93242
JY
167 return EFI_DEVICE_ERROR;\r
168 }\r
169 }\r
170\r
171 //\r
172 // Last one\r
173 //\r
174 HashBuffer.size = (UINT16)HashLen;\r
c411b485 175 CopyMem (HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
c1d93242 176\r
c411b485 177 ZeroMem (DigestList, sizeof (*DigestList));\r
c1d93242
JY
178 DigestList->count = HASH_COUNT;\r
179\r
180 if (AlgoId == TPM_ALG_NULL) {\r
181 Status = Tpm2EventSequenceComplete (\r
182 PcrIndex,\r
183 (TPMI_DH_OBJECT)HashHandle,\r
184 &HashBuffer,\r
185 DigestList\r
186 );\r
187 } else {\r
188 Status = Tpm2SequenceComplete (\r
189 (TPMI_DH_OBJECT)HashHandle,\r
190 &HashBuffer,\r
191 &Result\r
192 );\r
c411b485 193 if (EFI_ERROR (Status)) {\r
c1d93242
JY
194 return EFI_DEVICE_ERROR;\r
195 }\r
196\r
c411b485 197 DigestList->count = 1;\r
c1d93242
JY
198 DigestList->digests[0].hashAlg = AlgoId;\r
199 CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);\r
200 Status = Tpm2PcrExtend (\r
201 PcrIndex,\r
202 DigestList\r
203 );\r
204 }\r
c411b485
MK
205\r
206 if (EFI_ERROR (Status)) {\r
c1d93242
JY
207 return EFI_DEVICE_ERROR;\r
208 }\r
c411b485 209\r
c1d93242
JY
210 return EFI_SUCCESS;\r
211}\r
212\r
213/**\r
214 Hash data and extend to PCR.\r
215\r
216 @param PcrIndex PCR to be extended.\r
217 @param DataToHash Data to be hashed.\r
218 @param DataToHashLen Data size.\r
219 @param DigestList Digest list.\r
220\r
221 @retval EFI_SUCCESS Hash data and DigestList is returned.\r
222**/\r
223EFI_STATUS\r
224EFIAPI\r
225HashAndExtend (\r
c411b485
MK
226 IN TPMI_DH_PCR PcrIndex,\r
227 IN VOID *DataToHash,\r
228 IN UINTN DataToHashLen,\r
229 OUT TPML_DIGEST_VALUES *DigestList\r
c1d93242
JY
230 )\r
231{\r
c411b485
MK
232 EFI_STATUS Status;\r
233 UINT8 *Buffer;\r
234 UINT64 HashLen;\r
235 TPMI_DH_OBJECT SequenceHandle;\r
236 TPM2B_MAX_BUFFER HashBuffer;\r
237 TPM_ALG_ID AlgoId;\r
238 TPM2B_EVENT EventData;\r
239 TPM2B_DIGEST Result;\r
c1d93242 240\r
c411b485 241 DEBUG ((DEBUG_VERBOSE, "\n HashAndExtend Entry \n"));\r
c1d93242
JY
242\r
243 SequenceHandle = 0xFFFFFFFF; // Know bad value\r
244\r
245 AlgoId = Tpm2GetAlgoFromHashMask ();\r
246\r
c411b485 247 if ((AlgoId == TPM_ALG_NULL) && (DataToHashLen <= sizeof (EventData.buffer))) {\r
c1d93242
JY
248 EventData.size = (UINT16)DataToHashLen;\r
249 CopyMem (EventData.buffer, DataToHash, DataToHashLen);\r
250 Status = Tpm2PcrEvent (PcrIndex, &EventData, DigestList);\r
c411b485 251 if (EFI_ERROR (Status)) {\r
c1d93242
JY
252 return EFI_DEVICE_ERROR;\r
253 }\r
c411b485 254\r
c1d93242
JY
255 return EFI_SUCCESS;\r
256 }\r
257\r
c411b485
MK
258 Status = Tpm2HashSequenceStart (AlgoId, &SequenceHandle);\r
259 if (EFI_ERROR (Status)) {\r
c1d93242
JY
260 return EFI_DEVICE_ERROR;\r
261 }\r
c1d93242 262\r
c411b485 263 DEBUG ((DEBUG_VERBOSE, "\n Tpm2HashSequenceStart Success \n"));\r
c1d93242 264\r
c411b485
MK
265 Buffer = (UINT8 *)(UINTN)DataToHash;\r
266 for (HashLen = DataToHashLen; HashLen > sizeof (HashBuffer.buffer); HashLen -= sizeof (HashBuffer.buffer)) {\r
267 HashBuffer.size = sizeof (HashBuffer.buffer);\r
268 CopyMem (HashBuffer.buffer, Buffer, sizeof (HashBuffer.buffer));\r
269 Buffer += sizeof (HashBuffer.buffer);\r
c1d93242 270\r
c411b485
MK
271 Status = Tpm2SequenceUpdate (SequenceHandle, &HashBuffer);\r
272 if (EFI_ERROR (Status)) {\r
c1d93242
JY
273 return EFI_DEVICE_ERROR;\r
274 }\r
275 }\r
c411b485
MK
276\r
277 DEBUG ((DEBUG_VERBOSE, "\n Tpm2SequenceUpdate Success \n"));\r
c1d93242
JY
278\r
279 HashBuffer.size = (UINT16)HashLen;\r
c411b485 280 CopyMem (HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
c1d93242 281\r
c411b485 282 ZeroMem (DigestList, sizeof (*DigestList));\r
c1d93242
JY
283 DigestList->count = HASH_COUNT;\r
284\r
285 if (AlgoId == TPM_ALG_NULL) {\r
286 Status = Tpm2EventSequenceComplete (\r
287 PcrIndex,\r
288 SequenceHandle,\r
289 &HashBuffer,\r
290 DigestList\r
291 );\r
c411b485 292 if (EFI_ERROR (Status)) {\r
c1d93242
JY
293 return EFI_DEVICE_ERROR;\r
294 }\r
c411b485
MK
295\r
296 DEBUG ((DEBUG_VERBOSE, "\n Tpm2EventSequenceComplete Success \n"));\r
c1d93242
JY
297 } else {\r
298 Status = Tpm2SequenceComplete (\r
299 SequenceHandle,\r
300 &HashBuffer,\r
301 &Result\r
302 );\r
c411b485 303 if (EFI_ERROR (Status)) {\r
c1d93242
JY
304 return EFI_DEVICE_ERROR;\r
305 }\r
c1d93242 306\r
c411b485
MK
307 DEBUG ((DEBUG_VERBOSE, "\n Tpm2SequenceComplete Success \n"));\r
308\r
309 DigestList->count = 1;\r
c1d93242
JY
310 DigestList->digests[0].hashAlg = AlgoId;\r
311 CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);\r
312 Status = Tpm2PcrExtend (\r
313 PcrIndex,\r
314 DigestList\r
315 );\r
c411b485 316 if (EFI_ERROR (Status)) {\r
c1d93242
JY
317 return EFI_DEVICE_ERROR;\r
318 }\r
c411b485
MK
319\r
320 DEBUG ((DEBUG_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
c411b485 338 IN HASH_INTERFACE *HashInterface\r
c1d93242
JY
339 )\r
340{\r
341 return EFI_UNSUPPORTED;\r
b3548d32 342}\r