]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c
Add TPM2 support defined in trusted computing group.
[mirror_edk2.git] / SecurityPkg / Library / HashLibBaseCryptoRouter / HashLibBaseCryptoRouterPei.c
1 /** @file
2 Ihis 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 - 2015, 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 *
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
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
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
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
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
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
262 //
263 // Check allow
264 //
265 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
266 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
267 return EFI_UNSUPPORTED;
268 }
269
270 HashInterfaceHob = InternalGetHashInterface ();
271 if (HashInterfaceHob == NULL) {
272 ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
273 HashInterfaceHob = BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
274 if (HashInterfaceHob == NULL) {
275 return EFI_OUT_OF_RESOURCES;
276 }
277 }
278
279 if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {
280 return EFI_OUT_OF_RESOURCES;
281 }
282 BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);
283 PcdSet32 (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask);
284
285 //
286 // Check duplication
287 //
288 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
289 if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
290 //
291 // In PEI phase, there will be shadow driver dispatched again.
292 //
293 DEBUG ((EFI_D_INFO, "RegisterHashInterfaceLib - Override\n"));
294 CopyMem (&HashInterfaceHob->HashInterface[Index], HashInterface, sizeof(*HashInterface));
295 return EFI_SUCCESS;
296 }
297 }
298
299 CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface));
300 HashInterfaceHob->HashInterfaceCount ++;
301
302 return EFI_SUCCESS;
303 }