1 /** @file
2 This library is BaseCrypto router. It will redirect hash request to each individual
3 hash handler registerd, such as SHA1, SHA256.
4 Platform can use PcdTpm2HashMask to mask some hash engines.
5
6 Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #include <PiPei.h>
18 #include <Library/BaseLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/Tpm2CommandLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/MemoryAllocationLib.h>
23 #include <Library/PcdLib.h>
24 #include <Library/HashLib.h>
25
26 #include "HashLibBaseCryptoRouterCommon.h"
27
28 HASH_INTERFACE mHashInterface[HASH_COUNT] = {{{0}, NULL, NULL, NULL}};
29 UINTN mHashInterfaceCount = 0;
30
31 /**
32 Start hash sequence.
33
34 @param HashHandle Hash handle.
35
36 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
37 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
38 **/
39 EFI_STATUS
40 EFIAPI
HashStart(OUT HASH_HANDLE * HashHandle)41 HashStart (
42 OUT HASH_HANDLE *HashHandle
43 )
44 {
45 HASH_HANDLE *HashCtx;
46 UINTN Index;
47 UINT32 HashMask;
48
49 if (mHashInterfaceCount == 0) {
50 return EFI_UNSUPPORTED;
51 }
52
53 HashCtx = AllocatePool (sizeof(*HashCtx) * mHashInterfaceCount);
54 ASSERT (HashCtx != NULL);
55
56 for (Index = 0; Index < mHashInterfaceCount; Index++) {
57 HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
58 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
59 mHashInterface[Index].HashInit (&HashCtx[Index]);
60 }
61 }
62
63 *HashHandle = (HASH_HANDLE)HashCtx;
64
65 return EFI_SUCCESS;
66 }
67
68 /**
69 Update hash sequence data.
70
71 @param HashHandle Hash handle.
72 @param DataToHash Data to be hashed.
73 @param DataToHashLen Data size.
74
75 @retval EFI_SUCCESS Hash sequence updated.
76 **/
77 EFI_STATUS
78 EFIAPI
HashUpdate(IN HASH_HANDLE HashHandle,IN VOID * DataToHash,IN UINTN DataToHashLen)79 HashUpdate (
80 IN HASH_HANDLE HashHandle,
81 IN VOID *DataToHash,
82 IN UINTN DataToHashLen
83 )
84 {
85 HASH_HANDLE *HashCtx;
86 UINTN Index;
87 UINT32 HashMask;
88
89 if (mHashInterfaceCount == 0) {
90 return EFI_UNSUPPORTED;
91 }
92
93 HashCtx = (HASH_HANDLE *)HashHandle;
94
95 for (Index = 0; Index < mHashInterfaceCount; Index++) {
96 HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
97 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
98 mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
99 }
100 }
101
102 return EFI_SUCCESS;
103 }
104
105 /**
106 Hash sequence complete and extend to PCR.
107
108 @param HashHandle Hash handle.
109 @param PcrIndex PCR to be extended.
110 @param DataToHash Data to be hashed.
111 @param DataToHashLen Data size.
112 @param DigestList Digest list.
113
114 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
115 **/
116 EFI_STATUS
117 EFIAPI
HashCompleteAndExtend(IN HASH_HANDLE HashHandle,IN TPMI_DH_PCR PcrIndex,IN VOID * DataToHash,IN UINTN DataToHashLen,OUT TPML_DIGEST_VALUES * DigestList)118 HashCompleteAndExtend (
119 IN HASH_HANDLE HashHandle,
120 IN TPMI_DH_PCR PcrIndex,
121 IN VOID *DataToHash,
122 IN UINTN DataToHashLen,
123 OUT TPML_DIGEST_VALUES *DigestList
124 )
125 {
126 TPML_DIGEST_VALUES Digest;
127 HASH_HANDLE *HashCtx;
128 UINTN Index;
129 EFI_STATUS Status;
130 UINT32 HashMask;
131
132 if (mHashInterfaceCount == 0) {
133 return EFI_UNSUPPORTED;
134 }
135
136 HashCtx = (HASH_HANDLE *)HashHandle;
137 ZeroMem (DigestList, sizeof(*DigestList));
138
139 for (Index = 0; Index < mHashInterfaceCount; Index++) {
140 HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
141 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
142 mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
143 mHashInterface[Index].HashFinal (HashCtx[Index], &Digest);
144 Tpm2SetHashToDigestList (DigestList, &Digest);
145 }
146 }
147
148 FreePool (HashCtx);
149
150 Status = Tpm2PcrExtend (
151 PcrIndex,
152 DigestList
153 );
154 return Status;
155 }
156
157 /**
158 Hash data and extend to PCR.
159
160 @param PcrIndex PCR to be extended.
161 @param DataToHash Data to be hashed.
162 @param DataToHashLen Data size.
163 @param DigestList Digest list.
164
165 @retval EFI_SUCCESS Hash data and DigestList is returned.
166 **/
167 EFI_STATUS
168 EFIAPI
HashAndExtend(IN TPMI_DH_PCR PcrIndex,IN VOID * DataToHash,IN UINTN DataToHashLen,OUT TPML_DIGEST_VALUES * DigestList)169 HashAndExtend (
170 IN TPMI_DH_PCR PcrIndex,
171 IN VOID *DataToHash,
172 IN UINTN DataToHashLen,
173 OUT TPML_DIGEST_VALUES *DigestList
174 )
175 {
176 HASH_HANDLE HashHandle;
177 EFI_STATUS Status;
178
179 if (mHashInterfaceCount == 0) {
180 return EFI_UNSUPPORTED;
181 }
182
183 HashStart (&HashHandle);
184 HashUpdate (HashHandle, DataToHash, DataToHashLen);
185 Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
186
187 return Status;
188 }
189
190 /**
191 This service register Hash.
192
193 @param HashInterface Hash interface
194
195 @retval EFI_SUCCESS This hash interface is registered successfully.
196 @retval EFI_UNSUPPORTED System does not support register this interface.
197 @retval EFI_ALREADY_STARTED System already register this interface.
198 **/
199 EFI_STATUS
200 EFIAPI
RegisterHashInterfaceLib(IN HASH_INTERFACE * HashInterface)201 RegisterHashInterfaceLib (
202 IN HASH_INTERFACE *HashInterface
203 )
204 {
205 UINTN Index;
206 UINT32 HashMask;
207 UINT32 BiosSupportedHashMask;
208 EFI_STATUS Status;
209
210 //
211 // Check allow
212 //
213 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
214 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
215 return EFI_UNSUPPORTED;
216 }
217
218 if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) {
219 return EFI_OUT_OF_RESOURCES;
220 }
221 BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);
222 Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask);
223 ASSERT_EFI_ERROR (Status);
224
225 //
226 // Check duplication
227 //
228 for (Index = 0; Index < mHashInterfaceCount; Index++) {
229 if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
230 return EFI_ALREADY_STARTED;
231 }
232 }
233
234 CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface));
235 mHashInterfaceCount ++;
236
237 return EFI_SUCCESS;
238 }