2 Ihis library uses TPM2 device to calculation hash.
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
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.
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>
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
},
37 The function get algorith from hash mask info.
39 @return Hash algorithm
42 Tpm2GetAlgoFromHashMask (
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
;
62 @param HashHandle Hash handle.
64 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
65 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
70 OUT HASH_HANDLE
*HashHandle
73 TPMI_DH_OBJECT SequenceHandle
;
77 AlgoId
= Tpm2GetAlgoFromHashMask ();
79 Status
= Tpm2HashSequenceStart (AlgoId
, &SequenceHandle
);
80 if (!EFI_ERROR (Status
)) {
81 *HashHandle
= (HASH_HANDLE
)SequenceHandle
;
87 Update hash sequence data.
89 @param HashHandle Hash handle.
90 @param DataToHash Data to be hashed.
91 @param DataToHashLen Data size.
93 @retval EFI_SUCCESS Hash sequence updated.
98 IN HASH_HANDLE HashHandle
,
100 IN UINTN DataToHashLen
105 TPM2B_MAX_BUFFER HashBuffer
;
108 Buffer
= (UINT8
*)(UINTN
)DataToHash
;
109 for (HashLen
= DataToHashLen
; HashLen
> sizeof(HashBuffer
.buffer
); HashLen
-= sizeof(HashBuffer
.buffer
)) {
111 HashBuffer
.size
= sizeof(HashBuffer
.buffer
);
112 CopyMem(HashBuffer
.buffer
, Buffer
, sizeof(HashBuffer
.buffer
));
113 Buffer
+= sizeof(HashBuffer
.buffer
);
115 Status
= Tpm2SequenceUpdate((TPMI_DH_OBJECT
)HashHandle
, &HashBuffer
);
116 if (EFI_ERROR(Status
)) {
117 return EFI_DEVICE_ERROR
;
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
;
135 Hash sequence complete and extend to PCR.
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.
143 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
147 HashCompleteAndExtend (
148 IN HASH_HANDLE HashHandle
,
149 IN TPMI_DH_PCR PcrIndex
,
151 IN UINTN DataToHashLen
,
152 OUT TPML_DIGEST_VALUES
*DigestList
157 TPM2B_MAX_BUFFER HashBuffer
;
162 AlgoId
= Tpm2GetAlgoFromHashMask ();
164 Buffer
= (UINT8
*)(UINTN
)DataToHash
;
165 for (HashLen
= DataToHashLen
; HashLen
> sizeof(HashBuffer
.buffer
); HashLen
-= sizeof(HashBuffer
.buffer
)) {
167 HashBuffer
.size
= sizeof(HashBuffer
.buffer
);
168 CopyMem(HashBuffer
.buffer
, Buffer
, sizeof(HashBuffer
.buffer
));
169 Buffer
+= sizeof(HashBuffer
.buffer
);
171 Status
= Tpm2SequenceUpdate((TPMI_DH_OBJECT
)HashHandle
, &HashBuffer
);
172 if (EFI_ERROR(Status
)) {
173 return EFI_DEVICE_ERROR
;
180 HashBuffer
.size
= (UINT16
)HashLen
;
181 CopyMem(HashBuffer
.buffer
, Buffer
, (UINTN
)HashLen
);
183 ZeroMem(DigestList
, sizeof(*DigestList
));
184 DigestList
->count
= HASH_COUNT
;
186 if (AlgoId
== TPM_ALG_NULL
) {
187 Status
= Tpm2EventSequenceComplete (
189 (TPMI_DH_OBJECT
)HashHandle
,
194 Status
= Tpm2SequenceComplete (
195 (TPMI_DH_OBJECT
)HashHandle
,
199 if (EFI_ERROR(Status
)) {
200 return EFI_DEVICE_ERROR
;
203 DigestList
->count
= 1;
204 DigestList
->digests
[0].hashAlg
= AlgoId
;
205 CopyMem (&DigestList
->digests
[0].digest
, Result
.buffer
, Result
.size
);
206 Status
= Tpm2PcrExtend (
211 if (EFI_ERROR(Status
)) {
212 return EFI_DEVICE_ERROR
;
218 Hash data and extend to PCR.
220 @param PcrIndex PCR to be extended.
221 @param DataToHash Data to be hashed.
222 @param DataToHashLen Data size.
223 @param DigestList Digest list.
225 @retval EFI_SUCCESS Hash data and DigestList is returned.
230 IN TPMI_DH_PCR PcrIndex
,
232 IN UINTN DataToHashLen
,
233 OUT TPML_DIGEST_VALUES
*DigestList
239 TPMI_DH_OBJECT SequenceHandle
;
240 TPM2B_MAX_BUFFER HashBuffer
;
242 TPM2B_EVENT EventData
;
245 DEBUG((EFI_D_INFO
, "\n HashAndExtend Entry \n"));
247 SequenceHandle
= 0xFFFFFFFF; // Know bad value
249 AlgoId
= Tpm2GetAlgoFromHashMask ();
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
;
261 Status
= Tpm2HashSequenceStart(AlgoId
, &SequenceHandle
);
262 if (EFI_ERROR(Status
)) {
263 return EFI_DEVICE_ERROR
;
265 DEBUG((EFI_D_INFO
, "\n Tpm2HashSequenceStart Success \n"));
267 Buffer
= (UINT8
*)(UINTN
)DataToHash
;
268 for (HashLen
= DataToHashLen
; HashLen
> sizeof(HashBuffer
.buffer
); HashLen
-= sizeof(HashBuffer
.buffer
)) {
270 HashBuffer
.size
= sizeof(HashBuffer
.buffer
);
271 CopyMem(HashBuffer
.buffer
, Buffer
, sizeof(HashBuffer
.buffer
));
272 Buffer
+= sizeof(HashBuffer
.buffer
);
274 Status
= Tpm2SequenceUpdate(SequenceHandle
, &HashBuffer
);
275 if (EFI_ERROR(Status
)) {
276 return EFI_DEVICE_ERROR
;
279 DEBUG((EFI_D_INFO
, "\n Tpm2SequenceUpdate Success \n"));
281 HashBuffer
.size
= (UINT16
)HashLen
;
282 CopyMem(HashBuffer
.buffer
, Buffer
, (UINTN
)HashLen
);
284 ZeroMem(DigestList
, sizeof(*DigestList
));
285 DigestList
->count
= HASH_COUNT
;
287 if (AlgoId
== TPM_ALG_NULL
) {
288 Status
= Tpm2EventSequenceComplete (
294 if (EFI_ERROR(Status
)) {
295 return EFI_DEVICE_ERROR
;
297 DEBUG((EFI_D_INFO
, "\n Tpm2EventSequenceComplete Success \n"));
299 Status
= Tpm2SequenceComplete (
304 if (EFI_ERROR(Status
)) {
305 return EFI_DEVICE_ERROR
;
307 DEBUG((EFI_D_INFO
, "\n Tpm2SequenceComplete Success \n"));
309 DigestList
->count
= 1;
310 DigestList
->digests
[0].hashAlg
= AlgoId
;
311 CopyMem (&DigestList
->digests
[0].digest
, Result
.buffer
, Result
.size
);
312 Status
= Tpm2PcrExtend (
316 if (EFI_ERROR(Status
)) {
317 return EFI_DEVICE_ERROR
;
319 DEBUG((EFI_D_INFO
, "\n Tpm2PcrExtend Success \n"));
326 This service register Hash.
328 @param HashInterface Hash interface
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.
336 RegisterHashInterfaceLib (
337 IN HASH_INTERFACE
*HashInterface
340 return EFI_UNSUPPORTED
;