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
;
83 Update hash sequence data.
85 @param HashHandle Hash handle.
86 @param DataToHash Data to be hashed.
87 @param DataToHashLen Data size.
89 @retval EFI_SUCCESS Hash sequence updated.
94 IN HASH_HANDLE HashHandle
,
96 IN UINTN DataToHashLen
101 TPM2B_MAX_BUFFER HashBuffer
;
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
);
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
)) {
161 HashBuffer
.size
= sizeof (HashBuffer
.buffer
);
162 CopyMem (HashBuffer
.buffer
, Buffer
, sizeof (HashBuffer
.buffer
));
163 Buffer
+= sizeof (HashBuffer
.buffer
);
165 Status
= Tpm2SequenceUpdate ((TPMI_DH_OBJECT
)HashHandle
, &HashBuffer
);
166 if (EFI_ERROR (Status
)) {
167 return EFI_DEVICE_ERROR
;
174 HashBuffer
.size
= (UINT16
)HashLen
;
175 CopyMem (HashBuffer
.buffer
, Buffer
, (UINTN
)HashLen
);
177 ZeroMem (DigestList
, sizeof (*DigestList
));
178 DigestList
->count
= HASH_COUNT
;
180 if (AlgoId
== TPM_ALG_NULL
) {
181 Status
= Tpm2EventSequenceComplete (
183 (TPMI_DH_OBJECT
)HashHandle
,
188 Status
= Tpm2SequenceComplete (
189 (TPMI_DH_OBJECT
)HashHandle
,
193 if (EFI_ERROR (Status
)) {
194 return EFI_DEVICE_ERROR
;
197 DigestList
->count
= 1;
198 DigestList
->digests
[0].hashAlg
= AlgoId
;
199 CopyMem (&DigestList
->digests
[0].digest
, Result
.buffer
, Result
.size
);
200 Status
= Tpm2PcrExtend (
206 if (EFI_ERROR (Status
)) {
207 return EFI_DEVICE_ERROR
;
214 Hash data and extend to PCR.
216 @param PcrIndex PCR to be extended.
217 @param DataToHash Data to be hashed.
218 @param DataToHashLen Data size.
219 @param DigestList Digest list.
221 @retval EFI_SUCCESS Hash data and DigestList is returned.
226 IN TPMI_DH_PCR PcrIndex
,
228 IN UINTN DataToHashLen
,
229 OUT TPML_DIGEST_VALUES
*DigestList
235 TPMI_DH_OBJECT SequenceHandle
;
236 TPM2B_MAX_BUFFER HashBuffer
;
238 TPM2B_EVENT EventData
;
241 DEBUG ((DEBUG_VERBOSE
, "\n HashAndExtend Entry \n"));
243 SequenceHandle
= 0xFFFFFFFF; // Know bad value
245 AlgoId
= Tpm2GetAlgoFromHashMask ();
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
;
258 Status
= Tpm2HashSequenceStart (AlgoId
, &SequenceHandle
);
259 if (EFI_ERROR (Status
)) {
260 return EFI_DEVICE_ERROR
;
263 DEBUG ((DEBUG_VERBOSE
, "\n Tpm2HashSequenceStart Success \n"));
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
);
271 Status
= Tpm2SequenceUpdate (SequenceHandle
, &HashBuffer
);
272 if (EFI_ERROR (Status
)) {
273 return EFI_DEVICE_ERROR
;
277 DEBUG ((DEBUG_VERBOSE
, "\n Tpm2SequenceUpdate Success \n"));
279 HashBuffer
.size
= (UINT16
)HashLen
;
280 CopyMem (HashBuffer
.buffer
, Buffer
, (UINTN
)HashLen
);
282 ZeroMem (DigestList
, sizeof (*DigestList
));
283 DigestList
->count
= HASH_COUNT
;
285 if (AlgoId
== TPM_ALG_NULL
) {
286 Status
= Tpm2EventSequenceComplete (
292 if (EFI_ERROR (Status
)) {
293 return EFI_DEVICE_ERROR
;
296 DEBUG ((DEBUG_VERBOSE
, "\n Tpm2EventSequenceComplete Success \n"));
298 Status
= Tpm2SequenceComplete (
303 if (EFI_ERROR (Status
)) {
304 return EFI_DEVICE_ERROR
;
307 DEBUG ((DEBUG_VERBOSE
, "\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
;
320 DEBUG ((DEBUG_VERBOSE
, "\n Tpm2PcrExtend Success \n"));
327 This service register Hash.
329 @param HashInterface Hash interface
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.
337 RegisterHashInterfaceLib (
338 IN HASH_INTERFACE
*HashInterface
341 return EFI_UNSUPPORTED
;