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