2 Ihis library uses TPM2 device to calculation hash.
4 Copyright (c) 2013, 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>
23 #include <Protocol/TrEEProtocol.h>
30 TPM2_HASH_MASK mTpm2HashMask
[] = {
31 {TPM_ALG_SHA1
, TREE_BOOT_HASH_ALG_SHA1
},
32 {TPM_ALG_SHA256
, TREE_BOOT_HASH_ALG_SHA256
},
33 {TPM_ALG_SHA384
, TREE_BOOT_HASH_ALG_SHA384
},
34 {TPM_ALG_SHA512
, TREE_BOOT_HASH_ALG_SHA512
},
38 The function get algorith from hash mask info.
40 @return Hash algorithm
43 Tpm2GetAlgoFromHashMask (
50 HashMask
= PcdGet32 (PcdTpm2HashMask
);
51 for (Index
= 0; Index
< sizeof(mTpm2HashMask
)/sizeof(mTpm2HashMask
[0]); Index
++) {
52 if (mTpm2HashMask
[Index
].Mask
== HashMask
) {
53 return mTpm2HashMask
[Index
].AlgoId
;
63 @param HashHandle Hash handle.
65 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
66 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
71 OUT HASH_HANDLE
*HashHandle
74 TPMI_DH_OBJECT SequenceHandle
;
78 AlgoId
= Tpm2GetAlgoFromHashMask ();
80 Status
= Tpm2HashSequenceStart (AlgoId
, &SequenceHandle
);
81 if (!EFI_ERROR (Status
)) {
82 *HashHandle
= (HASH_HANDLE
)SequenceHandle
;
88 Update hash sequence data.
90 @param HashHandle Hash handle.
91 @param DataToHash Data to be hashed.
92 @param DataToHashLen Data size.
94 @retval EFI_SUCCESS Hash sequence updated.
99 IN HASH_HANDLE HashHandle
,
101 IN UINTN DataToHashLen
106 TPM2B_MAX_BUFFER HashBuffer
;
109 Buffer
= (UINT8
*)(UINTN
)DataToHash
;
110 for (HashLen
= DataToHashLen
; HashLen
> sizeof(HashBuffer
.buffer
); HashLen
-= sizeof(HashBuffer
.buffer
)) {
112 HashBuffer
.size
= sizeof(HashBuffer
.buffer
);
113 CopyMem(HashBuffer
.buffer
, Buffer
, sizeof(HashBuffer
.buffer
));
114 Buffer
+= sizeof(HashBuffer
.buffer
);
116 Status
= Tpm2SequenceUpdate((TPMI_DH_OBJECT
)HashHandle
, &HashBuffer
);
117 if (EFI_ERROR(Status
)) {
118 return EFI_DEVICE_ERROR
;
125 HashBuffer
.size
= (UINT16
)HashLen
;
126 CopyMem(HashBuffer
.buffer
, Buffer
, (UINTN
)HashLen
);
127 Status
= Tpm2SequenceUpdate((TPMI_DH_OBJECT
)HashHandle
, &HashBuffer
);
128 if (EFI_ERROR(Status
)) {
129 return EFI_DEVICE_ERROR
;
136 Hash sequence complete and extend to PCR.
138 @param HashHandle Hash handle.
139 @param PcrIndex PCR to be extended.
140 @param DataToHash Data to be hashed.
141 @param DataToHashLen Data size.
142 @param DigestList Digest list.
144 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
148 HashCompleteAndExtend (
149 IN HASH_HANDLE HashHandle
,
150 IN TPMI_DH_PCR PcrIndex
,
152 IN UINTN DataToHashLen
,
153 OUT TPML_DIGEST_VALUES
*DigestList
158 TPM2B_MAX_BUFFER HashBuffer
;
163 AlgoId
= Tpm2GetAlgoFromHashMask ();
165 Buffer
= (UINT8
*)(UINTN
)DataToHash
;
166 for (HashLen
= DataToHashLen
; HashLen
> sizeof(HashBuffer
.buffer
); HashLen
-= sizeof(HashBuffer
.buffer
)) {
168 HashBuffer
.size
= sizeof(HashBuffer
.buffer
);
169 CopyMem(HashBuffer
.buffer
, Buffer
, sizeof(HashBuffer
.buffer
));
170 Buffer
+= sizeof(HashBuffer
.buffer
);
172 Status
= Tpm2SequenceUpdate((TPMI_DH_OBJECT
)HashHandle
, &HashBuffer
);
173 if (EFI_ERROR(Status
)) {
174 return EFI_DEVICE_ERROR
;
181 HashBuffer
.size
= (UINT16
)HashLen
;
182 CopyMem(HashBuffer
.buffer
, Buffer
, (UINTN
)HashLen
);
184 ZeroMem(DigestList
, sizeof(*DigestList
));
185 DigestList
->count
= HASH_COUNT
;
187 if (AlgoId
== TPM_ALG_NULL
) {
188 Status
= Tpm2EventSequenceComplete (
190 (TPMI_DH_OBJECT
)HashHandle
,
195 Status
= Tpm2SequenceComplete (
196 (TPMI_DH_OBJECT
)HashHandle
,
200 if (EFI_ERROR(Status
)) {
201 return EFI_DEVICE_ERROR
;
204 DigestList
->count
= 1;
205 DigestList
->digests
[0].hashAlg
= AlgoId
;
206 CopyMem (&DigestList
->digests
[0].digest
, Result
.buffer
, Result
.size
);
207 Status
= Tpm2PcrExtend (
212 if (EFI_ERROR(Status
)) {
213 return EFI_DEVICE_ERROR
;
219 Hash data and extend to PCR.
221 @param PcrIndex PCR to be extended.
222 @param DataToHash Data to be hashed.
223 @param DataToHashLen Data size.
224 @param DigestList Digest list.
226 @retval EFI_SUCCESS Hash data and DigestList is returned.
231 IN TPMI_DH_PCR PcrIndex
,
233 IN UINTN DataToHashLen
,
234 OUT TPML_DIGEST_VALUES
*DigestList
240 TPMI_DH_OBJECT SequenceHandle
;
241 TPM2B_MAX_BUFFER HashBuffer
;
243 TPM2B_EVENT EventData
;
246 DEBUG((EFI_D_INFO
, "\n HashAndExtend Entry \n"));
248 SequenceHandle
= 0xFFFFFFFF; // Know bad value
250 AlgoId
= Tpm2GetAlgoFromHashMask ();
252 if ((AlgoId
== TPM_ALG_NULL
) && (DataToHashLen
<= sizeof(EventData
.buffer
))) {
253 EventData
.size
= (UINT16
)DataToHashLen
;
254 CopyMem (EventData
.buffer
, DataToHash
, DataToHashLen
);
255 Status
= Tpm2PcrEvent (PcrIndex
, &EventData
, DigestList
);
256 if (EFI_ERROR(Status
)) {
257 return EFI_DEVICE_ERROR
;
262 Status
= Tpm2HashSequenceStart(AlgoId
, &SequenceHandle
);
263 if (EFI_ERROR(Status
)) {
264 return EFI_DEVICE_ERROR
;
266 DEBUG((EFI_D_INFO
, "\n Tpm2HashSequenceStart Success \n"));
268 Buffer
= (UINT8
*)(UINTN
)DataToHash
;
269 for (HashLen
= DataToHashLen
; HashLen
> sizeof(HashBuffer
.buffer
); HashLen
-= sizeof(HashBuffer
.buffer
)) {
271 HashBuffer
.size
= sizeof(HashBuffer
.buffer
);
272 CopyMem(HashBuffer
.buffer
, Buffer
, sizeof(HashBuffer
.buffer
));
273 Buffer
+= sizeof(HashBuffer
.buffer
);
275 Status
= Tpm2SequenceUpdate(SequenceHandle
, &HashBuffer
);
276 if (EFI_ERROR(Status
)) {
277 return EFI_DEVICE_ERROR
;
280 DEBUG((EFI_D_INFO
, "\n Tpm2SequenceUpdate Success \n"));
282 HashBuffer
.size
= (UINT16
)HashLen
;
283 CopyMem(HashBuffer
.buffer
, Buffer
, (UINTN
)HashLen
);
285 ZeroMem(DigestList
, sizeof(*DigestList
));
286 DigestList
->count
= HASH_COUNT
;
288 if (AlgoId
== TPM_ALG_NULL
) {
289 Status
= Tpm2EventSequenceComplete (
295 if (EFI_ERROR(Status
)) {
296 return EFI_DEVICE_ERROR
;
298 DEBUG((EFI_D_INFO
, "\n Tpm2EventSequenceComplete Success \n"));
300 Status
= Tpm2SequenceComplete (
305 if (EFI_ERROR(Status
)) {
306 return EFI_DEVICE_ERROR
;
308 DEBUG((EFI_D_INFO
, "\n Tpm2SequenceComplete Success \n"));
310 DigestList
->count
= 1;
311 DigestList
->digests
[0].hashAlg
= AlgoId
;
312 CopyMem (&DigestList
->digests
[0].digest
, Result
.buffer
, Result
.size
);
313 Status
= Tpm2PcrExtend (
317 if (EFI_ERROR(Status
)) {
318 return EFI_DEVICE_ERROR
;
320 DEBUG((EFI_D_INFO
, "\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
;