]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c
5bc8d01ad56028bfcf81b40f86e5b580dfac1c59
[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 - 2014, 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
76 HashInterfaceHob = InternalGetHashInterface ();
77 if (HashInterfaceHob == NULL) {
78 return EFI_UNSUPPORTED;
79 }
80
81 if (HashInterfaceHob->HashInterfaceCount == 0) {
82 return EFI_UNSUPPORTED;
83 }
84
85 HashCtx = AllocatePool (sizeof(*HashCtx) * HashInterfaceHob->HashInterfaceCount);
86 ASSERT (HashCtx != NULL);
87
88 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
89 HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]);
90 }
91
92 *HashHandle = (HASH_HANDLE)HashCtx;
93
94 return EFI_SUCCESS;
95 }
96
97 /**
98 Update hash sequence data.
99
100 @param HashHandle Hash handle.
101 @param DataToHash Data to be hashed.
102 @param DataToHashLen Data size.
103
104 @retval EFI_SUCCESS Hash sequence updated.
105 **/
106 EFI_STATUS
107 EFIAPI
108 HashUpdate (
109 IN HASH_HANDLE HashHandle,
110 IN VOID *DataToHash,
111 IN UINTN DataToHashLen
112 )
113 {
114 HASH_INTERFACE_HOB *HashInterfaceHob;
115 HASH_HANDLE *HashCtx;
116 UINTN Index;
117
118 HashInterfaceHob = InternalGetHashInterface ();
119 if (HashInterfaceHob == NULL) {
120 return EFI_UNSUPPORTED;
121 }
122
123 if (HashInterfaceHob->HashInterfaceCount == 0) {
124 return EFI_UNSUPPORTED;
125 }
126
127 HashCtx = (HASH_HANDLE *)HashHandle;
128
129 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
130 HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
131 }
132
133 return EFI_SUCCESS;
134 }
135
136 /**
137 Hash sequence complete and extend to PCR.
138
139 @param HashHandle Hash handle.
140 @param PcrIndex PCR to be extended.
141 @param DataToHash Data to be hashed.
142 @param DataToHashLen Data size.
143 @param DigestList Digest list.
144
145 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
146 **/
147 EFI_STATUS
148 EFIAPI
149 HashCompleteAndExtend (
150 IN HASH_HANDLE HashHandle,
151 IN TPMI_DH_PCR PcrIndex,
152 IN VOID *DataToHash,
153 IN UINTN DataToHashLen,
154 OUT TPML_DIGEST_VALUES *DigestList
155 )
156 {
157 TPML_DIGEST_VALUES Digest;
158 HASH_INTERFACE_HOB *HashInterfaceHob;
159 HASH_HANDLE *HashCtx;
160 UINTN Index;
161 EFI_STATUS Status;
162
163 HashInterfaceHob = InternalGetHashInterface ();
164 if (HashInterfaceHob == NULL) {
165 return EFI_UNSUPPORTED;
166 }
167
168 if (HashInterfaceHob->HashInterfaceCount == 0) {
169 return EFI_UNSUPPORTED;
170 }
171
172 HashCtx = (HASH_HANDLE *)HashHandle;
173 ZeroMem (DigestList, sizeof(*DigestList));
174
175 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
176 HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
177 HashInterfaceHob->HashInterface[Index].HashFinal (HashCtx[Index], &Digest);
178 Tpm2SetHashToDigestList (DigestList, &Digest);
179 }
180
181 FreePool (HashCtx);
182
183 Status = Tpm2PcrExtend (
184 PcrIndex,
185 DigestList
186 );
187 return Status;
188 }
189
190 /**
191 Hash data and extend to PCR.
192
193 @param PcrIndex PCR to be extended.
194 @param DataToHash Data to be hashed.
195 @param DataToHashLen Data size.
196 @param DigestList Digest list.
197
198 @retval EFI_SUCCESS Hash data and DigestList is returned.
199 **/
200 EFI_STATUS
201 EFIAPI
202 HashAndExtend (
203 IN TPMI_DH_PCR PcrIndex,
204 IN VOID *DataToHash,
205 IN UINTN DataToHashLen,
206 OUT TPML_DIGEST_VALUES *DigestList
207 )
208 {
209 HASH_INTERFACE_HOB *HashInterfaceHob;
210 HASH_HANDLE HashHandle;
211 EFI_STATUS Status;
212
213 HashInterfaceHob = InternalGetHashInterface ();
214 if (HashInterfaceHob == NULL) {
215 return EFI_UNSUPPORTED;
216 }
217
218 if (HashInterfaceHob->HashInterfaceCount == 0) {
219 return EFI_UNSUPPORTED;
220 }
221
222 HashStart (&HashHandle);
223 HashUpdate (HashHandle, DataToHash, DataToHashLen);
224 Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
225
226 return Status;
227 }
228
229 /**
230 This service register Hash.
231
232 @param HashInterface Hash interface
233
234 @retval EFI_SUCCESS This hash interface is registered successfully.
235 @retval EFI_UNSUPPORTED System does not support register this interface.
236 @retval EFI_ALREADY_STARTED System already register this interface.
237 **/
238 EFI_STATUS
239 EFIAPI
240 RegisterHashInterfaceLib (
241 IN HASH_INTERFACE *HashInterface
242 )
243 {
244 UINTN Index;
245 HASH_INTERFACE_HOB *HashInterfaceHob;
246 HASH_INTERFACE_HOB LocalHashInterfaceHob;
247 UINT32 HashMask;
248
249 //
250 // Check allow
251 //
252 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
253 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
254 return EFI_UNSUPPORTED;
255 }
256
257 HashInterfaceHob = InternalGetHashInterface ();
258 if (HashInterfaceHob == NULL) {
259 ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
260 HashInterfaceHob = BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
261 if (HashInterfaceHob == NULL) {
262 return EFI_OUT_OF_RESOURCES;
263 }
264 }
265
266 if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {
267 return EFI_OUT_OF_RESOURCES;
268 }
269
270 //
271 // Check duplication
272 //
273 for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
274 if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
275 //
276 // In PEI phase, there will be shadow driver dispatched again.
277 //
278 DEBUG ((EFI_D_INFO, "RegisterHashInterfaceLib - Override\n"));
279 CopyMem (&HashInterfaceHob->HashInterface[Index], HashInterface, sizeof(*HashInterface));
280 return EFI_SUCCESS;
281 }
282 }
283
284 CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface));
285 HashInterfaceHob->HashInterfaceCount ++;
286
287 return EFI_SUCCESS;
288 }