2 This library uses TPM2 device to calculation hash.
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
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>
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
},
32 The function get algorithm from hash mask info.
34 @return Hash algorithm
37 Tpm2GetAlgoFromHashMask (
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
;
57 @param HashHandle Hash handle.
59 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
60 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
65 OUT HASH_HANDLE
*HashHandle
68 TPMI_DH_OBJECT SequenceHandle
;
72 AlgoId
= Tpm2GetAlgoFromHashMask ();
74 Status
= Tpm2HashSequenceStart (AlgoId
, &SequenceHandle
);
75 if (!EFI_ERROR (Status
)) {
76 *HashHandle
= (HASH_HANDLE
)SequenceHandle
;
82 Update hash sequence data.
84 @param HashHandle Hash handle.
85 @param DataToHash Data to be hashed.
86 @param DataToHashLen Data size.
88 @retval EFI_SUCCESS Hash sequence updated.
93 IN HASH_HANDLE HashHandle
,
95 IN UINTN DataToHashLen
100 TPM2B_MAX_BUFFER HashBuffer
;
103 Buffer
= (UINT8
*)(UINTN
)DataToHash
;
104 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
);
110 Status
= Tpm2SequenceUpdate((TPMI_DH_OBJECT
)HashHandle
, &HashBuffer
);
111 if (EFI_ERROR(Status
)) {
112 return EFI_DEVICE_ERROR
;
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
;
130 Hash sequence complete and extend to PCR.
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.
138 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
142 HashCompleteAndExtend (
143 IN HASH_HANDLE HashHandle
,
144 IN TPMI_DH_PCR PcrIndex
,
146 IN UINTN DataToHashLen
,
147 OUT TPML_DIGEST_VALUES
*DigestList
152 TPM2B_MAX_BUFFER HashBuffer
;
157 AlgoId
= Tpm2GetAlgoFromHashMask ();
159 Buffer
= (UINT8
*)(UINTN
)DataToHash
;
160 for (HashLen
= DataToHashLen
; HashLen
> sizeof(HashBuffer
.buffer
); HashLen
-= sizeof(HashBuffer
.buffer
)) {
162 HashBuffer
.size
= sizeof(HashBuffer
.buffer
);
163 CopyMem(HashBuffer
.buffer
, Buffer
, sizeof(HashBuffer
.buffer
));
164 Buffer
+= sizeof(HashBuffer
.buffer
);
166 Status
= Tpm2SequenceUpdate((TPMI_DH_OBJECT
)HashHandle
, &HashBuffer
);
167 if (EFI_ERROR(Status
)) {
168 return EFI_DEVICE_ERROR
;
175 HashBuffer
.size
= (UINT16
)HashLen
;
176 CopyMem(HashBuffer
.buffer
, Buffer
, (UINTN
)HashLen
);
178 ZeroMem(DigestList
, sizeof(*DigestList
));
179 DigestList
->count
= HASH_COUNT
;
181 if (AlgoId
== TPM_ALG_NULL
) {
182 Status
= Tpm2EventSequenceComplete (
184 (TPMI_DH_OBJECT
)HashHandle
,
189 Status
= Tpm2SequenceComplete (
190 (TPMI_DH_OBJECT
)HashHandle
,
194 if (EFI_ERROR(Status
)) {
195 return EFI_DEVICE_ERROR
;
198 DigestList
->count
= 1;
199 DigestList
->digests
[0].hashAlg
= AlgoId
;
200 CopyMem (&DigestList
->digests
[0].digest
, Result
.buffer
, Result
.size
);
201 Status
= Tpm2PcrExtend (
206 if (EFI_ERROR(Status
)) {
207 return EFI_DEVICE_ERROR
;
213 Hash data and extend to PCR.
215 @param PcrIndex PCR to be extended.
216 @param DataToHash Data to be hashed.
217 @param DataToHashLen Data size.
218 @param DigestList Digest list.
220 @retval EFI_SUCCESS Hash data and DigestList is returned.
225 IN TPMI_DH_PCR PcrIndex
,
227 IN UINTN DataToHashLen
,
228 OUT TPML_DIGEST_VALUES
*DigestList
234 TPMI_DH_OBJECT SequenceHandle
;
235 TPM2B_MAX_BUFFER HashBuffer
;
237 TPM2B_EVENT EventData
;
240 DEBUG((DEBUG_VERBOSE
, "\n HashAndExtend Entry \n"));
242 SequenceHandle
= 0xFFFFFFFF; // Know bad value
244 AlgoId
= Tpm2GetAlgoFromHashMask ();
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
;
256 Status
= Tpm2HashSequenceStart(AlgoId
, &SequenceHandle
);
257 if (EFI_ERROR(Status
)) {
258 return EFI_DEVICE_ERROR
;
260 DEBUG((DEBUG_VERBOSE
, "\n Tpm2HashSequenceStart Success \n"));
262 Buffer
= (UINT8
*)(UINTN
)DataToHash
;
263 for (HashLen
= DataToHashLen
; HashLen
> sizeof(HashBuffer
.buffer
); HashLen
-= sizeof(HashBuffer
.buffer
)) {
265 HashBuffer
.size
= sizeof(HashBuffer
.buffer
);
266 CopyMem(HashBuffer
.buffer
, Buffer
, sizeof(HashBuffer
.buffer
));
267 Buffer
+= sizeof(HashBuffer
.buffer
);
269 Status
= Tpm2SequenceUpdate(SequenceHandle
, &HashBuffer
);
270 if (EFI_ERROR(Status
)) {
271 return EFI_DEVICE_ERROR
;
274 DEBUG((DEBUG_VERBOSE
, "\n Tpm2SequenceUpdate Success \n"));
276 HashBuffer
.size
= (UINT16
)HashLen
;
277 CopyMem(HashBuffer
.buffer
, Buffer
, (UINTN
)HashLen
);
279 ZeroMem(DigestList
, sizeof(*DigestList
));
280 DigestList
->count
= HASH_COUNT
;
282 if (AlgoId
== TPM_ALG_NULL
) {
283 Status
= Tpm2EventSequenceComplete (
289 if (EFI_ERROR(Status
)) {
290 return EFI_DEVICE_ERROR
;
292 DEBUG((DEBUG_VERBOSE
, "\n Tpm2EventSequenceComplete Success \n"));
294 Status
= Tpm2SequenceComplete (
299 if (EFI_ERROR(Status
)) {
300 return EFI_DEVICE_ERROR
;
302 DEBUG((DEBUG_VERBOSE
, "\n Tpm2SequenceComplete Success \n"));
304 DigestList
->count
= 1;
305 DigestList
->digests
[0].hashAlg
= AlgoId
;
306 CopyMem (&DigestList
->digests
[0].digest
, Result
.buffer
, Result
.size
);
307 Status
= Tpm2PcrExtend (
311 if (EFI_ERROR(Status
)) {
312 return EFI_DEVICE_ERROR
;
314 DEBUG((DEBUG_VERBOSE
, "\n Tpm2PcrExtend Success \n"));
321 This service register Hash.
323 @param HashInterface Hash interface
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.
331 RegisterHashInterfaceLib (
332 IN HASH_INTERFACE
*HashInterface
335 return EFI_UNSUPPORTED
;