pc1crypt: make decrypt/encrypt functions take void * as argument
[project/firmware-utils.git] / src / makeamitbin.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * makeamitbin - create firmware binaries for MGB100
4 *
5 * Copyright (C) 2007 Volker Weiss <dev@tintuc.de>
6 * Christian Welzel <dev@welzel-online.ch>
7 */
8
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13
14
15 /* defaults: Level One WAP-0007 */
16 static char *ascii1 = "DDC_RUS001";
17 static char *ascii2 = "Queen";
18
19 static struct hdrinfo {
20 char *name;
21 unsigned long unknown; /* can probably be any number, maybe version number */
22 int topalign;
23 unsigned int addr;
24 unsigned int size;
25 } hdrinfo[] = {
26 { "bios", 0xc76be111, 1, 0x3fa000, 0x006000 }, /* BIOS */
27 { "recovery", 0xc76be222, 0, 0x3f0000, 0x004000 }, /* Recovery Loader */
28 { "linux", 0xc76bee9d, 0, 0x000000, 0x100000 }, /* Linux */
29 { "ramdisk", 0xc76bee9d, 0, 0x100000, 0x280000 }, /* ramdisk */
30 { "amitconfig", 0xc76bee8b, 0, 0x380000, 0x060000 }, /* AMIT config */
31 { "redboot", 0x00000000, 1, 0x3d0000, 0x030000 }, /* Redboot 128kB image */
32 { "redbootlow", 0, 0, 0x3e0000, 0x18000 }, /* Redboot 1. part */
33 { "redboothigh", 0, 0, 0x3fa000, 0x6000 }, /* Redboot 2. part */
34 { "linux3g", 0xcb5f06b5, 0, 0x000000, 0x100000 }, /* Linux */
35 { "ramdisk3g", 0xcb5f06b5, 0, 0x100000, 0x280000 }, /* ramdisk */
36 { NULL }
37 };
38
39 /*
40 CHD2WLANU_R400b7
41
42 11e1 6bc7
43 22e2 6bc7
44 5dc3 47c8
45 5cc3 47c8
46 21c3 47c8
47 */
48
49 /*
50 20060106_DDC_WAP-0007_R400b4
51
52 11e1 6bc7
53 22e2 6bc7
54 9dee 6bc7
55 9dee 6bc7
56 8bee 6bc7
57 */
58
59 /*
60 WMU-6000FS_R400b6
61
62 11e1 6bc7
63 22e2 6bc7
64 6d2d 0fc8
65 6c2d 0fc8
66 542d 0fc8
67 */
68
69 /*
70 WAP-0007(R4.00b8)_2006-10-02
71
72 9979 5fc8
73 22e2 6bc7
74 c46e cec8
75 c36e cec8
76 a76e cec8
77 */
78
79
80
81 #define HDRSIZE 80
82
83 #define COPY_SHORT(d, o, v) d[o+0] = (unsigned char)((v) & 0xff); \
84 d[o+1] = (unsigned char)(((v) >> 8) & 0xff)
85 #define COPY_LONG(d, o, v) d[o+0] = (unsigned char)((v) & 0xff); \
86 d[o+1] = (unsigned char)(((v) >> 8) & 0xff); \
87 d[o+2] = (unsigned char)(((v) >> 16) & 0xff); \
88 d[o+3] = (unsigned char)(((v) >> 24) & 0xff)
89 #define READ_SHORT(d, o) ((unsigned short)(d[o+0]) + \
90 (((unsigned short)(d[o+1])) << 8))
91
92 /*
93 00..0d ASCII product ID
94 0e..0f checksum of payload
95 10..1b ASCII Queen
96 1c..1f AMIT BIOS: 11e1 6bc7, Recovery Tool: 22e2 6bc7
97 Linux: 5dc3 47c8, ramdisk: 5cc3 47c8
98 AMIT FS: 21c3 47c8 VERSION NUMBER??????
99 20..23 offset in flash aligned to segment boundary
100 24..27 length in flash aligned to segment boundary
101 28..2b offset in flash (payload)
102 2c..2f length (payload)
103 30..3f always 0
104 40..47 always 4248 0101 5000 0001 (last maybe .....0501)
105 48..4b same as 20..23
106 4c..4d always 0b00
107 4e..4f inverted checksum of header
108 */
109
110 unsigned short checksum(unsigned char *data, long size)
111 {
112 long n;
113 unsigned short d, cs = 0;
114 for (n = 0; n < size; n += 2)
115 {
116 d = READ_SHORT(data, n);
117 cs += d;
118 if (cs < d)
119 cs++;
120 }
121 if (size & 1)
122 {
123 d = data[n];
124 cs += d;
125 if (cs < d)
126 cs++;
127 }
128 return cs;
129 }
130
131 void showhdr(unsigned char *hdr)
132 {
133 int i, j;
134 for (j = 0; j < 5; j++)
135 {
136 for (i = 0; i < 16; i++)
137 {
138 printf("%02x ", (unsigned int)(hdr[j * 16 + i]));
139 }
140 printf(" ");
141 for (i = 0; i < 16; i++)
142 {
143 unsigned char d = hdr[j * 16 + i];
144 printf("%c", (d >= ' ' && d < 127) ? d : '.');
145 }
146 printf("\n");
147 }
148 }
149
150 void makehdr(unsigned char *hdr, struct hdrinfo *info,
151 unsigned char *data, long size, int last)
152 {
153 unsigned int offset = info->addr + 0x10;
154 memset(hdr, 0, HDRSIZE);
155 if (info->topalign)
156 offset = info->addr + info->size - size; /* top align */
157 strncpy((char *)hdr + 0x00, ascii1, 14);
158 strncpy((char *)hdr + 0x10, ascii2, 12);
159 COPY_LONG(hdr, 0x1c, info->unknown);
160 COPY_LONG(hdr, 0x20, info->addr);
161 COPY_LONG(hdr, 0x24, info->size);
162 COPY_LONG(hdr, 0x28, offset);
163 COPY_LONG(hdr, 0x2c, size);
164 COPY_LONG(hdr, 0x40, 0x01014842);
165 COPY_LONG(hdr, 0x44, last ? 0x01050050 : 0x01000050);
166 COPY_LONG(hdr, 0x48, info->addr);
167 COPY_SHORT(hdr, 0x4c, info->unknown == 0xcb5f06b5 ? 0x0016 : 0x000b);
168 COPY_SHORT(hdr, 0x0e, checksum(data, size));
169 COPY_SHORT(hdr, 0x4e, ~checksum(hdr, HDRSIZE));
170 }
171
172 unsigned char *read_file(const char *name, long *size)
173 {
174 FILE *f;
175 unsigned char *data = NULL;
176 *size = 0;
177 f = fopen(name, "r");
178 if (f != NULL)
179 {
180 if (fseek(f, 0, SEEK_END) == 0)
181 {
182 *size = ftell(f);
183 if (*size != -1)
184 {
185 if (fseek(f, 0, SEEK_SET) == 0)
186 {
187 data = (unsigned char *)malloc(*size);
188 if (data != NULL)
189 {
190 if (fread(data, sizeof(char), *size, f) != *size)
191 {
192 free(data);
193 data = NULL;
194 }
195 }
196 }
197 }
198 }
199 fclose(f);
200 }
201 return data;
202 }
203
204 struct hdrinfo *find_hdrinfo(const char *name)
205 {
206 int n;
207 for (n = 0; hdrinfo[n].name != NULL; n++)
208 {
209 if (strcmp(name, hdrinfo[n].name) == 0)
210 return &hdrinfo[n];
211 }
212 return NULL;
213 }
214
215 void oferror(FILE *f)
216 {
217 printf("file error\n");
218 exit(2);
219 }
220
221 void showhelp(void)
222 {
223 printf("Syntax: makeamitbin [options]\n");
224 printf("Options:\n");
225 printf(" -1 ID1\tFirmware identifier 1, e.g. 'DDC_RUS001' for manufacturer LevelOne\n");
226 printf(" -2 ID2\tFirmware identifier 2, 'Queen' in all known cases\n");
227 printf(" -o FILE\tOutput file\n");
228 printf(" -ids\t\tShow a list of known firmware identifiers.\n");
229 exit(1);
230 }
231
232 void show_fwids(void)
233 {
234 printf("List of known firmware identifiers:\n");
235 printf("Manufacturer\t\tProduct\t\tIdentifier\n");
236 printf("=====================================================\n");
237 printf("Conceptronic\t\tCHD2WLANU\tLLM_RUS001\n");
238 printf("Pearl\t\t\tPE6643\t\tQueen\n");
239 printf("Micronica\t\tMGB100\t\tQueen\n");
240 printf("LevelOne\t\tWAP-0007\tDDC_RUS001\n");
241 printf("SMC\t\t\tWAPS-G\t\tSMC_RUS001\n");
242 printf("OvisLink (AirLive)\tWMU-6\t\tOVS_RUS001\n");
243 printf("SafeCom SWSAPUR-5\tFMW\t\tSafeco_RPS001\n");
244 exit(1);
245 }
246
247 int main(int argc, char *argv[])
248 {
249 unsigned char hdr[HDRSIZE];
250 unsigned char *data;
251 FILE *of;
252 char *outfile = NULL;
253 char *type;
254 struct hdrinfo *info;
255 long size;
256 int last = 0;
257 int n;
258 for (n = 1; n < argc; n++)
259 {
260 if (strcmp(argv[n], "-1") == 0)
261 ascii1 = argv[n+1];
262 if (strcmp(argv[n], "-2") == 0)
263 ascii2 = argv[n+1];
264 if (strcmp(argv[n], "-o") == 0)
265 outfile = argv[n+1];
266 if (strcmp(argv[n], "-ids") == 0)
267 show_fwids();
268 }
269 if (ascii1 == NULL || ascii2 == NULL || outfile == NULL)
270 showhelp();
271 of = fopen(outfile, "w");
272 if (of == NULL)
273 oferror(of);
274 for (n = 1; n < argc; n++)
275 {
276 if (strncmp(argv[n], "-", 1) != 0)
277 {
278 type = argv[n++];
279 if (n >= argc)
280 showhelp();
281 last = ((n + 1) >= argc); /* dirty, options first! */
282 info = find_hdrinfo(type);
283 if (info == NULL)
284 showhelp();
285 data = read_file(argv[n], &size);
286 if (data == NULL)
287 showhelp();
288 makehdr(hdr, info, data, size, last);
289 /* showhdr(hdr); */
290 if (fwrite(hdr, HDRSIZE, 1, of) != 1)
291 oferror(of);
292 if (fwrite(data, size, 1, of) != 1)
293 oferror(of);
294 free(data);
295 }
296 else
297 n++;
298 }
299 if (fclose(of) != 0)
300 oferror(NULL);
301 return 0;
302 }