summaryrefslogtreecommitdiff
path: root/utils/atj2137/atjboottool/atjboottool.c
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2017-09-29 17:53:06 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2017-09-29 17:56:04 +0200
commit95c32a505a7bfef2dcac2a975b1f5875f490c405 (patch)
treea0ff67def67d7ba45ba0907078d61d8a22bd001d /utils/atj2137/atjboottool/atjboottool.c
parent13364c552548ca15c34f781613762e88f6f2e327 (diff)
downloadrockbox-95c32a505a7bfef2dcac2a975b1f5875f490c405.tar.gz
rockbox-95c32a505a7bfef2dcac2a975b1f5875f490c405.zip
atjboottool: split fwu code into its own file
Slightly cleanup the code by removing the old and dangerous --force option. Change-Id: I776633a9924797fcd509b8b80623bcd64b391672
Diffstat (limited to 'utils/atj2137/atjboottool/atjboottool.c')
-rw-r--r--utils/atj2137/atjboottool/atjboottool.c1092
1 files changed, 27 insertions, 1065 deletions
diff --git a/utils/atj2137/atjboottool/atjboottool.c b/utils/atj2137/atjboottool/atjboottool.c
index 5f4d8afd40..676fdae199 100644
--- a/utils/atj2137/atjboottool/atjboottool.c
+++ b/utils/atj2137/atjboottool/atjboottool.c
@@ -26,978 +26,13 @@
26#include <getopt.h> 26#include <getopt.h>
27#include <stdarg.h> 27#include <stdarg.h>
28#include <ctype.h> 28#include <ctype.h>
29#include "misc.h"
30#include "elf.h"
31#include <sys/stat.h> 29#include <sys/stat.h>
32 30#include "misc.h"
33#ifndef MIN 31#include "fwu.h"
34#define MIN(a,b) ((a) < (b) ? (a) : (b))
35#endif
36
37#define cprintf(col, ...) do {color(col); printf(__VA_ARGS__); }while(0)
38
39#define cprintf_field(str1, ...) do{ cprintf(GREEN, str1); cprintf(YELLOW, __VA_ARGS__); }while(0)
40 32
41bool g_debug = false; 33bool g_debug = false;
42char *g_out_prefix = NULL; 34char *g_out_prefix = NULL;
43char *g_in_file = NULL; 35char *g_in_file = NULL;
44bool g_force = false;
45
46#define let_the_force_flow(x) do { if(!g_force) return x; } while(0)
47#define continue_the_force(x) if(x) let_the_force_flow(x)
48
49#define check_field(v_exp, v_have, str_ok, str_bad) \
50 if((v_exp) != (v_have)) \
51 { cprintf(RED, str_bad); let_the_force_flow(__LINE__); } \
52 else { cprintf(RED, str_ok); }
53
54static void print_hex(void *p, int size, int unit)
55{
56 uint8_t *p8 = p;
57 uint16_t *p16 = p;
58 uint32_t *p32 = p;
59 for(int i = 0; i < size; i += unit, p8++, p16++, p32++)
60 {
61 if(i != 0 && (i % 16) == 0)
62 printf("\n");
63 if(unit == 1)
64 printf(" %02x", *p8);
65 else if(unit == 2)
66 printf(" %04x", *p16);
67 else
68 printf(" %08x", *p32);
69 }
70}
71
72/**
73 * FWU
74 **/
75
76#define FWU_SIG_SIZE 16
77#define FWU_BLOCK_SIZE 512
78
79struct fwu_hdr_t
80{
81 uint8_t sig[FWU_SIG_SIZE];
82 uint32_t fw_size;
83 uint32_t block_size;// always 512
84 uint8_t version;
85 uint8_t unk;
86 uint8_t sig2[FWU_SIG_SIZE];
87} __attribute__((packed));
88
89const uint8_t g_fwu_signature[FWU_SIG_SIZE] =
90{
91 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x75
92};
93
94struct version_desc_t
95{
96 uint8_t version;
97 uint8_t value;
98 uint8_t unk;
99 uint8_t sig2[FWU_SIG_SIZE];
100};
101
102struct version_desc_t g_version[] =
103{
104 { 1, 0xd, 0xd0, { 0x76, 0x5c, 0x50, 0x94, 0x69, 0xb0, 0xa7, 0x03, 0x10, 0xf1, 0x7e, 0xdb, 0x88, 0x90, 0x86, 0x9d } },
105 { 1, 0xe, 0xd0, { 0x92, 0x22, 0x7a, 0x77, 0x08, 0x67, 0xae, 0x06, 0x16, 0x06, 0xb8, 0x65, 0xa6, 0x42, 0xf7, 0X52 } },
106 { 3, 0x7e, 0xe1, { 0x3f, 0xad, 0xf8, 0xb0, 0x2e, 0xaf, 0x67, 0x49, 0xb9, 0x85, 0x5f, 0x63, 0x4e, 0x5e, 0x8e, 0x2e } },
107};
108
109#define NR_VERSIONS (int)(sizeof(g_version)/sizeof(g_version[0]))
110
111typedef struct ptr_bundle_t
112{
113 uint32_t *ptrA;
114 uint32_t *ptrB;
115}ptr_bundle_t;
116
117struct block_A_info_t
118{
119 int nr_bits;
120 uint16_t field_2;
121 int nr_words;
122 int nr_dwords_x12;
123 uint32_t *ptr6; // size
124 uint32_t *ptr7; // size
125 uint32_t *ptr5; // size
126 uint32_t size;
127 uint32_t field_1C;
128 ptr_bundle_t ptr1;
129 uint32_t *ptr3; // size
130 uint32_t *ptr4; // size
131 int nr_words2;
132 uint32_t field_34;
133 int nr_dwords_x8;
134 int nr_bytes;
135 int nr_bytes2;
136 int nr_dwords_m1;
137 int nr_dwords_x2_m1;
138 int nr_dwords_x2;
139 int nr_dwords;
140 uint32_t field_54;
141 uint32_t field_58;
142};
143
144struct block_A_info_t g_decode_A_info;
145uint8_t g_subblock_A[0x128];
146uint8_t g_key_B[20];
147uint8_t g_perm_B[258];
148uint8_t g_crypto_info_byte;
149uint8_t *g_decode_buffer;
150uint8_t *g_decode_buffer2;
151void *g_decode_buffer3;
152
153#include "atj_tables.h"
154
155void compute_checksum(uint8_t *buf, int size, uint8_t t[20])
156{
157 memset(t, 0, 20);
158
159 for(int i = 0; i < size; i++)
160 t[i % 20] ^= buf[i];
161 for(int i = 0; i < 20; i++)
162 t[i] = ~t[i];
163}
164
165int check_block(uint8_t *buf, uint8_t ref[20], unsigned size)
166{
167 uint8_t t[20];
168 compute_checksum(buf, size, t);
169
170 return memcmp(ref, t, 20);
171}
172
173
174int get_version(uint8_t *buf, unsigned long size)
175{
176 (void) size;
177 struct fwu_hdr_t *hdr = (void *)buf;
178 for(int i = 0; i < NR_VERSIONS; i++)
179 if(hdr->version == g_version[i].value)
180 return i;
181 return -1;
182}
183
184static int decode_block_A(uint8_t block[1020])
185{
186 uint8_t *p = &g_check_block_A_table[32 * (block[998] & 0x1f)];
187 uint8_t key[32];
188
189 for(int i = 0; i < 20; i++)
190 {
191 block[1000 + i] ^= p[i];
192 key[i] = block[1000 + i];
193 }
194 for(int i = 20; i < 32; i++)
195 key[i] = key[i - 20];
196
197 for(int i = 0; i < 992; i++)
198 block[i] ^= key[i % 32] ^ g_check_block_A_table[i];
199
200 return check_block(block - 1, block + 1000, 1001);
201}
202
203static void compute_perm(uint8_t *keybuf, int size, uint8_t perm[258])
204{
205 for(int i = 0; i < 256; i++)
206 perm[i] = i;
207 perm[256] = perm[257] = 0;
208 uint8_t idx = 0;
209 for(int i = 0; i < 256; i++)
210 {
211 uint8_t v = perm[i];
212 idx = (v + keybuf[i % size] + idx) % 256;
213 perm[i] = perm[idx];
214 perm[idx] = v;
215 }
216}
217
218static void decode_perm(uint8_t *buf, int size, uint8_t perm[258])
219{
220 uint8_t idxa = perm[256];
221 uint8_t idxb = perm[257];
222 for(int i = 0; i < size; i++)
223 {
224 idxa = (idxa + 1) % 256;
225 uint8_t v = perm[idxa];
226 idxb = (idxb + v) % 256;
227 perm[idxa] = perm[idxb];
228 perm[idxb] = v;
229 buf[i] ^= perm[(v + perm[idxa]) % 256];
230 }
231}
232
233static void decode_block_with_perm(uint8_t *keybuf, int keysize,
234 uint8_t *buf, int bufsize, uint8_t perm[258])
235{
236 compute_perm(keybuf, keysize, perm);
237 decode_perm(buf, bufsize, perm);
238}
239
240static void apply_perm(uint8_t *inbuf, uint8_t *outbuf, int size, int swap)
241{
242 memcpy(outbuf, inbuf, size);
243 int a = swap & 0xf;
244 int b = (swap >> 4) + 16;
245 uint8_t v = outbuf[a];
246 outbuf[a] = outbuf[b];
247 outbuf[b] = v;
248}
249
250static void decode_block_with_swap(uint8_t keybuf[32], int swap,
251 uint8_t *buf, int bufsize, uint8_t perm[258])
252{
253 uint8_t keybuf_interm[32];
254
255 apply_perm(keybuf, keybuf_interm, 32, swap);
256 decode_block_with_perm(keybuf_interm, 32, buf, bufsize, perm);
257}
258
259static void clear_memory(void *buf, int size_dwords)
260{
261 memset(buf, 0, 4 * size_dwords);
262}
263
264static void set_bit(int bit_pos, uint32_t *buf)
265{
266 buf[bit_pos / 32] |= 1 << (bit_pos % 32);
267}
268
269static int fill_decode_info(uint8_t sz)
270{
271 if(sz == 2) sz = 233;
272 else if(sz == 3) sz = 163;
273 else return 1;
274
275 g_decode_A_info.nr_bits = sz;
276 g_decode_A_info.nr_bytes2 = sz / 8 + (sz % 8 != 0);
277 g_decode_A_info.nr_words = 2 * g_decode_A_info.nr_bytes2;
278 g_decode_A_info.nr_bytes = sz / 8 + (sz % 8 != 0);
279 g_decode_A_info.nr_words2 = 2 * g_decode_A_info.nr_bytes2;
280 g_decode_A_info.nr_dwords = sz / 32 + (sz % 32 != 0);
281 g_decode_A_info.size = 4 * g_decode_A_info.nr_dwords;
282 g_decode_A_info.nr_dwords_x8 = 8 * g_decode_A_info.nr_dwords;
283 g_decode_A_info.nr_dwords_m1 = g_decode_A_info.nr_dwords - 1;
284 g_decode_A_info.nr_dwords_x2 = 2 * g_decode_A_info.nr_dwords;
285 g_decode_A_info.nr_dwords_x2_m1 = g_decode_A_info.nr_dwords_x2 - 1;
286 g_decode_A_info.nr_dwords_x12 = 12 * g_decode_A_info.nr_dwords;
287 g_decode_A_info.ptr1.ptrA = malloc(4 * g_decode_A_info.nr_dwords);
288 g_decode_A_info.ptr1.ptrB = malloc(g_decode_A_info.size);
289 g_decode_A_info.ptr3 = malloc(g_decode_A_info.size);
290 g_decode_A_info.ptr4 = malloc(g_decode_A_info.size);
291 g_decode_A_info.ptr5 = malloc(g_decode_A_info.size);
292 g_decode_A_info.ptr6 = malloc(g_decode_A_info.size);
293 g_decode_A_info.ptr7 = malloc(g_decode_A_info.size);
294
295 cprintf(BLUE, " Decode Info:\n");
296 cprintf_field(" Nr Bits: ", "%d\n", g_decode_A_info.nr_bits);
297 cprintf_field(" Nr Bytes: ", "%d\n", g_decode_A_info.nr_bytes);
298 cprintf_field(" Nr Bytes 2: ", "%d\n", g_decode_A_info.nr_bytes2);
299 cprintf_field(" Nr Words: ", "%d\n", g_decode_A_info.nr_words);
300 cprintf_field(" Nr Words 2: ", "%d\n", g_decode_A_info.nr_words2);
301 cprintf_field(" Nr DWords: ", "%d\n", g_decode_A_info.nr_dwords);
302 cprintf_field(" Size: ", "%d\n", g_decode_A_info.size);
303
304 return 0;
305}
306
307static int process_block_A(uint8_t block[1024])
308{
309 cprintf(BLUE, "Block A\n");
310 int ret = decode_block_A(block + 4);
311 cprintf(GREEN, " Check: ");
312 check_field(ret, 0, "Pass\n", "Fail\n");
313
314 memcpy(g_subblock_A, block, sizeof(g_subblock_A));
315 ret = fill_decode_info(g_subblock_A[276]);
316 cprintf(GREEN, " Info: ");
317 check_field(ret, 0, "Pass\n", "Fail\n");
318
319 int tmp = 2 * g_decode_A_info.nr_bytes2 + 38;
320 int offset = 1004 - tmp + 5;
321 g_crypto_info_byte = block[offset - 1];
322 g_decode_buffer = malloc(g_decode_A_info.size);
323 g_decode_buffer2 = malloc(g_decode_A_info.size);
324
325 memset(g_decode_buffer, 0, g_decode_A_info.size);
326 memset(g_decode_buffer2, 0, g_decode_A_info.size);
327
328 memcpy(g_decode_buffer, &block[offset], g_decode_A_info.nr_bytes2);
329 int offset2 = g_decode_A_info.nr_bytes2 + offset;
330 memcpy(g_decode_buffer2, &block[offset2], g_decode_A_info.nr_bytes2);
331
332
333 cprintf_field(" Word: ", "%d ", *(uint16_t *)&g_subblock_A[286]);
334 check_field(*(uint16_t *)&g_subblock_A[286], 1, "Ok\n", "Mismatch\n");
335
336 return 0;
337}
338
339static void decode_key_B(uint8_t buf[20], uint8_t buf2[16], uint8_t key[20])
340{
341 for(int i = 0; i < 20; i++)
342 {
343 uint8_t v = buf[i] ^ g_decode_B_table[i];
344 key[i] = v;
345 buf[i] = v ^ buf2[i % 16];
346 }
347}
348
349static void decode_block_B(uint8_t *buf, uint8_t key[16], int size)
350{
351 decode_key_B(&buf[size], key, g_key_B);
352 decode_block_with_perm(g_key_B, 20, buf, size, g_perm_B);
353}
354
355static int find_last_bit_set(uint32_t *buf, bool a)
356{
357 int i = a ? g_decode_A_info.nr_dwords_m1 : g_decode_A_info.nr_dwords_x2_m1;
358
359 while(i >= 0 && buf[i] == 0)
360 i--;
361 if(i < 0)
362 return -1;
363 for(int j = 31; j >= 0; j--)
364 if(buf[i] & (1 << j))
365 return 32 * i + j;
366 return -1; // unreachable
367}
368
369static void xor_with_ptrs(uint8_t *buf, ptr_bundle_t *ptrs)
370{
371 /*
372 int sz = g_decode_A_info.nr_bytes2 - 1;
373 if(sz <= 32)
374 {
375 for(int i = 0; i < sz; i++)
376 buf[i] ^= ptrs->ptrA[i];
377 for(int i = sz; i < 32; i++)
378 buf[i] ^= ptrs->ptrB[i - sz];
379 }
380 else
381 for(int i = 0; i < 32; i++)
382 buf[i] ^= ptrs->ptrA[i];
383 */
384 uint8_t *ptrA = (uint8_t *)ptrs->ptrA;
385 uint8_t *ptrB = (uint8_t *)ptrs->ptrB;
386 int sz = MIN(g_decode_A_info.nr_bytes2 - 1, 32);
387 for(int i = 0; i < sz; i++)
388 buf[i] ^= ptrA[i];
389 for(int i = sz; i < 32; i++)
390 buf[i] ^= ptrB[i - sz];
391}
392
393static void copy_memory(uint32_t *to, uint32_t *from)
394{
395 for(int i = 0; i < g_decode_A_info.nr_dwords; i++)
396 to[i] = from[i];
397}
398
399static void swap_memory(uint32_t *a, uint32_t *b)
400{
401 for(int i = 0; i < g_decode_A_info.nr_dwords; i++)
402 {
403 uint32_t c = a[i];
404 a[i] = b[i];
405 b[i] = c;
406 }
407}
408
409static void shift_left(uint32_t *buf, int nr_bits)
410{
411 for(int i = g_decode_A_info.nr_dwords_m1; i >= 0; i--)
412 buf[i + (nr_bits / 32)] = buf[i];
413 memset(buf, 0, 4 * (nr_bits / 32));
414
415 int size = g_decode_A_info.nr_dwords + (nr_bits + 31) / 32;
416 nr_bits = nr_bits % 32;
417
418 uint32_t acc = 0;
419 for(int i = 0; i < size; i++)
420 {
421 uint32_t new_val = buf[i] << nr_bits | acc;
422 /* WARNING if nr_bits = 0 then the right shift by 32 is undefined and so
423 * the following code could break. The additional AND catches this case
424 * and make sure the result is 0 */
425 acc = ((1 << nr_bits) - 1) & (buf[i] >> (32 - nr_bits));
426 buf[i] = new_val;
427 }
428}
429
430static void xor_big(uint32_t *res, uint32_t *a, uint32_t *b)
431{
432 for(int i = 0; i < g_decode_A_info.nr_dwords_x2; i++)
433 res[i] = a[i] ^ b[i];
434}
435
436static void decode_with_xor(uint32_t *res, uint32_t *key)
437{
438 uint32_t *tmp = malloc(g_decode_A_info.nr_dwords_x8);
439 uint32_t *copy = malloc(g_decode_A_info.nr_dwords_x8);
440 uint32_t *copy_arg = malloc(g_decode_A_info.nr_dwords_x8);
441 uint32_t *tmp2 = malloc(g_decode_A_info.nr_dwords_x8);
442 clear_memory(tmp, g_decode_A_info.nr_dwords_x2);
443 clear_memory(res, g_decode_A_info.nr_dwords);
444 *res = 1;
445 clear_memory(tmp2, g_decode_A_info.nr_dwords);
446 copy_memory(copy_arg, key);
447 copy_memory(copy, (uint32_t *)g_decode_A_info.ptr5);
448
449 for(int i = find_last_bit_set(copy_arg, 1); i; i = find_last_bit_set(copy_arg, 1))
450 {
451 int pos = i - find_last_bit_set(copy, 1);
452 if(pos < 0)
453 {
454 swap_memory(copy_arg, copy);
455 swap_memory(res, tmp2);
456 pos = -pos;
457 }
458 copy_memory(tmp, copy);
459 shift_left(tmp, pos);
460 xor_big(copy_arg, copy_arg, tmp);
461 copy_memory(tmp, tmp2);
462 shift_left(tmp, pos);
463 xor_big(res, res, tmp);
464 }
465 free(tmp);
466 free(copy);
467 free(copy_arg);
468 free(tmp2);
469}
470
471static void shift_left_one(uint32_t *a)
472{
473 int pos = find_last_bit_set(a, 0) / 32 + 1;
474 if(pos <= 0)
475 return;
476 uint32_t v = 0;
477 for(int i = 0; i < pos; i++)
478 {
479 uint32_t new_val = v | a[i] << 1;
480 v = a[i] >> 31;
481 a[i] = new_val;
482 }
483 if(v)
484 a[pos] = v;
485}
486
487
488#if 1
489static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3)
490{
491 uint32_t *tmp2 = malloc(g_decode_A_info.nr_dwords_x8);
492 clear_memory(tmp2, g_decode_A_info.nr_dwords_x2);
493 copy_memory(tmp2, a3);
494
495 int pos = g_decode_A_info.nr_dwords;
496 uint32_t mask = 1;
497 for(int i = 0; i < 32; i++)
498 {
499 for(int j = 0; j < g_decode_A_info.nr_dwords; j++)
500 {
501 if(a2[j] & mask)
502 for(int k = 0; k < pos; k++)
503 a1[j + k] ^= tmp2[k];
504 }
505 shift_left_one(tmp2);
506 mask <<= 1;
507 pos = find_last_bit_set(tmp2, 0) / 32 + 1;
508 }
509 free(tmp2);
510}
511#else
512static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3)
513{
514 for(int i = 0; i < 32 * g_decode_A_info.nr_dwords; i++)
515 for(int j = 0; j < 32 * g_decode_A_info.nr_dwords; j++)
516 {
517 int k = i + j;
518 uint32_t v1 = (a2[i / 32] >> (i % 32)) & 1;
519 uint32_t v2 = (a3[j / 32] >> (j % 32)) & 1;
520 a1[k / 32] ^= (v1 * v2) << (k % 32);
521 }
522}
523#endif
524
525static int compare(uint32_t *a, uint32_t *b)
526{
527 return memcmp(a, b, g_decode_A_info.nr_dwords * 4);
528}
529
530static void xor_mult_high(uint32_t *a1, uint32_t *buf, uint32_t *a3)
531{
532 (void) a1;
533 uint32_t *tmp = malloc(g_decode_A_info.nr_dwords_x8);
534 int v4 = g_decode_A_info.field_34;
535 int pos = find_last_bit_set(buf, 0);
536 for(int i = pos - v4; i >= 0; i = find_last_bit_set(buf, 0) - v4)
537 {
538 clear_memory(tmp, g_decode_A_info.nr_dwords_x2);
539 copy_memory(tmp, a3);
540 shift_left(tmp, i);
541 xor_big(buf, buf, tmp);
542 }
543 free(tmp);
544}
545
546static void xor_small(uint32_t *res, uint32_t *a, uint32_t *b)
547{
548 for(int i = 0; i < g_decode_A_info.nr_dwords; i++)
549 res[i] = a[i] ^ b[i];
550}
551
552static void crypto(ptr_bundle_t *a1, ptr_bundle_t *a2)
553{
554 uint32_t *v2 = malloc(g_decode_A_info.nr_dwords_x8);
555 uint32_t *v3 = malloc(g_decode_A_info.nr_dwords_x8);
556 uint32_t *v4 = malloc(g_decode_A_info.nr_dwords_x8);
557 uint32_t *v5 = malloc(g_decode_A_info.nr_dwords_x8);
558 uint32_t *v6 = malloc(g_decode_A_info.nr_dwords_x8);
559 clear_memory(a2->ptrA, g_decode_A_info.nr_dwords);
560 clear_memory(a2->ptrB, g_decode_A_info.nr_dwords);
561 clear_memory(v3, g_decode_A_info.nr_dwords_x2);
562 clear_memory(v6, g_decode_A_info.nr_dwords_x2);
563 clear_memory(v4, g_decode_A_info.nr_dwords_x2);
564 decode_with_xor(v4, a1->ptrA);
565 clear_memory(v5, g_decode_A_info.nr_dwords_x2);
566
567 xor_mult(v5, v4, a1->ptrB);
568 xor_mult_high(v5, v5, g_decode_A_info.ptr5);
569 xor_small(v2, a1->ptrA, v5);
570 xor_small(v4, v2, g_decode_A_info.ptr6);
571 clear_memory(v3, g_decode_A_info.nr_dwords_x2);
572 xor_mult(v3, v2, v2);
573 xor_mult_high(v3, v3, g_decode_A_info.ptr5);
574 xor_small(a2->ptrA, v4, v3);
575 clear_memory(v5, g_decode_A_info.nr_dwords_x2);
576 xor_small(v4, v2, g_xor_key);
577 xor_mult(v5, v4, a2->ptrA);
578 xor_mult_high(v5, v5, g_decode_A_info.ptr5);
579 clear_memory(v6, g_decode_A_info.nr_dwords_x2);
580 xor_mult(v6, a1->ptrA, a1->ptrA);
581 xor_mult_high(v6, v6, g_decode_A_info.ptr5);
582 xor_small(a2->ptrB, v5, v6);
583 free(v2);
584 free(v3);
585 free(v4);
586 free(v5);
587 free(v6);
588}
589
590static void crypto2(ptr_bundle_t *a1, ptr_bundle_t *a2, ptr_bundle_t *a3)
591{
592 uint32_t *v3 = malloc(g_decode_A_info.nr_dwords_x8);
593 uint32_t *v4 = malloc(g_decode_A_info.nr_dwords_x8);
594 uint32_t *v5 = malloc(g_decode_A_info.nr_dwords_x8);
595 uint32_t *v6 = malloc(g_decode_A_info.nr_dwords_x8);
596 uint32_t *v7 = malloc(g_decode_A_info.nr_dwords_x8);
597 clear_memory(a3->ptrA, g_decode_A_info.nr_dwords);
598 clear_memory(a3->ptrB, g_decode_A_info.nr_dwords);
599 clear_memory(v4, g_decode_A_info.nr_dwords_x2);
600 clear_memory(v7, g_decode_A_info.nr_dwords_x2);
601 xor_small(v5, a1->ptrB, a2->ptrB);
602 xor_small(v6, a1->ptrA, a2->ptrA);
603 decode_with_xor(v7, v6);
604 clear_memory(v3, g_decode_A_info.nr_dwords_x2);
605 xor_mult(v3, v7, v5);
606 xor_mult_high(v3, v3, g_decode_A_info.ptr5);
607 xor_small(v5, v3, g_decode_A_info.ptr6);
608 clear_memory(v4, g_decode_A_info.nr_dwords_x2);
609 xor_mult(v4, v3, v3);
610 xor_mult_high(v4, v4, g_decode_A_info.ptr5);
611 xor_small(v7, v5, v4);
612 xor_small(a3->ptrA, v7, v6);
613 xor_small(v5, a1->ptrA, a3->ptrA);
614 xor_small(v6, a3->ptrA, a1->ptrB);
615 clear_memory(v7, g_decode_A_info.nr_dwords_x2);
616 xor_mult(v7, v5, v3);
617 xor_mult_high(v7, v7, g_decode_A_info.ptr5);
618 xor_small(a3->ptrB, v7, v6);
619 free(v3);
620 free(v4);
621 free(v5);
622 free(v6);
623 free(v7);
624}
625
626static int crypto3(uint32_t *a1, ptr_bundle_t *ptrs_alt, ptr_bundle_t *ptrs)
627{
628 ptr_bundle_t ptrs_others;
629
630 ptrs_others.ptrA = malloc(g_decode_A_info.size);
631 ptrs_others.ptrB = malloc(g_decode_A_info.size);
632 clear_memory(ptrs->ptrA, g_decode_A_info.nr_dwords);
633 clear_memory(ptrs->ptrB, g_decode_A_info.nr_dwords);
634 clear_memory(ptrs_others.ptrA, g_decode_A_info.nr_dwords);
635 clear_memory(ptrs_others.ptrB, g_decode_A_info.nr_dwords);
636 int pos = find_last_bit_set(a1, 1);
637
638 copy_memory(ptrs_others.ptrA, ptrs_alt->ptrA);
639 copy_memory(ptrs_others.ptrB, ptrs_alt->ptrB);
640 for(int bit = (pos % 32) - 1; bit >= 0; bit--)
641 {
642 crypto(&ptrs_others, ptrs);
643 copy_memory(ptrs_others.ptrA, ptrs->ptrA);
644 copy_memory(ptrs_others.ptrB, ptrs->ptrB);
645 if(a1[pos / 32] & (1 << bit))
646 {
647 crypto2(&ptrs_others, ptrs_alt, ptrs);
648 copy_memory(ptrs_others.ptrA, ptrs->ptrA);
649 copy_memory(ptrs_others.ptrB, ptrs->ptrB);
650 }
651 }
652 for(int i = pos / 32 - 1; i >= 0; i--)
653 {
654 for(int bit = 31; bit >= 0; bit--)
655 {
656 crypto(&ptrs_others, ptrs);
657 copy_memory(ptrs_others.ptrA, ptrs->ptrA);
658 copy_memory(ptrs_others.ptrB, ptrs->ptrB);
659 if(a1[i] & (1 << bit))
660 {
661 crypto2(&ptrs_others, ptrs_alt, ptrs);
662 copy_memory(ptrs_others.ptrA, ptrs->ptrA);
663 copy_memory(ptrs_others.ptrB, ptrs->ptrB);
664 }
665 }
666 }
667 copy_memory(ptrs->ptrA, ptrs_others.ptrA);
668 copy_memory(ptrs->ptrB, ptrs_others.ptrB);
669 free(ptrs_others.ptrA);
670 free(ptrs_others.ptrB);
671 return 0;
672}
673
674static int crypto4(uint8_t *a1, ptr_bundle_t *ptrs, uint32_t *a3)
675{
676 ptr_bundle_t ptrs_others;
677
678 ptrs_others.ptrA = malloc(g_decode_A_info.size);
679 ptrs_others.ptrB = malloc(g_decode_A_info.size);
680 clear_memory(ptrs_others.ptrA, g_decode_A_info.nr_dwords);
681 clear_memory(ptrs_others.ptrB, g_decode_A_info.nr_dwords);
682 int ret = crypto3(a3, ptrs, &ptrs_others);
683 if(ret == 0)
684 xor_with_ptrs(a1, &ptrs_others);
685 free(ptrs_others.ptrA);
686 free(ptrs_others.ptrB);
687 return ret;
688}
689
690static int crypto_bits(uint32_t *buf, int a2)
691{
692 clear_memory(buf, g_decode_A_info.nr_dwords);
693 g_decode_A_info.field_34 = 0;
694 if(a2 == 4)
695 {
696 set_bit(0, buf);
697 set_bit(74, buf);
698 set_bit(233, buf);
699 g_decode_A_info.field_34 = 233;
700 return 0;
701 }
702 else if (a2 == 5)
703 {
704 set_bit(0, buf);
705 set_bit(3, buf);
706 set_bit(6, buf);
707 set_bit(7, buf);
708 set_bit(163, buf);
709 g_decode_A_info.field_34 = 163;
710 return 0;
711 }
712 else
713 return 1;
714}
715
716static int crypto_bits_copy(ptr_bundle_t *a1, char a2)
717{
718 int ret = crypto_bits(g_decode_A_info.ptr5, a2);
719 if(ret) return ret;
720 if(a2 == 4)
721 {
722 copy_memory(a1->ptrA, g_crypto_table);
723 copy_memory(a1->ptrB, g_crypto_table2);
724 copy_memory(g_decode_A_info.ptr6, g_crypto_data);
725 copy_memory(g_decode_A_info.ptr7, g_crypto_key6);
726 return 0;
727 }
728 else if ( a2 == 5 )
729 {
730 copy_memory(a1->ptrA, g_crypto_key3);
731 copy_memory(a1->ptrB, g_crypto_key4);
732 copy_memory(g_decode_A_info.ptr6, g_crypto_data3);
733 copy_memory(g_decode_A_info.ptr7, g_crypto_key5);
734 return 0;
735 }
736 else
737 return 1;
738}
739
740static void create_guid(void *uid, int bit_size)
741{
742 uint8_t *p = uid;
743 for(int i = 0; i < bit_size / 8; i++)
744 p[i] = rand() % 256;
745}
746
747static int process_block_B(uint8_t block[512])
748{
749 cprintf(BLUE, "Block B\n");
750 decode_block_B(block + 3, g_subblock_A + 4, 489);
751 cprintf_field(" Word: ", "%d ", *(uint16_t *)(block + 3));
752 check_field(*(uint16_t *)(block + 3), 1, "Ok\n", "Mismatch\n");
753
754 int ret = check_block(block, block + 492, 492);
755 cprintf(GREEN, " Check: ");
756 check_field(ret, 0, "Pass\n", "Fail\n");
757
758 g_decode_buffer3 = malloc(g_decode_A_info.size);
759 memset(g_decode_buffer3, 0, g_decode_A_info.size);
760 int offset = *(uint16_t *)(block + 13) + 16;
761 memcpy(g_decode_buffer3, &block[offset], g_decode_A_info.nr_bytes2);
762
763 return 0;
764}
765
766static int get_key_fwu_v3(int size, uint8_t *buf, uint8_t *blockA, uint8_t *blockB,
767 uint8_t *keybuf, uint8_t *blo)
768{
769 (void) size;
770 uint8_t smallblock[512];
771 uint8_t bigblock[1024];
772
773 memset(smallblock, 0, sizeof(smallblock));
774 memset(bigblock, 0, sizeof(bigblock));
775
776 uint8_t ba = buf[0x1ee] & 0xf;
777 uint8_t bb = buf[0x1fe] & 0xf;
778
779 cprintf_field(" Block A: ", "%d\n", ba + 2);
780 cprintf_field(" Block B: ", "%d\n", ba + bb + 5);
781
782 *blockA = buf[494] & 0xf;
783 *blockB = buf[510] & 0xf;
784 memcpy(bigblock, &buf[512 * (*blockA + 2)], sizeof(bigblock));
785
786 int ret = process_block_A(bigblock);
787 continue_the_force(ret);
788
789 memcpy(smallblock, &buf[512 * (*blockA + *blockB + 5)], sizeof(smallblock));
790 ret = process_block_B(smallblock);
791 continue_the_force(ret);
792
793 cprintf(BLUE, "Main\n");
794
795 // WARNING you need more that 48 because 17+32 > 48 !! (see code below) */
796 uint8_t smallbuf[50];
797 memcpy(smallbuf, buf + 42, sizeof(smallbuf));
798 cprintf_field(" Byte: ", "%d ", smallbuf[16]);
799 check_field(smallbuf[16], 3, "Ok\n", "Mismatch\n");
800
801 ptr_bundle_t ptrs;
802 ptrs.ptrA = malloc(g_decode_A_info.size);
803 ptrs.ptrB = malloc(g_decode_A_info.size);
804 memset(ptrs.ptrA, 0, g_decode_A_info.size);
805 memset(ptrs.ptrB, 0, g_decode_A_info.size);
806 memcpy(ptrs.ptrA, buf + 91, g_decode_A_info.nr_bytes2);
807 memcpy(ptrs.ptrB, buf + 91 + g_decode_A_info.nr_bytes2, g_decode_A_info.nr_bytes2);
808
809 ret = crypto_bits_copy(&g_decode_A_info.ptr1, g_crypto_info_byte);
810 cprintf(GREEN, " Crypto bits copy: ");
811 check_field(ret, 0, "Pass\n", "Fail\n");
812
813 ret = crypto4(smallbuf + 17, &ptrs, g_decode_buffer3);
814 cprintf(GREEN, " Crypto 4: ");
815 check_field(ret, 0, "Pass\n", "Fail\n");
816
817 memcpy(keybuf, &smallbuf[17], 32);
818 int offset = g_decode_A_info.nr_words + 91;
819
820 decode_block_with_swap(keybuf, 0, &buf[offset], 512 - offset, g_perm_B);
821
822 int pos = *(uint16_t *)&buf[offset];
823 cprintf_field(" Word: ", "%d ", pos);
824 int tmp = g_decode_A_info.nr_words2 + 199;
825 check_field(pos, 510 - tmp, "Ok\n", "Mismatch\n");
826
827 uint8_t midbuf[108];
828 memcpy(midbuf, &buf[pos + offset + 2], sizeof(midbuf));
829
830 cprintf_field(" Byte: ", "%d ", midbuf[0]);
831 check_field(midbuf[0], 2, "Ok\n", "Invalid\n");
832 cprintf_field(" DWord: ", "%d ", *(uint32_t *)&midbuf[1]);
833 check_field(*(uint32_t *)&midbuf[1], 2056, "Ok\n", "Invalid\n");
834 cprintf_field(" DWord: ", "%d ", *(uint32_t *)&midbuf[5]);
835 check_field(*(uint32_t *)&midbuf[5], 8, "Ok\n", "Invalid\n");
836 cprintf_field(" Byte: ", "%d ", midbuf[41]);
837 check_field(midbuf[41], 190, "Ok\n", "Invalid\n");
838
839 memset(blo, 0, 512);
840 create_guid(smallblock, 3808);
841 memcpy(smallblock + 476, midbuf + 42, 16);
842 compute_checksum(smallblock, 492, blo + 492);
843 int bsz = blo[500];
844 memcpy(blo, smallblock, bsz);
845 memcpy(blo + bsz, midbuf + 42, 16);
846 memcpy(blo + bsz + 16, smallblock + bsz, 476 - bsz);
847
848 decode_block_with_perm(blo + 492, 16, blo, 492, g_perm_B);
849 ret = check_block(buf + 42, midbuf + 88, 450);
850 cprintf(GREEN, " Decode block: ");
851 check_field(ret, 0, "Pass\n", "Fail\n");
852
853 ret = memcmp(g_subblock_A + 4, midbuf + 9, 16);
854 cprintf(GREEN, " Compare: ");
855 check_field(ret, 0, "Pass\n", "Fail\n");
856
857 /*
858 ret = memcmp(midbuf + 25, zero, sizeof(zero));
859 cprintf(GREEN, " Sanity: ");
860 check_field(ret, 0, "Pass\n", "Fail\n");
861 */
862
863 return 0;
864}
865
866/* stolen from https://github.com/nfd/atj2127decrypt, I have no idea from where
867 * he got this sequence of code. This code is really weird, I copy verbatim
868 * his authors comment below. */
869uint32_t atj2127_key[] =
870{
871 0x42146ea2, 0x892c8e85, 0x9f9f6d27, 0x545fedc3,
872 0x09e5c0ca, 0x2dfa7e61, 0x4e5322e6, 0xb19185b9
873};
874
875/* decrypt a 512-byte sector */
876static void atj2127_decrypt_sector(void *inbuf, size_t size,
877 uint32_t session_key[8], int rounds_to_perform)
878{
879 uint32_t key[8];
880 for(int i = 0; i < 8; i++)
881 key[i] = atj2127_key[i] ^ session_key[i];
882 uint32_t *buf = inbuf;
883 if(size % 32)
884 cprintf(GREY, "Size is not a multiple of 32!!!\n");
885 while(rounds_to_perform > 0)
886 {
887 uint32_t rollover = buf[7] ^ session_key[7];
888
889 buf[0] ^= key[1];
890 buf[1] ^= key[2];
891 buf[2] ^= key[3];
892 buf[3] ^= key[4];
893 buf[4] ^= key[5];
894 buf[5] ^= key[6];
895 buf[6] ^= key[7];
896 buf[7] ^= key[1] ^ key[4];
897
898 key[1] = key[2];
899 key[2] = key[3];
900 key[3] = key[4];
901 key[4] = key[5];
902 key[5] = key[6];
903 key[6] = key[7];
904 key[7] = rollover;
905
906 buf += 8;
907 rounds_to_perform -= 1;
908 }
909}
910
911static void atj2127_decrypt(uint8_t *dst, const uint8_t *src, size_t size,
912 uint8_t keybuf[32], int rounds_to_perform)
913{
914 cprintf(BLUE, "ATJ2127:\n");
915 cprintf_field(" Rounds: ", "%d\n", rounds_to_perform);
916 while(size > 0)
917 {
918 int sec_sz = MIN(size, 512);
919 memcpy(dst, src, sec_sz);
920 atj2127_decrypt_sector(dst, sec_sz, (uint32_t *)keybuf, rounds_to_perform);
921 src += sec_sz;
922 dst += sec_sz;
923 size -= sec_sz;
924 }
925}
926
927static bool check_afi(uint8_t *buf, int size);
928
929static int decrypt_fwu_v3(uint8_t *buf, int *size, uint8_t block[512], bool force_atj2127)
930{
931 uint8_t blockA;
932 uint8_t blockB;
933 uint8_t keybuf[32];
934 memset(keybuf, 0, sizeof(keybuf));
935 int ret = get_key_fwu_v3(*size, buf, &blockA, &blockB, keybuf, block);
936 continue_the_force(ret);
937
938 int file_size = *size;
939 /* the input buffer is reorganized based on two offsets (blockA and blockB),
940 * skip 2048 bytes of data used for crypto init */
941 *size -= 2048;
942 uint8_t *tmpbuf = malloc(*size);
943 memset(tmpbuf, 0, *size);
944 int offsetA = (blockA + 1) << 9;
945 int offsetB = (blockB + 1) << 9;
946 memcpy(tmpbuf, buf + 512, offsetA);
947 memcpy(tmpbuf + offsetA, buf + offsetA + 1536, offsetB);
948 memcpy(tmpbuf + offsetA + offsetB,
949 buf + offsetA + 1536 + offsetB + 512, *size - offsetA - offsetB);
950 /* stolen from https://github.com/nfd/atj2127decrypt, I have no idea from where
951 * he got this sequence of code. This code is really weird, I copy verbatim
952 * his authors comment below.
953 *
954 * This is really weird. This is passed to the decrypt-sector function and
955 * determines how much of each 512-byte sector to decrypt, where for every
956 * 32MB of size above the first 32MB, one 32 byte chunk of each sector
957 * (starting from the end) will remain unencrypted, up to a maximum of 480
958 * bytes of plaintext. Was this a speed-related thing? It just seems
959 * completely bizarre. */
960
961 /* NOTE: the original code uses the file length to determine how much
962 * to encrypt and not the size reported in the header. Since
963 * the file size can be different from the size reported in the header
964 * (the infamous 512 bytes described above), this might be wrong. */
965 int rounds_to_perform = 16 - (file_size >> 0x19);
966 if(rounds_to_perform <= 0)
967 rounds_to_perform = 1;
968 /* the ATJ213x and ATJ2127 do not use the same encryption at this point, and I
969 * don't see any obvious way to tell which encryption is used (since they
970 * use the same version above). The only difference is that ATJ2127 images
971 * I have seen have an extra 512 bytes at the end file (ie the actual file
972 * is 512 bytes larger than indicated by the header) but I don't know if this
973 * is the case for all files. Thus, unless the user force encryption mode,
974 * try both and see if one looks like an AFI file. To guess which one to use,
975 * decrypt the first sector and see if it looks like an AFI file */
976 bool is_atj2127 = false;
977 if(force_atj2127)
978 is_atj2127 = true;
979 else
980 {
981 uint8_t hdr_buf[512];
982 atj2127_decrypt(hdr_buf, tmpbuf, sizeof(hdr_buf), keybuf, rounds_to_perform);
983 is_atj2127 = check_afi(hdr_buf, sizeof(hdr_buf));
984 if(is_atj2127)
985 cprintf(BLUE, "File looks like an ATJ2127 firmware\n");
986 else
987 cprintf(BLUE, "File does not looks like an ATJ2127 firmware\n");
988 }
989
990 if(is_atj2127)
991 atj2127_decrypt(buf, tmpbuf, *size, keybuf, rounds_to_perform);
992 else
993 {
994 compute_perm(keybuf, 32, g_perm_B);
995 decode_perm(tmpbuf, *size, g_perm_B);
996 memcpy(buf, tmpbuf, *size);
997 }
998
999 return 0;
1000}
1001 36
1002/* [add]: string to add when there is no extension 37/* [add]: string to add when there is no extension
1003 * [replace]: string to replace extension */ 38 * [replace]: string to replace extension */
@@ -1030,96 +65,28 @@ static void build_out_prefix(char *add, char *replace, bool slash)
1030 } 65 }
1031} 66}
1032 67
1033static int do_fwu(uint8_t *buf, int size, bool force_atj2127) 68static int do_fwu(uint8_t *buf, size_t size, enum fwu_mode_t mode)
1034{ 69{
1035 struct fwu_hdr_t *hdr = (void *)buf; 70 int ret = fwu_decrypt(buf, &size, mode);
1036 71 if(ret != 0)
1037 if(size < (int)sizeof(struct fwu_hdr_t)) 72 return ret;
1038 {
1039 cprintf(GREY, "File too small\n");
1040 return 1;
1041 }
1042 cprintf(BLUE, "Header\n");
1043 cprintf(GREEN, " Signature:");
1044 for(int i = 0; i < FWU_SIG_SIZE; i++)
1045 cprintf(YELLOW, " %02x", hdr->sig[i]);
1046 if(memcmp(hdr->sig, g_fwu_signature, FWU_SIG_SIZE) == 0)
1047 cprintf(RED, " Ok\n");
1048 else
1049 {
1050 cprintf(RED, " Mismatch\n");
1051 let_the_force_flow(__LINE__);
1052 }
1053
1054 cprintf_field(" FW size: ", "%d ", hdr->fw_size);
1055 if((int)hdr->fw_size == size)
1056 cprintf(RED, " Ok\n");
1057 else if((int)hdr->fw_size < size)
1058 cprintf(RED, " Ok (file greater than firmware)\n");
1059 else
1060 {
1061 cprintf(RED, " Error (file too small)\n");
1062 let_the_force_flow(__LINE__);
1063 }
1064
1065 cprintf_field(" Block size: ", "%d ", hdr->block_size);
1066 check_field(hdr->block_size, FWU_BLOCK_SIZE, "Ok\n", "Invalid\n");
1067 73
1068 cprintf_field(" Version: ", "%x ", hdr->version); 74 build_out_prefix(".afi", ".afi", false);
1069 int ver = get_version(buf, size); 75 cprintf(GREY, "Descrambling to %s... ", g_out_prefix);
1070 if(ver < 0) 76 FILE *f = fopen(g_out_prefix, "wb");
77 if(f)
1071 { 78 {
1072 cprintf(RED, "(Unknown)\n"); 79 fwrite(buf, size, 1, f);
1073 return -1; 80 fclose(f);
81 cprintf(RED, "Ok\n");
82 return 0;
1074 } 83 }
1075 else 84 else
1076 cprintf(RED, "(Ver. %d)\n", g_version[ver].version);
1077
1078 cprintf_field(" Unknown: ", "0x%x ", hdr->unk);
1079 check_field(hdr->unk, g_version[ver].unk, "Ok\n", "Invalid\n");
1080
1081 cprintf(GREEN, " Signature:");
1082 for(int i = 0; i < FWU_SIG_SIZE; i++)
1083 cprintf(YELLOW, " %02x", hdr->sig2[i]);
1084 if(memcmp(hdr->sig2, g_version[ver].sig2, FWU_SIG_SIZE) == 0)
1085 cprintf(RED, " Ok\n");
1086 else
1087 { 85 {
1088 cprintf(RED, " Mismatch\n"); 86 color(RED);
1089 let_the_force_flow(__LINE__); 87 perror("Failed");
1090 } 88 return 1;
1091
1092 build_out_prefix(".afi", ".afi", false);
1093
1094 if(g_version[ver].version == 3)
1095 {
1096 uint8_t block[512];
1097 memset(block, 0, sizeof(block));
1098 int ret = decrypt_fwu_v3(buf, &size, block, force_atj2127);
1099 continue_the_force(ret);
1100
1101 cprintf(GREY, "Descrambling to %s... ", g_out_prefix);
1102 FILE *f = fopen(g_out_prefix, "wb");
1103 if(f)
1104 {
1105 fwrite(buf, size, 1, f);
1106 fclose(f);
1107 cprintf(RED, "Ok\n");
1108 }
1109 else
1110 cprintf(RED, "Failed: %m\n");
1111 } 89 }
1112
1113 return 0;
1114}
1115
1116static bool check_fwu(uint8_t *buf, int size)
1117{
1118 struct fwu_hdr_t *hdr = (void *)buf;
1119
1120 if(size < (int)sizeof(struct fwu_hdr_t))
1121 return false;
1122 return memcmp(hdr->sig, g_fwu_signature, FWU_SIG_SIZE) == 0;
1123} 90}
1124 91
1125/** 92/**
@@ -1230,7 +197,7 @@ static int do_afi(uint8_t *buf, int size)
1230 else 197 else
1231 { 198 {
1232 cprintf(RED, " Mismatch\n"); 199 cprintf(RED, " Mismatch\n");
1233 let_the_force_flow(__LINE__); 200 return 1;
1234 } 201 }
1235 202
1236 cprintf_field(" Vendor ID: ", "0x%x\n", afi->hdr.vendor_id); 203 cprintf_field(" Vendor ID: ", "0x%x\n", afi->hdr.vendor_id);
@@ -1249,7 +216,7 @@ static int do_afi(uint8_t *buf, int size)
1249 else 216 else
1250 { 217 {
1251 cprintf(RED, " Error (file too small)\n"); 218 cprintf(RED, " Error (file too small)\n");
1252 let_the_force_flow(__LINE__); 219 return 1;
1253 } 220 }
1254 221
1255 cprintf_field(" Reserved: ", "%x %x %x\n", afi->hdr.res[0], 222 cprintf_field(" Reserved: ", "%x %x %x\n", afi->hdr.res[0],
@@ -1301,7 +268,7 @@ static int do_afi(uint8_t *buf, int size)
1301 return 0; 268 return 0;
1302} 269}
1303 270
1304bool check_afi(uint8_t *buf, int size) 271bool afi_check(uint8_t *buf, int size)
1305{ 272{
1306 struct afi_hdr_t *hdr = (void *)buf; 273 struct afi_hdr_t *hdr = (void *)buf;
1307 274
@@ -1420,7 +387,7 @@ static int do_fw(uint8_t *buf, int size)
1420 else 387 else
1421 { 388 {
1422 cprintf(RED, " Mismatch\n"); 389 cprintf(RED, " Mismatch\n");
1423 let_the_force_flow(__LINE__); 390 return 1;
1424 } 391 }
1425 392
1426 /* both variants have the same header size, only the fields differ */ 393 /* both variants have the same header size, only the fields differ */
@@ -1454,7 +421,7 @@ static int do_fw(uint8_t *buf, int size)
1454 } 421 }
1455 else 422 else
1456 { 423 {
1457 struct fw_hdr_f0_t *hdr_f0 = (void *)hdr; 424 /* struct fw_hdr_f0_t *hdr_f0 = (void *)hdr; */
1458 cprintf(GREEN, " Header not dumped because format is unclear.\n"); 425 cprintf(GREEN, " Header not dumped because format is unclear.\n");
1459 } 426 }
1460 427
@@ -1534,7 +501,7 @@ int main(int argc, char **argv)
1534 bool try_fwu = false; 501 bool try_fwu = false;
1535 bool try_afi = false; 502 bool try_afi = false;
1536 bool try_fw = false; 503 bool try_fw = false;
1537 bool force_atj2127 = false; 504 enum fwu_mode_t fwu_mode = FWU_AUTO;
1538 505
1539 while(1) 506 while(1)
1540 { 507 {
@@ -1543,7 +510,6 @@ int main(int argc, char **argv)
1543 {"help", no_argument, 0, '?'}, 510 {"help", no_argument, 0, '?'},
1544 {"debug", no_argument, 0, 'd'}, 511 {"debug", no_argument, 0, 'd'},
1545 {"no-color", no_argument, 0, 'c'}, 512 {"no-color", no_argument, 0, 'c'},
1546 {"force", no_argument, 0, 'f'},
1547 {"fwu", no_argument, 0, 'u'}, 513 {"fwu", no_argument, 0, 'u'},
1548 {"afi", no_argument, 0, 'a'}, 514 {"afi", no_argument, 0, 'a'},
1549 {"fw", no_argument, 0, 'w'}, 515 {"fw", no_argument, 0, 'w'},
@@ -1564,8 +530,6 @@ int main(int argc, char **argv)
1564 case 'd': 530 case 'd':
1565 g_debug = true; 531 g_debug = true;
1566 break; 532 break;
1567 case 'f':
1568 g_force = true;
1569 break; 533 break;
1570 case '?': 534 case '?':
1571 usage(); 535 usage();
@@ -1583,7 +547,7 @@ int main(int argc, char **argv)
1583 try_fw = true; 547 try_fw = true;
1584 break; 548 break;
1585 case '2': 549 case '2':
1586 force_atj2127 = true; 550 fwu_mode = FWU_ATJ2127;
1587 break; 551 break;
1588 default: 552 default:
1589 abort(); 553 abort();
@@ -1623,9 +587,9 @@ int main(int argc, char **argv)
1623 fclose(fin); 587 fclose(fin);
1624 588
1625 int ret = -99; 589 int ret = -99;
1626 if(try_fwu || check_fwu(buf, size)) 590 if(try_fwu || fwu_check(buf, size))
1627 ret = do_fwu(buf, size, force_atj2127); 591 ret = do_fwu(buf, size, fwu_mode);
1628 else if(try_afi || check_afi(buf, size)) 592 else if(try_afi || afi_check(buf, size))
1629 ret = do_afi(buf, size); 593 ret = do_afi(buf, size);
1630 else if(try_fw || check_fw(buf, size)) 594 else if(try_fw || check_fw(buf, size))
1631 ret = do_fw(buf, size); 595 ret = do_fw(buf, size);
@@ -1638,8 +602,6 @@ int main(int argc, char **argv)
1638 if(ret != 0) 602 if(ret != 0)
1639 { 603 {
1640 cprintf(GREY, "Error: %d", ret); 604 cprintf(GREY, "Error: %d", ret);
1641 if(!g_force)
1642 cprintf(GREY, " (use --force to force processing)");
1643 printf("\n"); 605 printf("\n");
1644 ret = 2; 606 ret = 2;
1645 } 607 }