OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
Img4.c
Go to the documentation of this file.
1#include <stdint.h>
2#include <stdio.h>
3#include <stdbool.h>
4#include <stdlib.h>
5#include <string.h>
6
7#include <UserFile.h>
8
10
11#include <Library/MemoryAllocationLib.h>
12#include <Library/OcCryptoLib.h>
13
14#include <libDER/oids.h>
15#include <libDERImg4/Img4oids.h>
17
18STATIC
19VOID
21 IN CONST DERImg4Environment *Env
22 )
23{
24 DEBUG ((
25 DEBUG_ERROR,
26 "\nEcid: %Lx\n"
27 "BoardId: %x\n"
28 "ChipId: %x\n"
29 "CertificateEpoch: %x\n"
30 "SecurityDomain: %x\n"
31 "ProductionStatus: %x\n"
32 "SecurityMode: %x\n"
33 "EffectiveProductionStatus: %x\n"
34 "EffectiveSecurityMode: %x\n"
35 "InternalUseOnlyUnit: %x\n"
36 "Xugs: %x\n\n",
37 (UINT64)Env->ecid,
38 Env->boardId,
39 Env->chipId,
40 Env->certificateEpoch,
41 Env->securityDomain,
42 Env->productionStatus,
43 Env->securityMode,
44 Env->effectiveProductionStatus,
45 Env->effectiveSecurityMode,
46 Env->internalUseOnlyUnit,
47 Env->xugs
48 ));
49}
50
51STATIC
52INT32
54 IN CONST CHAR8 *ManifestName
55 )
56{
57 //
58 // The keys are iterated in the order in which they are defined here in
59 // AppleBds to validate any loaded image.
60 //
61 STATIC CONST UINT32 Objs[] = {
74 };
75
76 UINT8 *Manifest;
77 UINT32 ManSize;
78 DERImg4ManifestInfo ManInfo;
79 UINT32 Success;
80 UINT32 Index;
81 DERReturn RetVal;
82
83 Manifest = UserReadFile (ManifestName, &ManSize);
84 if (Manifest == NULL) {
85 DEBUG ((DEBUG_ERROR, "\n!!! read error !!!\n"));
86 return -1;
87 }
88
89 Success = 0;
90 for (Index = 0; Index < ARRAY_SIZE (Objs); ++Index) {
91 RetVal = DERImg4ParseManifest (
92 &ManInfo,
93 Manifest,
94 ManSize,
95 Objs[Index]
96 );
97
98 if (RetVal == DR_Success) {
99 DEBUG ((
100 DEBUG_ERROR,
101 "Manifest has %c%c%c%c\n",
102 ((CHAR8 *)&Objs[Index])[3],
103 ((CHAR8 *)&Objs[Index])[2],
104 ((CHAR8 *)&Objs[Index])[1],
105 ((CHAR8 *)&Objs[Index])[0]
106 ));
108 ++Success;
109 }
110 }
111
112 FreePool (Manifest);
113
114 if (Success == 0) {
115 DEBUG ((DEBUG_ERROR, "Supplied manifest is not valid or has no known objects!\n"));
116 return -1;
117 }
118
119 return 0;
120}
121
122STATIC
123INT32
125 IN CONST CHAR8 *ImageName,
126 IN CONST CHAR8 *ManifestName,
127 IN CONST CHAR8 *type
128 )
129{
130 UINT8 *Manifest;
131 UINT8 *Image;
132 UINT32 ManSize;
133 UINT32 ImgSize;
134 DERImg4ManifestInfo ManInfo;
135 DERReturn RetVal;
136 INTN CmpResult;
137
138 Manifest = UserReadFile (ManifestName, &ManSize);
139 if (Manifest == NULL) {
140 DEBUG ((DEBUG_ERROR, "\n!!! read error !!!\n"));
141 return -1;
142 }
143
144 RetVal = DERImg4ParseManifest (
145 &ManInfo,
146 Manifest,
147 ManSize,
148 SIGNATURE_32 (type[3], type[2], type[1], type[0])
149 );
150 FreePool (Manifest);
151 if (RetVal != DR_Success) {
152 DEBUG ((DEBUG_ERROR, "\n !!! DERImg4ParseManifest failed - %d !!!\n", RetVal));
153 return -1;
154 }
155
157
158 Image = UserReadFile (ImageName, &ImgSize);
159 if (Image == NULL) {
160 DEBUG ((DEBUG_ERROR, "\n!!! read error !!!\n"));
161 return -1;
162 }
163
164 DEBUG ((
165 DEBUG_ERROR,
166 "ManInfo.imageDigestSize %02X%02X%02X%02X %u\n",
167 ManInfo.imageDigest[0],
168 ManInfo.imageDigest[1],
169 ManInfo.imageDigest[2],
170 ManInfo.imageDigest[3],
171 ManInfo.imageDigestSize
172 ));
173
174 CmpResult = SigVerifyShaHashBySize (
175 Image,
176 ImgSize,
177 ManInfo.imageDigest,
178 ManInfo.imageDigestSize
179 );
180
181 FreePool (Image);
182
183 if (CmpResult != 0) {
184 DEBUG ((DEBUG_ERROR, "\n!!! digest mismatch !!!\n"));
185 return -1;
186 }
187
188 return 0;
189}
190
191int
193 int argc,
194 char *argv[]
195 )
196{
197 INT32 RetVal;
198 INT32 Index;
199
200 if ((argc < 2) || (((argc % 3) != 1) && (argc != 2))) {
201 DEBUG ((DEBUG_ERROR, "Usage: ./Img4 ([image path] [manifest path] [object type])*\n"));
202 DEBUG ((DEBUG_ERROR, "Usage: Img4 [manifest path]\n"));
203 return -1;
204 }
205
206 if (argc == 2) {
207 return DebugManifest (argv[1]);
208 }
209
210 RetVal = 0;
211 for (Index = 1; Index < (argc - 1); Index += 3) {
212 if (AsciiStrLen (argv[Index + 2]) != 4) {
213 DEBUG ((DEBUG_ERROR, "Object types require exactly 4 characters.\n"));
214 return -1;
215 }
216
217 RetVal = VerifyImg4 (
218 argv[Index + 0],
219 argv[Index + 1],
220 argv[Index + 2]
221 );
222 if (RetVal != 0) {
223 return RetVal;
224 }
225 }
226
227 return RetVal;
228}
229
230int
232 const uint8_t *Data,
233 size_t Size
234 )
235{
236 STATIC CONST UINT32 Signatures[] = {
247 };
248
249 DERImg4ManifestInfo ManInfo;
250 UINTN Index;
251
252 if ((Data == NULL) || (Size == 0)) {
253 return 0;
254 }
255
256 for (Index = 0; Index < ARRAY_SIZE (Signatures); ++Index) {
258 &ManInfo,
259 Data,
260 Size,
261 Signatures[Index]
262 );
263 }
264
265 return 0;
266}
#define ARRAY_SIZE(Array)
Definition AppleMacEfi.h:34
#define APPLE_SB_OBJ_KERNEL_DEBUG
#define APPLE_SB_OBJ_EFIBOOT
#define APPLE_SB_OBJ_MUPD
#define APPLE_SB_OBJ_KERNEL
#define APPLE_SB_OBJ_EFIBOOT_DEBUG
#define APPLE_SB_OBJ_EFIBOOT_BASE
#define APPLE_SB_OBJ_SDFU
#define APPLE_SB_OBJ_HPMU
#define APPLE_SB_OBJ_THOU
#define APPLE_SB_OBJ_DTHU
#define APPLE_SB_OBJ_GPUU
#define APPLE_SB_OBJ_ETHU
cache_type_t type
DERReturn DERImg4ParseManifest(DERImg4ManifestInfo *ManInfo, const void *ManBuffer, size_t ManSize, uint32_t ObjType)
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
Definition Img4.c:231
STATIC INT32 DebugManifest(IN CONST CHAR8 *ManifestName)
Definition Img4.c:53
STATIC INT32 VerifyImg4(IN CONST CHAR8 *ImageName, IN CONST CHAR8 *ManifestName, IN CONST CHAR8 *type)
Definition Img4.c:124
STATIC VOID InternalDebugEnvInfo(IN CONST DERImg4Environment *Env)
Definition Img4.c:20
DMG_SIZE_DEVICE_PATH Size
INTN SigVerifyShaHashBySize(IN CONST VOID *Data, IN UINTN DataSize, IN CONST UINT8 *Hash, IN UINTN HashSize)
UINT8 * UserReadFile(IN CONST CHAR8 *FileName, OUT UINT32 *Size)
Definition UserFile.c:62
DERReturn
Definition libDER.h:20
@ DR_Success
Definition libDER.h:21
UINT8 uint8_t
int ENTRY_POINT(void)
uint8_t imageDigest[DER_IMG4_MAX_DIGEST_SIZE]
Definition libDERImg4.h:51
DERImg4Environment environment
Definition libDERImg4.h:45