OpenCore  1.0.4
OpenCore Bootloader
1.0.4
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
OcHashServicesLib.c
Go to the documentation of this file.
1
10#include <Library/BaseMemoryLib.h>
11#include <Library/DebugLib.h>
12#include <Library/MemoryAllocationLib.h>
13#include <Library/OcMiscLib.h>
14#include <Library/UefiBootServicesTableLib.h>
15
16#include <Protocol/Hash.h>
17#include <Protocol/ServiceBinding.h>
18
20
21STATIC EFI_SERVICE_BINDING_PROTOCOL mHashBindingProto = {
24};
25
26STATIC
27EFI_STATUS
28EFIAPI
30 IN CONST EFI_HASH_PROTOCOL *This,
31 IN CONST EFI_GUID *HashAlgorithm,
32 OUT UINTN *HashSize
33 )
34{
35 if (!HashAlgorithm || !HashSize) {
36 return EFI_INVALID_PARAMETER;
37 }
38
39 if (CompareGuid (&gEfiHashAlgorithmMD5Guid, HashAlgorithm)) {
40 *HashSize = sizeof (EFI_MD5_HASH);
41 return EFI_SUCCESS;
42 } else if (CompareGuid (&gEfiHashAlgorithmSha1Guid, HashAlgorithm)) {
43 *HashSize = sizeof (EFI_SHA1_HASH);
44 return EFI_SUCCESS;
45 } else if (CompareGuid (&gEfiHashAlgorithmSha256Guid, HashAlgorithm)) {
46 *HashSize = sizeof (EFI_SHA256_HASH);
47 return EFI_SUCCESS;
48 }
49
50 return EFI_UNSUPPORTED;
51}
52
53STATIC
54EFI_STATUS
55EFIAPI
57 IN CONST EFI_HASH_PROTOCOL *This,
58 IN CONST EFI_GUID *HashAlgorithm,
59 IN BOOLEAN Extend,
60 IN CONST UINT8 *Message,
61 IN UINT64 MessageSize,
62 IN OUT EFI_HASH_OUTPUT *Hash
63 )
64{
65 HS_PRIVATE_DATA *PrivateData;
66 HS_CONTEXT_DATA CtxCopy;
67
68 if (!This || !HashAlgorithm || !Message || !Hash || !MessageSize || (MessageSize > MAX_UINTN)) {
69 return EFI_INVALID_PARAMETER;
70 }
71
72 PrivateData = HS_PRIVATE_FROM_PROTO (This);
73
74 if (CompareGuid (&gEfiHashAlgorithmMD5Guid, HashAlgorithm)) {
75 if (!Extend) {
76 Md5Init (&PrivateData->Ctx.Md5);
77 }
78
79 Md5Update (&PrivateData->Ctx.Md5, Message, (UINTN)MessageSize);
80 CopyMem (&CtxCopy, &PrivateData->Ctx, sizeof (PrivateData->Ctx));
81 Md5Final (&CtxCopy.Md5, *Hash->Md5Hash);
82 return EFI_SUCCESS;
83 } else if (CompareGuid (&gEfiHashAlgorithmSha1Guid, HashAlgorithm)) {
84 if (!Extend) {
85 Sha1Init (&PrivateData->Ctx.Sha1);
86 }
87
88 Sha1Update (&PrivateData->Ctx.Sha1, Message, (UINTN)MessageSize);
89 CopyMem (&CtxCopy, &PrivateData->Ctx, sizeof (PrivateData->Ctx));
90 Sha1Final (&CtxCopy.Sha1, *Hash->Sha1Hash);
91 return EFI_SUCCESS;
92 } else if (CompareGuid (&gEfiHashAlgorithmSha256Guid, HashAlgorithm)) {
93 if (!Extend) {
94 Sha256Init (&PrivateData->Ctx.Sha256);
95 }
96
97 Sha256Update (&PrivateData->Ctx.Sha256, Message, (UINTN)MessageSize);
98 CopyMem (&CtxCopy, &PrivateData->Ctx, sizeof (PrivateData->Ctx));
99 Sha256Final (&CtxCopy.Sha256, *Hash->Sha256Hash);
100 return EFI_SUCCESS;
101 }
102
103 return EFI_UNSUPPORTED;
104}
105
106STATIC
107EFI_STATUS
108EFIAPI
110 IN EFI_SERVICE_BINDING_PROTOCOL *This,
111 IN OUT EFI_HANDLE *ChildHandle
112 )
113{
114 HS_PRIVATE_DATA *PrivateData;
115 EFI_STATUS Status;
116
117 PrivateData = AllocateZeroPool (sizeof (*PrivateData));
118 if (!PrivateData) {
119 return EFI_OUT_OF_RESOURCES;
120 }
121
122 PrivateData->Signature = HS_PRIVATE_SIGNATURE;
123 PrivateData->Proto.GetHashSize = HSGetHashSize;
124 PrivateData->Proto.Hash = HSHash;
125
126 Status = gBS->InstallProtocolInterface (
127 ChildHandle,
128 &gEfiHashProtocolGuid,
129 EFI_NATIVE_INTERFACE,
130 &PrivateData->Proto
131 );
132
133 if (EFI_ERROR (Status)) {
134 FreePool (PrivateData);
135 }
136
137 return Status;
138}
139
140STATIC
141EFI_STATUS
142EFIAPI
144 IN EFI_SERVICE_BINDING_PROTOCOL *This,
145 IN EFI_HANDLE ChildHandle
146 )
147{
148 EFI_HASH_PROTOCOL *HashProto;
149 EFI_STATUS Status;
150
151 if (!This || !ChildHandle) {
152 return EFI_INVALID_PARAMETER;
153 }
154
155 Status = gBS->HandleProtocol (
156 ChildHandle,
157 &gEfiHashProtocolGuid,
158 (VOID **)&HashProto
159 );
160
161 if (EFI_ERROR (Status)) {
162 return Status;
163 }
164
165 Status = gBS->UninstallProtocolInterface (
166 ChildHandle,
167 &gEfiHashProtocolGuid,
168 HashProto
169 );
170
171 if (EFI_ERROR (Status)) {
172 return Status;
173 }
174
175 FreePool (HS_PRIVATE_FROM_PROTO (HashProto));
176 return EFI_SUCCESS;
177}
178
187EFI_SERVICE_BINDING_PROTOCOL *
189 IN BOOLEAN Reinstall
190 )
191{
192 EFI_STATUS Status;
193 EFI_HANDLE NewHandle = NULL;
194 EFI_SERVICE_BINDING_PROTOCOL *OriginalProto = NULL;
195
196 if (Reinstall) {
197 //
198 // Uninstall all the existing protocol instances (which are not to be trusted).
199 //
200 Status = OcUninstallAllProtocolInstances (&gEfiHashServiceBindingProtocolGuid);
201 if (EFI_ERROR (Status)) {
202 DEBUG ((DEBUG_ERROR, "OCHS: Uninstall failed - %r\n", Status));
203 return NULL;
204 }
205 } else {
206 Status = gBS->LocateProtocol (
207 &gEfiHashServiceBindingProtocolGuid,
208 NULL,
209 (VOID **)&OriginalProto
210 );
211 if (!EFI_ERROR (Status)) {
212 return OriginalProto;
213 }
214 }
215
216 //
217 // Install our own protocol binding
218 //
219 Status = gBS->InstallMultipleProtocolInterfaces (
220 &NewHandle,
221 &gEfiHashServiceBindingProtocolGuid,
223 NULL
224 );
225 if (EFI_ERROR (Status)) {
226 return NULL;
227 }
228
229 return &mHashBindingProto;
230}
EFI_BOOT_SERVICES * gBS
VOID Sha256Init(SHA256_CONTEXT *Context)
VOID Sha1Update(SHA1_CONTEXT *Context, CONST UINT8 *Data, UINTN Len)
VOID Sha1Init(SHA1_CONTEXT *Context)
VOID Md5Init(MD5_CONTEXT *Context)
VOID Md5Final(MD5_CONTEXT *Context, UINT8 *Hash)
VOID Sha256Final(SHA256_CONTEXT *Context, UINT8 *HashDigest)
VOID Sha1Final(SHA1_CONTEXT *Context, UINT8 *Hash)
VOID Sha256Update(SHA256_CONTEXT *Context, CONST UINT8 *Data, UINTN Len)
VOID Md5Update(MD5_CONTEXT *Context, CONST UINT8 *Data, UINTN Len)
EFI_SERVICE_BINDING_PROTOCOL * OcHashServicesInstallProtocol(IN BOOLEAN Reinstall)
STATIC EFI_SERVICE_BINDING_PROTOCOL mHashBindingProto
STATIC EFI_STATUS EFIAPI HSDestroyChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN EFI_HANDLE ChildHandle)
STATIC EFI_STATUS EFIAPI HSGetHashSize(IN CONST EFI_HASH_PROTOCOL *This, IN CONST EFI_GUID *HashAlgorithm, OUT UINTN *HashSize)
STATIC EFI_STATUS EFIAPI HSCreateChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN OUT EFI_HANDLE *ChildHandle)
STATIC EFI_STATUS EFIAPI HSHash(IN CONST EFI_HASH_PROTOCOL *This, IN CONST EFI_GUID *HashAlgorithm, IN BOOLEAN Extend, IN CONST UINT8 *Message, IN UINT64 MessageSize, IN OUT EFI_HASH_OUTPUT *Hash)
#define HS_PRIVATE_FROM_PROTO(a)
#define HS_PRIVATE_SIGNATURE
EFI_STATUS OcUninstallAllProtocolInstances(EFI_GUID *Protocol)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)