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