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/HobLib.h>
25 #include <Library/HashLib.h>
26
27 #include "HashLibBaseCryptoRouterCommon.h"
28
29 #define HASH_LIB_PEI_ROUTER_GUID \
30 { 0x84681c08, 0x6873, 0x46f3, { 0x8b, 0xb7, 0xab, 0x66, 0x18, 0x95, 0xa1, 0xb3 } }
31
32 EFI_GUID mHashLibPeiRouterGuid = HASH_LIB_PEI_ROUTER_GUID;
33
34 typedef struct {
35 UINTN HashInterfaceCount;
36 HASH_INTERFACE HashInterface[HASH_COUNT];
37 } HASH_INTERFACE_HOB;
38
39 /**
40 This function get hash interface.
41
42 @retval hash interface.
43 **/
44 HASH_INTERFACE_HOB *
InternalGetHashInterface(VOID)45 InternalGetHashInterface (
46 VOID
47 )
48 {
49 EFI_HOB_GUID_TYPE *Hob;
50
51 Hob = GetFirstGuidHob (&mHashLibPeiRouterGuid);
52 if (Hob == NULL) {
53 return NULL;
54 }
55 return (HASH_INTERFACE_HOB *)(Hob + 1);
56 }
57
58 /**
59 Start hash sequence.
60
61 @param HashHandle Hash handle.
62
63 @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
64 @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
65 **/
66 EFI_STATUS
67 EFIAPI
HashStart(OUT HASH_HANDLE * HashHandle)68 HashStart (
69 OUT HASH_HANDLE *HashHandle
70 )
71 {
72 HASH_INTERFACE_HOB *HashInterfaceHob;
73 HASH_HANDLE *HashCtx;
74 UINTN Index;
75 UINT32 HashMask;
76
77 HashInterfaceHob = InternalGetHashInterface ();
78 if (HashInterfaceHob == NULL) {
79 return EFI_UNSUPPORTED;
80 }
81
82 if (HashInterfaceHob->HashInterfaceCount == 0) {
83 return EFI_UNSUPPORTED;
84 }
85
86 HashCtx = AllocatePool (sizeof(*HashCtx) * HashInterfaceHob->HashInterfaceCount);
87 ASSERT (HashCtx != NULL);
88
89 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
90 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);
91 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
92 HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]);
93 }
94 }
95
96 *HashHandle = (HASH_HANDLE)HashCtx;
97
98 return EFI_SUCCESS;
99 }
100
101 /**
102 Update hash sequence data.
103
104 @param HashHandle Hash handle.
105 @param DataToHash Data to be hashed.
106 @param DataToHashLen Data size.
107
108 @retval EFI_SUCCESS Hash sequence updated.
109 **/
110 EFI_STATUS
111 EFIAPI
HashUpdate(IN HASH_HANDLE HashHandle,IN VOID * DataToHash,IN UINTN DataToHashLen)112 HashUpdate (
113 IN HASH_HANDLE HashHandle,
114 IN VOID *DataToHash,
115 IN UINTN DataToHashLen
116 )
117 {
118 HASH_INTERFACE_HOB *HashInterfaceHob;
119 HASH_HANDLE *HashCtx;
120 UINTN Index;
121 UINT32 HashMask;
122
123 HashInterfaceHob = InternalGetHashInterface ();
124 if (HashInterfaceHob == NULL) {
125 return EFI_UNSUPPORTED;
126 }
127
128 if (HashInterfaceHob->HashInterfaceCount == 0) {
129 return EFI_UNSUPPORTED;
130 }
131
132 HashCtx = (HASH_HANDLE *)HashHandle;
133
134 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
135 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);
136 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
137 HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
138 }
139 }
140
141 return EFI_SUCCESS;
142 }
143
144 /**
145 Hash sequence complete and extend to PCR.
146
147 @param HashHandle Hash handle.
148 @param PcrIndex PCR to be extended.
149 @param DataToHash Data to be hashed.
150 @param DataToHashLen Data size.
151 @param DigestList Digest list.
152
153 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
154 **/
155 EFI_STATUS
156 EFIAPI
HashCompleteAndExtend(IN HASH_HANDLE HashHandle,IN TPMI_DH_PCR PcrIndex,IN VOID * DataToHash,IN UINTN DataToHashLen,OUT TPML_DIGEST_VALUES * DigestList)157 HashCompleteAndExtend (
158 IN HASH_HANDLE HashHandle,
159 IN TPMI_DH_PCR PcrIndex,
160 IN VOID *DataToHash,
161 IN UINTN DataToHashLen,
162 OUT TPML_DIGEST_VALUES *DigestList
163 )
164 {
165 TPML_DIGEST_VALUES Digest;
166 HASH_INTERFACE_HOB *HashInterfaceHob;
167 HASH_HANDLE *HashCtx;
168 UINTN Index;
169 EFI_STATUS Status;
170 UINT32 HashMask;
171
172 HashInterfaceHob = InternalGetHashInterface ();
173 if (HashInterfaceHob == NULL) {
174 return EFI_UNSUPPORTED;
175 }
176
177 if (HashInterfaceHob->HashInterfaceCount == 0) {
178 return EFI_UNSUPPORTED;
179 }
180
181 HashCtx = (HASH_HANDLE *)HashHandle;
182 ZeroMem (DigestList, sizeof(*DigestList));
183
184 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
185 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);
186 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
187 HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
188 HashInterfaceHob->HashInterface[Index].HashFinal (HashCtx[Index], &Digest);
189 Tpm2SetHashToDigestList (DigestList, &Digest);
190 }
191 }
192
193 FreePool (HashCtx);
194
195 Status = Tpm2PcrExtend (
196 PcrIndex,
197 DigestList
198 );
199 return Status;
200 }
201
202 /**
203 Hash data and extend to PCR.
204
205 @param PcrIndex PCR to be extended.
206 @param DataToHash Data to be hashed.
207 @param DataToHashLen Data size.
208 @param DigestList Digest list.
209
210 @retval EFI_SUCCESS Hash data and DigestList is returned.
211 **/
212 EFI_STATUS
213 EFIAPI
HashAndExtend(IN TPMI_DH_PCR PcrIndex,IN VOID * DataToHash,IN UINTN DataToHashLen,OUT TPML_DIGEST_VALUES * DigestList)214 HashAndExtend (
215 IN TPMI_DH_PCR PcrIndex,
216 IN VOID *DataToHash,
217 IN UINTN DataToHashLen,
218 OUT TPML_DIGEST_VALUES *DigestList
219 )
220 {
221 HASH_INTERFACE_HOB *HashInterfaceHob;
222 HASH_HANDLE HashHandle;
223 EFI_STATUS Status;
224
225 HashInterfaceHob = InternalGetHashInterface ();
226 if (HashInterfaceHob == NULL) {
227 return EFI_UNSUPPORTED;
228 }
229
230 if (HashInterfaceHob->HashInterfaceCount == 0) {
231 return EFI_UNSUPPORTED;
232 }
233
234 HashStart (&HashHandle);
235 HashUpdate (HashHandle, DataToHash, DataToHashLen);
236 Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
237
238 return Status;
239 }
240
241 /**
242 This service register Hash.
243
244 @param HashInterface Hash interface
245
246 @retval EFI_SUCCESS This hash interface is registered successfully.
247 @retval EFI_UNSUPPORTED System does not support register this interface.
248 @retval EFI_ALREADY_STARTED System already register this interface.
249 **/
250 EFI_STATUS
251 EFIAPI
RegisterHashInterfaceLib(IN HASH_INTERFACE * HashInterface)252 RegisterHashInterfaceLib (
253 IN HASH_INTERFACE *HashInterface
254 )
255 {
256 UINTN Index;
257 HASH_INTERFACE_HOB *HashInterfaceHob;
258 HASH_INTERFACE_HOB LocalHashInterfaceHob;
259 UINT32 HashMask;
260 UINT32 BiosSupportedHashMask;
261 EFI_STATUS Status;
262
263 //
264 // Check allow
265 //
266 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
267 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
268 return EFI_UNSUPPORTED;
269 }
270
271 HashInterfaceHob = InternalGetHashInterface ();
272 if (HashInterfaceHob == NULL) {
273 ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
274 HashInterfaceHob = BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
275 if (HashInterfaceHob == NULL) {
276 return EFI_OUT_OF_RESOURCES;
277 }
278 }
279
280 if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {
281 return EFI_OUT_OF_RESOURCES;
282 }
283 BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);
284 Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask);
285 ASSERT_EFI_ERROR (Status);
286
287 //
288 // Check duplication
289 //
290 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
291 if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
292 //
293 // In PEI phase, there will be shadow driver dispatched again.
294 //
295 DEBUG ((EFI_D_INFO, "RegisterHashInterfaceLib - Override\n"));
296 CopyMem (&HashInterfaceHob->HashInterface[Index], HashInterface, sizeof(*HashInterface));
297 return EFI_SUCCESS;
298 }
299 }
300
301 CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface));
302 HashInterfaceHob->HashInterfaceCount ++;
303
304 return EFI_SUCCESS;
305 }