]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
d93b33bfcfb009dbc41180ef58f32a19f0023da2
[mirror_edk2.git] / SecurityPkg / Library / HashLibBaseCryptoRouter / HashLibBaseCryptoRouterDxe.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/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
41 HashStart (
42 OUT HASH_HANDLE *HashHandle
43 )
44 {
45 HASH_HANDLE *HashCtx;
46 UINTN Index;
47
48 if (mHashInterfaceCount == 0) {
49 return EFI_UNSUPPORTED;
50 }
51
52 HashCtx = AllocatePool (sizeof(*HashCtx) * mHashInterfaceCount);
53 ASSERT (HashCtx != NULL);
54
55 for (Index = 0; Index < mHashInterfaceCount; Index++) {
56 mHashInterface[Index].HashInit (&HashCtx[Index]);
57 }
58
59 *HashHandle = (HASH_HANDLE)HashCtx;
60
61 return EFI_SUCCESS;
62 }
63
64 /**
65 Update hash sequence data.
66
67 @param HashHandle Hash handle.
68 @param DataToHash Data to be hashed.
69 @param DataToHashLen Data size.
70
71 @retval EFI_SUCCESS Hash sequence updated.
72 **/
73 EFI_STATUS
74 EFIAPI
75 HashUpdate (
76 IN HASH_HANDLE HashHandle,
77 IN VOID *DataToHash,
78 IN UINTN DataToHashLen
79 )
80 {
81 HASH_HANDLE *HashCtx;
82 UINTN Index;
83
84 if (mHashInterfaceCount == 0) {
85 return EFI_UNSUPPORTED;
86 }
87
88 HashCtx = (HASH_HANDLE *)HashHandle;
89
90 for (Index = 0; Index < mHashInterfaceCount; Index++) {
91 mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
92 }
93
94 return EFI_SUCCESS;
95 }
96
97 /**
98 Hash sequence complete and extend to PCR.
99
100 @param HashHandle Hash handle.
101 @param PcrIndex PCR to be extended.
102 @param DataToHash Data to be hashed.
103 @param DataToHashLen Data size.
104 @param DigestList Digest list.
105
106 @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
107 **/
108 EFI_STATUS
109 EFIAPI
110 HashCompleteAndExtend (
111 IN HASH_HANDLE HashHandle,
112 IN TPMI_DH_PCR PcrIndex,
113 IN VOID *DataToHash,
114 IN UINTN DataToHashLen,
115 OUT TPML_DIGEST_VALUES *DigestList
116 )
117 {
118 TPML_DIGEST_VALUES Digest;
119 HASH_HANDLE *HashCtx;
120 UINTN Index;
121 EFI_STATUS Status;
122
123 if (mHashInterfaceCount == 0) {
124 return EFI_UNSUPPORTED;
125 }
126
127 HashCtx = (HASH_HANDLE *)HashHandle;
128 ZeroMem (DigestList, sizeof(*DigestList));
129
130 for (Index = 0; Index < mHashInterfaceCount; Index++) {
131 mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
132 mHashInterface[Index].HashFinal (HashCtx[Index], &Digest);
133 Tpm2SetHashToDigestList (DigestList, &Digest);
134 }
135
136 FreePool (HashCtx);
137
138 Status = Tpm2PcrExtend (
139 PcrIndex,
140 DigestList
141 );
142 return Status;
143 }
144
145 /**
146 Hash data and extend to PCR.
147
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 data and DigestList is returned.
154 **/
155 EFI_STATUS
156 EFIAPI
157 HashAndExtend (
158 IN TPMI_DH_PCR PcrIndex,
159 IN VOID *DataToHash,
160 IN UINTN DataToHashLen,
161 OUT TPML_DIGEST_VALUES *DigestList
162 )
163 {
164 HASH_HANDLE HashHandle;
165 EFI_STATUS Status;
166
167 if (mHashInterfaceCount == 0) {
168 return EFI_UNSUPPORTED;
169 }
170
171 HashStart (&HashHandle);
172 HashUpdate (HashHandle, DataToHash, DataToHashLen);
173 Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
174
175 return Status;
176 }
177
178 /**
179 This service register Hash.
180
181 @param HashInterface Hash interface
182
183 @retval EFI_SUCCESS This hash interface is registered successfully.
184 @retval EFI_UNSUPPORTED System does not support register this interface.
185 @retval EFI_ALREADY_STARTED System already register this interface.
186 **/
187 EFI_STATUS
188 EFIAPI
189 RegisterHashInterfaceLib (
190 IN HASH_INTERFACE *HashInterface
191 )
192 {
193 UINTN Index;
194 UINT32 HashMask;
195
196 //
197 // Check allow
198 //
199 HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
200 if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
201 return EFI_UNSUPPORTED;
202 }
203
204 if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) {
205 return EFI_OUT_OF_RESOURCES;
206 }
207
208 //
209 // Check duplication
210 //
211 for (Index = 0; Index < mHashInterfaceCount; Index++) {
212 if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
213 return EFI_ALREADY_STARTED;
214 }
215 }
216
217 CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface));
218 mHashInterfaceCount ++;
219
220 return EFI_SUCCESS;
221 }