]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c
SecurityPkg: Replace BSD License with BSD+Patent License
[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
20 TPM_ALG_ID AlgoId;\r
21 UINT32 Mask;\r
22} TPM2_HASH_MASK;\r
23\r
24TPM2_HASH_MASK mTpm2HashMask[] = {\r
1abfa4ce
JY
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
32 The function get algorith from hash mask info.\r
33\r
34 @return Hash algorithm\r
35**/\r
36TPM_ALG_ID\r
37Tpm2GetAlgoFromHashMask (\r
38 VOID\r
39 )\r
40{\r
41 UINT32 HashMask;\r
42 UINTN Index;\r
43\r
44 HashMask = PcdGet32 (PcdTpm2HashMask);\r
45 for (Index = 0; Index < sizeof(mTpm2HashMask)/sizeof(mTpm2HashMask[0]); Index++) {\r
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
65 OUT HASH_HANDLE *HashHandle\r
66 )\r
67{\r
68 TPMI_DH_OBJECT SequenceHandle;\r
69 EFI_STATUS Status;\r
70 TPM_ALG_ID AlgoId;\r
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
78 return Status;\r
79}\r
80\r
81/**\r
82 Update hash sequence data.\r
83\r
84 @param HashHandle Hash handle.\r
85 @param DataToHash Data to be hashed.\r
86 @param DataToHashLen Data size.\r
87\r
88 @retval EFI_SUCCESS Hash sequence updated.\r
89**/\r
90EFI_STATUS\r
91EFIAPI\r
92HashUpdate (\r
93 IN HASH_HANDLE HashHandle,\r
94 IN VOID *DataToHash,\r
95 IN UINTN DataToHashLen\r
96 )\r
97{\r
98 UINT8 *Buffer;\r
99 UINT64 HashLen;\r
100 TPM2B_MAX_BUFFER HashBuffer;\r
101 EFI_STATUS Status;\r
102\r
103 Buffer = (UINT8 *)(UINTN)DataToHash;\r
104 for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {\r
105\r
106 HashBuffer.size = sizeof(HashBuffer.buffer);\r
107 CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));\r
108 Buffer += sizeof(HashBuffer.buffer);\r
109\r
110 Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
111 if (EFI_ERROR(Status)) {\r
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
120 CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
121 Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
122 if (EFI_ERROR(Status)) {\r
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
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
148 )\r
149{\r
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
156\r
157 AlgoId = Tpm2GetAlgoFromHashMask ();\r
158\r
159 Buffer = (UINT8 *)(UINTN)DataToHash;\r
160 for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {\r
161\r
162 HashBuffer.size = sizeof(HashBuffer.buffer);\r
163 CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));\r
164 Buffer += sizeof(HashBuffer.buffer);\r
165\r
166 Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
167 if (EFI_ERROR(Status)) {\r
168 return EFI_DEVICE_ERROR;\r
169 }\r
170 }\r
171\r
172 //\r
173 // Last one\r
174 //\r
175 HashBuffer.size = (UINT16)HashLen;\r
176 CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
177\r
178 ZeroMem(DigestList, sizeof(*DigestList));\r
179 DigestList->count = HASH_COUNT;\r
180\r
181 if (AlgoId == TPM_ALG_NULL) {\r
182 Status = Tpm2EventSequenceComplete (\r
183 PcrIndex,\r
184 (TPMI_DH_OBJECT)HashHandle,\r
185 &HashBuffer,\r
186 DigestList\r
187 );\r
188 } else {\r
189 Status = Tpm2SequenceComplete (\r
190 (TPMI_DH_OBJECT)HashHandle,\r
191 &HashBuffer,\r
192 &Result\r
193 );\r
194 if (EFI_ERROR(Status)) {\r
195 return EFI_DEVICE_ERROR;\r
196 }\r
197\r
198 DigestList->count = 1;\r
199 DigestList->digests[0].hashAlg = AlgoId;\r
200 CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);\r
201 Status = Tpm2PcrExtend (\r
202 PcrIndex,\r
203 DigestList\r
204 );\r
205 }\r
206 if (EFI_ERROR(Status)) {\r
207 return EFI_DEVICE_ERROR;\r
208 }\r
209 return EFI_SUCCESS;\r
210}\r
211\r
212/**\r
213 Hash data and extend to PCR.\r
214\r
215 @param PcrIndex PCR to be extended.\r
216 @param DataToHash Data to be hashed.\r
217 @param DataToHashLen Data size.\r
218 @param DigestList Digest list.\r
219\r
220 @retval EFI_SUCCESS Hash data and DigestList is returned.\r
221**/\r
222EFI_STATUS\r
223EFIAPI\r
224HashAndExtend (\r
225 IN TPMI_DH_PCR PcrIndex,\r
226 IN VOID *DataToHash,\r
227 IN UINTN DataToHashLen,\r
228 OUT TPML_DIGEST_VALUES *DigestList\r
229 )\r
230{\r
231 EFI_STATUS Status;\r
232 UINT8 *Buffer;\r
233 UINT64 HashLen;\r
234 TPMI_DH_OBJECT SequenceHandle;\r
235 TPM2B_MAX_BUFFER HashBuffer;\r
236 TPM_ALG_ID AlgoId;\r
237 TPM2B_EVENT EventData;\r
238 TPM2B_DIGEST Result;\r
239\r
6aaac383 240 DEBUG((EFI_D_VERBOSE, "\n HashAndExtend Entry \n"));\r
c1d93242
JY
241\r
242 SequenceHandle = 0xFFFFFFFF; // Know bad value\r
243\r
244 AlgoId = Tpm2GetAlgoFromHashMask ();\r
245\r
246 if ((AlgoId == TPM_ALG_NULL) && (DataToHashLen <= sizeof(EventData.buffer))) {\r
247 EventData.size = (UINT16)DataToHashLen;\r
248 CopyMem (EventData.buffer, DataToHash, DataToHashLen);\r
249 Status = Tpm2PcrEvent (PcrIndex, &EventData, DigestList);\r
250 if (EFI_ERROR(Status)) {\r
251 return EFI_DEVICE_ERROR;\r
252 }\r
253 return EFI_SUCCESS;\r
254 }\r
255\r
256 Status = Tpm2HashSequenceStart(AlgoId, &SequenceHandle);\r
257 if (EFI_ERROR(Status)) {\r
258 return EFI_DEVICE_ERROR;\r
259 }\r
6aaac383 260 DEBUG((EFI_D_VERBOSE, "\n Tpm2HashSequenceStart Success \n"));\r
c1d93242
JY
261\r
262 Buffer = (UINT8 *)(UINTN)DataToHash;\r
263 for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {\r
264\r
265 HashBuffer.size = sizeof(HashBuffer.buffer);\r
266 CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));\r
267 Buffer += sizeof(HashBuffer.buffer);\r
268\r
269 Status = Tpm2SequenceUpdate(SequenceHandle, &HashBuffer);\r
270 if (EFI_ERROR(Status)) {\r
271 return EFI_DEVICE_ERROR;\r
272 }\r
273 }\r
6aaac383 274 DEBUG((EFI_D_VERBOSE, "\n Tpm2SequenceUpdate Success \n"));\r
c1d93242
JY
275\r
276 HashBuffer.size = (UINT16)HashLen;\r
277 CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
278\r
279 ZeroMem(DigestList, sizeof(*DigestList));\r
280 DigestList->count = HASH_COUNT;\r
281\r
282 if (AlgoId == TPM_ALG_NULL) {\r
283 Status = Tpm2EventSequenceComplete (\r
284 PcrIndex,\r
285 SequenceHandle,\r
286 &HashBuffer,\r
287 DigestList\r
288 );\r
289 if (EFI_ERROR(Status)) {\r
290 return EFI_DEVICE_ERROR;\r
291 }\r
6aaac383 292 DEBUG((EFI_D_VERBOSE, "\n Tpm2EventSequenceComplete Success \n"));\r
c1d93242
JY
293 } else {\r
294 Status = Tpm2SequenceComplete (\r
295 SequenceHandle,\r
296 &HashBuffer,\r
297 &Result\r
298 );\r
299 if (EFI_ERROR(Status)) {\r
300 return EFI_DEVICE_ERROR;\r
301 }\r
6aaac383 302 DEBUG((EFI_D_VERBOSE, "\n Tpm2SequenceComplete Success \n"));\r
c1d93242
JY
303\r
304 DigestList->count = 1;\r
305 DigestList->digests[0].hashAlg = AlgoId;\r
306 CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);\r
307 Status = Tpm2PcrExtend (\r
308 PcrIndex,\r
309 DigestList\r
310 );\r
311 if (EFI_ERROR(Status)) {\r
312 return EFI_DEVICE_ERROR;\r
313 }\r
6aaac383 314 DEBUG((EFI_D_VERBOSE, "\n Tpm2PcrExtend Success \n"));\r
c1d93242
JY
315 }\r
316\r
317 return EFI_SUCCESS;\r
318}\r
319\r
320/**\r
321 This service register Hash.\r
322\r
323 @param HashInterface Hash interface\r
324\r
325 @retval EFI_SUCCESS This hash interface is registered successfully.\r
326 @retval EFI_UNSUPPORTED System does not support register this interface.\r
327 @retval EFI_ALREADY_STARTED System already register this interface.\r
328**/\r
329EFI_STATUS\r
330EFIAPI\r
331RegisterHashInterfaceLib (\r
332 IN HASH_INTERFACE *HashInterface\r
333 )\r
334{\r
335 return EFI_UNSUPPORTED;\r
b3548d32 336}\r