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